shared_examples 'a authenticator' do describe '#authenticate!' do let(:login) { double('login') } if described_class::PROVIDER.eql? 'edx' subject { described_class.new(username, auth_code).authenticate! } elsif described_class::PROVIDER.eql? 'github' subject { described_class.new(auth_state, auth_code).authenticate! } else subject { described_class.new(auth_code).authenticate! } end context "when no login for the #{described_class::PROVIDER} account exists" do let(:login_attributes) do { identification: authenticated_user_data[:email], uid: authenticated_user_data[uid_mapped_field.to_sym], provider: described_class::PROVIDER } end before do allow(Login).to receive(:create!).with(login_attributes).and_return(login) end it "returns a login created from the #{described_class::PROVIDER} account" do expect(subject).to eql(login) end end context "when a login for the #{described_class::PROVIDER} account exists already" do before do expect(Login).to receive(:where).with(identification: authenticated_user_data[:email]).and_return([login]) allow(login).to receive(:update_attributes!).with(uid: authenticated_user_data[uid_mapped_field.to_sym], provider: described_class::PROVIDER) end it "connects the login to the #{described_class::PROVIDER} account" do expect(login).to receive(:update_attributes!).with(uid: authenticated_user_data[uid_mapped_field.to_sym], provider: described_class::PROVIDER) subject end end end end