require 'rails_helper' describe Agents::DropboxWatchAgent do before(:each) do @agent = Agents::DropboxWatchAgent.new( name: 'save to dropbox', options: { access_token: '70k3n', dir_to_watch: '/my/dropbox/dir', expected_update_period_in_days: 2 } ) @agent.user = users(:bob) @agent.service = services(:generic) @agent.save! end it 'cannot receive events' do expect(@agent.cannot_receive_events?).to eq true end it 'has agent description' do expect(@agent.description).to_not be_nil end it 'has event description' do expect(@agent.event_description).to_not be_nil end describe '#valid?' do before(:each) { expect(@agent.valid?).to eq true } it 'requires a "dir_to_watch"' do @agent.options[:dir_to_watch] = nil expect(@agent.valid?).to eq false end describe 'expected_update_period_in_days' do it 'needs to be present' do @agent.options[:expected_update_period_in_days] = nil expect(@agent.valid?).to eq false end it 'needs to be a positive integer' do @agent.options[:expected_update_period_in_days] = -1 expect(@agent.valid?).to eq false end end end describe '#check' do let(:first_result) do Dropbox::API::Object.convert( [ { 'path_display' => '1.json', 'rev' => '1', 'server_modified' => '01-01-01' }, { 'path_display' => 'sub_dir_1', '.tag' => 'folder' } ], nil ) end before(:each) do allow(Dropbox::API::Client).to receive(:new) do instance_double(Dropbox::API::Client).tap { |api| allow(api).to receive(:ls).with('/my/dropbox/dir') { first_result } } end end it 'saves the directory listing in its memory' do @agent.check expect(@agent.memory).to eq({"contents"=>[{"path"=>"1.json", "rev"=>"1", "modified"=>"01-01-01"}]}) end context 'first time' do before(:each) { @agent.memory = {} } it 'does not send any events' do expect { @agent.check }.to_not change(Event, :count) end end context 'subsequent calls' do let(:second_result) do Dropbox::API::Object.convert( [ { 'path_display' => '2.json', 'rev' => '1', 'server_modified' => '02-02-02' }, { 'path_display' => 'sub_dir_2', '.tag' => 'folder' } ], nil ) end before(:each) do @agent.memory = { 'contents' => 'not_empty' } allow(Dropbox::API::Client).to receive(:new) do instance_double(Dropbox::API::Client).tap { |api| allow(api).to receive(:ls).with('/my/dropbox/dir') { second_result } } end end it 'sends an event upon a different directory listing' do payload = { 'diff' => 'object as hash' } allow(Agents::DropboxWatchAgent::DropboxDirDiff).to receive(:new).with(@agent.memory['contents'], [{"path"=>"2.json", "rev"=>"1", "modified"=>"02-02-02"}]) do instance_double(Agents::DropboxWatchAgent::DropboxDirDiff).tap { |diff| allow(diff).to receive(:empty?) { false } allow(diff).to receive(:to_hash) { payload } } end expect { @agent.check }.to change(Event, :count).by(1) expect(Event.last.payload).to eq(payload) end it 'does not sent any events when there is no difference on the directory listing' do allow(Agents::DropboxWatchAgent::DropboxDirDiff).to receive(:new).with(@agent.memory['contents'], [{"path"=>"2.json", "rev"=>"1", "modified"=>"02-02-02"}]) do instance_double(Agents::DropboxWatchAgent::DropboxDirDiff).tap { |diff| allow(diff).to receive(:empty?) { true } } end expect { @agent.check }.to_not change(Event, :count) end end end describe Agents::DropboxWatchAgent::DropboxDirDiff do let(:previous) { [ { 'path' => '1.json', 'rev' => '1' }, { 'path' => '2.json', 'rev' => '1' }, { 'path' => '3.json', 'rev' => '1' } ] } let(:current) { [ { 'path' => '1.json', 'rev' => '2' }, { 'path' => '3.json', 'rev' => '1' }, { 'path' => '4.json', 'rev' => '1' } ] } describe '#empty?' do it 'is true when no differences are detected' do diff = Agents::DropboxWatchAgent::DropboxDirDiff.new(previous, previous) expect(diff.empty?).to eq true end it 'is false when differences were detected' do diff = Agents::DropboxWatchAgent::DropboxDirDiff.new(previous, current) expect(diff.empty?).to eq false end end describe '#to_hash' do subject(:diff_hash) { Agents::DropboxWatchAgent::DropboxDirDiff.new(previous, current).to_hash } it 'detects additions' do expect(diff_hash[:added]).to eq [{ 'path' => '4.json', 'rev' => '1' }] end it 'detects removals' do expect(diff_hash[:removed]).to eq [ { 'path' => '2.json', 'rev' => '1' } ] end it 'detects updates' do expect(diff_hash[:updated]).to eq [ { 'path' => '1.json', 'rev' => '2' } ] end context 'when the previous value is not defined' do it 'considers all additions' do diff_hash = Agents::DropboxWatchAgent::DropboxDirDiff.new(nil, current).to_hash expect(diff_hash[:added]).to eq current expect(diff_hash[:removed]).to eq [] expect(diff_hash[:updated]).to eq [] end end context 'when the current value is not defined' do it 'considers all removals' do diff_hash = Agents::DropboxWatchAgent::DropboxDirDiff.new(previous, nil).to_hash expect(diff_hash[:added]).to eq [] expect(diff_hash[:removed]).to eq previous expect(diff_hash[:updated]).to eq [] end end end end end