# frozen_string_literal: true require 'spec_helper' describe Split::Persistence::DualAdapter do let(:context) { 'some context' } let(:logged_in_adapter_instance) { double } let(:logged_in_adapter) do Class.new.tap { |c| allow(c).to receive(:new) { logged_in_adapter_instance } } end let(:logged_out_adapter_instance) { double } let(:logged_out_adapter) do Class.new.tap { |c| allow(c).to receive(:new) { logged_out_adapter_instance } } end context 'when fallback_to_logged_out_adapter is false' do context 'when logged in' do subject do described_class.with_config( logged_in: lambda { |context| true }, logged_in_adapter: logged_in_adapter, logged_out_adapter: logged_out_adapter, fallback_to_logged_out_adapter: false ).new(context) end it '#[]=' do expect(logged_in_adapter_instance).to receive(:[]=).with('my_key', 'my_value') expect_any_instance_of(logged_out_adapter).not_to receive(:[]=) subject['my_key'] = 'my_value' end it '#[]' do expect(logged_in_adapter_instance).to receive(:[]).with('my_key') { 'my_value' } expect_any_instance_of(logged_out_adapter).not_to receive(:[]) expect(subject['my_key']).to eq('my_value') end it '#delete' do expect(logged_in_adapter_instance).to receive(:delete).with('my_key') { 'my_value' } expect_any_instance_of(logged_out_adapter).not_to receive(:delete) expect(subject.delete('my_key')).to eq('my_value') end it '#keys' do expect(logged_in_adapter_instance).to receive(:keys) { ['my_value'] } expect_any_instance_of(logged_out_adapter).not_to receive(:keys) expect(subject.keys).to eq(['my_value']) end end context 'when logged out' do subject do described_class.with_config( logged_in: lambda { |context| false }, logged_in_adapter: logged_in_adapter, logged_out_adapter: logged_out_adapter, fallback_to_logged_out_adapter: false ).new(context) end it '#[]=' do expect_any_instance_of(logged_in_adapter).not_to receive(:[]=) expect(logged_out_adapter_instance).to receive(:[]=).with('my_key', 'my_value') subject['my_key'] = 'my_value' end it '#[]' do expect_any_instance_of(logged_in_adapter).not_to receive(:[]) expect(logged_out_adapter_instance).to receive(:[]).with('my_key') { 'my_value' } expect(subject['my_key']).to eq('my_value') end it '#delete' do expect_any_instance_of(logged_in_adapter).not_to receive(:delete) expect(logged_out_adapter_instance).to receive(:delete).with('my_key') { 'my_value' } expect(subject.delete('my_key')).to eq('my_value') end it '#keys' do expect_any_instance_of(logged_in_adapter).not_to receive(:keys) expect(logged_out_adapter_instance).to receive(:keys) { ['my_value', 'my_value2'] } expect(subject.keys).to eq(['my_value', 'my_value2']) end end end context 'when fallback_to_logged_out_adapter is true' do context 'when logged in' do subject do described_class.with_config( logged_in: lambda { |context| true }, logged_in_adapter: logged_in_adapter, logged_out_adapter: logged_out_adapter, fallback_to_logged_out_adapter: true ).new(context) end it '#[]=' do expect(logged_in_adapter_instance).to receive(:[]=).with('my_key', 'my_value') expect(logged_out_adapter_instance).to receive(:[]=).with('my_key', 'my_value') expect(logged_out_adapter_instance).to receive(:[]).with('my_key') { nil } subject['my_key'] = 'my_value' end it '#[]' do expect(logged_in_adapter_instance).to receive(:[]).with('my_key') { 'my_value' } expect_any_instance_of(logged_out_adapter).not_to receive(:[]) expect(subject['my_key']).to eq('my_value') end it '#delete' do expect(logged_in_adapter_instance).to receive(:delete).with('my_key') { 'my_value' } expect(logged_out_adapter_instance).to receive(:delete).with('my_key') { 'my_value' } expect(subject.delete('my_key')).to eq('my_value') end it '#keys' do expect(logged_in_adapter_instance).to receive(:keys) { ['my_value'] } expect(logged_out_adapter_instance).to receive(:keys) { ['my_value', 'my_value2'] } expect(subject.keys).to eq(['my_value', 'my_value2']) end end context 'when logged out' do subject do described_class.with_config( logged_in: lambda { |context| false }, logged_in_adapter: logged_in_adapter, logged_out_adapter: logged_out_adapter, fallback_to_logged_out_adapter: true ).new(context) end it '#[]=' do expect_any_instance_of(logged_in_adapter).not_to receive(:[]=) expect(logged_out_adapter_instance).to receive(:[]=).with('my_key', 'my_value') expect(logged_out_adapter_instance).to receive(:[]).with('my_key') { nil } subject['my_key'] = 'my_value' end it '#[]' do expect_any_instance_of(logged_in_adapter).not_to receive(:[]) expect(logged_out_adapter_instance).to receive(:[]).with('my_key') { 'my_value' } expect(subject['my_key']).to eq('my_value') end it '#delete' do expect(logged_in_adapter_instance).to receive(:delete).with('my_key') { 'my_value' } expect(logged_out_adapter_instance).to receive(:delete).with('my_key') { 'my_value' } expect(subject.delete('my_key')).to eq('my_value') end it '#keys' do expect(logged_in_adapter_instance).to receive(:keys) { ['my_value'] } expect(logged_out_adapter_instance).to receive(:keys) { ['my_value', 'my_value2'] } expect(subject.keys).to eq(['my_value', 'my_value2']) end end end describe 'when errors in config' do before { described_class.config.clear } let(:some_proc) { ->{} } it 'when no logged in adapter' do expect{ described_class.with_config( logged_in: some_proc, logged_out_adapter: logged_out_adapter ).new(context) }.to raise_error(StandardError, /:logged_in_adapter/) end it 'when no logged out adapter' do expect{ described_class.with_config( logged_in: some_proc, logged_in_adapter: logged_in_adapter ).new(context) }.to raise_error(StandardError, /:logged_out_adapter/) end it 'when no logged in detector' do expect{ described_class.with_config( logged_in_adapter: logged_in_adapter, logged_out_adapter: logged_out_adapter ).new(context) }.to raise_error(StandardError, /:logged_in$/) end end end