summaryrefslogtreecommitdiff
path: root/spec/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'spec/controllers')
-rw-r--r--spec/controllers/acme_challenges_controller_spec.rb44
-rw-r--r--spec/controllers/application_controller_spec.rb55
-rw-r--r--spec/controllers/concerns/import_url_params_spec.rb56
-rw-r--r--spec/controllers/concerns/project_unauthorized_spec.rb2
-rw-r--r--spec/controllers/concerns/routable_actions_spec.rb156
-rw-r--r--spec/controllers/concerns/send_file_upload_spec.rb3
-rw-r--r--spec/controllers/groups_controller_spec.rb22
-rw-r--r--spec/controllers/import/phabricator_controller_spec.rb92
-rw-r--r--spec/controllers/projects/avatars_controller_spec.rb2
-rw-r--r--spec/controllers/projects/ci/lints_controller_spec.rb4
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb36
-rw-r--r--spec/controllers/projects/imports_controller_spec.rb15
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb31
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb93
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb18
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb34
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb2
-rw-r--r--spec/controllers/projects/serverless/functions_controller_spec.rb92
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb17
-rw-r--r--spec/controllers/projects_controller_spec.rb12
-rw-r--r--spec/controllers/registrations_controller_spec.rb19
-rw-r--r--spec/controllers/sent_notifications_controller_spec.rb109
-rw-r--r--spec/controllers/sessions_controller_spec.rb34
23 files changed, 854 insertions, 94 deletions
diff --git a/spec/controllers/acme_challenges_controller_spec.rb b/spec/controllers/acme_challenges_controller_spec.rb
new file mode 100644
index 00000000000..cee06bed27b
--- /dev/null
+++ b/spec/controllers/acme_challenges_controller_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe AcmeChallengesController do
+ describe '#show' do
+ let!(:acme_order) { create(:pages_domain_acme_order) }
+
+ def make_request(domain, token)
+ get(:show, params: { domain: domain, token: token })
+ end
+
+ before do
+ make_request(domain, token)
+ end
+
+ context 'with right domain and token' do
+ let(:domain) { acme_order.pages_domain.domain }
+ let(:token) { acme_order.challenge_token }
+
+ it 'renders acme challenge file content' do
+ expect(response.body).to eq(acme_order.challenge_file_content)
+ end
+ end
+
+ context 'when domain is invalid' do
+ let(:domain) { 'somewrongdomain.com' }
+ let(:token) { acme_order.challenge_token }
+
+ it 'renders not found' do
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+
+ context 'when token is invalid' do
+ let(:domain) { acme_order.pages_domain.domain }
+ let(:token) { 'wrongtoken' }
+
+ it 'renders not found' do
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 7296a4b4526..40669ec5451 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -206,8 +206,19 @@ describe ApplicationController do
describe '#check_two_factor_requirement' do
subject { controller.send :check_two_factor_requirement }
+ 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
+
it 'does not redirect if 2FA is not required' do
allow(controller).to receive(:two_factor_authentication_required?).and_return(false)
+
expect(controller).not_to receive(:redirect_to)
subject
@@ -216,6 +227,7 @@ describe ApplicationController do
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)
+
expect(controller).not_to receive(:redirect_to)
subject
@@ -223,8 +235,9 @@ describe ApplicationController do
it 'does not redirect if user has 2FA enabled' do
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
- allow(controller).to receive(:current_user).twice.and_return(user)
+ allow(controller).to receive(:current_user).thrice.and_return(user)
allow(user).to receive(:two_factor_enabled?).and_return(true)
+
expect(controller).not_to receive(:redirect_to)
subject
@@ -232,9 +245,10 @@ describe ApplicationController do
it 'does not redirect if 2FA setup can be skipped' do
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
- allow(controller).to receive(:current_user).twice.and_return(user)
+ allow(controller).to receive(:current_user).thrice.and_return(user)
allow(user).to receive(:two_factor_enabled?).and_return(false)
allow(controller).to receive(:skip_two_factor?).and_return(true)
+
expect(controller).not_to receive(:redirect_to)
subject
@@ -242,10 +256,11 @@ describe ApplicationController do
it 'redirects to 2FA setup otherwise' do
allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
- allow(controller).to receive(:current_user).twice.and_return(user)
+ allow(controller).to receive(:current_user).thrice.and_return(user)
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)
+
expect(controller).to receive(:redirect_to)
subject
@@ -676,4 +691,38 @@ describe ApplicationController do
end
end
end
+
+ 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
end
diff --git a/spec/controllers/concerns/import_url_params_spec.rb b/spec/controllers/concerns/import_url_params_spec.rb
new file mode 100644
index 00000000000..adbe6e5d3bf
--- /dev/null
+++ b/spec/controllers/concerns/import_url_params_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ImportUrlParams do
+ let(:import_url_params) do
+ controller = OpenStruct.new(params: params).extend(described_class)
+ controller.import_url_params
+ end
+
+ context 'empty URL' do
+ let(:params) do
+ ActionController::Parameters.new(project: {
+ title: 'Test'
+ })
+ end
+
+ it 'returns empty hash' do
+ expect(import_url_params).to eq({})
+ end
+ end
+
+ context 'url and password separately provided' do
+ let(:params) do
+ ActionController::Parameters.new(project: {
+ import_url: 'https://url.com',
+ import_url_user: 'user', import_url_password: 'password'
+ })
+ end
+
+ describe '#import_url_params' do
+ it 'returns hash with import_url' do
+ expect(import_url_params).to eq(
+ import_url: "https://user:password@url.com"
+ )
+ end
+ end
+ end
+
+ context 'url with provided empty credentials' do
+ let(:params) do
+ ActionController::Parameters.new(project: {
+ import_url: 'https://user:password@url.com',
+ import_url_user: '', import_url_password: ''
+ })
+ end
+
+ describe '#import_url_params' do
+ it 'does not change the url' do
+ expect(import_url_params).to eq(
+ import_url: "https://user:password@url.com"
+ )
+ end
+ end
+ end
+end
diff --git a/spec/controllers/concerns/project_unauthorized_spec.rb b/spec/controllers/concerns/project_unauthorized_spec.rb
index 57ac00cf4dd..5834b1ef37f 100644
--- a/spec/controllers/concerns/project_unauthorized_spec.rb
+++ b/spec/controllers/concerns/project_unauthorized_spec.rb
@@ -12,7 +12,7 @@ describe ProjectUnauthorized do
render_views
- describe '#project_unauthorized_proc' do
+ describe '.on_routable_not_found' do
controller(::Projects::ApplicationController) do
def show
head :ok
diff --git a/spec/controllers/concerns/routable_actions_spec.rb b/spec/controllers/concerns/routable_actions_spec.rb
new file mode 100644
index 00000000000..59d48c68b9c
--- /dev/null
+++ b/spec/controllers/concerns/routable_actions_spec.rb
@@ -0,0 +1,156 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe RoutableActions do
+ controller(::ApplicationController) do
+ include RoutableActions # rubocop:disable RSpec/DescribedClass
+
+ before_action :routable
+
+ def routable
+ @klass = params[:type].constantize
+ @routable = find_routable!(params[:type].constantize, params[:id])
+ end
+
+ def show
+ head :ok
+ end
+ end
+
+ def get_routable(routable)
+ get :show, params: { id: routable.full_path, type: routable.class }
+ end
+
+ describe '#find_routable!' do
+ context 'when signed in' do
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ end
+
+ context 'with a project' do
+ let(:routable) { create(:project) }
+
+ context 'when authorized' do
+ before do
+ routable.add_guest(user)
+ end
+
+ it 'returns the project' do
+ get_routable(routable)
+
+ expect(assigns[:routable]).to be_a(Project)
+ end
+
+ it 'allows access' do
+ get_routable(routable)
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+
+ it 'prevents access when not authorized' do
+ get_routable(routable)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+
+ context 'with a group' do
+ let(:routable) { create(:group, :private) }
+
+ context 'when authorized' do
+ before do
+ routable.add_guest(user)
+ end
+
+ it 'returns the group' do
+ get_routable(routable)
+
+ expect(assigns[:routable]).to be_a(Group)
+ end
+
+ it 'allows access' do
+ get_routable(routable)
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+
+ it 'prevents access when not authorized' do
+ get_routable(routable)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+
+ context 'with a user' do
+ let(:routable) { user }
+
+ it 'allows access when authorized' do
+ get_routable(routable)
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'prevents access when unauthorized' do
+ allow(subject).to receive(:can?).and_return(false)
+
+ get_routable(user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+ end
+
+ context 'when not signed in' do
+ it 'redirects to sign in for private resouces' do
+ routable = create(:project, :private)
+
+ get_routable(routable)
+
+ expect(response).to have_gitlab_http_status(302)
+ expect(response.location).to end_with('/users/sign_in')
+ end
+ end
+ end
+
+ describe '#perform_not_found_actions' do
+ let(:routable) { create(:project) }
+
+ before do
+ sign_in(create(:user))
+ end
+
+ it 'performs multiple checks' do
+ last_check_called = false
+ checks = [proc {}, proc { last_check_called = true }]
+ allow(subject).to receive(:not_found_actions).and_return(checks)
+
+ get_routable(routable)
+
+ expect(last_check_called).to eq(true)
+ end
+
+ it 'performs checks in the context of the controller' do
+ check = lambda { |routable| redirect_to routable }
+ allow(subject).to receive(:not_found_actions).and_return([check])
+
+ get_routable(routable)
+
+ expect(response.location).to end_with(routable.to_param)
+ end
+
+ it 'skips checks once one has resulted in a render/redirect' do
+ first_check = proc { render plain: 'first' }
+ second_check = proc { render plain: 'second' }
+ allow(subject).to receive(:not_found_actions).and_return([first_check, second_check])
+
+ get_routable(routable)
+
+ expect(response.body).to eq('first')
+ end
+ end
+end
diff --git a/spec/controllers/concerns/send_file_upload_spec.rb b/spec/controllers/concerns/send_file_upload_spec.rb
index 8408578a7db..a3ce08f736c 100644
--- a/spec/controllers/concerns/send_file_upload_spec.rb
+++ b/spec/controllers/concerns/send_file_upload_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
# frozen_string_literal: true
require 'spec_helper'
@@ -13,7 +14,7 @@ describe SendFileUpload do
# user/:id
def dynamic_segment
- File.join(model.class.to_s.underscore, model.id.to_s)
+ File.join(model.class.underscore, model.id.to_s)
end
end
end
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index 1cd08200552..47d7e278183 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -141,6 +141,28 @@ describe GroupsController do
end
describe 'POST #create' do
+ it 'allows creating a group' do
+ sign_in(user)
+
+ expect do
+ post :create, params: { group: { name: 'new_group', path: "new_group" } }
+ end.to change { Group.count }.by(1)
+
+ expect(response).to have_gitlab_http_status(302)
+ end
+
+ context 'authorization' do
+ it 'allows an admin to create a group' do
+ sign_in(create(:admin))
+
+ expect do
+ post :create, params: { group: { name: 'new_group', path: "new_group" } }
+ end.to change { Group.count }.by(1)
+
+ expect(response).to have_gitlab_http_status(302)
+ end
+ end
+
context 'when creating subgroups', :nested_groups do
[true, false].each do |can_create_group_status|
context "and can_create_group is #{can_create_group_status}" do
diff --git a/spec/controllers/import/phabricator_controller_spec.rb b/spec/controllers/import/phabricator_controller_spec.rb
new file mode 100644
index 00000000000..85085a8e996
--- /dev/null
+++ b/spec/controllers/import/phabricator_controller_spec.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Import::PhabricatorController do
+ let(:current_user) { create(:user) }
+
+ before do
+ sign_in current_user
+ end
+
+ describe 'GET #new' do
+ subject { get :new }
+
+ context 'when the import source is not available' do
+ before do
+ stub_feature_flags(phabricator_import: true)
+ stub_application_setting(import_sources: [])
+ end
+
+ it { is_expected.to have_gitlab_http_status(404) }
+ end
+
+ context 'when the feature is disabled' do
+ before do
+ stub_feature_flags(phabricator_import: false)
+ stub_application_setting(import_sources: ['phabricator'])
+ end
+
+ it { is_expected.to have_gitlab_http_status(404) }
+ end
+
+ context 'when the import is available' do
+ before do
+ stub_feature_flags(phabricator_import: true)
+ stub_application_setting(import_sources: ['phabricator'])
+ end
+
+ it { is_expected.to have_gitlab_http_status(200) }
+ end
+ end
+
+ describe 'POST #create' do
+ subject(:post_create) { post :create, params: params }
+
+ context 'with valid params' do
+ let(:params) do
+ { path: 'phab-import',
+ name: 'Phab import',
+ phabricator_server_url: 'https://phabricator.example.com',
+ api_token: 'hazaah',
+ namespace_id: current_user.namespace_id }
+ end
+
+ it 'creates a project to import' do
+ expect_next_instance_of(Gitlab::PhabricatorImport::Importer) do |importer|
+ expect(importer).to receive(:execute)
+ end
+
+ expect { post_create }.to change { current_user.namespace.projects.reload.size }.from(0).to(1)
+
+ expect(current_user.namespace.projects.last).to be_import
+ end
+ end
+
+ context 'when an import param is missing' do
+ let(:params) do
+ { path: 'phab-import',
+ name: 'Phab import',
+ phabricator_server_url: nil,
+ api_token: 'hazaah',
+ namespace_id: current_user.namespace_id }
+ end
+
+ it 'does not create the project' do
+ expect { post_create }.not_to change { current_user.namespace.projects.reload.size }
+ end
+ end
+
+ context 'when a project param is missing' do
+ let(:params) do
+ { phabricator_server_url: 'https://phabricator.example.com',
+ api_token: 'hazaah',
+ namespace_id: current_user.namespace_id }
+ end
+
+ it 'does not create the project' do
+ expect { post_create }.not_to change { current_user.namespace.projects.reload.size }
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb
index de1b9dc0bf3..d463619ad0b 100644
--- a/spec/controllers/projects/avatars_controller_spec.rb
+++ b/spec/controllers/projects/avatars_controller_spec.rb
@@ -39,7 +39,7 @@ describe Projects::AvatarsController do
end
context 'when the avatar is stored in lfs' do
- it_behaves_like 'repository lfs file load' do
+ it_behaves_like 'a controller that can serve LFS files' do
let(:filename) { 'lfs_object.iso' }
let(:filepath) { "files/lfs/#{filename}" }
end
diff --git a/spec/controllers/projects/ci/lints_controller_spec.rb b/spec/controllers/projects/ci/lints_controller_spec.rb
index 323a32575af..cc6ac83ca38 100644
--- a/spec/controllers/projects/ci/lints_controller_spec.rb
+++ b/spec/controllers/projects/ci/lints_controller_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
describe Projects::Ci::LintsController do
+ include StubRequests
+
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
@@ -70,7 +72,7 @@ describe Projects::Ci::LintsController do
context 'with a valid gitlab-ci.yml' do
before do
- WebMock.stub_request(:get, remote_file_path).to_return(body: remote_file_content)
+ stub_full_request(remote_file_path).to_return(body: remote_file_content)
project.add_developer(user)
post :create, params: { namespace_id: project.namespace, project_id: project, content: content }
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index cf23d937037..9699f2952f2 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -383,6 +383,8 @@ describe Projects::EnvironmentsController do
end
describe 'GET #additional_metrics' do
+ let(:window_params) { { start: '1554702993.5398998', end: '1554717396.996232' } }
+
before do
allow(controller).to receive(:environment).and_return(environment)
end
@@ -394,7 +396,7 @@ describe Projects::EnvironmentsController do
context 'when requesting metrics as JSON' do
it 'returns a metrics JSON document' do
- additional_metrics
+ additional_metrics(window_params)
expect(response).to have_gitlab_http_status(204)
expect(json_response).to eq({})
@@ -414,43 +416,25 @@ describe Projects::EnvironmentsController do
end
it 'returns a metrics JSON document' do
- additional_metrics
+ additional_metrics(window_params)
expect(response).to be_ok
expect(json_response['success']).to be(true)
expect(json_response['data']).to eq({})
expect(json_response['last_update']).to eq(42)
end
+ end
- context 'when time params are provided' do
- it 'returns a metrics JSON document' do
- additional_metrics(start: '1554702993.5398998', end: '1554717396.996232')
-
- expect(response).to be_ok
- expect(json_response['success']).to be(true)
- expect(json_response['data']).to eq({})
- expect(json_response['last_update']).to eq(42)
- end
+ context 'when time params are missing' do
+ it 'raises an error when window params are missing' do
+ expect { additional_metrics }
+ .to raise_error(ActionController::ParameterMissing)
end
end
context 'when only one time param is provided' do
- context 'when :metrics_time_window feature flag is disabled' do
- before do
- stub_feature_flags(metrics_time_window: false)
- expect(environment).to receive(:additional_metrics).with(no_args).and_return(nil)
- end
-
- it 'returns a time-window agnostic response' do
- additional_metrics(start: '1552647300.651094')
-
- expect(response).to have_gitlab_http_status(204)
- expect(json_response).to eq({})
- end
- end
-
it 'raises an error when start is missing' do
- expect { additional_metrics(start: '1552647300.651094') }
+ expect { additional_metrics(end: '1552647300.651094') }
.to raise_error(ActionController::ParameterMissing)
end
diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb
index 8d88ee7dfd6..bdc81efe3bc 100644
--- a/spec/controllers/projects/imports_controller_spec.rb
+++ b/spec/controllers/projects/imports_controller_spec.rb
@@ -122,4 +122,19 @@ describe Projects::ImportsController do
end
end
end
+
+ describe 'POST #create' do
+ let(:params) { { import_url: 'https://github.com/vim/vim.git', import_url_user: 'user', import_url_password: 'password' } }
+ let(:project) { create(:project) }
+
+ before do
+ allow(RepositoryImportWorker).to receive(:perform_async)
+
+ post :create, params: { project: params, namespace_id: project.namespace.to_param, project_id: project }
+ end
+
+ it 'sets import_url to the project' do
+ expect(project.reload.import_url).to eq('https://user:password@github.com/vim/vim.git')
+ end
+ end
end
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 0c46b43f080..32607fc5f56 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -130,6 +130,37 @@ describe Projects::IssuesController do
end
end
+ context 'with relative_position sorting' do
+ let!(:issue_list) { create_list(:issue, 2, project: project) }
+
+ before do
+ sign_in(user)
+ project.add_developer(user)
+ allow(Kaminari.config).to receive(:default_per_page).and_return(1)
+ end
+
+ it 'overrides the number allowed on the page' do
+ get :index,
+ params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ sort: 'relative_position'
+ }
+
+ expect(assigns(:issues).count).to eq 2
+ end
+
+ it 'allows the default number on the page' do
+ get :index,
+ params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project
+ }
+
+ expect(assigns(:issues).count).to eq 1
+ end
+ end
+
context 'external authorization' do
before do
sign_in user
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index bd30d4ee88b..490e9841492 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -101,7 +101,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end
end
- describe 'GET show' do
+ describe 'GET show', :request_store do
let!(:job) { create(:ci_build, :failed, pipeline: pipeline) }
let!(:second_job) { create(:ci_build, :failed, pipeline: pipeline) }
let!(:third_job) { create(:ci_build, :failed) }
@@ -143,13 +143,24 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
project.add_developer(user)
sign_in(user)
- allow_any_instance_of(Ci::Build).to receive(:merge_request).and_return(merge_request)
+ allow_any_instance_of(Ci::Build)
+ .to receive(:merge_request)
+ .and_return(merge_request)
+ end
+
+ it 'does not serialize builds in exposed stages' do
+ get_show_json
- get_show(id: job.id, format: :json)
+ json_response.dig('pipeline', 'details', 'stages').tap do |stages|
+ expect(stages.map(&:keys).flatten)
+ .to eq %w[name title status path dropdown_path]
+ end
end
context 'when job failed' do
it 'exposes needed information' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['raw_path']).to match(%r{jobs/\d+/raw\z})
@@ -159,6 +170,10 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end
context 'when job is running' do
+ before do
+ get_show_json
+ end
+
context 'job is cancelable' do
let(:job) { create(:ci_build, :running, pipeline: pipeline) }
@@ -181,6 +196,10 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end
context 'when job has artifacts' do
+ before do
+ get_show_json
+ end
+
context 'with not expiry date' do
let(:job) { create(:ci_build, :success, :artifacts, pipeline: pipeline) }
@@ -212,6 +231,8 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
let(:job) { create(:ci_build, :success, :artifacts, pipeline: pipeline) }
it 'exposes empty state illustrations' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['status']['illustration']).to have_key('image')
@@ -224,6 +245,8 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
let(:job) { create(:ci_build, :success, pipeline: pipeline) }
it 'does not exposes the deployment information' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['deployment_status']).to be_nil
end
@@ -234,11 +257,20 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
let(:environment) { create(:environment, project: project, name: 'staging', state: :available) }
let(:job) { create(:ci_build, :running, environment: environment.name, pipeline: pipeline) }
+ before do
+ create(:deployment, :success, environment: environment, project: project)
+ end
+
it 'exposes the deployment information' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to match_schema('job/job_details')
- expect(json_response['deployment_status']["status"]).to eq 'creating'
- expect(json_response['deployment_status']["environment"]).not_to be_nil
+ expect(json_response.dig('deployment_status', 'status')).to eq 'creating'
+ expect(json_response.dig('deployment_status', 'environment')).not_to be_nil
+ expect(json_response.dig('deployment_status', 'environment', 'last_deployment')).not_to be_nil
+ expect(json_response.dig('deployment_status', 'environment', 'last_deployment'))
+ .not_to include('commit')
end
end
@@ -250,11 +282,11 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
before do
project.add_maintainer(user)
sign_in(user)
-
- get_show(id: job.id, format: :json)
end
it 'user can edit runner' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['runner']).to have_key('edit_path')
@@ -270,11 +302,11 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
before do
project.add_maintainer(user)
sign_in(user)
-
- get_show(id: job.id, format: :json)
end
it 'user can not edit runner' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['runner']).not_to have_key('edit_path')
@@ -289,11 +321,11 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
before do
project.add_maintainer(user)
sign_in(user)
-
- get_show(id: job.id, format: :json)
end
it 'user can not edit runner' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['runner']).not_to have_key('edit_path')
@@ -306,6 +338,8 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
let(:job) { create(:ci_build, :pending, pipeline: pipeline, runner: runner) }
it 'exposes needed information' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['runners']['online']).to be false
@@ -319,6 +353,8 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
let(:job) { create(:ci_build, :pending, pipeline: pipeline, runner: runner) }
it 'exposes needed information' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['runners']['online']).to be false
@@ -328,6 +364,10 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end
context 'settings_path' do
+ before do
+ get_show_json
+ end
+
context 'when user is developer' do
it 'settings_path is not available' do
expect(response).to have_gitlab_http_status(:ok)
@@ -354,6 +394,8 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
context 'when no trace is available' do
it 'has_trace is false' do
+ get_show_json
+
expect(response).to match_response_schema('job/job_details')
expect(json_response['has_trace']).to be false
end
@@ -363,17 +405,21 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
let(:job) { create(:ci_build, :running, :trace_live, pipeline: pipeline) }
it "has_trace is true" do
+ get_show_json
+
expect(response).to match_response_schema('job/job_details')
expect(json_response['has_trace']).to be true
end
end
it 'exposes the stage the job belongs to' do
+ get_show_json
+
expect(json_response['stage']).to eq('test')
end
end
- context 'when requesting JSON job is triggered' do
+ context 'when requesting triggered job JSON' do
let!(:merge_request) { create(:merge_request, source_project: project) }
let(:trigger) { create(:ci_trigger, project: project) }
let(:trigger_request) { create(:ci_trigger_request, pipeline: pipeline, trigger: trigger) }
@@ -383,15 +429,15 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
project.add_developer(user)
sign_in(user)
- allow_any_instance_of(Ci::Build).to receive(:merge_request).and_return(merge_request)
+ allow_any_instance_of(Ci::Build)
+ .to receive(:merge_request)
+ .and_return(merge_request)
end
context 'with no variables' do
- before do
- get_show(id: job.id, format: :json)
- end
-
it 'exposes trigger information' do
+ get_show_json
+
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('job/job_details')
expect(json_response['trigger']['short_token']).to eq 'toke'
@@ -408,7 +454,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
before do
project.add_maintainer(user)
- get_show(id: job.id, format: :json)
+ get_show_json
end
it 'returns a job_detail' do
@@ -432,7 +478,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
context 'user is not a mantainer' do
before do
- get_show(id: job.id, format: :json)
+ get_show_json
end
it 'returns a job_detail' do
@@ -456,6 +502,11 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end
end
+ def get_show_json
+ expect { get_show(id: job.id, format: :json) }
+ .not_to change { Gitlab::GitalyClient.get_request_count }
+ end
+
def get_show(**extra_params)
params = {
namespace_id: project.namespace.to_param,
@@ -790,8 +841,8 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end
it 'erases artifacts' do
- expect(job.artifacts_file.exists?).to be_falsey
- expect(job.artifacts_metadata.exists?).to be_falsey
+ expect(job.artifacts_file.present?).to be_falsey
+ expect(job.artifacts_metadata.present?).to be_falsey
end
it 'erases trace' do
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index f4a18dcba51..f8c0ab55eb4 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -429,8 +429,9 @@ describe Projects::MergeRequestsController do
it 'sets the MR to merge when the pipeline succeeds' do
service = double(:merge_when_pipeline_succeeds_service)
+ allow(service).to receive(:available_for?) { true }
- expect(MergeRequests::MergeWhenPipelineSucceedsService)
+ expect(AutoMerge::MergeWhenPipelineSucceedsService)
.to receive(:new).with(project, anything, anything)
.and_return(service)
expect(service).to receive(:execute).with(merge_request)
@@ -713,9 +714,9 @@ describe Projects::MergeRequestsController do
end
end
- describe 'POST cancel_merge_when_pipeline_succeeds' do
+ describe 'POST cancel_auto_merge' do
subject do
- post :cancel_merge_when_pipeline_succeeds,
+ post :cancel_auto_merge,
params: {
format: :json,
namespace_id: merge_request.project.namespace.to_param,
@@ -725,14 +726,15 @@ describe Projects::MergeRequestsController do
xhr: true
end
- it 'calls MergeRequests::MergeWhenPipelineSucceedsService' do
- mwps_service = double
+ it 'calls AutoMergeService' do
+ auto_merge_service = double
- allow(MergeRequests::MergeWhenPipelineSucceedsService)
+ allow(AutoMergeService)
.to receive(:new)
- .and_return(mwps_service)
+ .and_return(auto_merge_service)
- expect(mwps_service).to receive(:cancel).with(merge_request)
+ allow(auto_merge_service).to receive(:available_strategies).with(merge_request)
+ expect(auto_merge_service).to receive(:cancel).with(merge_request)
subject
end
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index f8470a94f98..767cee7d54a 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -175,6 +175,40 @@ describe Projects::MilestonesController do
end
end
+ describe '#labels' do
+ render_views
+
+ context 'as json' do
+ let!(:guest) { create(:user, username: 'guest1') }
+ let!(:group) { create(:group, :public) }
+ let!(:project) { create(:project, :public, group: group) }
+ let!(:label) { create(:label, title: 'test_label_on_private_issue', project: project) }
+ let!(:confidential_issue) { create(:labeled_issue, confidential: true, project: project, milestone: milestone, labels: [label]) }
+
+ it 'does not render labels of private issues if user has no access' do
+ sign_in(guest)
+
+ get :labels, params: { namespace_id: group.id, project_id: project.id, id: milestone.iid }, format: :json
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.content_type).to eq 'application/json'
+
+ expect(json_response['html']).not_to include(label.title)
+ end
+
+ it 'does render labels of private issues if user has access' do
+ sign_in(user)
+
+ get :labels, params: { namespace_id: group.id, project_id: project.id, id: milestone.iid }, format: :json
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.content_type).to eq 'application/json'
+
+ expect(json_response['html']).to include(label.title)
+ end
+ end
+ end
+
context 'promotion succeeds' do
before do
group.add_developer(user)
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index 3a89d8ce032..97acd47b4da 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -42,7 +42,7 @@ describe Projects::RawController do
end
end
- it_behaves_like 'repository lfs file load' do
+ it_behaves_like 'a controller that can serve LFS files' do
let(:filename) { 'lfs_object.iso' }
let(:filepath) { "be93687/files/lfs/#{filename}" }
end
diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb
index 782f5f272d9..18c594acae0 100644
--- a/spec/controllers/projects/serverless/functions_controller_spec.rb
+++ b/spec/controllers/projects/serverless/functions_controller_spec.rb
@@ -8,9 +8,8 @@ describe Projects::Serverless::FunctionsController do
let(:user) { create(:user) }
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
- let(:knative) { create(:clusters_applications_knative, :installed, cluster: cluster) }
let(:service) { cluster.platform_kubernetes }
- let(:project) { cluster.project}
+ let(:project) { cluster.project }
let(:namespace) do
create(:cluster_kubernetes_namespace,
@@ -30,17 +29,69 @@ describe Projects::Serverless::FunctionsController do
end
describe 'GET #index' do
- context 'empty cache' do
- it 'has no data' do
+ let(:expected_json) { { 'knative_installed' => knative_state, 'functions' => functions } }
+
+ context 'when cache is being read' do
+ let(:knative_state) { 'checking' }
+ let(:functions) { [] }
+
+ before do
get :index, params: params({ format: :json })
+ end
- expect(response).to have_gitlab_http_status(204)
+ it 'returns checking' do
+ expect(json_response).to eq expected_json
end
- it 'renders an html page' do
- get :index, params: params
+ it { expect(response).to have_gitlab_http_status(200) }
+ end
+
+ context 'when cache is ready' do
+ let(:knative_services_finder) { project.clusters.first.knative_services_finder(project) }
+ let(:knative_state) { true }
- expect(response).to have_gitlab_http_status(200)
+ before do
+ allow_any_instance_of(Clusters::Cluster)
+ .to receive(:knative_services_finder)
+ .and_return(knative_services_finder)
+ synchronous_reactive_cache(knative_services_finder)
+ stub_kubeclient_service_pods(
+ kube_response({ "kind" => "PodList", "items" => [] }),
+ namespace: namespace.namespace
+ )
+ end
+
+ context 'when no functions were found' do
+ let(:functions) { [] }
+
+ before do
+ stub_kubeclient_knative_services(
+ namespace: namespace.namespace,
+ response: kube_response({ "kind" => "ServiceList", "items" => [] })
+ )
+ get :index, params: params({ format: :json })
+ end
+
+ it 'returns checking' do
+ expect(json_response).to eq expected_json
+ end
+
+ it { expect(response).to have_gitlab_http_status(200) }
+ end
+
+ context 'when functions were found' do
+ let(:functions) { ["asdf"] }
+
+ before do
+ stub_kubeclient_knative_services(namespace: namespace.namespace)
+ get :index, params: params({ format: :json })
+ end
+
+ it 'returns functions' do
+ expect(json_response["functions"]).not_to be_empty
+ end
+
+ it { expect(response).to have_gitlab_http_status(200) }
end
end
end
@@ -56,11 +107,12 @@ describe Projects::Serverless::FunctionsController do
context 'valid data', :use_clean_rails_memory_store_caching do
before do
stub_kubeclient_service_pods
- stub_reactive_cache(knative,
+ stub_reactive_cache(cluster.knative_services_finder(project),
{
services: kube_knative_services_body(namespace: namespace.namespace, name: cluster.project.name)["items"],
pods: kube_knative_pods_body(cluster.project.name, namespace.namespace)["items"]
- })
+ },
+ *cluster.knative_services_finder(project).cache_args)
end
it 'has a valid function name' do
@@ -88,11 +140,12 @@ describe Projects::Serverless::FunctionsController do
describe 'GET #index with data', :use_clean_rails_memory_store_caching do
before do
stub_kubeclient_service_pods
- stub_reactive_cache(knative,
+ stub_reactive_cache(cluster.knative_services_finder(project),
{
services: kube_knative_services_body(namespace: namespace.namespace, name: cluster.project.name)["items"],
pods: kube_knative_pods_body(cluster.project.name, namespace.namespace)["items"]
- })
+ },
+ *cluster.knative_services_finder(project).cache_args)
end
it 'has data' do
@@ -100,11 +153,16 @@ describe Projects::Serverless::FunctionsController do
expect(response).to have_gitlab_http_status(200)
- expect(json_response).to contain_exactly(
- a_hash_including(
- "name" => project.name,
- "url" => "http://#{project.name}.#{namespace.namespace}.example.com"
- )
+ expect(json_response).to match(
+ {
+ "knative_installed" => "checking",
+ "functions" => [
+ a_hash_including(
+ "name" => project.name,
+ "url" => "http://#{project.name}.#{namespace.namespace}.example.com"
+ )
+ ]
+ }
)
end
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index db53e5bc8a4..117b9cf7915 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -109,7 +109,7 @@ describe Projects::Settings::CiCdController do
end
context 'when updating the auto_devops settings' do
- let(:params) { { auto_devops_attributes: { enabled: '', domain: 'mepmep.md' } } }
+ let(:params) { { auto_devops_attributes: { enabled: '' } } }
context 'following the instance default' do
let(:params) { { auto_devops_attributes: { enabled: '' } } }
@@ -200,6 +200,21 @@ describe Projects::Settings::CiCdController do
expect(response).to redirect_to(namespace_project_settings_ci_cd_path)
end
end
+
+ context 'when default_git_depth is not specified' do
+ let(:params) { { ci_cd_settings_attributes: { default_git_depth: 10 } } }
+
+ before do
+ project.ci_cd_settings.update!(default_git_depth: nil)
+ end
+
+ it 'set specified git depth' do
+ subject
+
+ project.reload
+ expect(project.default_git_depth).to eq(10)
+ end
+ end
end
end
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 7f1bbebd128..8d2412f97ef 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -292,6 +292,18 @@ describe ProjectsController do
end
describe 'GET edit' do
+ it 'allows an admin user to access the page' do
+ sign_in(create(:user, :admin))
+
+ get :edit,
+ params: {
+ namespace_id: project.namespace.path,
+ id: project.path
+ }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
it 'sets the badge API endpoint' do
sign_in(user)
project.add_maintainer(user)
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 088c515c3a6..9a598790ff2 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -46,13 +46,17 @@ describe RegistrationsController do
end
context 'when reCAPTCHA is enabled' do
+ def fail_recaptcha
+ # Without this, `verify_recaptcha` arbitrarily returns true in test env
+ Recaptcha.configuration.skip_verify_env.delete('test')
+ end
+
before do
stub_application_setting(recaptcha_enabled: true)
end
it 'displays an error when the reCAPTCHA is not solved' do
- # Without this, `verify_recaptcha` arbitrarily returns true in test env
- Recaptcha.configuration.skip_verify_env.delete('test')
+ fail_recaptcha
post(:create, params: user_params)
@@ -70,6 +74,17 @@ describe RegistrationsController do
expect(flash[:notice]).to include 'Welcome! You have signed up successfully.'
end
+
+ it 'does not require reCAPTCHA if disabled by feature flag' do
+ stub_feature_flags(registrations_recaptcha: false)
+ fail_recaptcha
+
+ post(:create, params: user_params)
+
+ expect(controller).not_to receive(:verify_recaptcha)
+ expect(flash[:alert]).to be_nil
+ expect(flash[:notice]).to include 'Welcome! You have signed up successfully.'
+ end
end
context 'when terms are enforced' do
diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb
index 2b9df71aa3a..89857a9d21b 100644
--- a/spec/controllers/sent_notifications_controller_spec.rb
+++ b/spec/controllers/sent_notifications_controller_spec.rb
@@ -4,15 +4,31 @@ require 'rails_helper'
describe SentNotificationsController do
let(:user) { create(:user) }
- let(:project) { create(:project) }
- let(:sent_notification) { create(:sent_notification, project: project, noteable: issue, recipient: user) }
+ let(:project) { create(:project, :public) }
+ let(:private_project) { create(:project, :private) }
+ let(:sent_notification) { create(:sent_notification, project: target_project, noteable: noteable, recipient: user) }
let(:issue) do
- create(:issue, project: project, author: user) do |issue|
- issue.subscriptions.create(user: user, project: project, subscribed: true)
+ create(:issue, project: target_project) do |issue|
+ issue.subscriptions.create(user: user, project: target_project, subscribed: true)
end
end
+ let(:confidential_issue) do
+ create(:issue, project: target_project, confidential: true) do |issue|
+ issue.subscriptions.create(user: user, project: target_project, subscribed: true)
+ end
+ end
+
+ let(:merge_request) do
+ create(:merge_request, source_project: target_project, target_project: target_project) do |mr|
+ mr.subscriptions.create(user: user, project: target_project, subscribed: true)
+ end
+ end
+
+ let(:noteable) { issue }
+ let(:target_project) { project }
+
describe 'GET unsubscribe' do
context 'when the user is not logged in' do
context 'when the force param is passed' do
@@ -34,20 +50,93 @@ describe SentNotificationsController do
end
context 'when the force param is not passed' do
+ render_views
+
before do
get(:unsubscribe, params: { id: sent_notification.reply_key })
end
- it 'does not unsubscribe the user' do
- expect(issue.subscribed?(user, project)).to be_truthy
+ shared_examples 'unsubscribing as anonymous' do
+ it 'does not unsubscribe the user' do
+ expect(noteable.subscribed?(user, target_project)).to be_truthy
+ end
+
+ it 'does not set the flash message' do
+ expect(controller).not_to set_flash[:notice]
+ end
+
+ it 'renders unsubscribe page' do
+ expect(response.status).to eq(200)
+ expect(response).to render_template :unsubscribe
+ end
end
- it 'does not set the flash message' do
- expect(controller).not_to set_flash[:notice]
+ context 'when project is public' do
+ context 'when unsubscribing from issue' do
+ let(:noteable) { issue }
+
+ it 'shows issue title' do
+ expect(response.body).to include(issue.title)
+ end
+
+ it_behaves_like 'unsubscribing as anonymous'
+ end
+
+ context 'when unsubscribing from confidential issue' do
+ let(:noteable) { confidential_issue }
+
+ it 'does not show issue title' do
+ expect(response.body).not_to include(confidential_issue.title)
+ expect(response.body).to include(confidential_issue.to_reference)
+ end
+
+ it_behaves_like 'unsubscribing as anonymous'
+ end
+
+ context 'when unsubscribing from merge request' do
+ let(:noteable) { merge_request }
+
+ it 'shows merge request title' do
+ expect(response.body).to include(merge_request.title)
+ end
+
+ it_behaves_like 'unsubscribing as anonymous'
+ end
end
- it 'redirects to the login page' do
- expect(response).to render_template :unsubscribe
+ context 'when project is not public' do
+ let(:target_project) { private_project }
+
+ context 'when unsubscribing from issue' do
+ let(:noteable) { issue }
+
+ it 'shows issue title' do
+ expect(response.body).not_to include(issue.title)
+ end
+
+ it_behaves_like 'unsubscribing as anonymous'
+ end
+
+ context 'when unsubscribing from confidential issue' do
+ let(:noteable) { confidential_issue }
+
+ it 'does not show issue title' do
+ expect(response.body).not_to include(confidential_issue.title)
+ expect(response.body).to include(confidential_issue.to_reference)
+ end
+
+ it_behaves_like 'unsubscribing as anonymous'
+ end
+
+ context 'when unsubscribing from merge request' do
+ let(:noteable) { merge_request }
+
+ it 'shows merge request title' do
+ expect(response.body).not_to include(merge_request.title)
+ end
+
+ it_behaves_like 'unsubscribing as anonymous'
+ end
end
end
end
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 6bcff7f975c..9c4ddce5409 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -58,7 +58,26 @@ describe SessionsController do
it 'authenticates user correctly' do
post(:create, params: { user: user_params })
- expect(subject.current_user). to eq user
+ expect(subject.current_user).to eq user
+ end
+
+ context 'with password authentication disabled' do
+ before do
+ stub_application_setting(password_authentication_enabled_for_web: false)
+ end
+
+ it 'does not sign in the user' do
+ post(:create, params: { user: user_params })
+
+ expect(@request.env['warden']).not_to be_authenticated
+ expect(subject.current_user).to be_nil
+ end
+
+ it 'returns status 403' do
+ post(:create, params: { user: user_params })
+
+ expect(response.status).to eq 403
+ end
end
it 'creates an audit log record' do
@@ -153,6 +172,19 @@ describe SessionsController do
end
end
+ context 'with password authentication disabled' do
+ before do
+ stub_application_setting(password_authentication_enabled_for_web: false)
+ end
+
+ it 'allows 2FA stage of non-password login' do
+ authenticate_2fa(otp_attempt: user.current_otp)
+
+ expect(@request.env['warden']).to be_authenticated
+ expect(subject.current_user).to eq user
+ end
+ end
+
##
# See #14900 issue
#