require 'spec_helper'

describe SimpleTokenAuthentication::EntitiesManager do

  # The 'model' argument is quite vague, as it is for Entity;
  # let's do nothing to solve that undefinition for now.

  it_behaves_like 'an entities manager'

  describe '#find_or_create_entity' do

    before(:each) do
      entity = double()
      allow(entity).to receive(:new).and_return('an Entity instance')
      stub_const('SimpleTokenAuthentication::Entity', entity)

      super_user = double()
      allow(super_user).to receive(:name) # any Ruby class has a name
      stub_const('SuperUser', super_user)
    end

    context 'when a model is provided for the first time', token_authenticatable_aliases_option: true do

      it 'creates an Entity instance for the model', private: true do
        expect(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, nil) # no alias
        expect(subject.find_or_create_entity(SuperUser)).to eq 'an Entity instance'
      end

      context 'even if Entity instances for other models exist', private: true do

        before(:each) do
          # define another model
          admin = double()
          allow(admin).to receive(:name).and_return('Admin')
          stub_const('Admin', admin)
          # ensure its Entity instance exists
          subject.find_or_create_entity(Admin)
          allow(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, nil).and_return('some new Entity instance')
          allow(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, 'some_alias').and_return('some new Entity instance with an alias')
        end

        it 'creates an Entity instance for the model', private: true do
          expect(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, nil)
          expect(subject.find_or_create_entity(SuperUser)).to eq 'some new Entity instance'
        end

        context 'when a model alias was provided' do

          it 'creates an Entity instance with that alias for the model', private: true do
            expect(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, 'some_alias')
            expect(subject.find_or_create_entity(SuperUser, 'some_alias')).to eq 'some new Entity instance with an alias'
          end
        end
      end
    end

    context 'when an Entity instance for that model already exists' do

      before(:each) do
        allow(SuperUser).to receive(:name).and_return('SuperUser')
        subject.find_or_create_entity(SuperUser)

        allow(SimpleTokenAuthentication::Entity).to receive(:new).and_return('some new Entity instance')
      end

      it 'returns that Entity instance', private: true do
        expect(subject.find_or_create_entity(SuperUser)).to eq 'an Entity instance'
      end

      it 'does not create a new Entity instance', private: true do
        expect(SimpleTokenAuthentication::Entity).not_to receive(:new).with(SuperUser)
        subject.find_or_create_entity(SuperUser)
      end
    end
  end
end
