diff options
Diffstat (limited to 'spec/controllers')
58 files changed, 1107 insertions, 365 deletions
diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb index e02589ddc83..ab0cad989cb 100644 --- a/spec/controllers/admin/application_settings_controller_spec.rb +++ b/spec/controllers/admin/application_settings_controller_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Admin::ApplicationSettingsController, :do_not_mock_admin_mode_set let(:group) { create(:group) } let(:project) { create(:project, namespace: group) } let(:admin) { create(:admin) } - let(:user) { create(:user)} + let(:user) { create(:user) } before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') @@ -362,6 +362,17 @@ RSpec.describe Admin::ApplicationSettingsController, :do_not_mock_admin_mode_set expect(application_settings.reload.pipeline_limit_per_project_user_sha).to eq(25) end end + + context 'invitation flow enforcement setting' do + let(:application_settings) { ApplicationSetting.current } + + it 'updates invitation_flow_enforcement setting' do + put :update, params: { application_setting: { invitation_flow_enforcement: true } } + + expect(response).to redirect_to(general_admin_application_settings_path) + expect(application_settings.reload.invitation_flow_enforcement).to eq(true) + end + end end describe 'PUT #reset_registration_token' do diff --git a/spec/controllers/admin/applications_controller_spec.rb b/spec/controllers/admin/applications_controller_spec.rb index 6c423097e70..bf7707f177c 100644 --- a/spec/controllers/admin/applications_controller_spec.rb +++ b/spec/controllers/admin/applications_controller_spec.rb @@ -39,17 +39,43 @@ RSpec.describe Admin::ApplicationsController do end describe 'POST #create' do - it 'creates the application' do - create_params = attributes_for(:application, trusted: true, confidential: false, scopes: ['api']) + context 'with hash_oauth_secrets flag off' do + before do + stub_feature_flags(hash_oauth_secrets: false) + end - expect do - post :create, params: { doorkeeper_application: create_params } - end.to change { Doorkeeper::Application.count }.by(1) + it 'creates the application' do + create_params = attributes_for(:application, trusted: true, confidential: false, scopes: ['api']) + + expect do + post :create, params: { doorkeeper_application: create_params } + end.to change { Doorkeeper::Application.count }.by(1) - application = Doorkeeper::Application.last + application = Doorkeeper::Application.last - expect(response).to redirect_to(admin_application_path(application)) - expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + expect(response).to redirect_to(admin_application_path(application)) + expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + end + end + + context 'with hash_oauth_secrets flag on' do + before do + stub_feature_flags(hash_oauth_secrets: true) + end + + it 'creates the application' do + create_params = attributes_for(:application, trusted: true, confidential: false, scopes: ['api']) + + expect do + post :create, params: { doorkeeper_application: create_params } + end.to change { Doorkeeper::Application.count }.by(1) + + application = Doorkeeper::Application.last + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template :show + expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + end end it 'renders the application form on errors' do @@ -62,17 +88,43 @@ RSpec.describe Admin::ApplicationsController do end context 'when the params are for a confidential application' do - it 'creates a confidential application' do - create_params = attributes_for(:application, confidential: true, scopes: ['read_user']) + context 'with hash_oauth_secrets flag off' do + before do + stub_feature_flags(hash_oauth_secrets: false) + end - expect do - post :create, params: { doorkeeper_application: create_params } - end.to change { Doorkeeper::Application.count }.by(1) + it 'creates a confidential application' do + create_params = attributes_for(:application, confidential: true, scopes: ['read_user']) - application = Doorkeeper::Application.last + expect do + post :create, params: { doorkeeper_application: create_params } + end.to change { Doorkeeper::Application.count }.by(1) - expect(response).to redirect_to(admin_application_path(application)) - expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + application = Doorkeeper::Application.last + + expect(response).to redirect_to(admin_application_path(application)) + expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + end + end + + context 'with hash_oauth_secrets flag on' do + before do + stub_feature_flags(hash_oauth_secrets: true) + end + + it 'creates a confidential application' do + create_params = attributes_for(:application, confidential: true, scopes: ['read_user']) + + expect do + post :create, params: { doorkeeper_application: create_params } + end.to change { Doorkeeper::Application.count }.by(1) + + application = Doorkeeper::Application.last + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template :show + expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + end end end diff --git a/spec/controllers/admin/cohorts_controller_spec.rb b/spec/controllers/admin/cohorts_controller_spec.rb index d271276a3e4..766073977c6 100644 --- a/spec/controllers/admin/cohorts_controller_spec.rb +++ b/spec/controllers/admin/cohorts_controller_spec.rb @@ -13,5 +13,17 @@ RSpec.describe Admin::CohortsController do it_behaves_like 'tracking unique visits', :index do let(:target_id) { 'i_analytics_cohorts' } end + + it_behaves_like 'Snowplow event tracking' do + subject { get :index } + + let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } + let(:category) { described_class.name } + let(:action) { 'perform_analytics_usage_action' } + let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' } + let(:property) { 'i_analytics_cohorts' } + let(:namespace) { nil } + let(:project) { nil } + end end end diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb index fea59969400..9e852cb28dd 100644 --- a/spec/controllers/admin/runners_controller_spec.rb +++ b/spec/controllers/admin/runners_controller_spec.rb @@ -74,7 +74,7 @@ RSpec.describe Admin::RunnersController do context 'with update succeeding' do before do expect_next_instance_of(Ci::Runners::UpdateRunnerService, runner) do |service| - expect(service).to receive(:update).with(anything).and_call_original + expect(service).to receive(:execute).with(anything).and_call_original end end @@ -91,7 +91,7 @@ RSpec.describe Admin::RunnersController do context 'with update failing' do before do expect_next_instance_of(Ci::Runners::UpdateRunnerService, runner) do |service| - expect(service).to receive(:update).with(anything).and_return(false) + expect(service).to receive(:execute).with(anything).and_return(ServiceResponse.error(message: 'failure')) end end diff --git a/spec/controllers/admin/spam_logs_controller_spec.rb b/spec/controllers/admin/spam_logs_controller_spec.rb index 13038339d08..48221f496fb 100644 --- a/spec/controllers/admin/spam_logs_controller_spec.rb +++ b/spec/controllers/admin/spam_logs_controller_spec.rb @@ -27,13 +27,34 @@ RSpec.describe Admin::SpamLogsController do expect(response).to have_gitlab_http_status(:ok) end - it 'removes user and their spam logs when removing the user', :sidekiq_might_not_need_inline do - delete :destroy, params: { id: first_spam.id, remove_user: true } + context 'when user_destroy_with_limited_execution_time_worker is enabled' do + it 'initiates user removal', :sidekiq_inline do + expect do + delete :destroy, params: { id: first_spam.id, remove_user: true } + end.not_to change { SpamLog.count } - expect(flash[:notice]).to eq "User #{user.username} was successfully removed." - expect(response).to have_gitlab_http_status(:found) - expect(SpamLog.count).to eq(0) - expect { User.find(user.id) }.to raise_error(ActiveRecord::RecordNotFound) + expect(response).to have_gitlab_http_status(:found) + expect( + Users::GhostUserMigration.where(user: user, + initiator_user: admin) + ).to be_exists + expect(flash[:notice]).to eq("User #{user.username} was successfully removed.") + end + end + + context 'when user_destroy_with_limited_execution_time_worker is disabled' do + before do + stub_feature_flags(user_destroy_with_limited_execution_time_worker: false) + end + + it 'removes user and their spam logs when removing the user', :sidekiq_inline do + delete :destroy, params: { id: first_spam.id, remove_user: true } + + expect(flash[:notice]).to eq "User #{user.username} was successfully removed." + expect(response).to have_gitlab_http_status(:found) + expect(SpamLog.count).to eq(0) + expect { User.find(user.id) }.to raise_error(ActiveRecord::RecordNotFound) + end end end diff --git a/spec/controllers/admin/topics_controller_spec.rb b/spec/controllers/admin/topics_controller_spec.rb index 87093e0263b..111fdcc3be6 100644 --- a/spec/controllers/admin/topics_controller_spec.rb +++ b/spec/controllers/admin/topics_controller_spec.rb @@ -194,7 +194,7 @@ RSpec.describe Admin::TopicsController do end it 'renders a 400 error for identical topic ids' do - post :merge, params: { source_topic_id: topic, target_topic_id: topic.id } + post :merge, params: { source_topic_id: topic.id, target_topic_id: topic.id } expect(response).to have_gitlab_http_status(:bad_request) expect { topic.reload }.not_to raise_error diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 515ad9daf36..682399f4dd9 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -73,51 +73,120 @@ RSpec.describe Admin::UsersController do project.add_developer(user) end - it 'deletes user and ghosts their contributions' do - delete :destroy, params: { id: user.username }, format: :json + context 'when user_destroy_with_limited_execution_time_worker is enabled' do + it 'initiates user removal' do + delete :destroy, params: { id: user.username }, format: :json - expect(response).to have_gitlab_http_status(:ok) - expect(User.exists?(user.id)).to be_falsy - expect(issue.reload.author).to be_ghost - end + expect(response).to have_gitlab_http_status(:ok) + expect( + Users::GhostUserMigration.where(user: user, + initiator_user: admin, + hard_delete: false) + ).to be_exists + end - it 'deletes the user and their contributions when hard delete is specified' do - delete :destroy, params: { id: user.username, hard_delete: true }, format: :json + it 'initiates user removal and passes hard delete option' do + delete :destroy, params: { id: user.username, hard_delete: true }, format: :json - expect(response).to have_gitlab_http_status(:ok) - expect(User.exists?(user.id)).to be_falsy - expect(Issue.exists?(issue.id)).to be_falsy - end + expect(response).to have_gitlab_http_status(:ok) + expect( + Users::GhostUserMigration.where(user: user, + initiator_user: admin, + hard_delete: true) + ).to be_exists + end - context 'prerequisites for account deletion' do - context 'solo-owned groups' do - let(:group) { create(:group) } + context 'prerequisites for account deletion' do + context 'solo-owned groups' do + let(:group) { create(:group) } - context 'if the user is the sole owner of at least one group' do - before do - create(:group_member, :owner, group: group, user: user) - end + context 'if the user is the sole owner of at least one group' do + before do + create(:group_member, :owner, group: group, user: user) + end + + context 'soft-delete' do + it 'fails' do + delete :destroy, params: { id: user.username } - context 'soft-delete' do - it 'fails' do - delete :destroy, params: { id: user.username } + message = s_('AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account') - message = s_('AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account') + expect(flash[:alert]).to eq(message) + expect(response).to have_gitlab_http_status(:see_other) + expect(response).to redirect_to admin_user_path(user) + expect(Users::GhostUserMigration).not_to exist + end + end - expect(flash[:alert]).to eq(message) - expect(response).to have_gitlab_http_status(:see_other) - expect(response).to redirect_to admin_user_path(user) - expect(User.exists?(user.id)).to be_truthy + context 'hard-delete' do + it 'succeeds' do + delete :destroy, params: { id: user.username, hard_delete: true } + + expect(response).to redirect_to(admin_users_path) + expect(flash[:notice]).to eq(_('The user is being deleted.')) + expect( + Users::GhostUserMigration.where(user: user, + initiator_user: admin, + hard_delete: true) + ).to be_exists + end end end + end + end + end + + context 'when user_destroy_with_limited_execution_time_worker is disabled' do + before do + stub_feature_flags(user_destroy_with_limited_execution_time_worker: false) + end + + it 'deletes user and ghosts their contributions' do + delete :destroy, params: { id: user.username }, format: :json - context 'hard-delete' do - it 'succeeds' do - delete :destroy, params: { id: user.username, hard_delete: true } + expect(response).to have_gitlab_http_status(:ok) + expect(User.exists?(user.id)).to be_falsy + expect(issue.reload.author).to be_ghost + end + + it 'deletes the user and their contributions when hard delete is specified' do + delete :destroy, params: { id: user.username, hard_delete: true }, format: :json - expect(response).to redirect_to(admin_users_path) - expect(flash[:notice]).to eq(_('The user is being deleted.')) - expect(User.exists?(user.id)).to be_falsy + expect(response).to have_gitlab_http_status(:ok) + expect(User.exists?(user.id)).to be_falsy + expect(Issue.exists?(issue.id)).to be_falsy + end + + context 'prerequisites for account deletion' do + context 'solo-owned groups' do + let(:group) { create(:group) } + + context 'if the user is the sole owner of at least one group' do + before do + create(:group_member, :owner, group: group, user: user) + end + + context 'soft-delete' do + it 'fails' do + delete :destroy, params: { id: user.username } + + message = s_('AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account') + + expect(flash[:alert]).to eq(message) + expect(response).to have_gitlab_http_status(:see_other) + expect(response).to redirect_to admin_user_path(user) + expect(User.exists?(user.id)).to be_truthy + end + end + + context 'hard-delete' do + it 'succeeds' do + delete :destroy, params: { id: user.username, hard_delete: true } + + expect(response).to redirect_to(admin_users_path) + expect(flash[:notice]).to eq(_('The user is being deleted.')) + expect(User.exists?(user.id)).to be_falsy + end end end end @@ -131,10 +200,27 @@ RSpec.describe Admin::UsersController do context 'when rejecting a pending user' do let(:user) { create(:user, :blocked_pending_approval) } - it 'hard deletes the user', :sidekiq_inline do - subject + context 'when user_destroy_with_limited_execution_time_worker is enabled' do + it 'initiates user removal', :sidekiq_inline do + subject - expect(User.exists?(user.id)).to be_falsy + expect( + Users::GhostUserMigration.where(user: user, + initiator_user: admin) + ).to be_exists + end + end + + context 'when user_destroy_with_limited_execution_time_worker is disabled' do + before do + stub_feature_flags(user_destroy_with_limited_execution_time_worker: false) + end + + it 'hard deletes the user', :sidekiq_inline do + subject + + expect(User.exists?(user.id)).to be_falsy + end end it 'displays the rejection message' do @@ -270,19 +356,19 @@ RSpec.describe Admin::UsersController do let(:user) { create(:user, **activity) } context 'with no recent activity' do - let(:activity) { { last_activity_on: ::User::MINIMUM_INACTIVE_DAYS.next.days.ago } } + let(:activity) { { last_activity_on: Gitlab::CurrentSettings.deactivate_dormant_users_period.next.days.ago } } it_behaves_like 'a request that deactivates the user' end context 'with recent activity' do - let(:activity) { { last_activity_on: ::User::MINIMUM_INACTIVE_DAYS.pred.days.ago } } + let(:activity) { { last_activity_on: Gitlab::CurrentSettings.deactivate_dormant_users_period.pred.days.ago } } it 'does not deactivate the user' do put :deactivate, params: { id: user.username } user.reload expect(user.deactivated?).to be_falsey - expect(flash[:notice]).to eq("The user you are trying to deactivate has been active in the past #{::User::MINIMUM_INACTIVE_DAYS} days and cannot be deactivated") + expect(flash[:notice]).to eq("The user you are trying to deactivate has been active in the past #{Gitlab::CurrentSettings.deactivate_dormant_users_period} days and cannot be deactivated") end end end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 1e28ef4ba93..f1adb9020fa 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -1006,7 +1006,7 @@ RSpec.describe ApplicationController do end describe '.endpoint_id_for_action' do - controller(described_class) { } + controller(described_class) {} it 'returns an expected endpoint id' do expect(controller.class.endpoint_id_for_action('hello')).to eq('AnonymousController#hello') diff --git a/spec/controllers/concerns/continue_params_spec.rb b/spec/controllers/concerns/continue_params_spec.rb index c010e8ffbd0..ba600b8156a 100644 --- a/spec/controllers/concerns/continue_params_spec.rb +++ b/spec/controllers/concerns/continue_params_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe ContinueParams do let(:controller_class) do + # rubocop:disable Rails/ApplicationController Class.new(ActionController::Base) do include ContinueParams @@ -11,6 +12,7 @@ RSpec.describe ContinueParams do @request ||= Struct.new(:host, :port).new('test.host', 80) end end + # rubocop:enable Rails/ApplicationController end subject(:controller) { controller_class.new } diff --git a/spec/controllers/concerns/product_analytics_tracking_spec.rb b/spec/controllers/concerns/product_analytics_tracking_spec.rb index 250cc3cf2cf..2e734d81ea0 100644 --- a/spec/controllers/concerns/product_analytics_tracking_spec.rb +++ b/spec/controllers/concerns/product_analytics_tracking_spec.rb @@ -18,7 +18,7 @@ RSpec.describe ProductAnalyticsTracking, :snowplow do skip_before_action :authenticate_user!, only: :show track_event(:index, :show, name: 'g_analytics_valuestream', destinations: [:redis_hll, :snowplow], - conditions: [:custom_condition_one?, :custom_condition_two?]) { |controller| controller.get_custom_id } + conditions: [:custom_condition_one?, :custom_condition_two?]) { |controller| controller.get_custom_id } def index render html: 'index' diff --git a/spec/controllers/concerns/redis_tracking_spec.rb b/spec/controllers/concerns/redis_tracking_spec.rb index 178684ae2d0..0ad8fa79e5e 100644 --- a/spec/controllers/concerns/redis_tracking_spec.rb +++ b/spec/controllers/concerns/redis_tracking_spec.rb @@ -11,7 +11,8 @@ RSpec.describe RedisTracking do include RedisTracking skip_before_action :authenticate_user!, only: :show - track_redis_hll_event(:index, :show, name: 'g_compliance_approval_rules', + track_redis_hll_event(:index, :show, + name: 'g_compliance_approval_rules', if: [:custom_condition_one?, :custom_condition_two?]) { |controller| controller.get_custom_id } def index diff --git a/spec/controllers/confirmations_controller_spec.rb b/spec/controllers/confirmations_controller_spec.rb index 5b137ada141..111bfb24c7e 100644 --- a/spec/controllers/confirmations_controller_spec.rb +++ b/spec/controllers/confirmations_controller_spec.rb @@ -129,6 +129,10 @@ RSpec.describe ConfirmationsController do subject(:perform_request) { post(:create, params: { user: { email: user.email } }) } + before do + stub_feature_flags(identity_verification: false) + end + context 'when reCAPTCHA is disabled' do before do stub_application_setting(recaptcha_enabled: false) diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb index 1d2f1085d3c..7c9236704ec 100644 --- a/spec/controllers/graphql_controller_spec.rb +++ b/spec/controllers/graphql_controller_spec.rb @@ -88,10 +88,11 @@ RSpec.describe GraphqlController do post :execute, params: { _json: multiplex } expect(response).to have_gitlab_http_status(:ok) - expect(json_response).to eq([ - { 'data' => { '__typename' => 'Query' } }, - { 'data' => { '__typename' => 'Query' } } - ]) + expect(json_response).to eq( + [ + { 'data' => { '__typename' => 'Query' } }, + { 'data' => { '__typename' => 'Query' } } + ]) end it 'sets a limit on the total query size' do diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb index c6fd184ede0..a3659ae9163 100644 --- a/spec/controllers/groups/group_members_controller_spec.rb +++ b/spec/controllers/groups/group_members_controller_spec.rb @@ -97,6 +97,25 @@ RSpec.describe Groups::GroupMembersController do expect(assigns(:members).map(&:user_id)).to contain_exactly(user.id) end end + + context 'when webui_members_inherited_users is disabled' do + let_it_be(:shared_group) { create(:group) } + let_it_be(:shared_group_user) { create(:user) } + let_it_be(:group_link) { create(:group_group_link, shared_group: shared_group, shared_with_group: group) } + + before do + group.add_owner(user) + shared_group.add_owner(shared_group_user) + stub_feature_flags(webui_members_inherited_users: false) + sign_in(user) + end + + it 'lists inherited group members only' do + get :index, params: { group_id: shared_group } + + expect(assigns(:members).map(&:user_id)).to contain_exactly(shared_group_user.id) + end + end end describe 'PUT update' do diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb index 90da40cd5f0..37db26096d3 100644 --- a/spec/controllers/groups/labels_controller_spec.rb +++ b/spec/controllers/groups/labels_controller_spec.rb @@ -20,7 +20,7 @@ RSpec.describe Groups::LabelsController do it 'returns group and project labels by default' do get :index, params: { group_id: group }, format: :json - label_ids = json_response.map {|label| label['title']} + label_ids = json_response.map { |label| label['title'] } expect(label_ids).to match_array([label_1.title, group_label_1.title]) end @@ -36,7 +36,7 @@ RSpec.describe Groups::LabelsController do params = { group_id: subgroup, only_group_labels: true } get :index, params: params, format: :json - label_ids = json_response.map {|label| label['title']} + label_ids = json_response.map { |label| label['title'] } expect(label_ids).to match_array([group_label_1.title, subgroup_label_1.title]) end end diff --git a/spec/controllers/groups/releases_controller_spec.rb b/spec/controllers/groups/releases_controller_spec.rb index 9d372114d62..7dd0bc6206a 100644 --- a/spec/controllers/groups/releases_controller_spec.rb +++ b/spec/controllers/groups/releases_controller_spec.rb @@ -42,7 +42,7 @@ RSpec.describe Groups::ReleasesController do end it 'does not return any releases' do - expect(json_response.map {|r| r['tag'] } ).to be_empty + expect(json_response.map { |r| r['tag'] } ).to be_empty end it 'returns OK' do @@ -56,7 +56,7 @@ RSpec.describe Groups::ReleasesController do index - expect(json_response.map {|r| r['tag'] } ).to match_array(%w(p2 p1 v2 v1)) + expect(json_response.map { |r| r['tag'] } ).to match_array(%w(p2 p1 v2 v1)) end end diff --git a/spec/controllers/groups/settings/applications_controller_spec.rb b/spec/controllers/groups/settings/applications_controller_spec.rb index 0804a5536e0..b9457770ed6 100644 --- a/spec/controllers/groups/settings/applications_controller_spec.rb +++ b/spec/controllers/groups/settings/applications_controller_spec.rb @@ -71,17 +71,43 @@ RSpec.describe Groups::Settings::ApplicationsController do group.add_owner(user) end - it 'creates the application' do - create_params = attributes_for(:application, trusted: false, confidential: false, scopes: ['api']) + context 'with hash_oauth_secrets flag on' do + before do + stub_feature_flags(hash_oauth_secrets: true) + end - expect do - post :create, params: { group_id: group, doorkeeper_application: create_params } - end.to change { Doorkeeper::Application.count }.by(1) + it 'creates the application' do + create_params = attributes_for(:application, trusted: false, confidential: false, scopes: ['api']) + + expect do + post :create, params: { group_id: group, doorkeeper_application: create_params } + end.to change { Doorkeeper::Application.count }.by(1) - application = Doorkeeper::Application.last + application = Doorkeeper::Application.last - expect(response).to redirect_to(group_settings_application_path(group, application)) - expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template :show + expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + end + end + + context 'with hash_oauth_secrets flag off' do + before do + stub_feature_flags(hash_oauth_secrets: false) + end + + it 'creates the application' do + create_params = attributes_for(:application, trusted: false, confidential: false, scopes: ['api']) + + expect do + post :create, params: { group_id: group, doorkeeper_application: create_params } + end.to change { Doorkeeper::Application.count }.by(1) + + application = Doorkeeper::Application.last + + expect(response).to redirect_to(group_settings_application_path(group, application)) + expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + end end it 'renders the application form on errors' do @@ -94,17 +120,43 @@ RSpec.describe Groups::Settings::ApplicationsController do end context 'when the params are for a confidential application' do - it 'creates a confidential application' do - create_params = attributes_for(:application, confidential: true, scopes: ['read_user']) + context 'with hash_oauth_secrets flag off' do + before do + stub_feature_flags(hash_oauth_secrets: false) + end - expect do - post :create, params: { group_id: group, doorkeeper_application: create_params } - end.to change { Doorkeeper::Application.count }.by(1) + it 'creates a confidential application' do + create_params = attributes_for(:application, confidential: true, scopes: ['read_user']) - application = Doorkeeper::Application.last + expect do + post :create, params: { group_id: group, doorkeeper_application: create_params } + end.to change { Doorkeeper::Application.count }.by(1) - expect(response).to redirect_to(group_settings_application_path(group, application)) - expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + application = Doorkeeper::Application.last + + expect(response).to redirect_to(group_settings_application_path(group, application)) + expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + end + end + + context 'with hash_oauth_secrets flag on' do + before do + stub_feature_flags(hash_oauth_secrets: true) + end + + it 'creates a confidential application' do + create_params = attributes_for(:application, confidential: true, scopes: ['read_user']) + + expect do + post :create, params: { group_id: group, doorkeeper_application: create_params } + end.to change { Doorkeeper::Application.count }.by(1) + + application = Doorkeeper::Application.last + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template :show + expect(application).to have_attributes(create_params.except(:uid, :owner_type)) + end end end diff --git a/spec/controllers/help_controller_spec.rb b/spec/controllers/help_controller_spec.rb index 26e65711e9f..2375146f346 100644 --- a/spec/controllers/help_controller_spec.rb +++ b/spec/controllers/help_controller_spec.rb @@ -139,6 +139,39 @@ RSpec.describe HelpController do end end + describe 'GET #drawers' do + subject { get :drawers, params: { markdown_file: path } } + + context 'when requested file exists' do + let(:path) { 'user/ssh' } + let(:file_name) { "#{path}.md" } + + before do + subject + end + + it 'assigns variables', :aggregate_failures do + expect(assigns[:path]).not_to be_empty + expect(assigns[:clean_path]).not_to be_empty + end + + it 'renders HTML', :aggregate_failures do + is_expected.to render_template('help/drawers') + expect(response.media_type).to eq 'text/html' + end + end + + context 'when requested file is missing' do + let(:path) { 'foo/bar' } + + it 'renders not found' do + subject + + expect(response).to be_not_found + end + end + end + describe 'GET #show' do context 'for Markdown formats' do subject { get :show, params: { path: path }, format: :md } diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index af220e2d515..e73e61b6ec5 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -49,10 +49,10 @@ RSpec.describe Import::BitbucketController do let(:expires_in) { 1.day } let(:access_token) do double(token: token, - secret: secret, - expires_at: expires_at, - expires_in: expires_in, - refresh_token: refresh_token) + secret: secret, + expires_at: expires_at, + expires_in: expires_in, + refresh_token: refresh_token) end before do diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb index 46160aac0c1..269eb62cae6 100644 --- a/spec/controllers/import/github_controller_spec.rb +++ b/spec/controllers/import/github_controller_spec.rb @@ -134,7 +134,7 @@ RSpec.describe Import::GithubController do it 'fetches repos using legacy client' do expect_next_instance_of(Gitlab::LegacyGithubImport::Client) do |client| - expect(client).to receive(:repos) + expect(client).to receive(:repos).and_return([]) end get :status @@ -164,8 +164,8 @@ RSpec.describe Import::GithubController do end it 'fetches repos using latest github client' do - expect_next_instance_of(Octokit::Client) do |client| - expect(client).to receive(:repos).and_return([].to_enum) + expect_next_instance_of(Gitlab::GithubImport::Client) do |client| + expect(client).to receive(:repos).and_return([]) end get :status @@ -184,8 +184,8 @@ RSpec.describe Import::GithubController do context 'pagination' do context 'when no page is specified' do it 'requests first page' do - expect_next_instance_of(Octokit::Client) do |client| - expect(client).to receive(:repos).with(nil, { page: 1, per_page: 25 }).and_return([].to_enum) + expect_next_instance_of(Gitlab::GithubImport::Client) do |client| + expect(client).to receive(:repos).with({ page: 1, per_page: 25 }).and_return([]) end get :status diff --git a/spec/controllers/import/manifest_controller_spec.rb b/spec/controllers/import/manifest_controller_spec.rb index 0111ad9501f..6f805b44e89 100644 --- a/spec/controllers/import/manifest_controller_spec.rb +++ b/spec/controllers/import/manifest_controller_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Import::ManifestController, :clean_gitlab_redis_shared_state do include ImportSpecHelper let_it_be(:user) { create(:user) } - let_it_be(:group) { create(:group)} + let_it_be(:group) { create(:group) } before(:all) do group.add_maintainer(user) diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb index 5bf3b4c48bf..9b16dc9a463 100644 --- a/spec/controllers/oauth/applications_controller_spec.rb +++ b/spec/controllers/oauth/applications_controller_spec.rb @@ -113,11 +113,30 @@ RSpec.describe Oauth::ApplicationsController do subject { post :create, params: oauth_params } - it 'creates an application' do - subject + context 'when hash_oauth_tokens flag set' do + before do + stub_feature_flags(hash_oauth_secrets: true) + end - expect(response).to have_gitlab_http_status(:found) - expect(response).to redirect_to(oauth_application_path(Doorkeeper::Application.last)) + it 'creates an application' do + subject + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template :show + end + end + + context 'when hash_oauth_tokens flag not set' do + before do + stub_feature_flags(hash_oauth_secrets: false) + end + + it 'creates an application' do + subject + + expect(response).to have_gitlab_http_status(:found) + expect(response).to redirect_to(oauth_application_path(Doorkeeper::Application.last)) + end end it 'redirects back to profile page if OAuth applications are disabled' do diff --git a/spec/controllers/oauth/token_info_controller_spec.rb b/spec/controllers/oauth/token_info_controller_spec.rb index b66fff4d4e9..3cd952d4935 100644 --- a/spec/controllers/oauth/token_info_controller_spec.rb +++ b/spec/controllers/oauth/token_info_controller_spec.rb @@ -24,12 +24,12 @@ RSpec.describe Oauth::TokenInfoController do expect(response).to have_gitlab_http_status(:ok) expect(Gitlab::Json.parse(response.body)).to eq( - 'scope' => %w[api], - 'scopes' => %w[api], - 'created_at' => access_token.created_at.to_i, - 'expires_in' => access_token.expires_in, - 'application' => { 'uid' => application.uid }, - 'resource_owner_id' => access_token.resource_owner_id, + 'scope' => %w[api], + 'scopes' => %w[api], + 'created_at' => access_token.created_at.to_i, + 'expires_in' => access_token.expires_in, + 'application' => { 'uid' => application.uid }, + 'resource_owner_id' => access_token.resource_owner_id, 'expires_in_seconds' => access_token.expires_in ) end diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb index 9ecef8b7450..df5da29495e 100644 --- a/spec/controllers/omniauth_callbacks_controller_spec.rb +++ b/spec/controllers/omniauth_callbacks_controller_spec.rb @@ -406,7 +406,7 @@ RSpec.describe OmniauthCallbacksController, type: :controller do before do stub_last_request_id(last_request_id) stub_omniauth_saml_config(enabled: true, auto_link_saml_user: true, allow_single_sign_on: ['saml'], - providers: [saml_config]) + providers: [saml_config]) mock_auth_hash_with_saml_xml('saml', +'my-uid', user.email, mock_saml_response) request.env['devise.mapping'] = Devise.mappings[:user] request.env['omniauth.auth'] = Rails.application.env_config['omniauth.auth'] diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb index 0e531dbaf4b..99e9644da66 100644 --- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb +++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb @@ -48,8 +48,8 @@ RSpec.describe Profiles::PersonalAccessTokensController do end it "only includes details of the active personal access token" do - active_personal_access_tokens_detail = ::API::Entities::PersonalAccessTokenWithDetails - .represent([active_personal_access_token]) + active_personal_access_tokens_detail = + ::PersonalAccessTokenSerializer.new.represent([active_personal_access_token]) expect(assigns(:active_personal_access_tokens).to_json).to eq(active_personal_access_tokens_detail.to_json) end @@ -100,8 +100,8 @@ RSpec.describe Profiles::PersonalAccessTokensController do get :index first_token = assigns(:active_personal_access_tokens).first.as_json - expect(first_token[:name]).to eq("Token1") - expect(first_token[:expires_at]).to eq(expires_1_day_from_now.strftime("%Y-%m-%d")) + expect(first_token['name']).to eq("Token1") + expect(first_token['expires_at']).to eq(expires_1_day_from_now.strftime("%Y-%m-%d")) end it "orders tokens on id in case token has same expires_at" do @@ -110,12 +110,12 @@ RSpec.describe Profiles::PersonalAccessTokensController do get :index first_token = assigns(:active_personal_access_tokens).first.as_json - expect(first_token[:name]).to eq("Token3") - expect(first_token[:expires_at]).to eq(expires_1_day_from_now.strftime("%Y-%m-%d")) + expect(first_token['name']).to eq("Token3") + expect(first_token['expires_at']).to eq(expires_1_day_from_now.strftime("%Y-%m-%d")) second_token = assigns(:active_personal_access_tokens).second.as_json - expect(second_token[:name]).to eq("Token1") - expect(second_token[:expires_at]).to eq(expires_1_day_from_now.strftime("%Y-%m-%d")) + expect(second_token['name']).to eq("Token1") + expect(second_token['expires_at']).to eq(expires_1_day_from_now.strftime("%Y-%m-%d")) end end diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb index 89185a8f856..aa92ff6be33 100644 --- a/spec/controllers/profiles_controller_spec.rb +++ b/spec/controllers/profiles_controller_spec.rb @@ -82,13 +82,17 @@ RSpec.describe ProfilesController, :request_store do expect(ldap_user.location).to eq('City, Country') end - it 'allows setting a user status' do + it 'allows setting a user status', :freeze_time do sign_in(user) - put :update, params: { user: { status: { message: 'Working hard!', availability: 'busy' } } } + put( + :update, + params: { user: { status: { message: 'Working hard!', availability: 'busy', clear_status_after: '8_hours' } } } + ) expect(user.reload.status.message).to eq('Working hard!') expect(user.reload.status.availability).to eq('busy') + expect(user.reload.status.clear_status_after).to eq(8.hours.from_now) expect(response).to have_gitlab_http_status(:found) end diff --git a/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb b/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb index 8903592ba15..b9e569b1647 100644 --- a/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb +++ b/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb @@ -16,7 +16,6 @@ RSpec.describe Projects::Analytics::CycleAnalytics::StagesController do end before do - stub_feature_flags(use_vsa_aggregated_tables: false) sign_in(user) end diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb index 958fcd4360c..263f488ddbf 100644 --- a/spec/controllers/projects/artifacts_controller_spec.rb +++ b/spec/controllers/projects/artifacts_controller_spec.rb @@ -488,7 +488,7 @@ RSpec.describe Projects::ArtifactsController do context 'with regular branch' do before do pipeline.update!(ref: 'master', - sha: project.commit('master').sha) + sha: project.commit('master').sha) get :latest_succeeded, params: params_from_ref('master') end @@ -499,7 +499,7 @@ RSpec.describe Projects::ArtifactsController do context 'with branch name containing slash' do before do pipeline.update!(ref: 'improve/awesome', - sha: project.commit('improve/awesome').sha) + sha: project.commit('improve/awesome').sha) get :latest_succeeded, params: params_from_ref('improve/awesome') end @@ -510,7 +510,7 @@ RSpec.describe Projects::ArtifactsController do context 'with branch name and path containing slashes' do before do pipeline.update!(ref: 'improve/awesome', - sha: project.commit('improve/awesome').sha) + sha: project.commit('improve/awesome').sha) get :latest_succeeded, params: params_from_ref('improve/awesome', job.name, 'file/README.md') end diff --git a/spec/controllers/projects/blame_controller_spec.rb b/spec/controllers/projects/blame_controller_spec.rb index bf475f6135a..62a544bb3fc 100644 --- a/spec/controllers/projects/blame_controller_spec.rb +++ b/spec/controllers/projects/blame_controller_spec.rb @@ -41,7 +41,7 @@ RSpec.describe Projects::BlameController do end context "invalid branch, valid file" do - let(:id) { 'invalid-branch/files/ruby/missing_file.rb'} + let(:id) { 'invalid-branch/files/ruby/missing_file.rb' } it { is_expected.to respond_with(:not_found) } end diff --git a/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb b/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb index 3c4376909f8..e5bffb7c265 100644 --- a/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb +++ b/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb @@ -59,12 +59,13 @@ RSpec.describe Projects::Ci::DailyBuildGroupReportResultsController do expect(response).to have_gitlab_http_status(:ok) expect(response.headers['Content-Type']).to eq('text/csv; charset=utf-8') - expect(csv_response).to eq([ - %w[date group_name coverage], - ['2020-03-09', 'rspec', '79.0'], - ['2020-03-08', 'rspec', '77.0'], - ['2019-12-10', 'karma', '81.0'] - ]) + expect(csv_response).to eq( + [ + %w[date group_name coverage], + ['2020-03-09', 'rspec', '79.0'], + ['2020-03-08', 'rspec', '77.0'], + ['2019-12-10', 'karma', '81.0'] + ]) end context 'when given date range spans more than 90 days' do @@ -72,12 +73,13 @@ RSpec.describe Projects::Ci::DailyBuildGroupReportResultsController do let(:end_date) { '2020-03-09' } it 'limits the result to 90 days from the given start_date' do - expect(csv_response).to eq([ - %w[date group_name coverage], - ['2020-03-09', 'rspec', '79.0'], - ['2020-03-08', 'rspec', '77.0'], - ['2019-12-10', 'karma', '81.0'] - ]) + expect(csv_response).to eq( + [ + %w[date group_name coverage], + ['2020-03-09', 'rspec', '79.0'], + ['2020-03-08', 'rspec', '77.0'], + ['2019-12-10', 'karma', '81.0'] + ]) end end @@ -89,29 +91,8 @@ RSpec.describe Projects::Ci::DailyBuildGroupReportResultsController do it 'serves the results in JSON' do expect(response).to have_gitlab_http_status(:ok) - expect(json_response).to eq([ - { - 'group_name' => 'rspec', - 'data' => [ - { 'date' => '2020-03-09', 'coverage' => 79.0 }, - { 'date' => '2020-03-08', 'coverage' => 77.0 } - ] - }, - { - 'group_name' => 'karma', - 'data' => [ - { 'date' => '2019-12-10', 'coverage' => 81.0 } - ] - } - ]) - end - - context 'when given date range spans more than 90 days' do - let(:start_date) { '2019-12-09' } - let(:end_date) { '2020-03-09' } - - it 'limits the result to 90 days from the given start_date' do - expect(json_response).to eq([ + expect(json_response).to eq( + [ { 'group_name' => 'rspec', 'data' => [ @@ -126,6 +107,29 @@ RSpec.describe Projects::Ci::DailyBuildGroupReportResultsController do ] } ]) + end + + context 'when given date range spans more than 90 days' do + let(:start_date) { '2019-12-09' } + let(:end_date) { '2020-03-09' } + + it 'limits the result to 90 days from the given start_date' do + expect(json_response).to eq( + [ + { + 'group_name' => 'rspec', + 'data' => [ + { 'date' => '2020-03-09', 'coverage' => 79.0 }, + { 'date' => '2020-03-08', 'coverage' => 77.0 } + ] + }, + { + 'group_name' => 'karma', + 'data' => [ + { 'date' => '2019-12-10', 'coverage' => 81.0 } + ] + } + ]) end end diff --git a/spec/controllers/projects/ci/lints_controller_spec.rb b/spec/controllers/projects/ci/lints_controller_spec.rb index d778739be38..403f99145fc 100644 --- a/spec/controllers/projects/ci/lints_controller_spec.rb +++ b/spec/controllers/projects/ci/lints_controller_spec.rb @@ -143,10 +143,11 @@ RSpec.describe Projects::Ci::LintsController do it_behaves_like 'returns a successful validation' it 'assigns result with errors' do - expect(parsed_body['errors']).to match_array([ - 'jobs rubocop config should implement a script: or a trigger: keyword', - 'jobs config should contain at least one visible job' - ]) + expect(parsed_body['errors']).to match_array( + [ + 'jobs rubocop config should implement a script: or a trigger: keyword', + 'jobs config should contain at least one visible job' + ]) end context 'with dry_run mode' do diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb index ccd213fdffa..f5dd8abd67b 100644 --- a/spec/controllers/projects/cycle_analytics_controller_spec.rb +++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb @@ -30,6 +30,18 @@ RSpec.describe Projects::CycleAnalyticsController do let(:request_params) { { namespace_id: project.namespace, project_id: project } } let(:target_id) { 'p_analytics_valuestream' } end + + it_behaves_like 'Snowplow event tracking' do + subject { get :show, params: request_params, format: :html } + + let(:request_params) { { namespace_id: project.namespace, project_id: project } } + let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } + let(:category) { described_class.name } + let(:action) { 'perform_analytics_usage_action' } + let(:namespace) { project.namespace } + let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' } + let(:property) { 'p_analytics_valuestream' } + end end include_examples GracefulTimeoutHandling diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb index 821f7fca73d..308146ce792 100644 --- a/spec/controllers/projects/deploy_keys_controller_spec.rb +++ b/spec/controllers/projects/deploy_keys_controller_spec.rb @@ -27,8 +27,8 @@ RSpec.describe Projects::DeployKeysController do end context 'when json requested' do - let(:project2) { create(:project, :internal)} - let(:project_private) { create(:project, :private)} + let(:project2) { create(:project, :internal) } + let(:project_private) { create(:project, :private) } let(:deploy_key_internal) { create(:deploy_key) } let(:deploy_key_actual) { create(:deploy_key) } diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 1a6edab795d..16a43bae674 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -32,6 +32,11 @@ RSpec.describe Projects::EnvironmentsController do get :index, params: environment_params end + + it_behaves_like 'tracking unique visits', :index do + let(:request_params) { environment_params } + let(:target_id) { 'users_visiting_environments_pages' } + end end context 'when requesting JSON response for folders' do @@ -68,6 +73,24 @@ RSpec.describe Projects::EnvironmentsController do expect(json_response['stopped_count']).to eq 1 end + it 'handles search option properly' do + get :index, params: environment_params(format: :json, search: 'staging/r') + + expect(environments.map { |env| env['name'] } ).to contain_exactly('staging/review-1', 'staging/review-2') + expect(json_response['available_count']).to eq 2 + expect(json_response['stopped_count']).to eq 1 + end + + it 'ignores search option if is shorter than a minimum' do + get :index, params: environment_params(format: :json, search: 'st') + + expect(environments.map { |env| env['name'] } ).to contain_exactly('production', + 'staging/review-1', + 'staging/review-2') + expect(json_response['available_count']).to eq 3 + expect(json_response['stopped_count']).to eq 1 + end + it 'sets the polling interval header' do subject @@ -149,29 +172,43 @@ RSpec.describe Projects::EnvironmentsController do end describe 'GET folder' do - before do - create(:environment, project: project, - name: 'staging-1.0/review', - state: :available) - create(:environment, project: project, - name: 'staging-1.0/zzz', - state: :available) - end - context 'when using default format' do it 'responds with HTML' do get :folder, params: { - namespace_id: project.namespace, - project_id: project, - id: 'staging-1.0' - } + namespace_id: project.namespace, + project_id: project, + id: 'staging-1.0' + } - expect(response).to be_ok + expect(response).to have_gitlab_http_status(:ok) expect(response).to render_template 'folder' end + + it_behaves_like 'tracking unique visits', :folder do + let(:request_params) do + { + namespace_id: project.namespace, + project_id: project, + id: 'staging-1.0' + } + end + + let(:target_id) { 'users_visiting_environments_pages' } + end end context 'when using JSON format' do + before do + create(:environment, project: project, + name: 'staging-1.0/review', + state: :available) + create(:environment, project: project, + name: 'staging-1.0/zzz', + state: :available) + end + + let(:environments) { json_response['environments'] } + it 'sorts the subfolders lexicographically' do get :folder, params: { namespace_id: project.namespace, @@ -187,6 +224,19 @@ RSpec.describe Projects::EnvironmentsController do expect(json_response['environments'][1]) .to include('name' => 'staging-1.0/zzz', 'name_without_type' => 'zzz') end + + it 'handles search option properly' do + get(:folder, params: { + namespace_id: project.namespace, + project_id: project, + id: 'staging-1.0', + search: 'staging-1.0/z' + }, format: :json) + + expect(environments.map { |env| env['name'] } ).to eq(['staging-1.0/zzz']) + expect(json_response['available_count']).to eq 1 + expect(json_response['stopped_count']).to eq 0 + end end end @@ -197,6 +247,11 @@ RSpec.describe Projects::EnvironmentsController do expect(response).to be_ok end + + it_behaves_like 'tracking unique visits', :show do + let(:request_params) { environment_params } + let(:target_id) { 'users_visiting_environments_pages' } + end end context 'with invalid id' do @@ -210,12 +265,30 @@ RSpec.describe Projects::EnvironmentsController do end end + describe 'GET new' do + it 'responds with a status code 200' do + get :new, params: environment_params + + expect(response).to be_ok + end + + it_behaves_like 'tracking unique visits', :new do + let(:request_params) { environment_params } + let(:target_id) { 'users_visiting_environments_pages' } + end + end + describe 'GET edit' do it 'responds with a status code 200' do get :edit, params: environment_params expect(response).to be_ok end + + it_behaves_like 'tracking unique visits', :edit do + let(:request_params) { environment_params } + let(:target_id) { 'users_visiting_environments_pages' } + end end describe 'PATCH #update' do @@ -230,6 +303,11 @@ RSpec.describe Projects::EnvironmentsController do expect(response).to have_gitlab_http_status(:ok) expect(json_response['path']).to eq("/#{project.full_path}/-/environments/#{environment.id}") end + + it_behaves_like 'tracking unique visits', :update do + let(:request_params) { params } + let(:target_id) { 'users_visiting_environments_pages' } + end end context "when environment params are invalid" do @@ -294,6 +372,11 @@ RSpec.describe Projects::EnvironmentsController do { 'redirect_url' => project_environment_url(project, environment) }) end + + it_behaves_like 'tracking unique visits', :stop do + let(:request_params) { environment_params(format: :json) } + let(:target_id) { 'users_visiting_environments_pages' } + end end context 'when no stop action' do @@ -321,6 +404,11 @@ RSpec.describe Projects::EnvironmentsController do it_behaves_like 'successful response for #cancel_auto_stop' + it_behaves_like 'tracking unique visits', :cancel_auto_stop do + let(:request_params) { environment_params } + let(:target_id) { 'users_visiting_environments_pages' } + end + context 'when user is reporter' do let(:user) { reporter } @@ -357,6 +445,11 @@ RSpec.describe Projects::EnvironmentsController do get :terminal, params: environment_params end + + it_behaves_like 'tracking unique visits', :terminal do + let(:request_params) { environment_params } + let(:target_id) { 'users_visiting_environments_pages' } + end end context 'with invalid id' do @@ -859,6 +952,11 @@ RSpec.describe Projects::EnvironmentsController do expect(response).to have_gitlab_http_status(:ok) expect(json_response['path']).to eq("/#{project.full_path}/-/environments/#{json_response['environment']['id']}") end + + it_behaves_like 'tracking unique visits', :create do + let(:request_params) { params } + let(:target_id) { 'users_visiting_environments_pages' } + end end context "when environment params are invalid" do diff --git a/spec/controllers/projects/feature_flags_controller_spec.rb b/spec/controllers/projects/feature_flags_controller_spec.rb index fd95aa44568..29ad51d590f 100644 --- a/spec/controllers/projects/feature_flags_controller_spec.rb +++ b/spec/controllers/projects/feature_flags_controller_spec.rb @@ -194,7 +194,7 @@ RSpec.describe Projects::FeatureFlagsController do other_project = create(:project) other_project.add_developer(user) other_feature_flag = create(:operations_feature_flag, project: other_project, - name: 'other_flag') + name: 'other_flag') params = { namespace_id: other_project.namespace, project_id: other_project, @@ -208,7 +208,7 @@ RSpec.describe Projects::FeatureFlagsController do end context 'when feature flag is not found' do - let!(:feature_flag) { } + let!(:feature_flag) {} let(:params) do { @@ -486,7 +486,7 @@ RSpec.describe Projects::FeatureFlagsController do context 'when creating a version 2 feature flag with a gitlabUserList strategy' do let!(:user_list) do create(:operations_feature_flag_user_list, project: project, - name: 'My List', user_xids: 'user1,user2') + name: 'My List', user_xids: 'user1,user2') end let(:params) do diff --git a/spec/controllers/projects/grafana_api_controller_spec.rb b/spec/controllers/projects/grafana_api_controller_spec.rb index baee9705127..2e25b0271ce 100644 --- a/spec/controllers/projects/grafana_api_controller_spec.rb +++ b/spec/controllers/projects/grafana_api_controller_spec.rb @@ -52,8 +52,8 @@ RSpec.describe Projects::GrafanaApiController do .with(project, '1', 'api/v1/query_range', { 'query' => params[:query], 'start' => params[:start_time], - 'end' => params[:end_time], - 'step' => params[:step] }) + 'end' => params[:end_time], + 'step' => params[:step] }) expect(response).to have_gitlab_http_status(:ok) expect(json_response).to eq({}) diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb index be89fa0d361..9227c7dd70a 100644 --- a/spec/controllers/projects/graphs_controller_spec.rb +++ b/spec/controllers/projects/graphs_controller_spec.rb @@ -89,6 +89,21 @@ RSpec.describe Projects::GraphsController do let(:request_params) { { namespace_id: project.namespace.path, project_id: project.path, id: 'master' } } let(:target_id) { 'p_analytics_repo' } end + + it_behaves_like 'Snowplow event tracking' do + subject do + sign_in(user) + get :charts, params: request_params, format: :html + end + + let(:request_params) { { namespace_id: project.namespace.path, project_id: project.path, id: 'master' } } + let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } + let(:category) { described_class.name } + let(:action) { 'perform_analytics_usage_action' } + let(:namespace) { project.namespace } + let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' } + let(:property) { 'p_analytics_repo' } + end end context 'when languages were previously detected' do diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb index e4e3151dd12..556dd23c135 100644 --- a/spec/controllers/projects/jobs_controller_spec.rb +++ b/spec/controllers/projects/jobs_controller_spec.rb @@ -5,9 +5,25 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do include ApiHelpers include HttpIOHelpers - let(:project) { create(:project, :public, :repository) } + let_it_be(:project) { create(:project, :public, :repository) } + let_it_be(:owner) { create(:owner) } + let_it_be(:admin) { create(:admin) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:developer) { create(:user) } + let_it_be(:reporter) { create(:user) } + let_it_be(:guest) { create(:user) } + + before_all do + project.add_owner(owner) + project.add_maintainer(maintainer) + project.add_developer(developer) + project.add_reporter(reporter) + project.add_guest(guest) + end + + let(:user) { developer } + let(:pipeline) { create(:ci_pipeline, project: project) } - let(:user) { create(:user) } before do stub_feature_flags(ci_enable_live_trace: true) @@ -136,9 +152,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'when requesting JSON' do let(:merge_request) { create(:merge_request, source_project: project) } + let(:user) { developer } before do - project.add_developer(user) sign_in(user) allow_any_instance_of(Ci::Build) @@ -307,9 +323,10 @@ RSpec.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) } + let(:user) { maintainer } + before do create(:deployment, :success, :on_cluster, environment: environment, project: project) - project.add_maintainer(user) # Need to be a maintianer to view cluster.path end it 'exposes the deployment information' do @@ -330,9 +347,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'that belongs to the project' do let(:runner) { create(:ci_runner, :project, projects: [project]) } let(:job) { create(:ci_build, :success, pipeline: pipeline, runner: runner) } + let(:user) { maintainer } before do - project.add_maintainer(user) sign_in(user) end @@ -349,10 +366,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do let(:group) { create(:group) } let(:runner) { create(:ci_runner, :group, groups: [group]) } let(:job) { create(:ci_build, :success, pipeline: pipeline, runner: runner) } - let(:user) { create(:user, :admin) } + let(:user) { maintainer } before do - project.add_maintainer(user) sign_in(user) end @@ -368,10 +384,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'that belongs to instance' do let(:runner) { create(:ci_runner, :instance) } let(:job) { create(:ci_build, :success, pipeline: pipeline, runner: runner) } - let(:user) { create(:user, :admin) } + let(:user) { maintainer } before do - project.add_maintainer(user) sign_in(user) end @@ -421,6 +436,8 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'when user is developer' do + let(:user) { developer } + it 'settings_path is not available' do expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('job/job_details') @@ -429,10 +446,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'when user is maintainer' do - let(:user) { create(:user, :admin) } + let(:user) { admin } before do - project.add_maintainer(user) sign_in(user) end @@ -499,9 +515,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do let(:trigger) { create(:ci_trigger, project: project) } let(:trigger_request) { create(:ci_trigger_request, pipeline: pipeline, trigger: trigger) } let(:job) { create(:ci_build, pipeline: pipeline, trigger_request: trigger_request) } + let(:user) { developer } before do - project.add_developer(user) sign_in(user) allow_any_instance_of(Ci::Build) @@ -526,9 +542,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'user is a maintainer' do - before do - project.add_maintainer(user) + let(:user) { maintainer } + before do get_show_json end @@ -579,7 +595,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do def get_show_json expect { get_show(id: job.id, format: :json) } - .to change { Gitlab::GitalyClient.get_request_count }.by_at_most(2) + .to change { Gitlab::GitalyClient.get_request_count }.by_at_most(3) end def get_show(**extra_params) @@ -617,8 +633,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do let!(:variable) { create(:ci_instance_variable, key: 'CI_DEBUG_TRACE', value: 'true') } context 'with proper permissions on a project' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -630,8 +647,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'without proper permissions for debug logging' do + let(:user) { guest } + before do - project.add_guest(user) sign_in(user) end @@ -700,7 +718,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do expect(response).to match_response_schema('job/build_trace') expect(json_response['id']).to eq job.id expect(json_response['status']).to eq job.status - expect(json_response['lines'].flat_map {|l| l['content'].map { |c| c['text'] } }).to include("ヾ(´༎ຶД༎ຶ`)ノ") + expect(json_response['lines'].flat_map { |l| l['content'].map { |c| c['text'] } }).to include("ヾ(´༎ຶД༎ຶ`)ノ") end end @@ -753,8 +771,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'POST retry' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -817,12 +836,13 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do describe 'POST play' do let(:variable_attributes) { [] } + let(:user) { developer } before do project.add_developer(user) create(:protected_branch, :developers_can_merge, - name: 'master', project: project) + name: 'protected-branch', project: project) sign_in(user) end @@ -899,8 +919,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do describe 'POST cancel' do context 'when user is authorized to cancel the build' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -965,8 +986,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'when user is not authorized to cancel the build' do let!(:job) { create(:ci_build, :cancelable, pipeline: pipeline) } + let(:user) { guest } + before do - project.add_reporter(user) sign_in(user) post_cancel @@ -990,12 +1012,13 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do describe 'POST unschedule' do before do - create(:protected_branch, :developers_can_merge, name: 'master', project: project) + create(:protected_branch, :developers_can_merge, name: 'protected-branch', project: project) end context 'when user is authorized to unschedule the build' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) post_unschedule @@ -1025,9 +1048,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do context 'when user is not authorized to unschedule the build' do let(:job) { create(:ci_build, :scheduled, pipeline: pipeline) } + let(:user) { guest } before do - project.add_reporter(user) sign_in(user) post_unschedule @@ -1048,10 +1071,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'POST erase' do - let(:role) { :maintainer } + let(:user) { maintainer } before do - project.add_role(user, role) sign_in(user) end @@ -1097,7 +1119,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'when user is developer' do - let(:role) { :developer } + let(:user) { developer } let(:job) { create(:ci_build, :erasable, :trace_artifact, pipeline: pipeline, user: triggered_by) } context 'when triggered by same user' do @@ -1109,7 +1131,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'when triggered by different user' do - let(:triggered_by) { create(:user) } + let(:triggered_by) { maintainer } it 'does not have successful status' do expect(response).not_to have_gitlab_http_status(:found) @@ -1168,8 +1190,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'with proper permissions for debug logging on a project' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -1181,8 +1204,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end context 'without proper permissions for debug logging on a project' do + let(:user) { reporter } + before do - project.add_reporter(user) sign_in(user) end @@ -1218,37 +1242,6 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end end - context "when job has a trace in database" do - let(:job) { create(:ci_build, pipeline: pipeline) } - - before do - job.update_column(:trace, "Sample trace") - end - - it 'sends a trace file' do - response = subject - - expect(response).to have_gitlab_http_status(:ok) - expect(response.headers['Content-Type']).to eq('text/plain; charset=utf-8') - expect(response.headers['Content-Disposition']).to match(/^inline/) - expect(response.body).to eq('Sample trace') - end - - context 'when trace format is not text/plain' do - before do - job.update_column(:trace, '<html></html>') - end - - it 'sets content disposition to attachment' do - response = subject - - expect(response).to have_gitlab_http_status(:ok) - expect(response.headers['Content-Type']).to eq('text/plain; charset=utf-8') - expect(response.headers['Content-Disposition']).to match(/^attachment/) - end - end - end - context 'when job does not have a trace file' do let(:job) { create(:ci_build, pipeline: pipeline) } @@ -1274,8 +1267,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'GET #terminal' do + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -1323,8 +1317,9 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do describe 'GET #terminal_websocket_authorize' do let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) } + let(:user) { developer } + before do - project.add_developer(user) sign_in(user) end @@ -1375,14 +1370,6 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'GET #proxy_websocket_authorize' do - let_it_be(:owner) { create(:owner) } - let_it_be(:admin) { create(:admin) } - let_it_be(:maintainer) { create(:user) } - let_it_be(:developer) { create(:user) } - let_it_be(:reporter) { create(:user) } - let_it_be(:guest) { create(:user) } - let_it_be(:project) { create(:project, :private, :repository, namespace: owner.namespace) } - let(:user) { maintainer } let(:pipeline) { create(:ci_pipeline, project: project, source: :webide, config_source: :webide_source, user: user) } let(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) } @@ -1407,11 +1394,6 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do stub_feature_flags(build_service_proxy: true) allow(job).to receive(:has_terminal?).and_return(true) - project.add_maintainer(maintainer) - project.add_developer(developer) - project.add_reporter(reporter) - project.add_guest(guest) - sign_in(user) end diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb index 776ed9774b1..a5259522fe2 100644 --- a/spec/controllers/projects/labels_controller_spec.rb +++ b/spec/controllers/projects/labels_controller_spec.rb @@ -25,10 +25,10 @@ RSpec.describe Projects::LabelsController do let_it_be(:group_label_3) { create(:group_label, group: group, title: 'Group Label 3') } let_it_be(:group_label_4) { create(:group_label, group: group, title: 'Group Label 4') } - let_it_be(:group_labels) { [group_label_3, group_label_4]} - let_it_be(:project_labels) { [label_4, label_5]} - let_it_be(:group_priority_labels) { [group_label_1, group_label_2]} - let_it_be(:project_priority_labels) { [label_1, label_2, label_3]} + let_it_be(:group_labels) { [group_label_3, group_label_4] } + let_it_be(:project_labels) { [label_4, label_5] } + let_it_be(:group_priority_labels) { [group_label_1, group_label_2] } + let_it_be(:project_priority_labels) { [label_1, label_2, label_3] } before do create(:label_priority, project: project, label: group_label_1, priority: 3) diff --git a/spec/controllers/projects/merge_requests/drafts_controller_spec.rb b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb index b9ede84157d..182d654aaa8 100644 --- a/spec/controllers/projects/merge_requests/drafts_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Projects::MergeRequests::DraftsController do include RepoHelpers let(:project) { create(:project, :repository) } - let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) } + let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project, author: create(:user)) } let(:user) { project.first_owner } let(:user2) { create(:user) } @@ -404,6 +404,11 @@ RSpec.describe Projects::MergeRequests::DraftsController do end context 'when feature flag is enabled' do + before do + allow(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter) + .to receive(:track_submit_review_comment) + end + it 'creates note' do post :publish, params: params.merge!(note: 'Hello world') @@ -415,6 +420,72 @@ RSpec.describe Projects::MergeRequests::DraftsController do expect(merge_request.notes.reload.size).to be(1) end + + it 'tracks merge request activity' do + post :publish, params: params.merge!(note: 'Hello world') + + expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter) + .to have_received(:track_submit_review_comment).with(user: user) + end + end + end + + context 'approve merge request' do + before do + create(:draft_note, merge_request: merge_request, author: user) + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(mr_review_submit_comment: false) + end + + it 'does not approve' do + post :publish, params: params.merge!(approve: true) + + expect(merge_request.approvals.reload.size).to be(0) + end + end + + context 'when feature flag is enabled' do + before do + allow(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter) + .to receive(:track_submit_review_approve) + end + + it 'approves merge request' do + post :publish, params: params.merge!(approve: true) + + expect(merge_request.approvals.reload.size).to be(1) + end + + it 'does not approve merge request' do + post :publish, params: params.merge!(approve: false) + + expect(merge_request.approvals.reload.size).to be(0) + end + + it 'tracks merge request activity' do + post :publish, params: params.merge!(approve: true) + + expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter) + .to have_received(:track_submit_review_approve).with(user: user) + end + + context 'when merge request is already approved by user' do + before do + create(:approval, merge_request: merge_request, user: user) + end + + it 'does return 200' do + post :publish, params: params.merge!(approve: true) + + expect(response).to have_gitlab_http_status(:ok) + + expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter) + .to have_received(:track_submit_review_approve).with(user: user) + end + end end end end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index ed5e32df8ea..9c4baeae836 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -896,12 +896,13 @@ RSpec.describe Projects::MergeRequestsController do end subject do - get :exposed_artifacts, params: { - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid - }, - format: :json + get :exposed_artifacts, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, + format: :json end describe 'permissions on a public project with private CI/CD' do @@ -1031,12 +1032,13 @@ RSpec.describe Projects::MergeRequestsController do end subject do - get :coverage_reports, params: { - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid - }, - format: :json + get :coverage_reports, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, + format: :json end describe 'permissions on a public project with private CI/CD' do @@ -1161,12 +1163,13 @@ RSpec.describe Projects::MergeRequestsController do end subject(:get_codequality_mr_diff_reports) do - get :codequality_mr_diff_reports, params: { - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid - }, - format: :json + get :codequality_mr_diff_reports, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, + format: :json end context 'permissions on a public project with private CI/CD' do @@ -1264,12 +1267,13 @@ RSpec.describe Projects::MergeRequestsController do end subject do - get :terraform_reports, params: { - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid - }, - format: :json + get :terraform_reports, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, + format: :json end describe 'permissions on a public project with private CI/CD' do @@ -1394,12 +1398,13 @@ RSpec.describe Projects::MergeRequestsController do end subject do - get :test_reports, params: { - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid - }, - format: :json + get :test_reports, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, + format: :json end before do @@ -1522,12 +1527,13 @@ RSpec.describe Projects::MergeRequestsController do end subject do - get :accessibility_reports, params: { - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid - }, - format: :json + get :accessibility_reports, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, + format: :json end context 'permissions on a public project with private CI/CD' do @@ -1642,12 +1648,13 @@ RSpec.describe Projects::MergeRequestsController do end subject do - get :codequality_reports, params: { - namespace_id: project.namespace.to_param, - project_id: project, - id: merge_request.iid - }, - format: :json + get :codequality_reports, + params: { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid + }, + format: :json end context 'permissions on a public project with private CI/CD' do diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb index 9050765afd6..1f8e96258ca 100644 --- a/spec/controllers/projects/notes_controller_spec.rb +++ b/spec/controllers/projects/notes_controller_spec.rb @@ -659,7 +659,7 @@ RSpec.describe Projects::NotesController do context 'when target_id and noteable_id do not match' do let(:locked_issue) { create(:issue, :locked, project: project) } - let(:issue) {create(:issue, project: project)} + let(:issue) { create(:issue, project: project) } it 'uses target_id and ignores noteable_id' do request_params = { diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb index 77acd5fe13c..5bcfae4227c 100644 --- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb +++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb @@ -354,7 +354,8 @@ RSpec.describe Projects::PipelineSchedulesController do end def go - put :update, params: { + put :update, + params: { namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule, diff --git a/spec/controllers/projects/pipelines/tests_controller_spec.rb b/spec/controllers/projects/pipelines/tests_controller_spec.rb index ddcab8b048e..07e3c28f685 100644 --- a/spec/controllers/projects/pipelines/tests_controller_spec.rb +++ b/spec/controllers/projects/pipelines/tests_controller_spec.rb @@ -86,11 +86,12 @@ RSpec.describe Projects::Pipelines::TestsController do # Each test failure in this pipeline has a matching failure in the default branch recent_failures = json_response['test_cases'].map { |tc| tc['recent_failures'] } - expect(recent_failures).to eq([ - { 'count' => 1, 'base_branch' => 'master' }, - { 'count' => 1, 'base_branch' => 'master' }, - { 'count' => 1, 'base_branch' => 'master' } - ]) + expect(recent_failures).to eq( + [ + { 'count' => 1, 'base_branch' => 'master' }, + { 'count' => 1, 'base_branch' => 'master' }, + { 'count' => 1, 'base_branch' => 'master' } + ]) end end end diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 06930d8727b..b9acaf65892 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -270,9 +270,13 @@ RSpec.describe Projects::PipelinesController do user: user, merge_request: merge_request) - create_build(pipeline, 'build', 1, 'build', user) - create_build(pipeline, 'test', 2, 'test', user) - create_build(pipeline, 'deploy', 3, 'deploy', user) + build_stage = create(:ci_stage, name: 'build', pipeline: pipeline) + test_stage = create(:ci_stage, name: 'test', pipeline: pipeline) + deploy_stage = create(:ci_stage, name: 'deploy', pipeline: pipeline) + + create_build(pipeline, build_stage, 1, 'build', user) + create_build(pipeline, test_stage, 2, 'test', user) + create_build(pipeline, deploy_stage, 3, 'deploy', user) pipeline end @@ -284,7 +288,7 @@ RSpec.describe Projects::PipelinesController do :artifacts, artifacts_expire_at: 2.days.from_now, pipeline: pipeline, - stage: stage, + ci_stage: stage, stage_idx: stage_idx, name: name, status: status, @@ -327,21 +331,24 @@ RSpec.describe Projects::PipelinesController do render_views let_it_be(:pipeline) { create(:ci_pipeline, project: project) } + let_it_be(:build_stage) { create(:ci_stage, name: 'build', pipeline: pipeline) } + let_it_be(:test_stage) { create(:ci_stage, name: 'test', pipeline: pipeline) } + let_it_be(:deploy_stage) { create(:ci_stage, name: 'deploy', pipeline: pipeline) } def create_build_with_artifacts(stage, stage_idx, name, status) - create(:ci_build, :artifacts, :tags, status, user: user, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name) + create(:ci_build, :artifacts, :tags, status, user: user, pipeline: pipeline, ci_stage: stage, stage_idx: stage_idx, name: name) end def create_bridge(stage, stage_idx, name, status) - create(:ci_bridge, status, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name) + create(:ci_bridge, status, pipeline: pipeline, ci_stage: stage, stage_idx: stage_idx, name: name) end before do - create_build_with_artifacts('build', 0, 'job1', :failed) - create_build_with_artifacts('build', 0, 'job2', :running) - create_build_with_artifacts('build', 0, 'job3', :pending) - create_bridge('deploy', 1, 'deploy-a', :failed) - create_bridge('deploy', 1, 'deploy-b', :created) + create_build_with_artifacts(build_stage, 0, 'job1', :failed) + create_build_with_artifacts(build_stage, 0, 'job2', :running) + create_build_with_artifacts(build_stage, 0, 'job3', :pending) + create_bridge(deploy_stage, 1, 'deploy-a', :failed) + create_bridge(deploy_stage, 1, 'deploy-b', :created) end it 'avoids N+1 database queries', :request_store, :use_sql_query_cache do @@ -354,11 +361,11 @@ RSpec.describe Projects::PipelinesController do expect(response).to have_gitlab_http_status(:ok) end - create_build_with_artifacts('build', 0, 'job4', :failed) - create_build_with_artifacts('build', 0, 'job5', :running) - create_build_with_artifacts('build', 0, 'job6', :pending) - create_bridge('deploy', 1, 'deploy-c', :failed) - create_bridge('deploy', 1, 'deploy-d', :created) + create_build_with_artifacts(build_stage, 0, 'job4', :failed) + create_build_with_artifacts(build_stage, 0, 'job5', :running) + create_build_with_artifacts(build_stage, 0, 'job6', :pending) + create_bridge(deploy_stage, 1, 'deploy-c', :failed) + create_bridge(deploy_stage, 1, 'deploy-d', :created) expect do get_pipeline_html @@ -402,11 +409,16 @@ RSpec.describe Projects::PipelinesController do sha: project.commit.id) end + let(:build_stage) { create(:ci_stage, name: 'build', pipeline: pipeline) } + let(:test_stage) { create(:ci_stage, name: 'test', pipeline: pipeline) } + let(:deploy_stage) { create(:ci_stage, name: 'deploy', pipeline: pipeline) } + let(:post_deploy_stage) { create(:ci_stage, name: 'post deploy', pipeline: pipeline) } + before do - create_build('build', 0, 'build') - create_build('test', 1, 'rspec 0') - create_build('deploy', 2, 'production') - create_build('post deploy', 3, 'pages 0') + create_build(build_stage, 0, 'build') + create_build(test_stage, 1, 'rspec 0') + create_build(deploy_stage, 2, 'production') + create_build(post_deploy_stage, 3, 'pages 0') end it 'does not perform N + 1 queries' do @@ -612,7 +624,9 @@ RSpec.describe Projects::PipelinesController do def create_pipeline(project) create(:ci_empty_pipeline, project: project).tap do |pipeline| - create(:ci_build, pipeline: pipeline, stage: 'test', name: 'rspec') + create(:ci_build, pipeline: pipeline, + ci_stage: create(:ci_stage, name: 'test', pipeline: pipeline), + name: 'rspec') end end @@ -642,7 +656,7 @@ RSpec.describe Projects::PipelinesController do end def create_build(stage, stage_idx, name) - create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name) + create(:ci_build, pipeline: pipeline, ci_stage: stage, stage_idx: stage_idx, name: name) end end @@ -654,10 +668,12 @@ RSpec.describe Projects::PipelinesController do describe 'GET dag.json' do let(:pipeline) { create(:ci_pipeline, project: project) } + let(:build_stage) { create(:ci_stage, name: 'build', pipeline: pipeline) } + let(:test_stage) { create(:ci_stage, name: 'test', pipeline: pipeline) } before do - create_build('build', 1, 'build') - create_build('test', 2, 'test', scheduling_type: 'dag').tap do |job| + create_build(build_stage, 1, 'build') + create_build(test_stage, 2, 'test', scheduling_type: 'dag').tap do |job| create(:ci_build_need, build: job, name: 'build') end end @@ -681,7 +697,7 @@ RSpec.describe Projects::PipelinesController do end def create_build(stage, stage_idx, name, params = {}) - create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name, **params) + create(:ci_build, pipeline: pipeline, ci_stage: stage, stage_idx: stage_idx, name: name, **params) end end @@ -730,11 +746,12 @@ RSpec.describe Projects::PipelinesController do describe 'GET stages.json' do let(:pipeline) { create(:ci_pipeline, project: project) } + let(:build_stage) { create(:ci_stage, name: 'build', pipeline: pipeline) } context 'when accessing existing stage' do before do - create(:ci_build, :retried, :failed, pipeline: pipeline, stage: 'build') - create(:ci_build, pipeline: pipeline, stage: 'build') + create(:ci_build, :retried, :failed, pipeline: pipeline, ci_stage: build_stage) + create(:ci_build, pipeline: pipeline, ci_stage: build_stage) end context 'without retried' do @@ -841,6 +858,18 @@ RSpec.describe Projects::PipelinesController 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 + + it_behaves_like 'Snowplow event tracking' do + subject { get :charts, params: request_params, format: :html } + + let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } } + let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } + let(:category) { described_class.name } + let(:action) { 'perform_analytics_usage_action' } + let(:namespace) { project.namespace } + let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' } + let(:property) { 'p_analytics_pipelines' } + end end end @@ -965,8 +994,8 @@ RSpec.describe Projects::PipelinesController do expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['errors']).to eq([ - 'test job: chosen stage does not exist; available stages are .pre, build, test, deploy, .post' - ]) + 'test job: chosen stage does not exist; available stages are .pre, build, test, deploy, .post' + ]) expect(json_response['warnings'][0]).to include( 'jobs:build may allow multiple pipelines to run for a single action due to `rules:when`' ) diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index 46eb340cbba..fb27fe58cd9 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -5,6 +5,7 @@ require('spec_helper') RSpec.describe Projects::ProjectMembersController do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group, :public) } + let_it_be(:sub_group) { create(:group, parent: group) } let_it_be(:project, reload: true) { create(:project, :public) } before do @@ -52,7 +53,36 @@ RSpec.describe Projects::ProjectMembersController do end end - context 'when invited members are present' do + context 'when project belongs to a sub-group' do + let_it_be(:user_in_group) { create(:user) } + let_it_be(:project_in_group) { create(:project, :public, group: sub_group) } + + before do + group.add_owner(user_in_group) + project_in_group.add_maintainer(user) + sign_in(user) + end + + it 'lists inherited project members by default' do + get :index, params: { namespace_id: project_in_group.namespace, project_id: project_in_group } + + expect(assigns(:project_members).map(&:user_id)).to contain_exactly(user.id, user_in_group.id) + end + + it 'lists direct project members only' do + get :index, params: { namespace_id: project_in_group.namespace, project_id: project_in_group, with_inherited_permissions: 'exclude' } + + expect(assigns(:project_members).map(&:user_id)).to contain_exactly(user.id) + end + + it 'lists inherited project members only' do + get :index, params: { namespace_id: project_in_group.namespace, project_id: project_in_group, with_inherited_permissions: 'only' } + + expect(assigns(:project_members).map(&:user_id)).to contain_exactly(user_in_group.id) + end + end + + context 'when invited project members are present' do let!(:invited_member) { create(:project_member, :invited, project: project) } before do diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb index c03a280d2cd..7b786f4a8af 100644 --- a/spec/controllers/projects/registry/tags_controller_spec.rb +++ b/spec/controllers/projects/registry/tags_controller_spec.rb @@ -167,7 +167,7 @@ RSpec.describe Projects::Registry::TagsController do repository_id: repository, ids: names }, - format: :json + format: :json end end diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb index ad6682601f3..b307bb357fa 100644 --- a/spec/controllers/projects/releases_controller_spec.rb +++ b/spec/controllers/projects/releases_controller_spec.rb @@ -312,7 +312,7 @@ RSpec.describe Projects::ReleasesController do end context 'suffix path abuse' do - let(:suffix_path) { 'downloads/zips/../../../../../../../robots.txt'} + let(:suffix_path) { 'downloads/zips/../../../../../../../robots.txt' } it 'raises attack error' do expect do diff --git a/spec/controllers/projects/service_desk_controller_spec.rb b/spec/controllers/projects/service_desk_controller_spec.rb index 1c4d6665414..e078bf9461e 100644 --- a/spec/controllers/projects/service_desk_controller_spec.rb +++ b/spec/controllers/projects/service_desk_controller_spec.rb @@ -4,8 +4,9 @@ require 'spec_helper' RSpec.describe Projects::ServiceDeskController do let_it_be(:project) do - create(:project, :private, :custom_repo, service_desk_enabled: true, - files: { '.gitlab/issue_templates/service_desk.md' => 'template' }) + create(:project, :private, :custom_repo, + service_desk_enabled: true, + files: { '.gitlab/issue_templates/service_desk.md' => 'template' }) end let_it_be(:user) { create(:user) } diff --git a/spec/controllers/projects/settings/integrations_controller_spec.rb b/spec/controllers/projects/settings/integrations_controller_spec.rb index 8ee9f22aa7f..b76269f6f93 100644 --- a/spec/controllers/projects/settings/integrations_controller_spec.rb +++ b/spec/controllers/projects/settings/integrations_controller_spec.rb @@ -50,7 +50,7 @@ RSpec.describe Projects::Settings::IntegrationsController do end end - context 'when validations fail' do + context 'when validations fail', :clean_gitlab_redis_rate_limiting do let(:integration_params) { { active: 'true', url: '' } } it 'returns error messages in JSON response' do @@ -62,7 +62,7 @@ RSpec.describe Projects::Settings::IntegrationsController do end end - context 'when successful' do + context 'when successful', :clean_gitlab_redis_rate_limiting do context 'with empty project' do let_it_be(:project) { create(:project) } @@ -200,8 +200,8 @@ RSpec.describe Projects::Settings::IntegrationsController do 2.times { post :test, params: project_params(service: integration_params) } - expect(response.body).to eq(_('This endpoint has been requested too many times. Try again later.')) - expect(response).to have_gitlab_http_status(:too_many_requests) + expect(response.body).to include(_('This endpoint has been requested too many times. Try again later.')) + expect(response).to have_gitlab_http_status(:ok) end end end diff --git a/spec/controllers/projects/settings/merge_requests_controller_spec.rb b/spec/controllers/projects/settings/merge_requests_controller_spec.rb new file mode 100644 index 00000000000..106ec62bea0 --- /dev/null +++ b/spec/controllers/projects/settings/merge_requests_controller_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::Settings::MergeRequestsController do + let(:project) { create(:project_empty_repo, :public) } + let(:user) { create(:user) } + + before do + project.add_maintainer(user) + sign_in(user) + end + + describe 'GET show' do + it 'renders show with 200 status code' do + get :show, params: { namespace_id: project.namespace, project_id: project } + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template(:show) + end + end + + describe '#update', :enable_admin_mode do + render_views + + let(:admin) { create(:admin) } + + before do + sign_in(admin) + end + + it 'updates Fast Forward Merge attributes' do + controller.instance_variable_set(:@project, project) + + params = { + merge_method: :ff + } + + put :update, + params: { + namespace_id: project.namespace, + project_id: project.id, + project: params + } + + expect(response).to redirect_to project_settings_merge_requests_path(project) + params.each do |param, value| + expect(project.public_send(param)).to eq(value) + end + end + end +end diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb index 143516e4712..9bc3065b6da 100644 --- a/spec/controllers/projects/tree_controller_spec.rb +++ b/spec/controllers/projects/tree_controller_spec.rb @@ -163,8 +163,8 @@ RSpec.describe Projects::TreeController do end context 'successful creation' do - let(:path) { 'files/new_dir'} - let(:branch_name) { 'master-test'} + let(:path) { 'files/new_dir' } + let(:branch_name) { 'master-test' } it 'redirects to the new directory' do expect(subject) @@ -175,7 +175,7 @@ RSpec.describe Projects::TreeController do context 'unsuccessful creation' do let(:path) { 'README.md' } - let(:branch_name) { 'master'} + let(:branch_name) { 'master' } it 'does not allow overwriting of existing files' do expect(subject) diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 94d75ab8d7d..b30610d98d7 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -920,6 +920,7 @@ RSpec.describe ProjectsController do environments_access_level feature_flags_access_level releases_access_level + monitor_access_level ] end @@ -947,6 +948,7 @@ RSpec.describe ProjectsController do where(:feature_access_level) do %i[ environments_access_level feature_flags_access_level + monitor_access_level ] end @@ -1217,6 +1219,40 @@ RSpec.describe ProjectsController do expect(json_response["Commits"]).to include("123456") end + it 'uses gitaly pagination' do + expected_params = ActionController::Parameters.new(ref: '123456', per_page: 100).permit! + + expect_next_instance_of(BranchesFinder, project.repository, expected_params) do |finder| + expect(finder).to receive(:execute).with(gitaly_pagination: true).and_call_original + end + + expect_next_instance_of(TagsFinder, project.repository, expected_params) do |finder| + expect(finder).to receive(:execute).with(gitaly_pagination: true).and_call_original + end + + get :refs, params: { namespace_id: project.namespace, id: project, ref: "123456" } + end + + context 'when use_gitaly_pagination_for_refs is disabled' do + before do + stub_feature_flags(use_gitaly_pagination_for_refs: false) + end + + it 'does not use gitaly pagination' do + expected_params = ActionController::Parameters.new(ref: '123456', per_page: 100).permit! + + expect_next_instance_of(BranchesFinder, project.repository, expected_params) do |finder| + expect(finder).to receive(:execute).with(gitaly_pagination: false).and_call_original + end + + expect_next_instance_of(TagsFinder, project.repository, expected_params) do |finder| + expect(finder).to receive(:execute).with(gitaly_pagination: false).and_call_original + end + + get :refs, params: { namespace_id: project.namespace, id: project, ref: "123456" } + end + end + context 'when gitaly is unavailable' do before do expect_next_instance_of(TagsFinder) do |finder| diff --git a/spec/controllers/registrations/welcome_controller_spec.rb b/spec/controllers/registrations/welcome_controller_spec.rb index 8a5a8490a23..14e88d469ba 100644 --- a/spec/controllers/registrations/welcome_controller_spec.rb +++ b/spec/controllers/registrations/welcome_controller_spec.rb @@ -36,7 +36,7 @@ RSpec.describe Registrations::WelcomeController do sign_in(user) end - it { is_expected.to redirect_to(dashboard_projects_path)} + it { is_expected.to redirect_to(dashboard_projects_path) } end context 'when role is set and setup_for_company is not set' do @@ -78,7 +78,7 @@ RSpec.describe Registrations::WelcomeController do sign_in(user) end - it { is_expected.to redirect_to(dashboard_projects_path)} + it { is_expected.to redirect_to(dashboard_projects_path) } context 'when the new user already has any accepted group membership' do let!(:member1) { create(:group_member, user: user) } diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 70d4559edc1..637c774c38b 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -7,6 +7,7 @@ RSpec.describe RegistrationsController do before do stub_application_setting(require_admin_approval_after_user_signup: false) + stub_feature_flags(arkose_labs_signup_challenge: false) end describe '#new' do @@ -121,6 +122,7 @@ RSpec.describe RegistrationsController do context 'when `send_user_confirmation_email` is true' do before do stub_application_setting(send_user_confirmation_email: true) + stub_feature_flags(identity_verification: false) end it 'sends a confirmation email' do @@ -133,6 +135,10 @@ RSpec.describe RegistrationsController do end context 'email confirmation' do + before do + stub_feature_flags(identity_verification: false) + end + context 'when send_user_confirmation_email is false' do it 'signs the user in' do stub_application_setting(send_user_confirmation_email: false) @@ -492,6 +498,33 @@ RSpec.describe RegistrationsController do end end end + + context 'when the password is weak' do + render_views + let_it_be(:new_user_params) { { new_user: base_user_params.merge({ password: "password" }) } } + + subject { post(:create, params: new_user_params) } + + context 'when block_weak_passwords is enabled (default)' do + it 'renders the form with errors' do + expect { subject }.not_to change(User, :count) + + expect(controller.current_user).to be_nil + expect(response).to render_template(:new) + expect(response.body).to include(_('Password must not contain commonly used combinations of words and letters')) + end + end + + context 'when block_weak_passwords is disabled' do + before do + stub_feature_flags(block_weak_passwords: false) + end + + it 'permits weak passwords' do + expect { subject }.to change(User, :count).by(1) + end + end + end end describe '#destroy' do diff --git a/spec/controllers/repositories/git_http_controller_spec.rb b/spec/controllers/repositories/git_http_controller_spec.rb index 448587c937a..da62acb1fda 100644 --- a/spec/controllers/repositories/git_http_controller_spec.rb +++ b/spec/controllers/repositories/git_http_controller_spec.rb @@ -55,11 +55,11 @@ RSpec.describe Repositories::GitHttpController do let_it_be(:namespace) { project.namespace } before do - OnboardingProgress.onboard(namespace) + Onboarding::Progress.onboard(namespace) send_request end - subject { OnboardingProgress.completed?(namespace, :git_pull) } + subject { Onboarding::Progress.completed?(namespace, :git_pull) } it { is_expected.to be(true) } end diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index 14b198dbefe..4131bd148da 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -270,6 +270,59 @@ RSpec.describe SearchController do get(:show, params: { search: 'foo@bar.com', scope: 'users' }) end end + + it 'increments the custom search sli apdex' do + expect(Gitlab::Metrics::GlobalSearchSlis).to receive(:record_apdex).with( + elapsed: a_kind_of(Numeric), + search_scope: 'issues', + search_type: 'basic', + search_level: 'global' + ) + + get :show, params: { scope: 'issues', search: 'hello world' } + end + + context 'custom search sli error rate' do + context 'when the search is successful' do + it 'increments the custom search sli error rate with error: false' do + expect(Gitlab::Metrics::GlobalSearchSlis).to receive(:record_error_rate).with( + error: false, + search_scope: 'issues', + search_type: 'basic', + search_level: 'global' + ) + + get :show, params: { scope: 'issues', search: 'hello world' } + end + end + + context 'when the search raises an error' do + before do + allow_next_instance_of(SearchService) do |service| + allow(service).to receive(:search_results).and_raise(ActiveRecord::QueryCanceled) + end + end + + it 'increments the custom search sli error rate with error: true' do + expect(Gitlab::Metrics::GlobalSearchSlis).to receive(:record_error_rate).with( + error: true, + search_scope: 'issues', + search_type: 'basic', + search_level: 'global' + ) + + get :show, params: { scope: 'issues', search: 'hello world' } + end + end + + context 'when something goes wrong before a search is done' do + it 'does not increment the error rate' do + expect(Gitlab::Metrics::GlobalSearchSlis).not_to receive(:record_error_rate) + + get :show, params: { scope: 'issues' } # no search query + end + end + end end describe 'GET #count', :aggregate_failures do diff --git a/spec/controllers/snippets/notes_controller_spec.rb b/spec/controllers/snippets/notes_controller_spec.rb index 8e85e283b31..00d99b46d0b 100644 --- a/spec/controllers/snippets/notes_controller_spec.rb +++ b/spec/controllers/snippets/notes_controller_spec.rb @@ -312,7 +312,7 @@ RSpec.describe Snippets::NotesController do describe 'POST toggle_award_emoji' do let(:note) { create(:note_on_personal_snippet, noteable: public_snippet) } - let(:emoji_name) { 'thumbsup'} + let(:emoji_name) { 'thumbsup' } before do sign_in(user) |