diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-09-20 13:18:24 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-09-20 13:18:24 +0000 |
commit | 0653e08efd039a5905f3fa4f6e9cef9f5d2f799c (patch) | |
tree | 4dcc884cf6d81db44adae4aa99f8ec1233a41f55 /spec/controllers | |
parent | 744144d28e3e7fddc117924fef88de5d9674fe4c (diff) | |
download | gitlab-ce-0653e08efd039a5905f3fa4f6e9cef9f5d2f799c.tar.gz |
Add latest changes from gitlab-org/gitlab@14-3-stable-eev14.3.0-rc42
Diffstat (limited to 'spec/controllers')
26 files changed, 499 insertions, 516 deletions
diff --git a/spec/controllers/admin/integrations_controller_spec.rb b/spec/controllers/admin/integrations_controller_spec.rb index 64ae2a95b4e..1793b3a86d1 100644 --- a/spec/controllers/admin/integrations_controller_spec.rb +++ b/spec/controllers/admin/integrations_controller_spec.rb @@ -9,6 +9,14 @@ RSpec.describe Admin::IntegrationsController do sign_in(admin) end + it_behaves_like IntegrationsActions do + let(:integration_attributes) { { instance: true, project: nil } } + + let(:routing_params) do + { id: integration.to_param } + end + end + describe '#edit' do Integration.available_integration_names.each do |integration_name| context "#{integration_name}" do diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb index 8e57b4f03a7..996964fdcf0 100644 --- a/spec/controllers/admin/runners_controller_spec.rb +++ b/spec/controllers/admin/runners_controller_spec.rb @@ -23,10 +23,6 @@ RSpec.describe Admin::RunnersController do describe '#show' do render_views - before do - stub_feature_flags(runner_detailed_view_vue_ui: false) - end - let_it_be(:project) { create(:project) } let_it_be(:project_two) { create(:project) } @@ -61,30 +57,6 @@ RSpec.describe Admin::RunnersController do expect(response).to have_gitlab_http_status(:ok) end - - describe 'Cost factors values' do - context 'when it is Gitlab.com' do - before do - expect(Gitlab).to receive(:com?).at_least(:once) { true } - end - - it 'renders cost factors fields' do - get :show, params: { id: runner.id } - - expect(response.body).to match /Private projects Minutes cost factor/ - expect(response.body).to match /Public projects Minutes cost factor/ - end - end - - context 'when it is not Gitlab.com' do - it 'does not show cost factor fields' do - get :show, params: { id: runner.id } - - expect(response.body).not_to match /Private projects Minutes cost factor/ - expect(response.body).not_to match /Public projects Minutes cost factor/ - end - end - end end describe '#update' do diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 6e172f53257..015c36c9335 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -146,7 +146,7 @@ RSpec.describe Admin::UsersController do it 'sends the user a rejection email' do expect_next_instance_of(NotificationService) do |notification| - allow(notification).to receive(:user_admin_rejection).with(user.name, user.notification_email) + allow(notification).to receive(:user_admin_rejection).with(user.name, user.notification_email_or_default) end subject @@ -165,7 +165,7 @@ RSpec.describe Admin::UsersController do it 'displays the error' do subject - expect(flash[:alert]).to eq('This user does not have a pending request') + expect(flash[:alert]).to eq('User does not have a pending request') end it 'does not email the user' do diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb index 48000284264..cc60ab16d2e 100644 --- a/spec/controllers/boards/issues_controller_spec.rb +++ b/spec/controllers/boards/issues_controller_spec.rb @@ -428,17 +428,21 @@ RSpec.describe Boards::IssuesController do describe 'POST create' do context 'with valid params' do - it 'returns a successful 200 response' do + before do create_issue user: user, board: board, list: list1, title: 'New issue' + end + it 'returns a successful 200 response' do expect(response).to have_gitlab_http_status(:ok) end it 'returns the created issue' do - create_issue user: user, board: board, list: list1, title: 'New issue' - expect(response).to match_response_schema('entities/issue_board') end + + it 'sets the default work_item_type' do + expect(Issue.last.work_item_type.base_type).to eq('issue') + end end context 'with invalid params' do diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb index a2b62aa49d2..2297198878d 100644 --- a/spec/controllers/explore/projects_controller_spec.rb +++ b/spec/controllers/explore/projects_controller_spec.rb @@ -200,6 +200,24 @@ RSpec.describe Explore::ProjectsController do let(:sorting_param) { 'created_asc' } end end + + describe 'GET #index' do + let(:controller_action) { :index } + let(:params_with_name) { { name: 'some project' } } + + context 'when disable_anonymous_project_search is enabled' do + before do + stub_feature_flags(disable_anonymous_project_search: true) + end + + it 'does not show a flash message' do + sign_in(create(:user)) + get controller_action, params: params_with_name + + expect(flash.now[:notice]).to be_nil + end + end + end end context 'when user is not signed in' do @@ -229,5 +247,50 @@ RSpec.describe Explore::ProjectsController do expect(response).to redirect_to new_user_session_path end end + + describe 'GET #index' do + let(:controller_action) { :index } + let(:params_with_name) { { name: 'some project' } } + + context 'when disable_anonymous_project_search is enabled' do + before do + stub_feature_flags(disable_anonymous_project_search: true) + end + + it 'shows a flash message' do + get controller_action, params: params_with_name + + expect(flash.now[:notice]).to eq('You must sign in to search for specific projects.') + end + + context 'when search param is not given' do + it 'does not show a flash message' do + get controller_action + + expect(flash.now[:notice]).to be_nil + end + end + + context 'when format is not HTML' do + it 'does not show a flash message' do + get controller_action, params: params_with_name.merge(format: :atom) + + expect(flash.now[:notice]).to be_nil + end + end + end + + context 'when disable_anonymous_project_search is disabled' do + before do + stub_feature_flags(disable_anonymous_project_search: false) + end + + it 'does not show a flash message' do + get controller_action, params: params_with_name + + expect(flash.now[:notice]).to be_nil + end + end + end end end diff --git a/spec/controllers/groups/children_controller_spec.rb b/spec/controllers/groups/children_controller_spec.rb index e97fe50c468..04cf7785f1e 100644 --- a/spec/controllers/groups/children_controller_spec.rb +++ b/spec/controllers/groups/children_controller_spec.rb @@ -227,8 +227,8 @@ RSpec.describe Groups::ChildrenController do context 'when rendering hierarchies' do # When loading hierarchies we load the all the ancestors for matched projects - # in 1 separate query - let(:extra_queries_for_hierarchies) { 1 } + # in 2 separate queries + let(:extra_queries_for_hierarchies) { 2 } def get_filtered_list get :index, params: { group_id: group.to_param, filter: 'filter' }, format: :json diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb index 1808969cd60..a8830efe653 100644 --- a/spec/controllers/groups/runners_controller_spec.rb +++ b/spec/controllers/groups/runners_controller_spec.rb @@ -3,11 +3,13 @@ require 'spec_helper' RSpec.describe Groups::RunnersController do - let(:user) { create(:user) } - let(:group) { create(:group) } - let(:runner) { create(:ci_runner, :group, groups: [group]) } - let(:project) { create(:project, group: group) } - let(:runner_project) { create(:ci_runner, :project, projects: [project]) } + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } + + let!(:runner) { create(:ci_runner, :group, groups: [group]) } + let!(:runner_project) { create(:ci_runner, :project, projects: [project]) } + let(:params_runner_project) { { group_id: group, id: runner_project } } let(:params) { { group_id: group, id: runner } } @@ -26,6 +28,7 @@ RSpec.describe Groups::RunnersController do expect(response).to have_gitlab_http_status(:ok) expect(response).to render_template(:index) + expect(assigns(:group_runners_limited_count)).to be(2) end end diff --git a/spec/controllers/groups/settings/integrations_controller_spec.rb b/spec/controllers/groups/settings/integrations_controller_spec.rb index 931e726850a..31d1946652d 100644 --- a/spec/controllers/groups/settings/integrations_controller_spec.rb +++ b/spec/controllers/groups/settings/integrations_controller_spec.rb @@ -10,6 +10,21 @@ RSpec.describe Groups::Settings::IntegrationsController do sign_in(user) end + it_behaves_like IntegrationsActions do + let(:integration_attributes) { { group: group, project: nil } } + + let(:routing_params) do + { + group_id: group, + id: integration.to_param + } + end + + before do + group.add_owner(user) + end + end + describe '#index' do context 'when user is not owner' do it 'renders not_found' do diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index 91b11cd46c5..a7625e65603 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -370,6 +370,57 @@ RSpec.describe GroupsController, factory_default: :keep do end end end + + context 'when creating a group with the `role` attribute present' do + it 'changes the users role' do + sign_in(user) + + expect do + post :create, params: { group: { name: 'new_group', path: 'new_group' }, user: { role: 'devops_engineer' } } + end.to change { user.reload.role }.to('devops_engineer') + end + end + + context 'when creating a group with the `setup_for_company` attribute present' do + before do + sign_in(user) + end + + subject do + post :create, params: { group: { name: 'new_group', path: 'new_group', setup_for_company: 'false' } } + end + + it 'sets the groups `setup_for_company` value' do + subject + expect(Group.last.setup_for_company).to be(false) + end + + context 'when the user already has a value for `setup_for_company`' do + before do + user.update_attribute(:setup_for_company, true) + end + + it 'does not change the users `setup_for_company` value' do + expect(Users::UpdateService).not_to receive(:new) + expect { subject }.not_to change { user.reload.setup_for_company }.from(true) + end + end + + context 'when the user has no value for `setup_for_company`' do + it 'changes the users `setup_for_company` value' do + expect(Users::UpdateService).to receive(:new).and_call_original + expect { subject }.to change { user.reload.setup_for_company }.to(false) + end + end + end + + context 'when creating a group with the `jobs_to_be_done` attribute present' do + it 'sets the groups `jobs_to_be_done` value' do + sign_in(user) + post :create, params: { group: { name: 'new_group', path: 'new_group', jobs_to_be_done: 'other' } } + expect(Group.last.jobs_to_be_done).to eq('other') + end + end end describe 'GET #index' do diff --git a/spec/controllers/import/manifest_controller_spec.rb b/spec/controllers/import/manifest_controller_spec.rb index d5a498e80d9..0111ad9501f 100644 --- a/spec/controllers/import/manifest_controller_spec.rb +++ b/spec/controllers/import/manifest_controller_spec.rb @@ -75,16 +75,6 @@ RSpec.describe Import::ManifestController, :clean_gitlab_redis_shared_state do expect(json_response.dig("provider_repos", 0, "id")).to eq(repo1[:id]) expect(json_response.dig("provider_repos", 1, "id")).to eq(repo2[:id]) end - - it "does not show already added project" do - project = create(:project, import_type: 'manifest', namespace: user.namespace, import_status: :finished, import_url: repo1[:url]) - - get :status, format: :json - - expect(json_response.dig("imported_projects", 0, "id")).to eq(project.id) - expect(json_response.dig("provider_repos").length).to eq(1) - expect(json_response.dig("provider_repos", 0, "id")).not_to eq(repo1[:id]) - end end context 'when the data is stored via Gitlab::ManifestImport::Metadata' do diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index dc1fb0454df..d4091461062 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -120,6 +120,29 @@ RSpec.describe InvitesController do end end + context 'when it is part of the invite_email_from experiment' do + let(:extra_params) { { invite_type: 'initial_email', experiment_name: 'invite_email_from' } } + + it 'tracks the initial join click from email' do + experiment = double(track: true) + allow(controller).to receive(:experiment).with(:invite_email_from, actor: member).and_return(experiment) + + request + + expect(experiment).to have_received(:track).with(:join_clicked) + end + + context 'when member does not exist' do + let(:raw_invite_token) { '_bogus_token_' } + + it 'does not track the experiment' do + expect(controller).not_to receive(:experiment).with(:invite_email_from, actor: member) + + request + end + end + end + context 'when member does not exist' do let(:raw_invite_token) { '_bogus_token_' } @@ -147,8 +170,9 @@ RSpec.describe InvitesController do end context 'when it is not part of our invite email experiment' do - it 'does not track via experiment' do + it 'does not track via experiment', :aggregate_failures do expect(controller).not_to receive(:experiment).with(:invite_email_preview_text, actor: member) + expect(controller).not_to receive(:experiment).with(:invite_email_from, actor: member) request end diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb index 9a142559fca..8c8de2f79a3 100644 --- a/spec/controllers/omniauth_callbacks_controller_spec.rb +++ b/spec/controllers/omniauth_callbacks_controller_spec.rb @@ -317,7 +317,7 @@ RSpec.describe OmniauthCallbacksController, type: :controller do it 'denies sign-in if sign-up is enabled, but block_auto_created_users is set' do post :atlassian_oauth2 - expect(flash[:alert]).to start_with 'Your account has been blocked.' + expect(flash[:alert]).to start_with 'Your account is pending approval' end it 'accepts sign-in if sign-up is enabled' do @@ -399,7 +399,7 @@ RSpec.describe OmniauthCallbacksController, type: :controller do it 'denies login if sign up is enabled, but block_auto_created_users is set' do post :saml, params: { SAMLResponse: mock_saml_response } - expect(flash[:alert]).to start_with 'Your account has been blocked.' + expect(flash[:alert]).to start_with 'Your account is pending approval' end it 'accepts login if sign up is enabled' do diff --git a/spec/controllers/profiles/two_factor_auths_controller_spec.rb b/spec/controllers/profiles/two_factor_auths_controller_spec.rb index 818bf2a4ae6..073180cbafd 100644 --- a/spec/controllers/profiles/two_factor_auths_controller_spec.rb +++ b/spec/controllers/profiles/two_factor_auths_controller_spec.rb @@ -10,8 +10,33 @@ RSpec.describe Profiles::TwoFactorAuthsController do allow(subject).to receive(:current_user).and_return(user) end + shared_examples 'user must first verify their primary email address' do + before do + allow(user).to receive(:primary_email_verified?).and_return(false) + end + + it 'redirects to profile_emails_path' do + go + + expect(response).to redirect_to(profile_emails_path) + end + + it 'displays a notice' do + go + + expect(flash[:notice]) + .to eq _('You need to verify your primary email first before enabling Two-Factor Authentication.') + end + + it 'does not redirect when the `ensure_verified_primary_email_for_2fa` feature flag is disabled' do + stub_feature_flags(ensure_verified_primary_email_for_2fa: false) + + expect(response).not_to redirect_to(profile_emails_path) + end + end + describe 'GET show' do - let(:user) { create(:user) } + let_it_be_with_reload(:user) { create(:user) } it 'generates otp_secret for user' do expect(User).to receive(:generate_otp_secret).with(32).and_call_original.once @@ -34,11 +59,16 @@ RSpec.describe Profiles::TwoFactorAuthsController do get :show end end + + it_behaves_like 'user must first verify their primary email address' do + let(:go) { get :show } + end end describe 'POST create' do - let(:user) { create(:user) } - let(:pin) { 'pin-code' } + let_it_be_with_reload(:user) { create(:user) } + + let(:pin) { 'pin-code' } def go post :create, params: { pin_code: pin } @@ -70,8 +100,8 @@ RSpec.describe Profiles::TwoFactorAuthsController do go end - it 'dismisses the `ACCOUNT_RECOVERY_REGULAR_CHECK` callout' do - expect(controller.helpers).to receive(:dismiss_account_recovery_regular_check) + it 'dismisses the `TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK` callout' do + expect(controller.helpers).to receive(:dismiss_two_factor_auth_recovery_settings_check) go end @@ -105,10 +135,12 @@ RSpec.describe Profiles::TwoFactorAuthsController do expect(response).to render_template(:show) end end + + it_behaves_like 'user must first verify their primary email address' end describe 'POST codes' do - let(:user) { create(:user, :two_factor) } + let_it_be_with_reload(:user) { create(:user, :two_factor) } it 'presents plaintext codes for the user to save' do expect(user).to receive(:generate_otp_backup_codes!).and_return(%w(a b c)) @@ -124,8 +156,8 @@ RSpec.describe Profiles::TwoFactorAuthsController do expect(user.otp_backup_codes).not_to be_empty end - it 'dismisses the `ACCOUNT_RECOVERY_REGULAR_CHECK` callout' do - expect(controller.helpers).to receive(:dismiss_account_recovery_regular_check) + it 'dismisses the `TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK` callout' do + expect(controller.helpers).to receive(:dismiss_two_factor_auth_recovery_settings_check) post :codes end @@ -135,7 +167,7 @@ RSpec.describe Profiles::TwoFactorAuthsController do subject { delete :destroy } context 'for a user that has 2FA enabled' do - let(:user) { create(:user, :two_factor) } + let_it_be_with_reload(:user) { create(:user, :two_factor) } it 'disables two factor' do subject @@ -158,7 +190,7 @@ RSpec.describe Profiles::TwoFactorAuthsController do end context 'for a user that does not have 2FA enabled' do - let(:user) { create(:user) } + let_it_be_with_reload(:user) { create(:user) } it 'redirects to profile_account_path' do subject diff --git a/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb b/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb index 1832b84ab6e..a366b2583d4 100644 --- a/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb +++ b/spec/controllers/projects/analytics/cycle_analytics/summary_controller_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project) } - let(:params) { { namespace_id: project.namespace.to_param, project_id: project.to_param, created_after: '2010-01-01', created_before: '2010-01-02' } } + let(:params) { { namespace_id: project.namespace.to_param, project_id: project.to_param, created_after: '2010-01-01', created_before: '2010-02-01' } } before do sign_in(user) @@ -42,5 +42,39 @@ RSpec.describe Projects::Analytics::CycleAnalytics::SummaryController do expect(response).to have_gitlab_http_status(:not_found) end end + + context 'when filters are applied' do + let_it_be(:author) { create(:user) } + let_it_be(:milestone) { create(:milestone, title: 'milestone 1', project: project) } + let_it_be(:issue_with_author) { create(:issue, project: project, author: author, created_at: Date.new(2010, 1, 15)) } + let_it_be(:issue_with_other_author) { create(:issue, project: project, author: user, created_at: Date.new(2010, 1, 15)) } + let_it_be(:issue_with_milestone) { create(:issue, project: project, milestone: milestone, created_at: Date.new(2010, 1, 15)) } + + before do + project.add_reporter(user) + end + + it 'filters by author username' do + params[:author_username] = author.username + + subject + + expect(response).to be_successful + + issue_count = json_response.first + expect(issue_count['value']).to eq('1') + end + + it 'filters by milestone title' do + params[:milestone_title] = milestone.title + + subject + + expect(response).to be_successful + + issue_count = json_response.first + expect(issue_count['value']).to eq('1') + end + end end end diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 7103d7df5c5..0fcdeb2edde 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -222,6 +222,16 @@ RSpec.describe Projects::EnvironmentsController do expect(response).to have_gitlab_http_status(:bad_request) end end + + context 'when name is passed' do + let(:params) { environment_params.merge(environment: { name: "new name" }) } + + it 'ignores name' do + expect do + subject + end.not_to change { environment.reload.name } + end + end end describe 'PATCH #stop' do diff --git a/spec/controllers/projects/feature_flags_controller_spec.rb b/spec/controllers/projects/feature_flags_controller_spec.rb index e038b247eff..fd95aa44568 100644 --- a/spec/controllers/projects/feature_flags_controller_spec.rb +++ b/spec/controllers/projects/feature_flags_controller_spec.rb @@ -94,20 +94,6 @@ RSpec.describe Projects::FeatureFlagsController do is_expected.to match_response_schema('feature_flags') end - it 'returns false for active when the feature flag is inactive even if it has an active scope' do - create(:operations_feature_flag_scope, - feature_flag: feature_flag_inactive, - environment_scope: 'production', - active: true) - - subject - - expect(response).to have_gitlab_http_status(:ok) - feature_flag_json = json_response['feature_flags'].second - - expect(feature_flag_json['active']).to eq(false) - end - it 'returns the feature flag iid' do subject @@ -181,7 +167,7 @@ RSpec.describe Projects::FeatureFlagsController do subject { get(:show, params: params, format: :json) } let!(:feature_flag) do - create(:operations_feature_flag, :legacy_flag, project: project) + create(:operations_feature_flag, project: project) end let(:params) do @@ -197,7 +183,7 @@ RSpec.describe Projects::FeatureFlagsController do expect(json_response['name']).to eq(feature_flag.name) expect(json_response['active']).to eq(feature_flag.active) - expect(json_response['version']).to eq('legacy_flag') + expect(json_response['version']).to eq('new_version_flag') end it 'matches json schema' do @@ -245,46 +231,6 @@ RSpec.describe Projects::FeatureFlagsController do end end - context 'when feature flags have additional scopes' do - context 'when there is at least one active scope' do - let!(:feature_flag) do - create(:operations_feature_flag, project: project, active: false) - end - - let!(:feature_flag_scope_production) do - create(:operations_feature_flag_scope, - feature_flag: feature_flag, - environment_scope: 'review/*', - active: true) - end - - it 'returns false for active' do - subject - - expect(json_response['active']).to eq(false) - end - end - - context 'when all scopes are inactive' do - let!(:feature_flag) do - create(:operations_feature_flag, project: project, active: false) - end - - let!(:feature_flag_scope_production) do - create(:operations_feature_flag_scope, - feature_flag: feature_flag, - environment_scope: 'production', - active: false) - end - - it 'recognizes the feature flag as inactive' do - subject - - expect(json_response['active']).to be_falsy - end - end - end - context 'with a version 2 feature flag' do let!(:new_version_feature_flag) do create(:operations_feature_flag, :new_version_flag, project: project) @@ -320,22 +266,6 @@ RSpec.describe Projects::FeatureFlagsController do describe 'GET edit' do subject { get(:edit, params: params) } - context 'with legacy flags' do - let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project) } - - let(:params) do - { - namespace_id: project.namespace, - project_id: project, - iid: feature_flag.iid - } - end - - it 'returns not found' do - is_expected.to have_gitlab_http_status(:not_found) - end - end - context 'with new version flags' do let!(:feature_flag) { create(:operations_feature_flag, project: project) } @@ -378,14 +308,6 @@ RSpec.describe Projects::FeatureFlagsController do expect(json_response['active']).to be_truthy end - it 'creates a default scope' do - subject - - expect(json_response['scopes'].count).to eq(1) - expect(json_response['scopes'].first['environment_scope']).to eq('*') - expect(json_response['scopes'].first['active']).to be_truthy - end - it 'matches json schema' do is_expected.to match_response_schema('feature_flag') end @@ -435,119 +357,6 @@ RSpec.describe Projects::FeatureFlagsController do end end - context 'when creates additional scope' do - let(:params) do - view_params.merge({ - operations_feature_flag: { - name: 'my_feature_flag', - active: true, - scopes_attributes: [{ environment_scope: '*', active: true }, - { environment_scope: 'production', active: false }] - } - }) - end - - it 'creates feature flag scopes successfully' do - expect { subject }.to change { Operations::FeatureFlagScope.count }.by(2) - - expect(response).to have_gitlab_http_status(:ok) - end - - it 'creates feature flag scopes in a correct order' do - subject - - expect(json_response['scopes'].first['environment_scope']).to eq('*') - expect(json_response['scopes'].second['environment_scope']).to eq('production') - end - - context 'when default scope is not placed first' do - let(:params) do - view_params.merge({ - operations_feature_flag: { - name: 'my_feature_flag', - active: true, - scopes_attributes: [{ environment_scope: 'production', active: false }, - { environment_scope: '*', active: true }] - } - }) - end - - it 'returns 400' do - subject - - expect(response).to have_gitlab_http_status(:bad_request) - expect(json_response['message']) - .to include('Default scope has to be the first element') - end - end - end - - context 'when creates additional scope with a percentage rollout' do - it 'creates a strategy for the scope' do - params = view_params.merge({ - operations_feature_flag: { - name: 'my_feature_flag', - active: true, - scopes_attributes: [{ environment_scope: '*', active: true }, - { environment_scope: 'production', active: false, - strategies: [{ name: 'gradualRolloutUserId', - parameters: { groupId: 'default', percentage: '42' } }] }] - } - }) - - post(:create, params: params, format: :json) - - expect(response).to have_gitlab_http_status(:ok) - production_strategies_json = json_response['scopes'].second['strategies'] - expect(production_strategies_json).to eq([{ - 'name' => 'gradualRolloutUserId', - 'parameters' => { "groupId" => "default", "percentage" => "42" } - }]) - end - end - - context 'when creates additional scope with a userWithId strategy' do - it 'creates a strategy for the scope' do - params = view_params.merge({ - operations_feature_flag: { - name: 'my_feature_flag', - active: true, - scopes_attributes: [{ environment_scope: '*', active: true }, - { environment_scope: 'production', active: false, - strategies: [{ name: 'userWithId', - parameters: { userIds: '123,4,6722' } }] }] - } - }) - - post(:create, params: params, format: :json) - - expect(response).to have_gitlab_http_status(:ok) - production_strategies_json = json_response['scopes'].second['strategies'] - expect(production_strategies_json).to eq([{ - 'name' => 'userWithId', - 'parameters' => { "userIds" => "123,4,6722" } - }]) - end - end - - context 'when creates an additional scope without a strategy' do - it 'creates a default strategy' do - params = view_params.merge({ - operations_feature_flag: { - name: 'my_feature_flag', - active: true, - scopes_attributes: [{ environment_scope: '*', active: true }] - } - }) - - post(:create, params: params, format: :json) - - expect(response).to have_gitlab_http_status(:ok) - default_strategies_json = json_response['scopes'].first['strategies'] - expect(default_strategies_json).to eq([{ "name" => "default", "parameters" => {} }]) - end - end - context 'when creating a version 2 feature flag' do let(:params) do { @@ -744,7 +553,7 @@ RSpec.describe Projects::FeatureFlagsController do describe 'DELETE destroy.json' do subject { delete(:destroy, params: params, format: :json) } - let!(:feature_flag) { create(:operations_feature_flag, :legacy_flag, project: project) } + let!(:feature_flag) { create(:operations_feature_flag, project: project) } let(:params) do { @@ -762,10 +571,6 @@ RSpec.describe Projects::FeatureFlagsController do expect { subject }.to change { Operations::FeatureFlag.count }.by(-1) end - it 'destroys the default scope' do - expect { subject }.to change { Operations::FeatureFlagScope.count }.by(-1) - end - it 'matches json schema' do is_expected.to match_response_schema('feature_flag') end @@ -792,14 +597,6 @@ RSpec.describe Projects::FeatureFlagsController do end end - context 'when there is an additional scope' do - let!(:scope) { create_scope(feature_flag, 'production', false) } - - it 'destroys the default scope and production scope' do - expect { subject }.to change { Operations::FeatureFlagScope.count }.by(-2) - end - end - context 'with a version 2 flag' do let!(:new_version_flag) { create(:operations_feature_flag, :new_version_flag, project: project) } let(:params) do @@ -828,70 +625,9 @@ RSpec.describe Projects::FeatureFlagsController do put(:update, params: params, format: :json, as: :json) end - context 'with a legacy feature flag' do - subject { put(:update, params: params, format: :json) } - - let!(:feature_flag) do - create(:operations_feature_flag, - :legacy_flag, - name: 'ci_live_trace', - active: true, - project: project) - end - - let(:params) do - { - namespace_id: project.namespace, - project_id: project, - iid: feature_flag.iid, - operations_feature_flag: { - name: 'ci_new_live_trace' - } - } - end - - context 'when user is reporter' do - let(:user) { reporter } - - it 'returns 404' do - is_expected.to have_gitlab_http_status(:not_found) - end - end - - context "when changing default scope's spec" do - let(:params) do - { - namespace_id: project.namespace, - project_id: project, - iid: feature_flag.iid, - operations_feature_flag: { - scopes_attributes: [ - { - id: feature_flag.default_scope.id, - environment_scope: 'review/*' - } - ] - } - } - end - - it 'returns 400' do - is_expected.to have_gitlab_http_status(:bad_request) - end - end - - it 'does not update a legacy feature flag' do - put_request(feature_flag, name: 'ci_new_live_trace') - - expect(response).to have_gitlab_http_status(:bad_request) - expect(json_response['message']).to eq(["Legacy feature flags are read-only"]) - end - end - context 'with a version 2 feature flag' do let!(:new_version_flag) do create(:operations_feature_flag, - :new_version_flag, name: 'new-feature', active: true, project: project) diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 0c29280316a..977879b453c 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -109,6 +109,14 @@ RSpec.describe Projects::IssuesController do end end + it_behaves_like 'issuable list with anonymous search disabled' do + let(:params) { { namespace_id: project.namespace, project_id: project } } + + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + end + end + it_behaves_like 'paginated collection' do let!(:issue_list) { create_list(:issue, 2, project: project) } let(:collection) { project.issues } @@ -301,6 +309,8 @@ RSpec.describe Projects::IssuesController do it 'fills in an issue for a discussion' do note = create(:note_on_merge_request, project: project) + expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).to receive(:track_resolve_thread_in_issue_action).with(user: user) + get :new, params: { namespace_id: project.namespace.path, project_id: project, merge_request_to_resolve_discussions_of: note.noteable.iid, discussion_to_resolve: note.discussion_id } expect(assigns(:issue).title).not_to be_empty @@ -1176,12 +1186,22 @@ RSpec.describe Projects::IssuesController do project.issues.first end + context 'when creating an incident' do + it 'sets the correct issue_type' do + issue = post_new_issue(issue_type: 'incident') + + expect(issue.issue_type).to eq('incident') + expect(issue.work_item_type.base_type).to eq('incident') + end + end + it 'creates the issue successfully', :aggregate_failures do issue = post_new_issue expect(issue).to be_a(Issue) expect(issue.persisted?).to eq(true) expect(issue.issue_type).to eq('issue') + expect(issue.work_item_type.base_type).to eq('issue') end context 'resolving discussions in MergeRequest' do diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb index e9e7c3c3bb3..06c29e767ad 100644 --- a/spec/controllers/projects/jobs_controller_spec.rb +++ b/spec/controllers/projects/jobs_controller_spec.rb @@ -755,23 +755,52 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do before do project.add_developer(user) sign_in(user) - - post_retry end context 'when job is retryable' do let(:job) { create(:ci_build, :retryable, pipeline: pipeline) } it 'redirects to the retried job page' do + post_retry + expect(response).to have_gitlab_http_status(:found) expect(response).to redirect_to(namespace_project_job_path(id: Ci::Build.last.id)) end + + shared_examples_for 'retried job has the same attributes' do + it 'creates a new build has the same attributes from the previous build' do + expect { post_retry }.to change { Ci::Build.count }.by(1) + + retried_build = Ci::Build.last + + Ci::RetryBuildService.clone_accessors.each do |accessor| + expect(job.read_attribute(accessor)) + .to eq(retried_build.read_attribute(accessor)), + "Mismatched attribute on \"#{accessor}\". " \ + "It was \"#{job.read_attribute(accessor)}\" but changed to \"#{retried_build.read_attribute(accessor)}\"" + end + end + end + + context 'with branch pipeline' do + let!(:job) { create(:ci_build, :retryable, tag: true, when: 'on_success', pipeline: pipeline) } + + it_behaves_like 'retried job has the same attributes' + end + + context 'with tag pipeline' do + let!(:job) { create(:ci_build, :retryable, tag: false, when: 'on_success', pipeline: pipeline) } + + it_behaves_like 'retried job has the same attributes' + end end context 'when job is not retryable' do let(:job) { create(:ci_build, pipeline: pipeline) } it 'renders unprocessable_entity' do + post_retry + expect(response).to have_gitlab_http_status(:unprocessable_entity) end end diff --git a/spec/controllers/projects/learn_gitlab_controller_spec.rb b/spec/controllers/projects/learn_gitlab_controller_spec.rb index f633f7aa246..620982f73be 100644 --- a/spec/controllers/projects/learn_gitlab_controller_spec.rb +++ b/spec/controllers/projects/learn_gitlab_controller_spec.rb @@ -7,13 +7,13 @@ RSpec.describe Projects::LearnGitlabController do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, namespace: user.namespace) } - let(:learn_gitlab_experiment_enabled) { true } + let(:learn_gitlab_enabled) { true } let(:params) { { namespace_id: project.namespace.to_param, project_id: project } } subject { get :index, params: params } before do - allow(controller.helpers).to receive(:learn_gitlab_experiment_enabled?).and_return(learn_gitlab_experiment_enabled) + allow(controller.helpers).to receive(:learn_gitlab_enabled?).and_return(learn_gitlab_enabled) end context 'unauthenticated user' do @@ -27,15 +27,8 @@ RSpec.describe Projects::LearnGitlabController do it { is_expected.to render_template(:index) } - it 'pushes experiment to frontend' do - expect(controller).to receive(:push_frontend_experiment).with(:learn_gitlab_a, subject: user) - expect(controller).to receive(:push_frontend_experiment).with(:learn_gitlab_b, subject: user) - - subject - end - context 'learn_gitlab experiment not enabled' do - let(:learn_gitlab_experiment_enabled) { false } + let(:learn_gitlab_enabled) { false } it { is_expected.to have_gitlab_http_status(:not_found) } end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 7b5a58fe2e5..0da8a30611c 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -349,6 +349,15 @@ RSpec.describe Projects::MergeRequestsController do end end end + + it_behaves_like 'issuable list with anonymous search disabled' do + let(:params) { { namespace_id: project.namespace, project_id: project } } + + before do + sign_out(user) + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + end + end end describe 'PUT update' do diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 65a563fac7c..1354e894872 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -311,23 +311,42 @@ RSpec.describe Projects::PipelinesController do let_it_be(:pipeline) { create(:ci_pipeline, project: project) } - def create_build_with_artifacts(stage, stage_idx, name) - create(:ci_build, :artifacts, :tags, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name) + 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) + end + + def create_bridge(stage, stage_idx, name, status) + create(:ci_bridge, status, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name) end before do - create_build_with_artifacts('build', 0, 'job1') - create_build_with_artifacts('build', 0, 'job2') + 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) end - it 'avoids N+1 database queries', :request_store do - control_count = ActiveRecord::QueryRecorder.new { get_pipeline_html }.count + it 'avoids N+1 database queries', :request_store, :use_sql_query_cache do + # warm up + get_pipeline_html expect(response).to have_gitlab_http_status(:ok) - create_build_with_artifacts('build', 0, 'job3') + control = ActiveRecord::QueryRecorder.new(skip_cached: false) do + get_pipeline_html + expect(response).to have_gitlab_http_status(:ok) + end - expect { get_pipeline_html }.not_to exceed_query_limit(control_count) - expect(response).to have_gitlab_http_status(:ok) + 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) + + expect do + get_pipeline_html + expect(response).to have_gitlab_http_status(:ok) + end.not_to exceed_all_query_limit(control) end end @@ -1273,6 +1292,38 @@ RSpec.describe Projects::PipelinesController do end end + context 'when project uses external project ci config' do + let(:other_project) { create(:project) } + let(:sha) { 'master' } + let(:service) { ::Ci::ListConfigVariablesService.new(other_project, user) } + + let(:ci_config) do + { + variables: { + KEY1: { value: 'val 1', description: 'description 1' } + }, + test: { + stage: 'test', + script: 'echo' + } + } + end + + before do + project.update!(ci_config_path: ".gitlab-ci.yml@#{other_project.full_path}") + synchronous_reactive_cache(service) + end + + it 'returns other project config variables' do + expect(::Ci::ListConfigVariablesService).to receive(:new).with(other_project, anything).and_return(service) + + get_config_variables + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['KEY1']).to eq({ 'value' => 'val 1', 'description' => 'description 1' }) + end + end + private def stub_gitlab_ci_yml_for_sha(sha, result) diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb index 419b5c7e101..482ba552f8f 100644 --- a/spec/controllers/projects/services_controller_spec.rb +++ b/spec/controllers/projects/services_controller_spec.rb @@ -18,6 +18,18 @@ RSpec.describe Projects::ServicesController do project.add_maintainer(user) end + it_behaves_like IntegrationsActions do + let(:integration_attributes) { { project: project } } + + let(:routing_params) do + { + namespace_id: project.namespace, + project_id: project, + id: integration.to_param + } + end + end + describe '#test' do context 'when the integration is not testable' do it 'renders 404' do diff --git a/spec/controllers/registrations/experience_levels_controller_spec.rb b/spec/controllers/registrations/experience_levels_controller_spec.rb deleted file mode 100644 index ad145264bb8..00000000000 --- a/spec/controllers/registrations/experience_levels_controller_spec.rb +++ /dev/null @@ -1,159 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Registrations::ExperienceLevelsController do - include AfterNextHelpers - - let_it_be(:namespace) { create(:group, path: 'group-path' ) } - let_it_be(:user) { create(:user) } - - let(:params) { { namespace_path: namespace.to_param } } - - describe 'GET #show' do - subject { get :show, params: params } - - context 'with an unauthenticated user' do - it { is_expected.to have_gitlab_http_status(:redirect) } - it { is_expected.to redirect_to(new_user_session_path) } - end - - context 'with an authenticated user' do - before do - sign_in(user) - end - - it { is_expected.to have_gitlab_http_status(:ok) } - it { is_expected.to render_template('layouts/minimal') } - it { is_expected.to render_template(:show) } - end - end - - describe 'PUT/PATCH #update' do - subject { patch :update, params: params } - - context 'with an unauthenticated user' do - it { is_expected.to have_gitlab_http_status(:redirect) } - it { is_expected.to redirect_to(new_user_session_path) } - end - - context 'with an authenticated user' do - let_it_be(:project) { build(:project, namespace: namespace, creator: user, path: 'project-path') } - let_it_be(:issues_board) { build(:board, id: 123, project: project) } - - before do - sign_in(user) - end - - context 'when user is successfully updated' do - context 'when no experience_level is sent' do - before do - user.user_preference.update_attribute(:experience_level, :novice) - end - - it 'will unset the user’s experience level' do - expect { subject }.to change { user.reload.experience_level }.to(nil) - end - end - - context 'when an expected experience level is sent' do - let(:params) { super().merge(experience_level: :novice) } - - it 'sets the user’s experience level' do - expect { subject }.to change { user.reload.experience_level }.from(nil).to('novice') - end - end - - context 'when an unexpected experience level is sent' do - let(:params) { super().merge(experience_level: :nonexistent) } - - it 'raises an exception' do - expect { subject }.to raise_error(ArgumentError, "'nonexistent' is not a valid experience_level") - end - end - - context 'when "Learn GitLab" project exists' do - let(:learn_gitlab_available?) { true } - - before do - allow_next_instance_of(LearnGitlab::Project) do |learn_gitlab| - allow(learn_gitlab).to receive(:available?).and_return(learn_gitlab_available?) - allow(learn_gitlab).to receive(:project).and_return(project) - allow(learn_gitlab).to receive(:board).and_return(issues_board) - allow(learn_gitlab).to receive(:label).and_return(double(id: 1)) - end - end - - context 'redirection' do - context 'when namespace_path param is missing' do - let(:params) { super().merge(namespace_path: nil) } - - where( - learn_gitlab_available?: [true, false] - ) - - with_them do - it { is_expected.to redirect_to('/') } - end - end - - context 'when we have a namespace_path param' do - using RSpec::Parameterized::TableSyntax - - where(:learn_gitlab_available?, :path) do - true | '/group-path/project-path/-/boards/123' - false | '/group-path' - end - - with_them do - it { is_expected.to redirect_to(path) } - end - end - end - - context 'when novice' do - let(:params) { super().merge(experience_level: :novice) } - - it 'adds a BoardLabel' do - expect_next(Boards::UpdateService).to receive(:execute) - - subject - end - end - - context 'when experienced' do - let(:params) { super().merge(experience_level: :experienced) } - - it 'does not add a BoardLabel' do - expect(Boards::UpdateService).not_to receive(:new) - - subject - end - end - end - - context 'when no "Learn GitLab" project exists' do - let(:params) { super().merge(experience_level: :novice) } - - before do - allow_next(LearnGitlab::Project).to receive(:available?).and_return(false) - end - - it 'does not add a BoardLabel' do - expect(Boards::UpdateService).not_to receive(:new) - - subject - end - end - end - - context 'when user update fails' do - before do - allow_any_instance_of(User).to receive(:save).and_return(false) - end - - it { is_expected.to render_template(:show) } - end - end - end -end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 301c60e89c8..5edd60ebc79 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -227,6 +227,40 @@ RSpec.describe RegistrationsController do end end end + + context 'with the invite_email_preview_text experiment', :experiment do + let(:extra_session_params) { { invite_email_experiment_name: 'invite_email_from' } } + + context 'when member and invite_email_experiment_name exists from the session key value' do + it 'tracks the invite acceptance' do + expect(experiment(:invite_email_from)).to track(:accepted) + .with_context(actor: member) + .on_next_instance + + subject + end + end + + context 'when member does not exist from the session key value' do + let(:originating_member_id) { -1 } + + it 'does not track invite acceptance' do + expect(experiment(:invite_email_from)).not_to track(:accepted) + + subject + end + end + + context 'when invite_email_experiment_name does not exist from the session key value' do + let(:extra_session_params) { {} } + + it 'does not track invite acceptance' do + expect(experiment(:invite_email_from)).not_to track(:accepted) + + subject + end + end + end end context 'when invite email matches email used on registration' do @@ -249,6 +283,26 @@ RSpec.describe RegistrationsController do end end + context 'when the registration fails' do + let_it_be(:member) { create(:project_member, :invited) } + let_it_be(:missing_user_params) do + { username: '', email: member.invite_email, password: 'Any_password' } + end + + let_it_be(:user_params) { { user: missing_user_params } } + + let(:session_params) { { invite_email: member.invite_email } } + + subject { post(:create, params: user_params, session: session_params) } + + it 'does not delete the invitation or register the new user' do + subject + + expect(member.invite_token).not_to be_nil + expect(controller.current_user).to be_nil + end + end + context 'when soft email confirmation is enabled' do before do stub_feature_flags(soft_email_confirmation: true) diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index e0870e17d99..4e87a9fc1ba 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -182,6 +182,37 @@ RSpec.describe SearchController do end end end + + context 'tab feature flags' do + subject { get :show, params: { scope: scope, search: 'term' }, format: :html } + + where(:feature_flag, :scope) do + :global_search_code_tab | 'blobs' + :global_search_issues_tab | 'issues' + :global_search_merge_requests_tab | 'merge_requests' + :global_search_wiki_tab | 'wiki_blobs' + :global_search_commits_tab | 'commits' + end + + with_them do + it 'returns 200 if flag is enabled' do + stub_feature_flags(feature_flag => true) + + subject + + expect(response).to have_gitlab_http_status(:ok) + end + + it 'redirects with alert if flag is disabled' do + stub_feature_flags(feature_flag => false) + + subject + + expect(response).to redirect_to search_path + expect(controller).to set_flash[:alert].to(/Global Search is disabled for this scope/) + end + end + end end it 'finds issue comments' do diff --git a/spec/controllers/user_callouts_controller_spec.rb b/spec/controllers/user_callouts_controller_spec.rb index 279f825e40f..3bb8d78a6b0 100644 --- a/spec/controllers/user_callouts_controller_spec.rb +++ b/spec/controllers/user_callouts_controller_spec.rb @@ -3,14 +3,16 @@ require 'spec_helper' RSpec.describe UserCalloutsController do - let(:user) { create(:user) } + let_it_be(:user) { create(:user) } before do sign_in(user) end describe "POST #create" do - subject { post :create, params: { feature_name: feature_name }, format: :json } + let(:params) { { feature_name: feature_name } } + + subject { post :create, params: params, format: :json } context 'with valid feature name' do let(:feature_name) { UserCallout.feature_names.each_key.first } @@ -30,9 +32,8 @@ RSpec.describe UserCalloutsController do context 'when callout entry already exists' do let!(:callout) { create(:user_callout, feature_name: UserCallout.feature_names.each_key.first, user: user) } - it 'returns success' do - subject - + it 'returns success', :aggregate_failures do + expect { subject }.not_to change { UserCallout.count } expect(response).to have_gitlab_http_status(:ok) end end |