2019-04-15 06:17:05 -04:00
|
|
|
# frozen_string_literal: true
|
2013-09-17 16:37:36 -04:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2020-06-03 23:08:05 -04:00
|
|
|
RSpec.describe ApplicationController do
|
2018-04-27 10:50:33 -04:00
|
|
|
include TermsHelper
|
|
|
|
|
2016-11-14 09:55:31 -05:00
|
|
|
let(:user) { create(:user) }
|
|
|
|
|
2013-09-17 16:37:36 -04:00
|
|
|
describe '#check_password_expiration' do
|
2017-05-01 11:13:33 -04:00
|
|
|
let(:controller) { described_class.new }
|
2013-09-17 16:37:36 -04:00
|
|
|
|
2017-09-13 07:18:15 -04:00
|
|
|
before do
|
|
|
|
allow(controller).to receive(:session).and_return({})
|
|
|
|
end
|
|
|
|
|
2016-07-25 14:16:19 -04:00
|
|
|
it 'redirects if the user is over their password expiry' do
|
2020-05-19 05:08:12 -04:00
|
|
|
user.password_expires_at = Time.zone.local(2002)
|
2017-08-31 06:21:40 -04:00
|
|
|
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(user.ldap_user?).to be_falsey
|
|
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
|
|
expect(controller).to receive(:redirect_to)
|
|
|
|
expect(controller).to receive(:new_profile_password_path)
|
2017-08-31 06:21:40 -04:00
|
|
|
|
2013-09-17 16:37:36 -04:00
|
|
|
controller.send(:check_password_expiration)
|
|
|
|
end
|
|
|
|
|
2016-07-25 14:16:19 -04:00
|
|
|
it 'does not redirect if the user is under their password expiry' do
|
2020-05-13 20:07:47 -04:00
|
|
|
user.password_expires_at = Time.current + 20010101
|
2017-08-31 06:21:40 -04:00
|
|
|
|
2015-02-12 13:17:35 -05:00
|
|
|
expect(user.ldap_user?).to be_falsey
|
|
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
|
|
expect(controller).not_to receive(:redirect_to)
|
2017-08-31 06:21:40 -04:00
|
|
|
|
2013-09-17 16:37:36 -04:00
|
|
|
controller.send(:check_password_expiration)
|
|
|
|
end
|
|
|
|
|
2016-07-25 14:16:19 -04:00
|
|
|
it 'does not redirect if the user is over their password expiry but they are an ldap user' do
|
2020-05-19 05:08:12 -04:00
|
|
|
user.password_expires_at = Time.zone.local(2002)
|
2017-08-31 06:21:40 -04:00
|
|
|
|
2015-02-12 13:17:35 -05:00
|
|
|
allow(user).to receive(:ldap_user?).and_return(true)
|
|
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
|
|
expect(controller).not_to receive(:redirect_to)
|
2017-08-31 06:21:40 -04:00
|
|
|
|
2013-09-17 16:37:36 -04:00
|
|
|
controller.send(:check_password_expiration)
|
|
|
|
end
|
2017-06-27 14:02:09 -04:00
|
|
|
|
2017-11-23 08:16:14 -05:00
|
|
|
it 'does not redirect if the user is over their password expiry but password authentication is disabled for the web interface' do
|
|
|
|
stub_application_setting(password_authentication_enabled_for_web: false)
|
|
|
|
stub_application_setting(password_authentication_enabled_for_git: false)
|
2020-05-19 05:08:12 -04:00
|
|
|
user.password_expires_at = Time.zone.local(2002)
|
2017-08-31 06:21:40 -04:00
|
|
|
|
2017-06-27 14:02:09 -04:00
|
|
|
allow(controller).to receive(:current_user).and_return(user)
|
2017-11-23 08:16:14 -05:00
|
|
|
expect(controller).not_to receive(:redirect_to)
|
2017-06-27 14:02:09 -04:00
|
|
|
|
|
|
|
controller.send(:check_password_expiration)
|
|
|
|
end
|
2013-09-17 16:37:36 -04:00
|
|
|
end
|
2016-04-19 06:52:15 -04:00
|
|
|
|
2019-09-26 17:06:29 -04:00
|
|
|
it_behaves_like 'a Trackable Controller'
|
|
|
|
|
2018-08-07 17:28:57 -04:00
|
|
|
describe '#add_gon_variables' do
|
|
|
|
before do
|
|
|
|
Gon.clear
|
|
|
|
sign_in user
|
|
|
|
end
|
|
|
|
|
|
|
|
controller(described_class) do
|
|
|
|
def index
|
|
|
|
render json: Gon.all_variables
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples 'setting gon variables' do
|
|
|
|
it 'sets gon variables' do
|
|
|
|
get :index, format: format
|
|
|
|
|
|
|
|
expect(json_response.size).not_to be_zero
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples 'not setting gon variables' do
|
|
|
|
it 'does not set gon variables' do
|
|
|
|
get :index, format: format
|
|
|
|
|
|
|
|
expect(json_response.size).to be_zero
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with html format' do
|
|
|
|
let(:format) { :html }
|
|
|
|
|
|
|
|
it_behaves_like 'setting gon variables'
|
2019-11-08 16:06:38 -05:00
|
|
|
end
|
2019-11-13 04:06:41 -05:00
|
|
|
|
2019-11-18 07:06:03 -05:00
|
|
|
context 'with json format' do
|
|
|
|
let(:format) { :json }
|
2019-11-13 04:06:41 -05:00
|
|
|
|
|
|
|
it_behaves_like 'not setting gon variables'
|
|
|
|
end
|
2019-12-03 13:06:49 -05:00
|
|
|
|
|
|
|
context 'with atom format' do
|
|
|
|
let(:format) { :atom }
|
|
|
|
|
|
|
|
it_behaves_like 'not setting gon variables'
|
|
|
|
end
|
2018-08-07 17:28:57 -04:00
|
|
|
end
|
|
|
|
|
2018-07-18 14:18:14 -04:00
|
|
|
describe 'session expiration' do
|
|
|
|
controller(described_class) do
|
2018-08-10 15:15:06 -04:00
|
|
|
# The anonymous controller will report 401 and fail to run any actions.
|
|
|
|
# Normally, GitLab will just redirect you to sign in.
|
|
|
|
skip_before_action :authenticate_user!, only: :index
|
|
|
|
|
2018-07-18 14:18:14 -04:00
|
|
|
def index
|
2018-11-28 13:08:21 -05:00
|
|
|
render html: 'authenticated'
|
2018-07-18 14:18:14 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'authenticated user' do
|
|
|
|
it 'does not set the expire_after option' do
|
|
|
|
sign_in(create(:user))
|
|
|
|
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(request.env['rack.session.options'][:expire_after]).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'unauthenticated user' do
|
|
|
|
it 'sets the expire_after option' do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(request.env['rack.session.options'][:expire_after]).to eq(Settings.gitlab['unauthenticated_session_expire_delay'])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-06-20 09:53:05 -04:00
|
|
|
describe 'response format' do
|
|
|
|
controller(described_class) do
|
|
|
|
def index
|
|
|
|
respond_to do |format|
|
|
|
|
format.json do
|
|
|
|
head :ok
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-10-12 05:01:12 -04:00
|
|
|
before do
|
|
|
|
sign_in user
|
|
|
|
end
|
|
|
|
|
2017-06-20 09:53:05 -04:00
|
|
|
context 'when format is handled' do
|
|
|
|
let(:requested_format) { :json }
|
|
|
|
|
|
|
|
it 'returns 200 response' do
|
2017-10-12 05:01:12 -04:00
|
|
|
get :index, format: requested_format
|
2017-06-20 09:53:05 -04:00
|
|
|
|
2020-01-27 07:08:35 -05:00
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
2017-06-20 09:53:05 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when format is not handled' do
|
|
|
|
it 'returns 404 response' do
|
2017-10-12 05:01:12 -04:00
|
|
|
get :index
|
2017-06-20 09:53:05 -04:00
|
|
|
|
2020-01-27 07:08:35 -05:00
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
2017-06-20 09:53:05 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-11-14 09:55:31 -05:00
|
|
|
describe '#route_not_found' do
|
2019-09-16 08:06:26 -04:00
|
|
|
controller(described_class) do
|
2020-10-21 08:08:47 -04:00
|
|
|
skip_before_action :authenticate_user!, only: :index
|
|
|
|
|
2019-09-16 08:06:26 -04:00
|
|
|
def index
|
|
|
|
route_not_found
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-11-14 09:55:31 -05:00
|
|
|
it 'renders 404 if authenticated' do
|
2019-09-16 08:06:26 -04:00
|
|
|
sign_in(user)
|
|
|
|
|
|
|
|
get :index
|
|
|
|
|
2020-01-27 07:08:35 -05:00
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
2016-11-14 09:55:31 -05:00
|
|
|
end
|
|
|
|
|
2020-10-21 08:08:47 -04:00
|
|
|
it 'renders 404 if client is a search engine crawler' do
|
|
|
|
request.env['HTTP_USER_AGENT'] = 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
|
|
|
|
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
|
2019-11-08 10:06:21 -05:00
|
|
|
it 'redirects to login page if not authenticated' do
|
2019-09-16 08:06:26 -04:00
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response).to redirect_to new_user_session_path
|
|
|
|
end
|
|
|
|
|
2020-08-06 14:09:41 -04:00
|
|
|
it 'redirects if unauthenticated and request format is unknown' do
|
|
|
|
get :index, format: 'unknown'
|
2019-09-16 08:06:26 -04:00
|
|
|
|
2020-08-06 14:09:41 -04:00
|
|
|
expect(response).to redirect_to new_user_session_path
|
2016-11-14 09:55:31 -05:00
|
|
|
end
|
|
|
|
end
|
2017-01-24 16:09:58 -05:00
|
|
|
|
2017-10-20 12:44:29 -04:00
|
|
|
describe '#set_page_title_header' do
|
|
|
|
let(:controller) { described_class.new }
|
|
|
|
|
|
|
|
it 'URI encodes UTF-8 characters in the title' do
|
|
|
|
response = double(headers: {})
|
|
|
|
allow_any_instance_of(PageLayoutHelper).to receive(:page_title).and_return('€100 · GitLab')
|
|
|
|
allow(controller).to receive(:response).and_return(response)
|
|
|
|
|
|
|
|
controller.send(:set_page_title_header)
|
|
|
|
|
|
|
|
expect(response.headers['Page-Title']).to eq('%E2%82%AC100%20%C2%B7%20GitLab')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-01-24 16:09:58 -05:00
|
|
|
context 'two-factor authentication' do
|
2017-05-01 11:13:33 -04:00
|
|
|
let(:controller) { described_class.new }
|
2017-01-24 16:09:58 -05:00
|
|
|
|
2017-03-07 13:48:57 -05:00
|
|
|
describe '#check_two_factor_requirement' do
|
|
|
|
subject { controller.send :check_two_factor_requirement }
|
2017-01-24 16:09:58 -05:00
|
|
|
|
2019-05-22 03:59:15 -04:00
|
|
|
it 'does not redirect if user has temporary oauth email' do
|
|
|
|
oauth_user = create(:user, email: 'temp-email-for-oauth@email.com')
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
|
|
|
|
allow(controller).to receive(:current_user).and_return(oauth_user)
|
|
|
|
|
|
|
|
expect(controller).not_to receive(:redirect_to)
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
2017-01-24 16:09:58 -05:00
|
|
|
it 'does not redirect if 2FA is not required' do
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(false)
|
2020-09-02 11:10:54 -04:00
|
|
|
allow(controller).to receive(:current_user).and_return(create(:user))
|
2019-05-22 03:59:15 -04:00
|
|
|
|
2017-01-24 16:09:58 -05:00
|
|
|
expect(controller).not_to receive(:redirect_to)
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not redirect if user is not logged in' do
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
|
|
|
|
allow(controller).to receive(:current_user).and_return(nil)
|
2019-05-22 03:59:15 -04:00
|
|
|
|
2017-01-24 16:09:58 -05:00
|
|
|
expect(controller).not_to receive(:redirect_to)
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not redirect if user has 2FA enabled' do
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
|
2019-05-22 03:59:15 -04:00
|
|
|
allow(controller).to receive(:current_user).thrice.and_return(user)
|
2017-01-24 16:09:58 -05:00
|
|
|
allow(user).to receive(:two_factor_enabled?).and_return(true)
|
2019-05-22 03:59:15 -04:00
|
|
|
|
2017-01-24 16:09:58 -05:00
|
|
|
expect(controller).not_to receive(:redirect_to)
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not redirect if 2FA setup can be skipped' do
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
|
2019-05-22 03:59:15 -04:00
|
|
|
allow(controller).to receive(:current_user).thrice.and_return(user)
|
2017-01-24 16:09:58 -05:00
|
|
|
allow(user).to receive(:two_factor_enabled?).and_return(false)
|
|
|
|
allow(controller).to receive(:skip_two_factor?).and_return(true)
|
2019-05-22 03:59:15 -04:00
|
|
|
|
2017-01-24 16:09:58 -05:00
|
|
|
expect(controller).not_to receive(:redirect_to)
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'redirects to 2FA setup otherwise' do
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
|
2019-05-22 03:59:15 -04:00
|
|
|
allow(controller).to receive(:current_user).thrice.and_return(user)
|
2017-01-24 16:09:58 -05:00
|
|
|
allow(user).to receive(:two_factor_enabled?).and_return(false)
|
|
|
|
allow(controller).to receive(:skip_two_factor?).and_return(false)
|
|
|
|
allow(controller).to receive(:profile_two_factor_auth_path)
|
2019-05-22 03:59:15 -04:00
|
|
|
|
2017-01-24 16:09:58 -05:00
|
|
|
expect(controller).to receive(:redirect_to)
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#two_factor_authentication_required?' do
|
|
|
|
subject { controller.send :two_factor_authentication_required? }
|
|
|
|
|
|
|
|
it 'returns false if no 2FA requirement is present' do
|
|
|
|
allow(controller).to receive(:current_user).and_return(nil)
|
|
|
|
|
|
|
|
expect(subject).to be_falsey
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns true if a 2FA requirement is set in the application settings' do
|
|
|
|
stub_application_setting require_two_factor_authentication: true
|
|
|
|
allow(controller).to receive(:current_user).and_return(nil)
|
|
|
|
|
|
|
|
expect(subject).to be_truthy
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns true if a 2FA requirement is set on the user' do
|
2017-03-14 09:34:21 -04:00
|
|
|
user.require_two_factor_authentication_from_group = true
|
2017-01-24 16:09:58 -05:00
|
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
|
|
|
|
|
|
expect(subject).to be_truthy
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#two_factor_grace_period' do
|
|
|
|
subject { controller.send :two_factor_grace_period }
|
|
|
|
|
|
|
|
it 'returns the grace period from the application settings' do
|
|
|
|
stub_application_setting two_factor_grace_period: 23
|
|
|
|
allow(controller).to receive(:current_user).and_return(nil)
|
|
|
|
|
|
|
|
expect(subject).to eq 23
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a 2FA requirement set on the user' do
|
2017-03-14 09:34:21 -04:00
|
|
|
let(:user) { create :user, require_two_factor_authentication_from_group: true, two_factor_grace_period: 23 }
|
2017-01-24 16:09:58 -05:00
|
|
|
|
|
|
|
it 'returns the user grace period if lower than the application grace period' do
|
|
|
|
stub_application_setting two_factor_grace_period: 24
|
|
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
|
|
|
|
|
|
expect(subject).to eq 23
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the application grace period if lower than the user grace period' do
|
|
|
|
stub_application_setting two_factor_grace_period: 22
|
|
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
|
|
|
|
|
|
expect(subject).to eq 22
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#two_factor_grace_period_expired?' do
|
|
|
|
subject { controller.send :two_factor_grace_period_expired? }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false if the user has not started their grace period yet' do
|
|
|
|
expect(subject).to be_falsey
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with grace period started' do
|
|
|
|
let(:user) { create :user, otp_grace_period_started_at: 2.hours.ago }
|
|
|
|
|
|
|
|
it 'returns true if the grace period has expired' do
|
2020-09-02 11:10:54 -04:00
|
|
|
allow_next_instance_of(Gitlab::Auth::TwoFactorAuthVerifier) do |verifier|
|
|
|
|
allow(verifier).to receive(:two_factor_grace_period).and_return(2)
|
|
|
|
end
|
2017-01-24 16:09:58 -05:00
|
|
|
|
|
|
|
expect(subject).to be_truthy
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false if the grace period is still active' do
|
2020-09-02 11:10:54 -04:00
|
|
|
allow_next_instance_of(Gitlab::Auth::TwoFactorAuthVerifier) do |verifier|
|
|
|
|
allow(verifier).to receive(:two_factor_grace_period).and_return(3)
|
|
|
|
end
|
2017-01-24 16:09:58 -05:00
|
|
|
|
|
|
|
expect(subject).to be_falsey
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#two_factor_skippable' do
|
|
|
|
subject { controller.send :two_factor_skippable? }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(controller).to receive(:current_user).and_return(user)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false if 2FA is not required' do
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(false)
|
|
|
|
|
|
|
|
expect(subject).to be_falsey
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false if the user has already enabled 2FA' do
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
|
|
|
|
allow(user).to receive(:two_factor_enabled?).and_return(true)
|
|
|
|
|
|
|
|
expect(subject).to be_falsey
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false if the 2FA grace period has expired' do
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
|
|
|
|
allow(user).to receive(:two_factor_enabled?).and_return(false)
|
|
|
|
allow(controller).to receive(:two_factor_grace_period_expired?).and_return(true)
|
|
|
|
|
|
|
|
expect(subject).to be_falsey
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns true otherwise' do
|
|
|
|
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
|
|
|
|
allow(user).to receive(:two_factor_enabled?).and_return(false)
|
|
|
|
allow(controller).to receive(:two_factor_grace_period_expired?).and_return(false)
|
|
|
|
|
|
|
|
expect(subject).to be_truthy
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#skip_two_factor?' do
|
|
|
|
subject { controller.send :skip_two_factor? }
|
|
|
|
|
|
|
|
it 'returns false if 2FA setup was not skipped' do
|
|
|
|
allow(controller).to receive(:session).and_return({})
|
|
|
|
|
|
|
|
expect(subject).to be_falsey
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with 2FA setup skipped' do
|
|
|
|
before do
|
2017-03-07 13:51:22 -05:00
|
|
|
allow(controller).to receive(:session).and_return({ skip_two_factor: 2.hours.from_now })
|
2017-01-24 16:09:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false if the grace period has expired' do
|
2020-10-02 08:09:03 -04:00
|
|
|
travel_to(3.hours.from_now) do
|
2017-01-24 16:09:58 -05:00
|
|
|
expect(subject).to be_falsey
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns true if the grace period is still active' do
|
2020-10-02 08:09:03 -04:00
|
|
|
travel_to(1.hour.from_now) do
|
2017-01-24 16:09:58 -05:00
|
|
|
expect(subject).to be_truthy
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-04-27 10:50:33 -04:00
|
|
|
|
2019-10-09 20:06:44 -04:00
|
|
|
context 'deactivated user' do
|
|
|
|
controller(described_class) do
|
|
|
|
def index
|
|
|
|
render html: 'authenticated'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
sign_in user
|
|
|
|
user.deactivate
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'signs out a deactivated user' do
|
|
|
|
get :index
|
|
|
|
expect(response).to redirect_to(new_user_session_path)
|
|
|
|
expect(flash[:alert]).to eq('Your account has been deactivated by your administrator. Please log back in to reactivate your account.')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-04-27 10:50:33 -04:00
|
|
|
context 'terms' do
|
|
|
|
controller(described_class) do
|
|
|
|
def index
|
2018-11-28 13:08:21 -05:00
|
|
|
render html: 'authenticated'
|
2018-04-27 10:50:33 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
|
|
|
|
sign_in user
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not query more when terms are enforced' do
|
|
|
|
control = ActiveRecord::QueryRecorder.new { get :index }
|
|
|
|
|
|
|
|
enforce_terms
|
|
|
|
|
|
|
|
expect { get :index }.not_to exceed_query_limit(control)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when terms are enforced' do
|
|
|
|
before do
|
|
|
|
enforce_terms
|
|
|
|
end
|
|
|
|
|
2019-01-16 07:09:29 -05:00
|
|
|
it 'redirects if the user did not accept the terms' do
|
2018-04-27 10:50:33 -04:00
|
|
|
get :index
|
|
|
|
|
2020-01-27 07:08:35 -05:00
|
|
|
expect(response).to have_gitlab_http_status(:found)
|
2018-04-27 10:50:33 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not redirect when the user accepted terms' do
|
|
|
|
accept_terms(user)
|
|
|
|
|
|
|
|
get :index
|
|
|
|
|
2020-01-27 07:08:35 -05:00
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
2018-04-27 10:50:33 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-06-04 11:04:04 -04:00
|
|
|
|
2018-06-06 03:47:53 -04:00
|
|
|
describe '#append_info_to_payload' do
|
|
|
|
controller(described_class) do
|
|
|
|
attr_reader :last_payload
|
|
|
|
|
|
|
|
def index
|
2018-11-28 13:08:21 -05:00
|
|
|
render html: 'authenticated'
|
2018-06-06 03:47:53 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def append_info_to_payload(payload)
|
|
|
|
super
|
|
|
|
|
|
|
|
@last_payload = payload
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not log errors with a 200 response' do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(controller.last_payload.has_key?(:response)).to be_falsey
|
|
|
|
end
|
|
|
|
|
2018-12-05 15:54:40 -05:00
|
|
|
it 'does log correlation id' do
|
2019-02-18 15:57:22 -05:00
|
|
|
Labkit::Correlation::CorrelationId.use_id('new-id') do
|
2018-12-05 15:54:40 -05:00
|
|
|
get :index
|
|
|
|
end
|
|
|
|
|
2018-12-06 15:46:31 -05:00
|
|
|
expect(controller.last_payload).to include('correlation_id' => 'new-id')
|
2018-12-05 15:54:40 -05:00
|
|
|
end
|
2020-05-15 14:07:52 -04:00
|
|
|
|
|
|
|
it 'adds context metadata to the payload' do
|
|
|
|
sign_in user
|
|
|
|
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(controller.last_payload[:metadata]).to include('meta.user' => user.username)
|
|
|
|
end
|
2018-06-06 03:47:53 -04:00
|
|
|
end
|
|
|
|
|
2018-06-04 11:04:04 -04:00
|
|
|
describe '#access_denied' do
|
|
|
|
controller(described_class) do
|
|
|
|
def index
|
2018-11-12 16:40:42 -05:00
|
|
|
access_denied!(params[:message], params[:status])
|
2018-06-04 11:04:04 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
sign_in user
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'renders a 404 without a message' do
|
|
|
|
get :index
|
|
|
|
|
2020-01-27 07:08:35 -05:00
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
2018-12-19 07:04:24 -05:00
|
|
|
expect(response).to render_template('errors/not_found')
|
2018-06-04 11:04:04 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'renders a 403 when a message is passed to access denied' do
|
2018-12-17 17:52:17 -05:00
|
|
|
get :index, params: { message: 'None shall pass' }
|
2018-06-04 11:04:04 -04:00
|
|
|
|
2020-01-27 07:08:35 -05:00
|
|
|
expect(response).to have_gitlab_http_status(:forbidden)
|
2018-12-19 07:04:24 -05:00
|
|
|
expect(response).to render_template('errors/access_denied')
|
2018-06-04 11:04:04 -04:00
|
|
|
end
|
2018-11-12 16:40:42 -05:00
|
|
|
|
|
|
|
it 'renders a status passed to access denied' do
|
2018-12-17 17:52:17 -05:00
|
|
|
get :index, params: { status: 401 }
|
2018-11-12 16:40:42 -05:00
|
|
|
|
2020-01-27 07:08:35 -05:00
|
|
|
expect(response).to have_gitlab_http_status(:unauthorized)
|
2018-11-12 16:40:42 -05:00
|
|
|
end
|
2018-06-04 11:04:04 -04:00
|
|
|
end
|
2018-09-05 15:41:59 -04:00
|
|
|
|
|
|
|
context 'when invalid UTF-8 parameters are received' do
|
|
|
|
controller(described_class) do
|
|
|
|
def index
|
|
|
|
params[:text].split(' ')
|
|
|
|
|
|
|
|
render json: :ok
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
sign_in user
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'html' do
|
2018-12-17 17:52:17 -05:00
|
|
|
subject { get :index, params: { text: "hi \255" } }
|
2018-10-13 13:45:27 -04:00
|
|
|
|
2018-09-05 15:41:59 -04:00
|
|
|
it 'renders 412' do
|
2018-12-15 04:06:56 -05:00
|
|
|
expect { subject }.to raise_error(ActionController::BadRequest)
|
2018-09-05 15:41:59 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'js' do
|
2018-12-17 17:52:17 -05:00
|
|
|
subject { get :index, format: :js, params: { text: "hi \255" } }
|
2018-10-13 13:45:27 -04:00
|
|
|
|
2018-09-05 15:41:59 -04:00
|
|
|
it 'renders 412' do
|
2018-12-15 04:06:56 -05:00
|
|
|
expect { subject }.to raise_error(ActionController::BadRequest)
|
2018-09-05 15:41:59 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-10-01 13:43:40 -04:00
|
|
|
|
|
|
|
context 'X-GitLab-Custom-Error header' do
|
|
|
|
before do
|
|
|
|
sign_in user
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'given a 422 error page' do
|
|
|
|
controller do
|
|
|
|
def index
|
2019-11-17 07:06:19 -05:00
|
|
|
render 'errors/omniauth_error', layout: 'errors', status: :unprocessable_entity
|
2018-10-01 13:43:40 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets a custom header' do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response.headers['X-GitLab-Custom-Error']).to eq '1'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'given a 500 error page' do
|
|
|
|
controller do
|
|
|
|
def index
|
2019-11-17 07:06:19 -05:00
|
|
|
render 'errors/omniauth_error', layout: 'errors', status: :internal_server_error
|
2018-10-01 13:43:40 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets a custom header' do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response.headers['X-GitLab-Custom-Error']).to eq '1'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'given a 200 success page' do
|
|
|
|
controller do
|
|
|
|
def index
|
2019-11-17 07:06:19 -05:00
|
|
|
render 'errors/omniauth_error', layout: 'errors', status: :ok
|
2018-10-01 13:43:40 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not set a custom header' do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response.headers['X-GitLab-Custom-Error']).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'given a json response' do
|
|
|
|
controller do
|
|
|
|
def index
|
|
|
|
render json: {}, status: :unprocessable_entity
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-08-14 07:07:42 -04:00
|
|
|
it 'sets a custom header' do
|
2018-10-01 13:43:40 -04:00
|
|
|
get :index, format: :json
|
|
|
|
|
2019-08-14 07:07:42 -04:00
|
|
|
expect(response.headers['X-GitLab-Custom-Error']).to eq '1'
|
2018-10-01 13:43:40 -04:00
|
|
|
end
|
|
|
|
|
2019-08-14 07:07:42 -04:00
|
|
|
context 'for html request' do
|
|
|
|
it 'sets a custom header' do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response.headers['X-GitLab-Custom-Error']).to eq '1'
|
2018-10-01 13:43:40 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-08-14 07:07:42 -04:00
|
|
|
context 'for 200 response' do
|
|
|
|
controller do
|
|
|
|
def index
|
|
|
|
render json: {}, status: :ok
|
|
|
|
end
|
|
|
|
end
|
2018-10-01 13:43:40 -04:00
|
|
|
|
2019-08-14 07:07:42 -04:00
|
|
|
it 'does not set a custom header' do
|
|
|
|
get :index, format: :json
|
|
|
|
|
|
|
|
expect(response.headers['X-GitLab-Custom-Error']).to be_nil
|
|
|
|
end
|
2018-10-01 13:43:40 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-10-18 07:28:12 -04:00
|
|
|
|
|
|
|
context 'control headers' do
|
|
|
|
controller(described_class) do
|
|
|
|
def index
|
|
|
|
render json: :ok
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'user not logged in' do
|
|
|
|
it 'sets the default headers' do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response.headers['Cache-Control']).to be_nil
|
2020-03-05 01:07:51 -05:00
|
|
|
expect(response.headers['Pragma']).to be_nil
|
2018-10-18 07:28:12 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'user logged in' do
|
|
|
|
it 'sets the default headers' do
|
|
|
|
sign_in(user)
|
|
|
|
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response.headers['Cache-Control']).to eq 'max-age=0, private, must-revalidate, no-store'
|
2020-03-05 01:07:51 -05:00
|
|
|
expect(response.headers['Pragma']).to eq 'no-cache'
|
2018-10-18 07:28:12 -04:00
|
|
|
end
|
2019-02-19 11:33:49 -05:00
|
|
|
|
|
|
|
it 'does not set the "no-store" header for XHR requests' do
|
|
|
|
sign_in(user)
|
|
|
|
|
|
|
|
get :index, xhr: true
|
|
|
|
|
|
|
|
expect(response.headers['Cache-Control']).to eq 'max-age=0, private, must-revalidate'
|
|
|
|
end
|
2018-10-18 07:28:12 -04:00
|
|
|
end
|
|
|
|
end
|
2019-06-04 11:21:05 -04:00
|
|
|
|
|
|
|
context 'Gitlab::Session' do
|
|
|
|
controller(described_class) do
|
|
|
|
prepend_before_action do
|
|
|
|
authenticate_sessionless_user!(:rss)
|
|
|
|
end
|
|
|
|
|
|
|
|
def index
|
|
|
|
if Gitlab::Session.current
|
|
|
|
head :created
|
|
|
|
else
|
|
|
|
head :not_found
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is set on web requests' do
|
|
|
|
sign_in(user)
|
|
|
|
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:created)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with sessionless user' do
|
|
|
|
it 'is not set' do
|
|
|
|
personal_access_token = create(:personal_access_token, user: user)
|
|
|
|
|
|
|
|
get :index, format: :atom, params: { private_token: personal_access_token.token }
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:not_found)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-09-26 08:06:00 -04:00
|
|
|
|
2020-04-14 14:09:54 -04:00
|
|
|
describe '#current_user_mode' do
|
2019-09-26 08:06:00 -04:00
|
|
|
include_context 'custom session'
|
|
|
|
|
|
|
|
controller(described_class) do
|
|
|
|
def index
|
|
|
|
render html: 'authenticated'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(ActiveSession).to receive(:list_sessions).with(user).and_return([session])
|
|
|
|
|
|
|
|
sign_in(user)
|
|
|
|
get :index
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a regular user' do
|
|
|
|
it 'admin mode is not set' do
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
expect(Gitlab::Auth::CurrentUserMode.new(user).admin_mode?).to be(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with an admin user' do
|
|
|
|
let(:user) { create(:admin) }
|
|
|
|
|
|
|
|
it 'admin mode is not set' do
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
expect(Gitlab::Auth::CurrentUserMode.new(user).admin_mode?).to be(false)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'that re-authenticated' do
|
|
|
|
before do
|
2019-12-11 07:08:10 -05:00
|
|
|
Gitlab::Auth::CurrentUserMode.new(user).request_admin_mode!
|
2019-09-26 08:06:00 -04:00
|
|
|
Gitlab::Auth::CurrentUserMode.new(user).enable_admin_mode!(password: user.password)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'admin mode is set' do
|
|
|
|
expect(response).to have_gitlab_http_status(:ok)
|
|
|
|
expect(Gitlab::Auth::CurrentUserMode.new(user).admin_mode?).to be(true)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-10-18 17:06:37 -04:00
|
|
|
|
2019-11-08 10:06:21 -05:00
|
|
|
describe '#required_signup_info' do
|
2019-10-18 17:06:37 -04:00
|
|
|
controller(described_class) do
|
|
|
|
def index; end
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
|
2020-09-10 11:09:10 -04:00
|
|
|
context 'user with required role' do
|
2019-10-18 17:06:37 -04:00
|
|
|
before do
|
|
|
|
user.set_role_required!
|
|
|
|
sign_in(user)
|
|
|
|
get :index
|
|
|
|
end
|
|
|
|
|
|
|
|
it { is_expected.to redirect_to users_sign_up_welcome_path }
|
|
|
|
end
|
|
|
|
|
2020-09-10 11:09:10 -04:00
|
|
|
context 'user without a required role' do
|
2019-10-18 17:06:37 -04:00
|
|
|
before do
|
|
|
|
sign_in(user)
|
|
|
|
get :index
|
|
|
|
end
|
|
|
|
|
|
|
|
it { is_expected.not_to redirect_to users_sign_up_welcome_path }
|
|
|
|
end
|
2020-09-10 11:09:10 -04:00
|
|
|
end
|
2019-10-18 17:06:37 -04:00
|
|
|
|
2020-09-10 11:09:10 -04:00
|
|
|
describe 'rescue_from Gitlab::Auth::IpBlacklisted' do
|
|
|
|
controller(described_class) do
|
|
|
|
skip_before_action :authenticate_user!
|
2019-10-18 17:06:37 -04:00
|
|
|
|
2020-09-10 11:09:10 -04:00
|
|
|
def index
|
|
|
|
raise Gitlab::Auth::IpBlacklisted
|
2019-10-18 17:06:37 -04:00
|
|
|
end
|
|
|
|
end
|
2019-12-03 16:06:23 -05:00
|
|
|
|
2020-09-10 11:09:10 -04:00
|
|
|
it 'returns a 403 and logs the request' do
|
|
|
|
expect(Gitlab::AuthLogger).to receive(:error).with({
|
|
|
|
message: 'Rack_Attack',
|
|
|
|
env: :blocklist,
|
|
|
|
remote_ip: '1.2.3.4',
|
|
|
|
request_method: 'GET',
|
|
|
|
path: '/anonymous'
|
|
|
|
})
|
2019-12-03 16:06:23 -05:00
|
|
|
|
2020-09-10 11:09:10 -04:00
|
|
|
request.remote_addr = '1.2.3.4'
|
2019-12-03 16:06:23 -05:00
|
|
|
|
2020-09-10 11:09:10 -04:00
|
|
|
get :index
|
2019-12-03 16:06:23 -05:00
|
|
|
|
2020-09-10 11:09:10 -04:00
|
|
|
expect(response).to have_gitlab_http_status(:forbidden)
|
2019-12-03 16:06:23 -05:00
|
|
|
end
|
2019-10-18 17:06:37 -04:00
|
|
|
end
|
2020-01-03 10:08:33 -05:00
|
|
|
|
2020-02-06 16:08:48 -05:00
|
|
|
describe '#set_current_context' do
|
2020-01-03 10:08:33 -05:00
|
|
|
controller(described_class) do
|
2020-10-15 05:08:41 -04:00
|
|
|
feature_category :issue_tracking
|
|
|
|
|
2020-01-03 10:08:33 -05:00
|
|
|
def index
|
|
|
|
Labkit::Context.with_context do |context|
|
|
|
|
render json: context.to_h
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
let_it_be(:user) { create(:user) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
sign_in(user)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not break anything when no group or project method is defined' do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(:success)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the username in the context when signed in' do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(json_response['meta.user']).to eq(user.username)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the group if it was available' do
|
2020-05-15 14:07:52 -04:00
|
|
|
group = build_stubbed(:group)
|
2020-01-03 10:08:33 -05:00
|
|
|
controller.instance_variable_set(:@group, group)
|
|
|
|
|
|
|
|
get :index, format: :json
|
|
|
|
|
|
|
|
expect(json_response['meta.root_namespace']).to eq(group.path)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the project if one was available' do
|
2020-05-15 14:07:52 -04:00
|
|
|
project = build_stubbed(:project)
|
2020-01-03 10:08:33 -05:00
|
|
|
controller.instance_variable_set(:@project, project)
|
|
|
|
|
|
|
|
get :index, format: :json
|
|
|
|
|
|
|
|
expect(json_response['meta.project']).to eq(project.full_path)
|
|
|
|
end
|
2020-01-23 10:08:46 -05:00
|
|
|
|
|
|
|
it 'sets the caller_id as controller#action' do
|
|
|
|
get :index, format: :json
|
|
|
|
|
|
|
|
expect(json_response['meta.caller_id']).to eq('AnonymousController#index')
|
|
|
|
end
|
2020-05-15 14:07:52 -04:00
|
|
|
|
2020-10-15 05:08:41 -04:00
|
|
|
it 'sets the feature_category as defined in the controller' do
|
|
|
|
get :index, format: :json
|
|
|
|
|
|
|
|
expect(json_response['meta.feature_category']).to eq('issue_tracking')
|
|
|
|
end
|
|
|
|
|
2020-05-15 14:07:52 -04:00
|
|
|
it 'assigns the context to a variable for logging' do
|
|
|
|
get :index, format: :json
|
|
|
|
|
|
|
|
expect(assigns(:current_context)).to include('meta.user' => user.username)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'assigns the context when the action caused an error' do
|
|
|
|
allow(controller).to receive(:index) { raise 'Broken' }
|
|
|
|
|
|
|
|
expect { get :index, format: :json }.to raise_error('Broken')
|
|
|
|
|
|
|
|
expect(assigns(:current_context)).to include('meta.user' => user.username)
|
|
|
|
end
|
2020-01-03 10:08:33 -05:00
|
|
|
end
|
2020-05-15 11:08:04 -04:00
|
|
|
|
|
|
|
describe '#current_user' do
|
|
|
|
controller(described_class) do
|
|
|
|
def index; end
|
|
|
|
end
|
|
|
|
|
|
|
|
let_it_be(:impersonator) { create(:user) }
|
|
|
|
let_it_be(:user) { create(:user) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
sign_in(user)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when being impersonated' do
|
|
|
|
before do
|
|
|
|
allow(controller).to receive(:session).and_return({ impersonator_id: impersonator.id })
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns a User with impersonator', :aggregate_failures do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(controller.current_user).to be_a(User)
|
|
|
|
expect(controller.current_user.impersonator).to eq(impersonator)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when not being impersonated' do
|
|
|
|
before do
|
|
|
|
allow(controller).to receive(:session).and_return({})
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns a User', :aggregate_failures do
|
|
|
|
get :index
|
|
|
|
|
|
|
|
expect(controller.current_user).to be_a(User)
|
|
|
|
expect(controller.current_user.impersonator).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-07-02 14:09:00 -04:00
|
|
|
|
|
|
|
describe 'locale' do
|
|
|
|
let(:user) { create(:user, preferred_language: 'uk') }
|
|
|
|
|
|
|
|
controller(described_class) do
|
|
|
|
def index
|
|
|
|
:ok
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
sign_in(user)
|
|
|
|
|
|
|
|
allow(Gitlab::I18n).to receive(:with_locale).and_call_original
|
|
|
|
end
|
|
|
|
|
|
|
|
it "sets user's locale" do
|
|
|
|
expect(Gitlab::I18n).to receive(:with_locale).with('uk')
|
|
|
|
|
|
|
|
get :index
|
|
|
|
end
|
|
|
|
end
|
2014-06-21 05:18:57 -04:00
|
|
|
end
|