diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2024-01-16 13:42:19 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2024-01-16 13:42:19 +0300 |
commit | 84d1bd786125c1c14a3ba5f63e38a4cc736a9027 (patch) | |
tree | f550fa965f507077e20dbb6d61a8269a99ef7107 /spec/controllers | |
parent | 3a105e36e689f7b75482236712f1a47fd5a76814 (diff) |
Add latest changes from gitlab-org/gitlab@16-8-stable-eev16.8.0-rc42
Diffstat (limited to 'spec/controllers')
28 files changed, 455 insertions, 119 deletions
diff --git a/spec/controllers/admin/projects_controller_spec.rb b/spec/controllers/admin/projects_controller_spec.rb index d81b067ffb6..95986b5c034 100644 --- a/spec/controllers/admin/projects_controller_spec.rb +++ b/spec/controllers/admin/projects_controller_spec.rb @@ -49,11 +49,11 @@ RSpec.describe Admin::ProjectsController do it 'does not have N+1 queries', :use_clean_rails_memory_store_caching, :request_store do get :index - control_count = ActiveRecord::QueryRecorder.new { get :index }.count + control = ActiveRecord::QueryRecorder.new { get :index } create(:project) - expect { get :index }.not_to exceed_query_limit(control_count) + expect { get :index }.not_to exceed_query_limit(control) end end diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb index d88fe41a869..186e1b13856 100644 --- a/spec/controllers/admin/runners_controller_spec.rb +++ b/spec/controllers/admin/runners_controller_spec.rb @@ -89,11 +89,11 @@ RSpec.describe Admin::RunnersController, feature_category: :fleet_visibility do it 'avoids N+1 queries', :request_store do get :edit, params: { id: runner.id } - control_count = ActiveRecord::QueryRecorder.new { get :edit, params: { id: runner.id } }.count + control = ActiveRecord::QueryRecorder.new { get :edit, params: { id: runner.id } } # There is one additional query looking up subject.group in ProjectPolicy for the # needs_new_sso_session permission - expect { get :edit, params: { id: runner.id } }.not_to exceed_query_limit(control_count + 1) + expect { get :edit, params: { id: runner.id } }.not_to exceed_query_limit(control).with_threshold(1) expect(response).to have_gitlab_http_status(:ok) end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index f4384dbaa69..715ded875fe 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -103,32 +103,6 @@ RSpec.describe ApplicationController, feature_category: :shared do end end - describe 'session expiration' do - controller(described_class) do - def index - render html: 'authenticated' - 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 - describe 'response format' do controller(described_class) do def index @@ -470,7 +444,7 @@ RSpec.describe ApplicationController, feature_category: :shared do enforce_terms - expect { get :index }.not_to exceed_query_limit(control.count).with_threshold(1) + expect { get :index }.not_to exceed_query_limit(control).with_threshold(1) end context 'when terms are enforced' do diff --git a/spec/controllers/concerns/issuable_collections_spec.rb b/spec/controllers/concerns/issuable_collections_spec.rb index 9eb0f36cb37..051172ea6da 100644 --- a/spec/controllers/concerns/issuable_collections_spec.rb +++ b/spec/controllers/concerns/issuable_collections_spec.rb @@ -74,7 +74,6 @@ RSpec.describe IssuableCollections do assignee_username: 'user1', author_id: '2', author_username: 'user2', - authorized_only: 'yes', confidential: true, due_date: '2017-01-01', group_id: '3', diff --git a/spec/controllers/concerns/renders_commits_spec.rb b/spec/controllers/concerns/renders_commits_spec.rb index 45f194b63e7..754107efee8 100644 --- a/spec/controllers/concerns/renders_commits_spec.rb +++ b/spec/controllers/concerns/renders_commits_spec.rb @@ -46,15 +46,15 @@ RSpec.describe RendersCommits do it 'avoids N + 1', :request_store do stub_const("MergeRequestDiff::COMMITS_SAFE_SIZE", 5) - control_count = ActiveRecord::QueryRecorder.new do + control = ActiveRecord::QueryRecorder.new do go - end.count + end stub_const("MergeRequestDiff::COMMITS_SAFE_SIZE", 15) expect do go - end.not_to exceed_all_query_limit(control_count) + end.not_to exceed_all_query_limit(control) end end @@ -73,7 +73,7 @@ RSpec.describe RendersCommits do expect do subject.prepare_commits_for_rendering(merge_request.commits) merge_request.commits.each(&:latest_pipeline) - end.not_to exceed_all_query_limit(control.count) + end.not_to exceed_all_query_limit(control) end end end diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb index 3dcf41941bb..38e39da2733 100644 --- a/spec/controllers/groups/labels_controller_spec.rb +++ b/spec/controllers/groups/labels_controller_spec.rb @@ -62,7 +62,9 @@ RSpec.describe Groups::LabelsController, feature_category: :team_planning do create_list(:group_label, 3, group: group) # some n+1 queries still exist - expect { get :index, params: { group_id: group.to_param } }.not_to exceed_all_query_limit(control.count).with_threshold(10) + expect do + get :index, params: { group_id: group.to_param } + end.not_to exceed_all_query_limit(control).with_threshold(10) expect(assigns(:labels).count).to eq(4) end end diff --git a/spec/controllers/groups/releases_controller_spec.rb b/spec/controllers/groups/releases_controller_spec.rb index 4b4333dea0e..1ca540ebb99 100644 --- a/spec/controllers/groups/releases_controller_spec.rb +++ b/spec/controllers/groups/releases_controller_spec.rb @@ -62,12 +62,12 @@ RSpec.describe Groups::ReleasesController do context 'N+1 queries' do it 'avoids N+1 database queries' do - control_count = ActiveRecord::QueryRecorder.new { subject }.count + control = ActiveRecord::QueryRecorder.new { subject } create_list(:release, 5, project: project) create_list(:release, 5, project: private_project) - expect { subject }.not_to exceed_query_limit(control_count) + expect { subject }.not_to exceed_query_limit(control) end end end diff --git a/spec/controllers/import/bitbucket_server_controller_spec.rb b/spec/controllers/import/bitbucket_server_controller_spec.rb index 3266c4d4d39..7e036b75e76 100644 --- a/spec/controllers/import/bitbucket_server_controller_spec.rb +++ b/spec/controllers/import/bitbucket_server_controller_spec.rb @@ -112,6 +112,7 @@ RSpec.describe Import::BitbucketServerController, feature_category: :importers d let(:token) { 'token' } let(:username) { 'bitbucket-user' } let(:url) { 'http://localhost:7990/bitbucket' } + let(:experiment) { instance_double(ApplicationExperiment) } it 'clears out existing session' do post :configure @@ -124,6 +125,17 @@ RSpec.describe Import::BitbucketServerController, feature_category: :importers d expect(response).to redirect_to(status_import_bitbucket_server_path) end + it 'tracks default_to_import_tab experiment' do + allow(controller) + .to receive(:experiment) + .with(:default_to_import_tab, actor: user) + .and_return(experiment) + + expect(experiment).to receive(:track).with(:authentication, property: :bitbucket_server) + + post :configure + end + it 'sets the session variables' do allow(controller).to receive(:allow_local_requests?).and_return(true) diff --git a/spec/controllers/import/bulk_imports_controller_spec.rb b/spec/controllers/import/bulk_imports_controller_spec.rb index 9b41089f4b8..54192f010ed 100644 --- a/spec/controllers/import/bulk_imports_controller_spec.rb +++ b/spec/controllers/import/bulk_imports_controller_spec.rb @@ -303,27 +303,11 @@ RSpec.describe Import::BulkImportsController, feature_category: :importers do describe 'GET details' do subject(:request) { get :details } - context 'when bulk_import_details_page feature flag is enabled' do - before do - stub_feature_flags(bulk_import_details_page: true) - request - end - - it 'responds with a 200 and shows the template', :aggregate_failures do - expect(response).to have_gitlab_http_status(:ok) - expect(response).to render_template(:details) - end - end + it 'responds with a 200 and shows the template', :aggregate_failures do + request - context 'when bulk_import_details_page feature flag is disabled' do - before do - stub_feature_flags(bulk_import_details_page: false) - request - end - - it 'responds with a 404' do - expect(response).to have_gitlab_http_status(:not_found) - end + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template(:details) end end diff --git a/spec/controllers/import/fogbugz_controller_spec.rb b/spec/controllers/import/fogbugz_controller_spec.rb index 273dfd6a9c7..45b959b1b78 100644 --- a/spec/controllers/import/fogbugz_controller_spec.rb +++ b/spec/controllers/import/fogbugz_controller_spec.rb @@ -17,6 +17,7 @@ RSpec.describe Import::FogbugzController, feature_category: :importers do end describe 'POST #callback' do + let(:experiment) { instance_double(ApplicationExperiment) } let(:xml_response) { %(<?xml version=\"1.0\" encoding=\"UTF-8\"?><response><token><![CDATA[#{token}]]></token></response>) } before do @@ -31,6 +32,17 @@ RSpec.describe Import::FogbugzController, feature_category: :importers do expect(response).to redirect_to(new_user_map_import_fogbugz_path) end + it 'tracks default_to_import_tab experiment' do + allow(controller) + .to receive(:experiment) + .with(:default_to_import_tab, actor: user) + .and_return(experiment) + + expect(experiment).to receive(:track).with(:successfully_authenticated, property: :fogbugz) + + post :callback, params: { uri: uri, email: 'test@example.com', password: 'mypassword' } + end + it 'preserves namespace_id query param on success' do post :callback, params: { uri: uri, email: 'test@example.com', password: 'mypassword', namespace_id: namespace_id } @@ -46,12 +58,27 @@ RSpec.describe Import::FogbugzController, feature_category: :importers do expect(response).to redirect_to(new_import_fogbugz_url(namespace_id: namespace_id)) end - it 'redirects to new page form when client raises authentication exception' do - allow(::Gitlab::FogbugzImport::Client).to receive(:new).and_raise(::Fogbugz::AuthenticationException) + context 'when client raises authentication exception' do + before do + allow(::Gitlab::FogbugzImport::Client).to receive(:new).and_raise(::Fogbugz::AuthenticationException) + end - post :callback, params: { uri: uri, email: 'test@example.com', password: 'mypassword' } + it 'redirects to new page form' do + post :callback, params: { uri: uri, email: 'test@example.com', password: 'mypassword' } + + expect(response).to redirect_to(new_import_fogbugz_url) + end - expect(response).to redirect_to(new_import_fogbugz_url) + it 'does not track default_to_import_tab experiment when client raises authentication exception' do + allow(controller) + .to receive(:experiment) + .with(:default_to_import_tab, actor: user) + .and_return(experiment) + + expect(experiment).not_to receive(:track) + + post :callback, params: { uri: uri, email: 'test@example.com', password: 'mypassword' } + end end context 'verify url' do diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb index aafba6e2b9f..3d6b35a5c26 100644 --- a/spec/controllers/import/github_controller_spec.rb +++ b/spec/controllers/import/github_controller_spec.rb @@ -100,7 +100,20 @@ RSpec.describe Import::GithubController, feature_category: :importers do end describe "POST personal_access_token" do + let(:experiment) { instance_double(ApplicationExperiment) } + it_behaves_like 'a GitHub-ish import controller: POST personal_access_token' + + it 'tracks default_to_import_tab experiment' do + allow(controller) + .to receive(:experiment) + .with(:default_to_import_tab, actor: user) + .and_return(experiment) + + expect(experiment).to receive(:track).with(:authentication, property: :github) + + post :personal_access_token + end end describe "GET status" do diff --git a/spec/controllers/import/manifest_controller_spec.rb b/spec/controllers/import/manifest_controller_spec.rb index c06bd660cd2..17a107dd839 100644 --- a/spec/controllers/import/manifest_controller_spec.rb +++ b/spec/controllers/import/manifest_controller_spec.rb @@ -19,6 +19,8 @@ RSpec.describe Import::ManifestController, :clean_gitlab_redis_shared_state, fea end describe 'POST upload' do + let(:experiment) { instance_double(ApplicationExperiment) } + context 'with a valid manifest' do it 'saves the manifest and redirects to the status page', :aggregate_failures do post :upload, params: { @@ -34,6 +36,20 @@ RSpec.describe Import::ManifestController, :clean_gitlab_redis_shared_state, fea expect(response).to redirect_to(status_import_manifest_path) end + + it 'tracks default_to_import_tab experiment' do + allow(controller) + .to receive(:experiment) + .with(:default_to_import_tab, actor: user) + .and_return(experiment) + + expect(experiment).to receive(:track).with(:successfully_imported, property: :manifest) + + post :upload, params: { + group_id: group.id, + manifest: fixture_file_upload('spec/fixtures/aosp_manifest.xml') + } + end end context 'with an invalid manifest' do @@ -45,6 +61,20 @@ RSpec.describe Import::ManifestController, :clean_gitlab_redis_shared_state, fea expect(assigns(:errors)).to be_present end + + it 'does not track default_to_import_tab experiment' do + allow(controller) + .to receive(:experiment) + .with(:default_to_import_tab, actor: user) + .and_return(experiment) + + expect(experiment).not_to receive(:track) + + post :upload, params: { + group_id: group.id, + manifest: fixture_file_upload('spec/fixtures/invalid_manifest.xml') + } + end end context 'when the user cannot import projects in the group' do diff --git a/spec/controllers/oauth/authorizations_controller_spec.rb b/spec/controllers/oauth/authorizations_controller_spec.rb index cfb512afc91..ce21c278a53 100644 --- a/spec/controllers/oauth/authorizations_controller_spec.rb +++ b/spec/controllers/oauth/authorizations_controller_spec.rb @@ -216,24 +216,6 @@ RSpec.describe Oauth::AuthorizationsController do end end - context 'when the user is not signed in' do - before do - sign_out(user) - end - - it 'sets a lower session expiry and redirects to the sign in page' do - subject - - expect(request.env['rack.session.options'][:expire_after]).to eq( - Settings.gitlab['unauthenticated_session_expire_delay'] - ) - - expect(request.session['user_return_to']).to eq("/oauth/authorize?#{params.to_query}") - expect(response).to have_gitlab_http_status(:found) - expect(response).to redirect_to(new_user_session_path) - end - end - context 'when the user is admin' do context 'when disable_admin_oauth_scopes is set' do before do diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb index 5b1fdd6388a..e99d9e949a8 100644 --- a/spec/controllers/omniauth_callbacks_controller_spec.rb +++ b/spec/controllers/omniauth_callbacks_controller_spec.rb @@ -31,6 +31,67 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: end end + shared_examples 'omniauth sign in that remembers user' do + before do + stub_omniauth_setting(allow_bypass_two_factor: allow_bypass_two_factor) + (request.env['omniauth.params'] ||= {}).deep_merge!('remember_me' => omniauth_params_remember_me) + end + + if params[:call_remember_me] + it 'calls devise method remember_me' do + expect(controller).to receive(:remember_me).with(user).and_call_original + + post_action + end + else + it 'does not calls devise method remember_me' do + expect(controller).not_to receive(:remember_me) + + post_action + end + end + end + + shared_examples 'omniauth sign in that remembers user with two factor enabled' do + using RSpec::Parameterized::TableSyntax + + subject(:post_action) { post provider } + + where(:allow_bypass_two_factor, :omniauth_params_remember_me, :call_remember_me) do + true | '1' | true + true | '0' | false + true | nil | false + false | '1' | false + false | '0' | false + false | nil | false + end + + with_them do + it_behaves_like 'omniauth sign in that remembers user' + end + end + + shared_examples 'omniauth sign in that remembers user with two factor disabled' do + context "when user selects remember me for omniauth sign in flow" do + using RSpec::Parameterized::TableSyntax + + subject(:post_action) { post provider } + + where(:allow_bypass_two_factor, :omniauth_params_remember_me, :call_remember_me) do + true | '1' | true + true | '0' | false + true | nil | false + false | '1' | true + false | '0' | false + false | nil | false + end + + with_them do + it_behaves_like 'omniauth sign in that remembers user' + end + end + end + describe 'omniauth' do let(:user) { create(:omniauth_user, extern_uid: extern_uid, provider: provider) } let(:additional_info) { {} } @@ -190,6 +251,8 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: request.env['omniauth.params'] = { 'redirect_fragment' => 'L101' } end + it_behaves_like 'omniauth sign in that remembers user with two factor disabled' + context 'when a redirect url is stored' do it 'redirects with fragment' do post provider, session: { user_return_to: '/fake/url' } @@ -214,6 +277,12 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: expect(response.location).not_to include('#L101') end end + + context 'when a user has 2FA enabled' do + let(:user) { create(:omniauth_user, :two_factor, extern_uid: extern_uid, provider: provider) } + + it_behaves_like 'omniauth sign in that remembers user with two factor enabled' + end end context 'with strategies' do @@ -271,6 +340,8 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: end end + it_behaves_like 'omniauth sign in that remembers user with two factor disabled' + context 'when a user has 2FA enabled' do render_views @@ -296,6 +367,8 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: expect(response).to have_gitlab_http_status(:ok) end end + + it_behaves_like 'omniauth sign in that remembers user with two factor enabled' end context 'for sign up' do @@ -357,6 +430,10 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: let(:extern_uid) { '' } let(:provider) { :auth0 } + it_behaves_like 'omniauth sign in that remembers user with two factor disabled' do + let(:extern_uid) { 'my-uid' } + end + it 'does not allow sign in without extern_uid' do post 'auth0' @@ -364,6 +441,14 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: expect(response).to have_gitlab_http_status(:found) expect(controller).to set_flash[:alert].to('Wrong extern UID provided. Make sure Auth0 is configured correctly.') end + + context 'when a user has 2FA enabled' do + let(:user) { create(:omniauth_user, :two_factor, extern_uid: extern_uid, provider: provider) } + + it_behaves_like 'omniauth sign in that remembers user with two factor enabled' do + let(:extern_uid) { 'my-uid' } + end + end end context 'for atlassian_oauth2' do @@ -373,6 +458,8 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: context 'when the user and identity already exist' do let(:user) { create(:atlassian_user, extern_uid: extern_uid) } + it_behaves_like 'omniauth sign in that remembers user with two factor disabled' + it 'allows sign-in' do post :atlassian_oauth2 @@ -391,6 +478,12 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: post :atlassian_oauth2 end + + context 'when a user has 2FA enabled' do + let(:user) { create(:atlassian_user, :two_factor, extern_uid: extern_uid) } + + it_behaves_like 'omniauth sign in that remembers user with two factor enabled' + end end context 'for a new user' do @@ -443,11 +536,21 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: include_context 'with sign_up' let(:additional_info) { { extra: { email_verified: true } } } + it_behaves_like 'omniauth sign in that remembers user with two factor disabled' do + let(:user) { create(:omniauth_user, extern_uid: extern_uid, provider: provider) } + end + it 'allows sign in' do post 'salesforce' expect(request.env['warden']).to be_authenticated end + + context 'when a user has 2FA enabled' do + let(:user) { create(:omniauth_user, :two_factor, extern_uid: extern_uid, provider: provider) } + + it_behaves_like 'omniauth sign in that remembers user with two factor enabled' + end end end end @@ -497,11 +600,19 @@ RSpec.describe OmniauthCallbacksController, type: :controller, feature_category: let(:post_action) { post provider } end + it_behaves_like 'omniauth sign in that remembers user with two factor disabled' + it 'allows sign in' do post provider expect(request.env['warden']).to be_authenticated end + + context 'when a user has 2FA enabled' do + let(:user) { create(:omniauth_user, :two_factor, extern_uid: extern_uid, provider: provider) } + + it_behaves_like 'omniauth sign in that remembers user with two factor enabled' + end end describe '#saml' do diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index b29a172f5b1..721125749a5 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -987,11 +987,11 @@ RSpec.describe Projects::IssuesController, :request_store, feature_category: :te labels = create_list(:label, 10, project: project).map(&:to_reference) issue = create(:issue, project: project, description: 'Test issue') - control_count = ActiveRecord::QueryRecorder.new { issue.update!(description: [issue.description, label].join(' ')) }.count + control = ActiveRecord::QueryRecorder.new { issue.update!(description: [issue.description, label].join(' ')) } # Follow-up to get rid of this `2 * label.count` requirement: https://gitlab.com/gitlab-org/gitlab-foss/issues/52230 expect { issue.update!(description: [issue.description, labels].join(' ')) } - .not_to exceed_query_limit(control_count + 2 * labels.count) + .not_to exceed_query_limit(control).with_threshold(2 * labels.count) end it 'logs the view with Gitlab::Search::RecentIssues' do @@ -1849,15 +1849,17 @@ RSpec.describe Projects::IssuesController, :request_store, feature_category: :te RequestStore.clear! - control_count = ActiveRecord::QueryRecorder.new do + control = ActiveRecord::QueryRecorder.new do get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } - end.count + end RequestStore.clear! create_list(:discussion_note_on_issue, 2, :system, noteable: issue, project: issue.project, note: cross_reference) - expect { get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } }.not_to exceed_query_limit(control_count) + expect do + get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } + end.not_to exceed_query_limit(control) end end diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb index db8cac8bb4a..2333ff0a937 100644 --- a/spec/controllers/projects/labels_controller_spec.rb +++ b/spec/controllers/projects/labels_controller_spec.rb @@ -108,7 +108,7 @@ RSpec.describe Projects::LabelsController, feature_category: :team_planning do # some n+1 queries still exist # calls to get max project authorization access level - expect { list_labels }.not_to exceed_all_query_limit(control.count).with_threshold(25) + expect { list_labels }.not_to exceed_all_query_limit(control).with_threshold(25) expect(assigns(:labels).count).to eq(10) end end diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb index b2b591d7929..3c975c76337 100644 --- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb @@ -138,10 +138,16 @@ RSpec.describe Projects::MergeRequests::DiffsController, feature_category: :code end let(:project) { create(:project, :repository) } - let(:user) { create(:user) } let(:maintainer) { true } let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) } + let_it_be_with_reload(:user) { create(:user) } + let_it_be(:other_project) { create(:project) } + + before_all do + other_project.add_maintainer(user) + end + before do project.add_maintainer(user) if maintainer sign_in(user) @@ -429,10 +435,7 @@ RSpec.describe Projects::MergeRequests::DiffsController, feature_category: :code end context 'when the merge request belongs to a different project' do - let(:other_project) { create(:project) } - before do - other_project.add_maintainer(user) diff_for_path(old_path: existing_path, new_path: existing_path, project_id: other_project) end @@ -442,6 +445,84 @@ RSpec.describe Projects::MergeRequests::DiffsController, feature_category: :code end end + describe 'GET diff_by_file_hash' do + def diff_by_file_hash(extra_params = {}) + params = { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid, + format: 'json' + } + + get :diff_by_file_hash, params: params.merge(extra_params) + end + + let(:file) { merge_request.merge_request_diff.diffs.diff_files.first } + let(:file_hash) { file.file_hash } + + context 'when the merge request exists' do + context 'when the user can view the merge request' do + context 'when the path exists in the diff' do + include_examples 'diff tracking' do + let(:method_call) { diff_by_file_hash(file_hash: file_hash) } + end + + it 'enables diff notes' do + diff_by_file_hash(file_hash: file_hash) + + expect(assigns(:diff_notes_disabled)).to be_falsey + expect(assigns(:new_diff_note_attrs)).to eq( + noteable_type: 'MergeRequest', + noteable_id: merge_request.id, + commit_id: nil + ) + end + + it 'only renders diff for the hash given' do + diff_by_file_hash(file_hash: file_hash) + + diffs = json_response['diff_files'] + + expect(diffs.count).to eq(1) + expect(diffs.first['file_hash']).to eq(file_hash) + end + end + end + + context 'when the user cannot view the merge request' do + let(:maintainer) { false } + + before do + diff_by_file_hash(file_hash: file_hash) + end + + it 'returns a 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'when the merge request does not exist' do + before do + diff_by_file_hash(id: merge_request.iid.succ, file_hash: file_hash) + end + + it 'returns a 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when the merge request belongs to a different project' do + before do + diff_by_file_hash(project_id: other_project, file_hash: file_hash) + end + + it 'returns a 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + describe 'GET diffs_batch' do shared_examples_for 'serializes diffs with expected arguments' do it 'serializes paginated merge request diff collection' do diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 55741a82862..d04cda240fa 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -244,6 +244,24 @@ RSpec.describe Projects::MergeRequestsController, feature_category: :code_review expect(response).to have_gitlab_http_status(:moved_permanently) end end + + context 'when has pinned file' do + let(:file) { merge_request.merge_request_diff.diffs.diff_files.first } + let(:file_hash) { file.file_hash } + + it 'adds pinned file url' do + go(pin: file_hash) + + expect(assigns['pinned_file_url']).to eq( + diff_by_file_hash_namespace_project_merge_request_path( + format: 'json', + id: merge_request.iid, + namespace_id: project.namespace.to_param, + project_id: project.path, + file_hash: file_hash + )) + end + end end context 'when user is setting notes filters' do diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb index 678991b91a5..6b440b90f37 100644 --- a/spec/controllers/projects/notes_controller_spec.rb +++ b/spec/controllers/projects/notes_controller_spec.rb @@ -249,15 +249,15 @@ RSpec.describe Projects::NotesController, type: :controller, feature_category: : RequestStore.clear! - control_count = ActiveRecord::QueryRecorder.new do + control = ActiveRecord::QueryRecorder.new do get :index, params: request_params - end.count + end RequestStore.clear! create_list(:discussion_note_on_issue, 2, :system, noteable: issue, project: issue.project, note: cross_reference) - expect { get :index, params: request_params }.not_to exceed_query_limit(control_count) + expect { get :index, params: request_params }.not_to exceed_query_limit(control) end end end diff --git a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb index fc741d0f3f6..292c4017d8e 100644 --- a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb +++ b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::Packages::InfrastructureRegistryController do +RSpec.describe Projects::Packages::InfrastructureRegistryController, feature_category: :package_registry do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :private) } diff --git a/spec/controllers/projects/packages/packages_controller_spec.rb b/spec/controllers/projects/packages/packages_controller_spec.rb index da9cae47c62..8570af075ad 100644 --- a/spec/controllers/projects/packages/packages_controller_spec.rb +++ b/spec/controllers/projects/packages/packages_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::Packages::PackagesController do +RSpec.describe Projects::Packages::PackagesController, feature_category: :package_registry do let_it_be(:project) { create(:project, :public) } let(:page) { :index } diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb index 7cd4f43d4da..9fe2e4c23e0 100644 --- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb +++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb @@ -108,11 +108,11 @@ RSpec.describe Projects::PipelineSchedulesController, feature_category: :continu end it 'avoids N + 1 queries', :request_store do - control_count = ActiveRecord::QueryRecorder.new { visit_pipelines_schedules }.count + control = ActiveRecord::QueryRecorder.new { visit_pipelines_schedules } create_list(:ci_pipeline_schedule, 2, project: project) - expect { visit_pipelines_schedules }.not_to exceed_query_limit(control_count) + expect { visit_pipelines_schedules }.not_to exceed_query_limit(control) end context 'when the scope is set to active' do diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index deaed8e1162..82c1aa3e18c 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -381,7 +381,7 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte # Set up all required variables get_pipeline_json - control_count = ActiveRecord::QueryRecorder.new { get_pipeline_json }.count + control = ActiveRecord::QueryRecorder.new { get_pipeline_json } first_build = pipeline.builds.first first_build.tag_list << [:hello, :world] @@ -391,9 +391,7 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte second_build.tag_list << [:docker, :ruby] create(:deployment, deployable: second_build) - new_count = ActiveRecord::QueryRecorder.new { get_pipeline_json }.count - - expect(new_count).to be_within(1).of(control_count) + expect { get_pipeline_json }.not_to exceed_query_limit(control).with_threshold(1) end end @@ -1074,7 +1072,7 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte clear_controller_memoization - control_count = ActiveRecord::QueryRecorder.new { get_test_report_json }.count + control = ActiveRecord::QueryRecorder.new { get_test_report_json } create(:ci_build, name: 'karma', pipeline: pipeline).tap do |build| create(:ci_job_artifact, :junit, job: build) @@ -1082,7 +1080,7 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte clear_controller_memoization - expect { get_test_report_json }.not_to exceed_query_limit(control_count) + expect { get_test_report_json }.not_to exceed_query_limit(control) end end diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb index 345e6e2e0de..ab879d9aeb7 100644 --- a/spec/controllers/projects/refs_controller_spec.rb +++ b/spec/controllers/projects/refs_controller_spec.rb @@ -78,6 +78,23 @@ RSpec.describe Projects::RefsController, feature_category: :source_code_manageme expect(response).to have_gitlab_http_status(:bad_request) end end + + context 'with an invalid path parameter' do + it 'returns 400 bad request' do + params = { + destination: 'graphs_commits', + namespace_id: project.namespace.to_param, + project_id: project, + id: 'master', + ref_type: nil, + path: '*' + } + + get :switch, params: params + + expect(response).to have_gitlab_http_status(:bad_request) + end + end end describe 'GET #logs_tree' do diff --git a/spec/controllers/projects/security/configuration_controller_spec.rb b/spec/controllers/projects/security/configuration_controller_spec.rb index 1ce0fcd85db..bfd269f9398 100644 --- a/spec/controllers/projects/security/configuration_controller_spec.rb +++ b/spec/controllers/projects/security/configuration_controller_spec.rb @@ -48,19 +48,6 @@ RSpec.describe Projects::Security::ConfigurationController do expect(sast_feature['available']).to be_truthy expect(dast_feature['available']).to be_falsey end - - context 'with feature flag unify_security_configuration turned off' do - before do - stub_feature_flags(unify_security_configuration: false) - end - - it 'responds with empty configuration data json' do - get :show, params: { namespace_id: project.namespace, project_id: project, format: :json } - - expect(response).to have_gitlab_http_status(:ok) - expect(json_response).to be_empty - end - end end end end diff --git a/spec/controllers/projects/starrers_controller_spec.rb b/spec/controllers/projects/starrers_controller_spec.rb index 2148f495c31..236bb408d32 100644 --- a/spec/controllers/projects/starrers_controller_spec.rb +++ b/spec/controllers/projects/starrers_controller_spec.rb @@ -40,11 +40,11 @@ RSpec.describe Projects::StarrersController do it 'avoids N+1s loading users', :request_store do get_starrers - control_count = ActiveRecord::QueryRecorder.new { get_starrers }.count + control = ActiveRecord::QueryRecorder.new { get_starrers } create_list(:user, 5).each { |user| user.toggle_star(project) } - expect { get_starrers }.not_to exceed_query_limit(control_count) + expect { get_starrers }.not_to exceed_query_limit(control) end end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 88d9d1228e3..3ddfb5e7262 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -43,6 +43,49 @@ RSpec.describe ProjectsController, feature_category: :groups_and_projects do end end end + + context 'with managable group' do + context 'when managable_group_count is 1' do + before do + group.add_owner(user) + end + + it 'renders the template' do + get :new + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template('new') + end + end + + context 'when managable_group_count is 0' do + context 'when create_projects on personal namespace is allowed' do + before do + allow(user).to receive(:can_create_project?).and_return(true) + end + + it 'renders the template' do + get :new + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template('new') + end + end + + context 'when create_projects on personal namespace is not allowed' do + before do + stub_application_setting(allow_project_creation_for_guest_and_below: false) + end + + it 'responds with status 404' do + get :new + + expect(response).to have_gitlab_http_status(:not_found) + expect(response).not_to render_template('new') + end + end + end + end end end @@ -1101,6 +1144,23 @@ RSpec.describe ProjectsController, feature_category: :groups_and_projects do it_behaves_like 'feature update success' end end + + context 'project topics' do + context 'on updates with topics of the same name (case insensitive)' do + it 'returns 200, with alert about update failing' do + put :update, params: { + namespace_id: project.namespace, + id: project.path, + project: { + topics: 'smoketest, SMOKETEST' + } + } + + expect(response).to be_successful + expect(flash[:alert]).to eq('Project could not be updated!') + end + end + end end describe '#transfer', :enable_admin_mode do diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index 8ae78c5ee35..9c246c21104 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -776,6 +776,45 @@ RSpec.describe UploadsController, feature_category: :groups_and_projects do end end end + + context 'when viewing an organization avatar' do + let(:organization_detail) { create(:organization_detail) } + let(:organization) { organization_detail.organization } + + subject(:request) do + get( + :show, + params: { + model: 'organizations/organization_detail', + mounted_as: 'avatar', + id: organization.id, + filename: 'dk.png' + } + ) + end + + context 'when signed in' do + before do + sign_in(user) + end + + it 'responds with status 200' do + request + expect(response).to have_gitlab_http_status(:ok) + end + + it_behaves_like 'content publicly cached' + end + + context 'when not signed in' do + it 'responds with status 200' do + request + expect(response).to have_gitlab_http_status(:ok) + end + + it_behaves_like 'content publicly cached' + end + end end def post_authorize(verified: true) |