# frozen_string_literal: true module NulogySSO RSpec.describe Authenticator do let(:sso_config) { NulogySSO.sso_config } let(:verifier) do MockAuth0Verifier.new( issuer: "#{sso_config.base_uri}/", audience: sso_config.audience, jwks: jwt_test_helper.jwks_json ) end let(:default_authenticator) { Authenticator.new(verifier: verifier, find_user_by_email: find_a_user) } let(:user) { User.new(email: email) } let(:find_a_user) { proc { user } } let(:find_no_user) { proc { nil } } let(:on_success) { spy("on_success") } let(:on_invalid_token) { spy("on_invalid_token") } let(:email) { "sso_test@nulogy.com" } let(:valid_signed_token) { jwt_test_helper.jwt(email) } let(:invalid_signed_token) { jwt_test_helper.jwt(email, "exp" => 1.day.ago.to_i) } let(:jwt_test_helper) { TestUtilities::JwtTestHelper.new } describe "#validate_token" do it "calls on_invalid_token when the access token is blank" do [nil, "", false].each(&method(:validate_token)) expect(on_invalid_token).to have_received(:call).exactly(3).times.with(NulogySSO::Authenticator::MissingTokenError) end context "JWT passes verification" do it "calls the success handler when a user matching the access token email exists" do validate_token(valid_signed_token) expect(on_success).to have_received(:call).with( a_hash_including(JWT_EMAIL_KEY => email) ).once expect(on_invalid_token).not_to have_received(:call) end it "calls the invalid token handler when there is no user matching the access token email" do authenticator = Authenticator.new(verifier: verifier, find_user_by_email: find_no_user) validate_token(valid_signed_token, authenticator: authenticator) expect(on_invalid_token).to have_received(:call).once.with(NulogySSO::Authenticator::MissingUserError) end end context "JWT fails verification" do it "calls the invalid token handler" do validate_token(invalid_signed_token) expect(on_invalid_token).to have_received(:call).once.with(NulogySSO::Authenticator::InvalidTokenError) end end def validate_token(raw_access_token, authenticator: default_authenticator) authenticator.validate_token( raw_access_token, on_success: on_success, on_invalid_token: on_invalid_token ) end end describe "#authenticated_user" do it "returns the user that is associated to a valid JWT" do expect(default_authenticator.authenticated_user(valid_signed_token)).to eq(user) end it "returns nil when the JWT is invalid" do expect(default_authenticator.authenticated_user(invalid_signed_token)).to be_nil end it "returns nil when the provided token is blank" do expect(default_authenticator.authenticated_user("")).to be_nil end it "returns nil when no user matching the JWT's email field exists" do authenticator = Authenticator.new(verifier: verifier, find_user_by_email: find_no_user) expect(authenticator.authenticated_user(valid_signed_token)).to be_nil end end end end