require 'spec_helper' describe BaseCRM::Sync do let(:device_uuid) { '6dadcec8-6e61-4691-b318-1aab27b8fecf' } let(:session_id) { '29f2aeeb-8d68-4ea7-95c3-a2c8e151f5a3' } subject { BaseCRM::Sync.new(device_uuid: device_uuid, client: client) } describe 'Responds to' do it { should respond_to :fetch } end describe :initialize do describe 'validation' do context 'no device_uuid option' do it 'raises BaseCRM::ConfigurationError exception' do expect { BaseCRM::Sync.new(client: client) }.to raise_error BaseCRM::ConfigurationError end end context 'no client option' do it 'raises BaseCRM::ConfigurationError exception' do expect { BaseCRM::Sync.new(device_uuid: device_uuid) }.to raise_error BaseCRM::ConfigurationError end end context 'required options passed' do it 'raises no exception' do expect { BaseCRM::Sync.new(client: client, device_uuid: device_uuid) }.not_to raise_error end end end end describe :fetch do context 'no block passed' do it 'does nothing' do expect(client).not_to receive(:sync) subject.fetch end end context 'nothing to synchronize' do before :each do expect(client.sync).to receive(:start).with(device_uuid).and_return(nil) end it 'returns early' do expect(subject.fetch { |s, r| :nop }).to be_nil end end context 'fresh data to synchronize' do let(:session) do BaseCRM::SyncSession.new(id: session_id) end let(:ack_keys) do ['User-1234-1', 'Source-1234-1'] end let(:queue_items) do [ [BaseCRM::Meta.new(type: 'user', sync: BaseCRM::SyncMeta.new(event_type: 'created', ack_key: 'User-1234-1')), BaseCRM::User.new(id: 1)], [BaseCRM::Meta.new(type: 'source', sync: BaseCRM::SyncMeta.new(event_type: 'created', ack_key: 'Source-1234-1')), BaseCRM::Source.new(id: 1)] ] end before :each do expect(client.sync).to receive(:start).with(device_uuid).and_return(session) expect(client.sync).to receive(:fetch).with(device_uuid, session_id).and_return(queue_items) expect(client.sync).to receive(:fetch).with(device_uuid, session_id).and_return([]) expect(client.sync).to receive(:fetch).with(device_uuid, session_id).and_return(nil) expect(client.sync).to receive(:ack).with(device_uuid, ack_keys).and_return(true) end it 'does whole synchronization flow' do subject.fetch { |m, r| m.sync.ack } end it 'calls a provided block as many times as items in the queue' do counter = 0 subject.fetch { |m, r| counter += 1; m.sync.ack } expect(counter).to eq(2) end it 'passes two elements to provided block: first element is BaseCRM::SyncMeta and the second is a resource' do subject.fetch do |m, r| expect(m).to be_a BaseCRM::Meta expect(m.sync).to be_a BaseCRM::SyncMeta m.sync.ack end end end end end