# frozen_string_literal: true require 'intranet/pictures/json_db_provider' RSpec.describe Intranet::Pictures::JsonDbProvider do describe '.initialize' do it 'should propagate the filesystem exceptions' do file = File.join(__dir__, 'non-existant.json') expect { described_class.new(file) }.to raise_error(Errno::ENOENT) end it 'should propagate the JSON parser exceptions (file format)' do file = __FILE__ expect { described_class.new(file) }.to raise_error(JSON::ParserError) end end describe '#title' do before do @provider = described_class.new(File.join(__dir__, 'sample-db.json')) end it 'should return the gallery title' do expect(@provider.title).to eql('My Gallery') end end describe '#list_pictures' do before do @provider = described_class.new(File.join(__dir__, 'sample-db.json')) end it 'should return the list of pictures without the uri key' do expect(@provider.list_pictures).to eql( [ { 'datetime' => '2019:07:22 09:41:31', 'author' => 'John Doe', 'location' => 'Paris, France', 'camera' => 'Apple iPhone 11' }, { 'datetime' => '2020:06:19 07:51:05', 'flash' => false, 'author' => 'Jane Doe', 'location' => 'Tokyo, Japan' }, { 'datetime' => '2020:06:20 18:14:09', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'New York, USA' }, { 'datetime' => '2020:06:20 06:09:54', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'Paris, France', 'camera' => 'Canon EOS 5D MARK IV' }, { 'datetime' => '2019:07:22 09:45:17', 'author' => 'John Doe', 'location' => 'Tokyo, Japan' } ] ) end it 'should return only the pictures matching the given selector' do selector = { 'author' => 'Jane Doe' } expect(@provider.list_pictures(selector)).to eql( [ { 'datetime' => '2020:06:19 07:51:05', 'flash' => false, 'author' => 'Jane Doe', 'location' => 'Tokyo, Japan' }, { 'datetime' => '2020:06:20 18:14:09', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'New York, USA' }, { 'datetime' => '2020:06:20 06:09:54', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'Paris, France', 'camera' => 'Canon EOS 5D MARK IV' } ] ) end context 'given a valid +sort_by+ key' do it 'should sort the pictures by the given key' do selector = { 'author' => 'Jane Doe' } expect(@provider.list_pictures(selector, 'location')).to eql( [ { 'datetime' => '2020:06:20 18:14:09', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'New York, USA' }, { 'datetime' => '2020:06:20 06:09:54', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'Paris, France', 'camera' => 'Canon EOS 5D MARK IV' }, { 'datetime' => '2020:06:19 07:51:05', 'flash' => false, 'author' => 'Jane Doe', 'location' => 'Tokyo, Japan' } ] ) expect(@provider.list_pictures(selector, 'datetime', false)).to eql( [ { 'datetime' => '2020:06:20 18:14:09', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'New York, USA' }, { 'datetime' => '2020:06:20 06:09:54', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'Paris, France', 'camera' => 'Canon EOS 5D MARK IV' }, { 'datetime' => '2020:06:19 07:51:05', 'flash' => false, 'author' => 'Jane Doe', 'location' => 'Tokyo, Japan' } ] ) end end context 'given an invalid +sort_by+ key' do it 'should raise KeyError' do expect { @provider.list_pictures({}, 'invalid') }.to raise_error(KeyError) end end end describe '#picture' do before do @provider = described_class.new(File.join(__dir__, 'sample-db.json')) end context 'when +selector+ matches exactly one picture, with +uri+ pointing to a valid image file' do it 'should return the file mime type and content' do selector = { 'uri' => 'white.jpg' } expect(@provider.picture(selector)).to eql( ['image/jpeg', File.read(File.join(__dir__, 'white.jpg'))] ) selector = { 'uri' => './alpha.png' } expect(@provider.picture(selector)).to eql( ['image/png', File.read(File.join(__dir__, 'alpha.png'))] ) end end context 'when +selector+ matches exactly one picture, with a +uri+ pointing to a non-existing file' do it 'should raise KeyError' do selector = { 'uri' => 'pic3.jpg' } expect { @provider.picture(selector) }.to raise_error(KeyError) end end context 'when +selector+ matches exactly one picture, with a +uri+ pointing to a non-image file' do it 'should raise KeyError' do selector = { 'uri' => 'sample-db.json' } expect { @provider.picture(selector) }.to raise_error(KeyError) end end context 'when +selector+ matches exactly one picture, with +uri+ not defined' do it 'should raise KeyError' do selector = { 'datetime' => '2019:07:22 09:45:17' } expect { @provider.picture(selector) }.to raise_error(KeyError) end end context 'when +selector+ matches zero or more than one picture' do it 'should raise KeyError' do selector = { 'author' => 'Jane Doe' } expect { @provider.picture(selector) }.to raise_error(KeyError) selector = { 'uri' => 'black.jpg' } expect { @provider.picture(selector) }.to raise_error(KeyError) end end end describe '#group_thumbnail' do before do @provider = described_class.new(File.join(__dir__, 'sample-db.json')) end context 'when +key+ and +value+ designate one group with +uri+ pointing to a valid image file' do it 'should return the thumbnail file mime type and content' do expect(@provider.group_thumbnail('author', 'John Doe')).to eql( ['image/jpeg', File.read(File.join(__dir__, 'white.jpg'))] ) expect(@provider.group_thumbnail('location', 'New York, USA')).to eql( ['image/png', File.read(File.join(__dir__, 'alpha.png'))] ) end end context 'when +key+ and +value+ designate one group with a +uri+ pointing to a non-existing file' do it 'should raise KeyError' do expect { @provider.group_thumbnail('author', 'Jane Doe') }.to raise_error(KeyError) end end context 'when +key+ and +value+ designate one group with +uri+ not defined' do it 'should return nil' do expect(@provider.group_thumbnail('location', 'Paris, France')).to be_nil end end context 'when +key+ and +value+ do not designate an existing group' do it 'should raise KeyError' do expect { @provider.group_thumbnail('author', 'invalid') }.to raise_error(KeyError) end end end describe '#group_brief' do before do @provider = described_class.new(File.join(__dir__, 'sample-db.json')) end context 'when +key+ and +value+ designate one group with a brief text' do it 'should return the brief text' do expect(@provider.group_brief('author', 'John Doe')).to eql('Best photographer ever') expect(@provider.group_brief('location', 'Paris, France')).to eql('The City of Light') end end context 'when +key+ and +value+ designate one group without a brief text' do it 'should return an empty string' do expect(@provider.group_brief('author', 'Jane Doe')).to be_empty end end context 'when +key+ and +value+ do not designate an existing group' do it 'should raise KeyError' do expect { @provider.group_brief('author', 'invalid') }.to raise_error(KeyError) end end end end