Files
codeocean/spec/controllers/internal_users_controller_spec.rb
Sebastian Serth 99bd46af1a Align project files with CodeHarbor
Since both projects are developed together and by the same team, we also want to have the same code structure and utility methods available in both projects. Therefore, this commit changes many files, but without a functional change.
2023-10-11 00:18:33 +02:00

352 lines
9.6 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe InternalUsersController do
render_views
let(:consumer) { create(:consumer) }
let(:user) { create(:admin, consumer:) }
describe 'GET #activate' do
let(:user) { InternalUser.create(attributes_for(:teacher).merge(consumer:)) }
before do
user.send(:setup_activation)
user.save(validate: false)
end
context 'without a valid activation token' do
before { get :activate, params: {id: user.id} }
expect_redirect(:root)
end
context 'with an already activated user' do
before do
user.activate!
get :activate, params: {id: user.id, token: user.activation_token}
end
expect_redirect(:root)
end
context 'with valid preconditions' do
before { get :activate, params: {id: user.id, token: user.activation_token} }
expect_assigns(user: InternalUser)
expect_http_status(:ok)
expect_template(:activate)
end
end
describe 'PUT #activate' do
let(:user) { InternalUser.create(build(:teacher, consumer:).attributes) }
let(:password) { SecureRandom.hex }
before do
user.send(:setup_activation)
user.save(validate: false)
end
it 'adds an activation token' do
expect(user.activation_token).to be_present
end
context 'without a valid activation token' do
before { put :activate, params: {id: user.id} }
expect_redirect(:root)
end
context 'with an already activated user' do
before do
user.activate!
put :activate, params: {id: user.id, internal_user: {activation_token: user.activation_token, password:, password_confirmation: password}}
end
expect_redirect(:root)
end
context 'without a password' do
before { put :activate, params: {id: user.id, internal_user: {activation_token: user.activation_token}} }
expect_assigns(user: InternalUser)
it 'builds a user with errors' do
expect(assigns(:user).errors).to be_present
end
expect_template(:activate)
end
context 'without a valid password confirmation' do
before { put :activate, params: {id: user.id, internal_user: {activation_token: user.activation_token, password:, password_confirmation: ''}} }
expect_assigns(user: InternalUser)
it 'builds a user with errors' do
expect(assigns(:user).errors).to be_present
end
expect_template(:activate)
end
context 'with valid preconditions' do
before { put :activate, params: {id: user.id, internal_user: {activation_token: user.activation_token, password:, password_confirmation: password}} }
expect_assigns(user: InternalUser)
it 'activates the user' do
expect(assigns[:user]).to be_activated
end
expect_flash_message(:notice, :'internal_users.activate.success')
expect_redirect(:sign_in)
end
end
describe 'POST #create' do
before { allow(controller).to receive(:current_user).and_return(user) }
context 'with a valid internal user' do
let(:perform_request) { proc { post :create, params: {internal_user: build(:teacher).attributes} } }
before { perform_request.call }
expect_assigns(user: InternalUser)
it 'creates the internal user' do
expect { perform_request.call }.to change(InternalUser, :count).by(1)
end
it 'creates an inactive user' do
expect(InternalUser.last).not_to be_activated
end
it 'sets up an activation token' do
expect(InternalUser.last.activation_token).to be_present
end
it 'sends an activation email' do
expect_any_instance_of(InternalUser).to receive(:send_activation_needed_email!)
perform_request.call
end
expect_redirect(InternalUser.last)
end
context 'with an invalid internal user' do
before { post :create, params: {internal_user: {invalid_attribute: 'a string'}} }
expect_assigns(user: InternalUser)
expect_http_status(:ok)
expect_template(:new)
end
end
describe 'DELETE #destroy' do
let(:second_user) { create(:teacher, consumer:) }
let(:third_user) { create(:teacher, consumer:) }
before do
allow(controller).to receive(:current_user).and_return(user)
delete :destroy, params: {id: second_user.id}
end
expect_assigns(user: InternalUser)
it 'destroys the internal user' do
# We want to ensure that the user is activated and valid before proceeding
third_user.activate!
expect { delete :destroy, params: {id: third_user.id} }.to change(InternalUser, :count).by(-1)
end
expect_redirect(:internal_users)
end
describe 'GET #edit' do
before do
allow(controller).to receive(:current_user).and_return(user)
get :edit, params: {id: user.id}
end
expect_assigns(user: InternalUser)
expect_http_status(:ok)
expect_template(:edit)
end
describe 'GET #forgot_password' do
context 'when no user is logged in' do
before do
allow(controller).to receive_messages(set_sentry_context: nil, current_user: nil)
get :forgot_password
end
expect_http_status(:ok)
expect_template(:forgot_password)
end
context 'when a user is already logged in' do
before do
allow(controller).to receive_messages(set_sentry_context: nil, current_user: user)
get :forgot_password
end
expect_flash_message(:alert, :'shared.already_signed_in')
expect_redirect(:root)
end
end
describe 'POST #forgot_password' do
context 'with an email address' do
let(:perform_request) { proc { post :forgot_password, params: {email: user.email} } }
before { perform_request.call }
it 'delivers instructions to reset the password' do
allow(InternalUser).to receive(:where).and_return([user])
expect(user).to receive(:deliver_reset_password_instructions!)
perform_request.call
end
expect_redirect(:root)
end
context 'without an email address' do
before { post :forgot_password }
expect_http_status(:ok)
expect_template(:forgot_password)
end
end
describe 'GET #index' do
before do
allow(controller).to receive(:current_user).and_return(user)
get :index
end
expect_assigns(users: InternalUser.all)
expect_http_status(:ok)
expect_template(:index)
end
describe 'GET #new' do
before do
allow(controller).to receive(:current_user).and_return(user)
get :new
end
expect_assigns(user: InternalUser)
expect_http_status(:ok)
expect_template(:new)
end
describe 'GET #reset_password' do
context 'without a valid password reset token' do
before { get :reset_password, params: {id: user.id} }
expect_redirect(:root)
end
context 'with a valid password reset token' do
before do
user.deliver_reset_password_instructions!
get :reset_password, params: {id: user.id, token: user.reset_password_token}
end
expect_assigns(user: :user)
expect_http_status(:ok)
expect_template(:reset_password)
end
end
describe 'PUT #reset_password' do
before { user.deliver_reset_password_instructions! }
context 'without a valid password reset token' do
before { put :reset_password, params: {id: user.id} }
expect_redirect(:root)
end
context 'with a valid password reset token' do
let(:password) { 'foo' }
context 'with a matching password confirmation' do
let(:perform_request) { proc { put :reset_password, params: {internal_user: {password:, password_confirmation: password}, id: user.id, token: user.reset_password_token} } }
before { perform_request.call }
expect_assigns(user: :user)
context 'with a weak password' do
let(:password) { 'foo' }
it 'does not change the password' do
expect { perform_request.call }.not_to change { user.reload.crypted_password }
expect(InternalUser.authenticate(user.email, password)).not_to eq(user)
end
expect_http_status(:ok)
expect_template(:reset_password)
end
context 'with a strong password' do
let(:password) { SecureRandom.hex(128) }
it 'changes the password' do
expect { perform_request.call }.not_to change { user.reload.crypted_password }
expect(InternalUser.authenticate(user.email, password)).to eq(user)
end
expect_redirect(:sign_in)
end
end
context 'without a matching password confirmation' do
before do
put :reset_password, params: {internal_user: {password:, password_confirmation: ''}, id: user.id, token: user.reset_password_token}
end
expect_assigns(user: :user)
expect_http_status(:ok)
expect_template(:reset_password)
end
end
end
describe 'GET #show' do
before do
allow(controller).to receive(:current_user).and_return(user)
get :show, params: {id: user.id}
end
expect_assigns(user: InternalUser)
expect_http_status(:ok)
expect_template(:show)
end
describe 'PUT #update' do
before { allow(controller).to receive(:current_user).and_return(user) }
context 'with a valid internal user' do
before { put :update, params: {internal_user: attributes_for(:teacher), id: user.id} }
expect_assigns(user: InternalUser)
expect_redirect { user }
end
context 'with an invalid internal user' do
before { put :update, params: {internal_user: {email: ''}, id: user.id} }
expect_assigns(user: InternalUser)
expect_http_status(:ok)
expect_template(:edit)
end
end
end