# frozen_string_literal: true require 'intranet/core' require 'intranet/logger' require 'intranet/abstract_responder' require 'intranet/pictures/responder' RSpec.describe Intranet::Pictures::Responder do it 'should inherit from Intranet::AbstractResponder' do expect(described_class.superclass).to eql(Intranet::AbstractResponder) end it 'should define its name, version and homepage' do expect { described_class.module_name }.not_to raise_error expect { described_class.module_version }.not_to raise_error expect { described_class.module_homepage }.not_to raise_error end before do logger = Intranet::Logger.new(Intranet::Logger::FATAL) @core = Intranet::Core.new(logger) @provider = Intranet::Pictures::JsonDbProvider.new(File.join(__dir__, 'sample-db.json')) @responder = described_class.new(@provider) @core.register_module( @responder, ['pictures'], File.absolute_path('../../../lib/intranet/resources', __dir__) ) end describe '#in_menu?' do it 'should return the value provided at initialization' do expect(described_class.new(nil, [], [], false).in_menu?).to be false expect(described_class.new(nil, [], [], true).in_menu?).to be true end end describe '#resources_dir' do it 'should return the absolute path of the resources directory' do expect(described_class.new(nil, [], [], false).resources_dir).to eql( File.absolute_path('../../../lib/intranet/resources', __dir__) ) end end describe '#title' do it 'should return the title of the webpage provided by the module' do expect(@responder.title).to eql('My Gallery') end end describe '#css_dependencies' do it 'should return the list of CSS dependencies' do expect(@responder.css_dependencies).to include( 'design/style.css', 'design/photoswipe/photoswipe.css', 'design/photoswipe/default-skin/default-skin.css' ) end end describe '#js_dependencies' do it 'should return the list of JavaScript dependencies' do expect(@responder.js_dependencies).to include( 'design/jpictures.js', 'design/photoswipe/photoswipe.min.js', 'design/photoswipe/photoswipe-ui-default.min.js' ) end end describe '#generate_page' do def photoswipe_markup # rubocop:disable Metrics/MethodLength "\n\n" end context 'when asked for \'/index.html\'' do it 'should return a partial HTML content showing recent groups according to configuration' do # Nominal case with limit recents = [{ group_type: 'group2', sort_by: 'value', asc: false, limit: 2 }] @responder.instance_variable_set(:@recents, recents) code, mime, content = @responder.generate_page('/index.html', {}) expect(code).to eql(206) expect(mime).to eql('text/html') expect(content).to eql( { content: "
\n

My Gallery

\n" \ "\n\n" \ "

#{I18n.t('pictures.recents.group2')}

\n" \ "\n" \ "

\n#{I18n.t('pictures.see_more')}\n

\n" \ "
\n" + photoswipe_markup, title: 'My Gallery' } ) # Nominal case with limit recents = [{ group_type: 'group2', sort_by: 'value', asc: true, limit: 2 }] @responder.instance_variable_set(:@recents, recents) code, mime, content = @responder.generate_page('/index.html', {}) expect(code).to eql(206) expect(mime).to eql('text/html') expect(content).to eql( { content: "
\n

My Gallery

\n" \ "\n\n" \ "

#{I18n.t('pictures.recents.group2')}

\n" \ "\n" \ "

\n#{I18n.t('pictures.see_more')}\n

\n" \ "
\n" + photoswipe_markup, title: 'My Gallery' } ) # Nominal case without limit recents = [{ group_type: 'group2' }] @responder.instance_variable_set(:@recents, recents) code, mime, content = @responder.generate_page('/index.html', {}) expect(code).to eql(206) expect(mime).to eql('text/html') expect(content).to eql( { content: "
\n

My Gallery

\n" \ "\n\n" \ "

#{I18n.t('pictures.recents.group2')}

\n" \ "\n" \ "
\n" + photoswipe_markup, title: 'My Gallery' } ) # Incorrect recents specification recents = [{ group_type: 'invalid', sort_by: 'id' }] @responder.instance_variable_set(:@recents, recents) code, mime, content = @responder.generate_page('/index.html', {}) expect(code).to eql(404) expect(mime).to be_empty expect(content).to be_empty end it 'should return a partial HTML content showing all groups according to configuration' do # Nominal case without recents home_groups = [{ group_type: 'group2', asc: true, browse: 'group1', browse_sort_by: 'uri', browse_asc: true }] @responder.instance_variable_set(:@home_groups, home_groups) code, mime, content = @responder.generate_page('/index.html', {}) expect(code).to eql(206) expect(mime).to eql('text/html') expect(content).to eql( { content: "
\n

My Gallery

\n" \ "\n\n" \ "

#{I18n.t('pictures.browse_by.group2')}

\n" \ "\n" \ "
\n", title: 'My Gallery' } ) # Nominal case with recents recents = [{ group_type: 'group2' }] @responder.instance_variable_set(:@recents, recents) home_groups = [{ group_type: 'group1', asc: false, browse: 'group2', browse_sort_by: 'value', browse_asc: false }] @responder.instance_variable_set(:@home_groups, home_groups) code, mime, content = @responder.generate_page('/index.html', {}) expect(code).to eql(206) expect(mime).to eql('text/html') expect(content).to eql( { content: "
\n

My Gallery

\n" \ "\n\n" \ "

#{I18n.t('pictures.recents.group2')}

\n" \ "\n" \ "

#{I18n.t('pictures.browse_by.group1')}

\n" \ "\n" \ "
\n" + photoswipe_markup, title: 'My Gallery' } ) end end context 'when asked for \'/browse_*.html\'' do it 'should return a partial HTML content with selected groups' do # Existing group, no selector nor sort order query = {} code, mime, content = @responder.generate_page('/browse_group1.html', query) expect(code).to eql(206) expect(mime).to eql('text/html') expect(content).to eql( { content: "
\n

My Gallery

\n" \ "\n\n" \ "\n" \ "
\n" + photoswipe_markup, title: 'My Gallery' } ) # Existing group, valid selector, valid sort order query = { 'group1' => 'group1_title1', 'sort_by' => 'id', 'sort_order' => 'desc' } code, mime, content = @responder.generate_page('/browse_group2.html', query) expect(code).to eql(206) expect(mime).to eql('text/html') expect(content).to eql( { content: "
\n

My Gallery

\n" \ "\n\n" \ "\n" \ "
\n" + photoswipe_markup, title: 'My Gallery' } ) # Invalid selector query = { 'foo' => 'bar' } code, mime, content = @responder.generate_page('/browse_group2.html', query) expect(code).to eql(206) expect(mime).to eql('text/html') expect(content).to eql( { content: "
\n

My Gallery

\n" \ "\n\n" \ "\n" \ "
\n" + photoswipe_markup, title: 'My Gallery' } ) # Invalid group type code, mime, content = @responder.generate_page('/browse_foo.html', {}) expect(code).to eql(404) expect(mime).to be_empty expect(content).to be_empty # Invalid sort order query = { 'sort_order' => 'foo' } code, mime, content = @responder.generate_page('/browse_group2.html', query) expect(code).to eql(404) expect(mime).to be_empty expect(content).to be_empty end end context 'when asked for \'/api/groups\'' do it 'should return a JSON representation of the selected groups' do # Existing group, no selector nor sort order query = {} code, mime, content = @responder.generate_page('/api/groups/group1', query) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql( [ { 'id' => 'group1_title1', 'title' => 'Group 1, Title 1', 'brief' => 'brief_text_1' }, { 'id' => 'group1_title2', 'title' => 'Group 1, Title 2' } ].to_json ) # Existing group, valid selector, no sort order query = { 'group1' => 'group1_title1' } code, mime, content = @responder.generate_page('/api/groups/group2', query) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql( [ { 'id' => 'group2_title2', 'title' => 'Group 2, Title 2', 'value' => 'bcde', 'brief' => 'brief_text_2' }, { 'id' => 'group2_title3', 'title' => 'Group 2, Title 3', 'value' => 'aabb' } ].to_json ) # Existing group, valid selector, valid sort order query = { 'group1' => 'group1_title1', 'sort_by' => 'value', 'sort_order' => 'asc' } code, mime, content = @responder.generate_page('/api/groups/group2', query) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql( [ { 'id' => 'group2_title3', 'title' => 'Group 2, Title 3', 'value' => 'aabb' }, { 'id' => 'group2_title2', 'title' => 'Group 2, Title 2', 'value' => 'bcde', 'brief' => 'brief_text_2' } ].to_json ) query = { 'group1' => 'group1_title1', 'sort_by' => 'id', 'sort_order' => 'desc' } code, mime, content = @responder.generate_page('/api/groups/group2', query) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql( [ { 'id' => 'group2_title3', 'title' => 'Group 2, Title 3', 'value' => 'aabb' }, { 'id' => 'group2_title2', 'title' => 'Group 2, Title 2', 'value' => 'bcde', 'brief' => 'brief_text_2' } ].to_json ) # Invalid selector query = { 'foo' => 'bar' } code, mime, content = @responder.generate_page('/api/groups/group2', query) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql([].to_json) # Invalid group type code, mime, content = @responder.generate_page('/api/groups/foo', {}) expect(code).to eql(404) expect(mime).to be_empty expect(content).to be_empty # Invalid sort order query = { 'sort_order' => 'foo' } code, mime, content = @responder.generate_page('/api/groups/group2', query) expect(code).to eql(404) expect(mime).to be_empty expect(content).to be_empty end end context 'when asked for \'/api/group\'' do it 'should return the selected group thumnail' do # Existing group with thumbnail query = { 'group2' => 'group2_title1' } code, mime, content = @responder.generate_page('/api/group/group2', query) expect(code).to eql(200) expect(mime).to eql('image/png') expect(content).to eql(File.read(File.join(__dir__, 'alpha.png'))) # Existing group with no specified thumbnail query = { 'group2' => 'group2_title2' } code, mime, content = @responder.generate_page('/api/group/group2', query) expect(code).to eql(200) expect(mime).to eql('image/jpeg') expect(content).to eql( File.read(File.join(__dir__, '../../../lib/intranet/resources/www/group_thumbnail.jpg')) ) # Existing group with non-existant thumbnail query = { 'group1' => 'group1_title2' } code, mime, content = @responder.generate_page('/api/group/group1', query) expect(code).to eql(404) expect(mime).to be_empty expect(content).to be_empty end end context 'when asked for \'/api/pictures\'' do it 'should return a JSON representation of the selected pictures' do # All pictures (no selector nor sort order) code, mime, content = @responder.generate_page('/api/pictures', {}) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql( [ { 'datetime' => '2019:07:22 09:41:31', 'group1' => 'group1_title1', 'group2' => 'group2_title2' }, { 'datetime' => '2020:06:19 07:51:05', 'value' => false, 'group1' => 'group1_title2', 'group2' => 'group2_title2' }, { 'datetime' => '2020:06:20 18:14:09', 'value' => true, 'group1' => 'group1_title2', 'group2' => 'group2_title1' }, { 'datetime' => '2020:06:20 06:09:54', 'value' => true, 'group1' => 'group1_title2', 'group2' => 'group2_title3' }, { 'datetime' => '2019:07:22 09:45:17', 'group1' => 'group1_title1', 'group2' => 'group2_title3' } ].to_json ) # Valid selector, no sort order query = { 'group1' => 'group1_title2', 'value' => true } code, mime, content = @responder.generate_page('/api/pictures', query) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql( [ { 'datetime' => '2020:06:20 18:14:09', 'value' => true, 'group1' => 'group1_title2', 'group2' => 'group2_title1' }, { 'datetime' => '2020:06:20 06:09:54', 'value' => true, 'group1' => 'group1_title2', 'group2' => 'group2_title3' } ].to_json ) # Valid selector, valid sort order query = { 'group1' => 'group1_title2', 'value' => true, 'sort_by' => 'datetime' } code, mime, content = @responder.generate_page('/api/pictures', query) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql( [ { 'datetime' => '2020:06:20 06:09:54', 'value' => true, 'group1' => 'group1_title2', 'group2' => 'group2_title3' }, { 'datetime' => '2020:06:20 18:14:09', 'value' => true, 'group1' => 'group1_title2', 'group2' => 'group2_title1' } ].to_json ) query = { 'group1' => 'group1_title2', 'value' => true, 'sort_by' => 'group2', 'sort_order' => 'desc' } code, mime, content = @responder.generate_page('/api/pictures', query) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql( [ { 'datetime' => '2020:06:20 06:09:54', 'value' => true, 'group1' => 'group1_title2', 'group2' => 'group2_title3' }, { 'datetime' => '2020:06:20 18:14:09', 'value' => true, 'group1' => 'group1_title2', 'group2' => 'group2_title1' } ].to_json ) # Invalid selector query = { 'a' => 'b' } code, mime, content = @responder.generate_page('/api/pictures', query) expect(code).to eql(200) expect(mime).to eql('application/json') expect(content).to eql([].to_json) # Invalid sort order query = { 'sort_order' => 'foo' } code, mime, content = @responder.generate_page('/api/pictures', query) expect(code).to eql(404) expect(mime).to be_empty expect(content).to be_empty end end context 'when asked for \'/api/picture\'' do it 'should return the selected picture' do # Existing picture query = { 'uri' => 'white.jpg' } code, mime, content = @responder.generate_page('/api/picture', query) expect(code).to eql(200) expect(mime).to eql('image/jpeg') expect(content).to eql(File.read(File.join(__dir__, 'white.jpg'))) # Invalid selector query = { 'value' => true } code, mime, content = @responder.generate_page('/api/picture', query) expect(code).to eql(404) expect(mime).to be_empty expect(content).to be_empty end end context 'otherwise' do it 'should return an HTTP 404 error' do expect(@responder.generate_page('index.html', {})).to eql([404, '', '']) expect(@responder.generate_page('/api/groups', {})).to eql([404, '', '']) expect(@responder.generate_page('/api/group', {})).to eql([404, '', '']) expect(@responder.generate_page('/api/pictures/foo', {})).to eql([404, '', '']) end end end end