
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.
352 lines
9.6 KiB
Ruby
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
|