diff --git a/spec/config/initializers/omniauth_spec.rb b/spec/config/initializers/omniauth_spec.rb new file mode 100644 index 00000000..2da707b4 --- /dev/null +++ b/spec/config/initializers/omniauth_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +RSpec.describe 'OmniAuth::Shibboleth Configuration' do + # set up mock shibboleth_config data + let(:shibboleth_config) do + { + host: 'medusatest.library.illinois.edu', + uid_field: 'eppn', + extra_fields: %w[eppn givenName mail org_dn sn telephoneNumber uid entitlement unscoped_affiliation], + request_type: 'header', + info_fields: { email: 'mail' } + } + end + + before do + # Mock Settings.shibboleth call and create the mocked object + allow(Settings).to receive(:shibboleth).and_return(OpenStruct.new(shibboleth_config)) + @strategy = OmniAuth::Strategies::Shibboleth.new(nil, shibboleth_config.symbolize_keys) + end + + it 'configures the Shibboleth provider with the correct settings' do + expect(@strategy.options[:host]).to eq('medusatest.library.illinois.edu') + expect(@strategy.options[:uid_field]).to eq('eppn') + expect(@strategy.options[:extra_fields]).to eq(%w[eppn givenName mail org_dn sn telephoneNumber uid entitlement unscoped_affiliation]) + expect(@strategy.options[:request_type]).to eq('header') + expect(@strategy.options[:info_fields]).to eq('email' => 'mail') + end +end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb new file mode 100644 index 00000000..f4decbe2 --- /dev/null +++ b/spec/controllers/sessions_controller_spec.rb @@ -0,0 +1,94 @@ +require 'rails_helper' + +RSpec.describe SessionsController, type: :controller do + describe 'GET #new' do + context 'in production environment' do + before { allow(Rails.env).to receive(:production?).and_return(true) } + + it 'saves the referring page in the session' do + request.env['HTTP_REFERER'] = '/login/page' + get :new + expect(session[:login_return_referer]).to eq('/login/page') + end + + it 'redirects to the Shibboleth login path' do + mocked_url = 'mock-shibboleth.local' + allow(MedusaCollectionRegistry::Application).to receive(:shibboleth_host).and_return(mocked_url) + get :new + expected_redirect_url = "/Shibboleth.sso/Login?target=https://#{mocked_url}/auth/shibboleth/callback" + expect(response).to redirect_to(expected_redirect_url) + end + end + + context 'in non-production environment' do + before { allow(Rails.env).to receive(:production?).and_return(false) } + + it 'redirects to /auth/identity' do + get :new + expect(response).to redirect_to('/auth/identity') + end + end + end + + describe 'POST #create' do + context 'in production environment' do + before do + allow(Rails.env).to receive(:production?).and_return(true) + OmniAuth.config.test_mode = true + session[:login_return_uri] = '/dashboard' + end + + after do + OmniAuth.config.test_mode = false + OmniAuth.config.mock_auth[:shibboleth] = nil + end + + it 'authenticates the user and sets the session' do + OmniAuth.config.mock_auth[:shibboleth] = OmniAuth::AuthHash.new({ + provider: 'shibboleth', + uid: 'testuser@illinois.edu', + info: { email: 'testuser@illinois.edu' } + }) + request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:shibboleth] + post :create, params: { provider: 'shibboleth' } + user = User.find_by(uid: 'testuser@illinois.edu') + expect(user).to be_present + expect(session[:current_user_id]).to eq(user.id) + expect(response).to redirect_to('/dashboard') + end + + it 'redirects to login if Shibboleth attributes are missing' do + OmniAuth.config.mock_auth[:shibboleth] = OmniAuth::AuthHash.new({ + provider: 'shibboleth', + uid: nil, + info: { email: nil } + }) + request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:shibboleth] + post :create, params: { provider: 'shibboleth' } + expect(session[:current_user_id]).to be_nil + expect(response).to redirect_to(login_url) + end + end + + context 'in development environment' do + before do + allow(Rails.env).to receive(:production?).and_return(false) + end + + it 'authenticates the user in development mode' do + post :create, params: { provider: 'identity', auth_key: 'testuser@illinois.edu' } + user = User.find_by(uid: 'testuser@illinois.edu') + expect(user).to be_present + expect(session[:current_user_id]).to eq(user.id) + expect(response).to redirect_to(root_path) + end + + it 'redirects to login if auth_key is missing' do + request.params['auth_key'] = nil + post :create, params: { provider: 'identity' } + expect(session[:user_id]).to be_nil + expect(response).to redirect_to(login_url) + end + end + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb new file mode 100644 index 00000000..59a29722 --- /dev/null +++ b/spec/models/user_spec.rb @@ -0,0 +1,63 @@ +require 'rails_helper' + +RSpec.describe User, type: :model do + describe 'User creation' do + let(:user_attributes) do + { + uid: 'testuser@illinois.edu', + email: 'testuser@illinois.edu' + } + end + + context 'when creating a new user' do + it 'creates a user with the correct attributes' do + user = User.create!( + uid: user_attributes[:uid], + email: user_attributes[:email] + ) + + expect(user).to be_persisted + expect(user.uid).to eq('testuser@illinois.edu') + expect(user.email).to eq('testuser@illinois.edu') + end + end + + context 'when a user already exists with the same uid' do + it 'does not create a duplicate user' do + existing_user = User.create!( + uid: user_attributes[:uid], + email: user_attributes[:email] + ) + + expect { + User.create!( + uid: user_attributes[:uid], + email: user_attributes[:email] + ) + }.to raise_error(ActiveRecord::RecordInvalid, /Uid has already been taken/) + + expect(User.count).to eq(1) + expect(User.first).to eq(existing_user) + end + end + + context 'when a user already exists with the same email' do + it 'does not create a duplicate user' do + existing_user = User.create!( + uid: 'differentuid@illinois.edu', + email: user_attributes[:email] + ) + + expect { + User.create!( + uid: user_attributes[:uid], + email: user_attributes[:email] + ) + }.to raise_error(ActiveRecord::RecordInvalid, /Email has already been taken/) + + expect(User.count).to eq(1) + expect(User.first).to eq(existing_user) + end + end + end +end