Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/controllers')
-rw-r--r--spec/controllers/admin/application_settings_controller_spec.rb7
-rw-r--r--spec/controllers/admin/cohorts_controller_spec.rb2
-rw-r--r--spec/controllers/admin/dev_ops_report_controller_spec.rb2
-rw-r--r--spec/controllers/admin/groups_controller_spec.rb60
-rw-r--r--spec/controllers/admin/usage_trends_controller_spec.rb2
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb2
-rw-r--r--spec/controllers/boards/issues_controller_spec.rb596
-rw-r--r--spec/controllers/boards/lists_controller_spec.rb333
-rw-r--r--spec/controllers/concerns/boards_responses_spec.rb23
-rw-r--r--spec/controllers/concerns/product_analytics_tracking_spec.rb44
-rw-r--r--spec/controllers/concerns/send_file_upload_spec.rb7
-rw-r--r--spec/controllers/dashboard_controller_spec.rb31
-rw-r--r--spec/controllers/groups/boards_controller_spec.rb84
-rw-r--r--spec/controllers/groups/runners_controller_spec.rb71
-rw-r--r--spec/controllers/groups_controller_spec.rb22
-rw-r--r--spec/controllers/health_check_controller_spec.rb13
-rw-r--r--spec/controllers/import/bulk_imports_controller_spec.rb23
-rw-r--r--spec/controllers/import/github_controller_spec.rb103
-rw-r--r--spec/controllers/profiles/personal_access_tokens_controller_spec.rb20
-rw-r--r--spec/controllers/profiles/preferences_controller_spec.rb3
-rw-r--r--spec/controllers/profiles/two_factor_auths_controller_spec.rb28
-rw-r--r--spec/controllers/projects/artifacts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/autocomplete_sources_controller_spec.rb136
-rw-r--r--spec/controllers/projects/boards_controller_spec.rb150
-rw-r--r--spec/controllers/projects/compare_controller_spec.rb94
-rw-r--r--spec/controllers/projects/cycle_analytics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/deploy_keys_controller_spec.rb31
-rw-r--r--spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb2
-rw-r--r--spec/controllers/projects/graphs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb56
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb23
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb20
-rw-r--r--spec/controllers/projects/pages_domains_controller_spec.rb56
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb2
-rw-r--r--spec/controllers/projects/prometheus/metrics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/protected_branches_controller_spec.rb46
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb25
-rw-r--r--spec/controllers/projects_controller_spec.rb30
-rw-r--r--spec/controllers/registrations/welcome_controller_spec.rb5
-rw-r--r--spec/controllers/search_controller_spec.rb2
-rw-r--r--spec/controllers/sessions_controller_spec.rb18
-rw-r--r--spec/controllers/uploads_controller_spec.rb2
42 files changed, 826 insertions, 1356 deletions
diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb
index ab0cad989cb..0ad0a111156 100644
--- a/spec/controllers/admin/application_settings_controller_spec.rb
+++ b/spec/controllers/admin/application_settings_controller_spec.rb
@@ -211,6 +211,13 @@ RSpec.describe Admin::ApplicationSettingsController, :do_not_mock_admin_mode_set
expect(ApplicationSetting.current.valid_runner_registrars).to eq(['project'])
end
+ it 'updates can_create_group setting' do
+ put :update, params: { application_setting: { can_create_group: false } }
+
+ expect(response).to redirect_to(general_admin_application_settings_path)
+ expect(ApplicationSetting.current.can_create_group).to eq(false)
+ end
+
context "personal access token prefix settings" do
let(:application_settings) { ApplicationSetting.current }
diff --git a/spec/controllers/admin/cohorts_controller_spec.rb b/spec/controllers/admin/cohorts_controller_spec.rb
index 766073977c6..50626a5da91 100644
--- a/spec/controllers/admin/cohorts_controller_spec.rb
+++ b/spec/controllers/admin/cohorts_controller_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Admin::CohortsController do
let(:target_id) { 'i_analytics_cohorts' }
end
- it_behaves_like 'Snowplow event tracking' do
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
subject { get :index }
let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
diff --git a/spec/controllers/admin/dev_ops_report_controller_spec.rb b/spec/controllers/admin/dev_ops_report_controller_spec.rb
index 5d7a7e089aa..52a46b5e99a 100644
--- a/spec/controllers/admin/dev_ops_report_controller_spec.rb
+++ b/spec/controllers/admin/dev_ops_report_controller_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe Admin::DevOpsReportController do
let(:request_params) { { tab: 'devops-score' } }
end
- it_behaves_like 'Snowplow event tracking' do
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
subject { get :show, format: :html }
let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb
index fb843ac6a7a..37cb0a1f289 100644
--- a/spec/controllers/admin/groups_controller_spec.rb
+++ b/spec/controllers/admin/groups_controller_spec.rb
@@ -44,64 +44,4 @@ RSpec.describe Admin::GroupsController do
end.to change { Namespace::AdminNote.count }.by(1)
end
end
-
- describe 'PUT #members_update' do
- let_it_be(:group_user) { create(:user) }
-
- it 'adds user to members', :aggregate_failures, :snowplow do
- put :members_update, params: {
- id: group,
- user_id: group_user.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(admin_group_path(group))
- expect(group.users).to include group_user
- expect_snowplow_event(
- category: 'Members::CreateService',
- action: 'create_member',
- label: 'admin-group-page',
- property: 'existing_user',
- user: admin
- )
- end
-
- it 'can add unlimited members', :aggregate_failures do
- put :members_update, params: {
- id: group,
- user_id: 1.upto(1000).to_a.join(','),
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(admin_group_path(group))
- end
-
- it 'adds no user to members', :aggregate_failures do
- put :members_update, params: {
- id: group,
- user_id: '',
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'No users specified.'
- expect(response).to redirect_to(admin_group_path(group))
- expect(group.users).not_to include group_user
- end
-
- it 'updates the project_creation_level successfully' do
- expect do
- post :update, params: { id: group.to_param, group: { project_creation_level: ::Gitlab::Access::NO_ONE_PROJECT_ACCESS } }
- end.to change { group.reload.project_creation_level }.to(::Gitlab::Access::NO_ONE_PROJECT_ACCESS)
- end
-
- it 'updates the subgroup_creation_level successfully' do
- expect do
- post :update,
- params: { id: group.to_param,
- group: { subgroup_creation_level: ::Gitlab::Access::OWNER_SUBGROUP_ACCESS } }
- end.to change { group.reload.subgroup_creation_level }.to(::Gitlab::Access::OWNER_SUBGROUP_ACCESS)
- end
- end
end
diff --git a/spec/controllers/admin/usage_trends_controller_spec.rb b/spec/controllers/admin/usage_trends_controller_spec.rb
index 356f603bf57..87cf8988b4e 100644
--- a/spec/controllers/admin/usage_trends_controller_spec.rb
+++ b/spec/controllers/admin/usage_trends_controller_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Admin::UsageTrendsController do
let(:target_id) { 'i_analytics_instance_statistics' }
end
- it_behaves_like 'Snowplow event tracking' do
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
subject { get :index }
let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index 70e58124d21..e9b39d44e46 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -96,7 +96,7 @@ RSpec.describe AutocompleteController do
end
context 'user order' do
- it 'shows exact matches first' do
+ it 'shows exact matches first', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/375028' do
reported_user = create(:user, username: 'reported_user', name: 'Doug')
user = create(:user, username: 'user', name: 'User')
user1 = create(:user, username: 'user1', name: 'Ian')
diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb
deleted file mode 100644
index 3e1cdfccc61..00000000000
--- a/spec/controllers/boards/issues_controller_spec.rb
+++ /dev/null
@@ -1,596 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Boards::IssuesController do
- include ExternalAuthorizationServiceHelpers
-
- let(:project) { create(:project, :private) }
- let(:board) { create(:board, project: project) }
- let(:user) { create(:user) }
- let(:guest) { create(:user) }
-
- let(:planning) { create(:label, project: project, name: 'Planning') }
- let(:development) { create(:label, project: project, name: 'Development') }
-
- let!(:list1) { create(:list, board: board, label: planning, position: 0) }
- let!(:list2) { create(:list, board: board, label: development, position: 1) }
-
- before do
- project.add_maintainer(user)
- project.add_guest(guest)
- end
-
- describe 'GET index', :request_store do
- let(:johndoe) { create(:user, avatar: fixture_file_upload(File.join('spec/fixtures/dk.png'))) }
-
- context 'with invalid board id' do
- it 'returns a not found 404 response' do
- list_issues user: user, board: non_existing_record_id, list: list2
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'when list id is present' do
- context 'with valid list id' do
- let(:group) { create(:group, :private, projects: [project]) }
- let(:group_board) { create(:board, group: group) }
- let!(:list3) { create(:list, board: group_board, label: development, position: 2) }
- let(:sub_group_1) { create(:group, :private, parent: group) }
-
- before do
- group.add_maintainer(user)
- end
-
- it 'returns issues that have the list label applied' do
- issue = create(:labeled_issue, project: project, labels: [planning])
- create(:labeled_issue, project: project, labels: [planning])
- create(:labeled_issue, project: project, labels: [development], due_date: Date.tomorrow)
- create(:labeled_issue, project: project, labels: [development], assignees: [johndoe])
- issue.subscribe(johndoe, project)
- expect(Issue).to receive(:move_nulls_to_end)
-
- list_issues user: user, board: board, list: list2
-
- expect(response).to match_response_schema('entities/issue_boards')
- expect(json_response['issues'].length).to eq 2
- expect(development.issues.map(&:relative_position)).not_to include(nil)
- end
-
- it 'returns issues by closed_at in descending order in closed list' do
- create(:closed_issue, project: project, title: 'New Issue 1', closed_at: 1.day.ago)
- create(:closed_issue, project: project, title: 'New Issue 2', closed_at: 1.week.ago)
-
- list_issues user: user, board: board, list: board.lists.last.id
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['issues'].length).to eq(2)
- expect(json_response['issues'][0]['title']).to eq('New Issue 1')
- expect(json_response['issues'][1]['title']).to eq('New Issue 2')
- end
-
- it 'avoids N+1 database queries' do
- create(:labeled_issue, project: project, labels: [development])
- control_count = ActiveRecord::QueryRecorder.new { list_issues(user: user, board: board, list: list2) }.count
-
- # 25 issues is bigger than the page size
- # the relative position will ignore the `#make_sure_position_set` queries
- create_list(:labeled_issue, 25, project: project, labels: [development], assignees: [johndoe], relative_position: 1)
-
- expect { list_issues(user: user, board: board, list: list2) }.not_to exceed_query_limit(control_count)
- end
-
- it 'avoids N+1 database queries when adding a project', :request_store do
- create(:labeled_issue, project: project, labels: [development])
- control_count = ActiveRecord::QueryRecorder.new { list_issues(user: user, board: group_board, list: list3) }.count
-
- 2.times do
- p = create(:project, group: group)
- create(:labeled_issue, project: p, labels: [development])
- end
-
- project_2 = create(:project, group: group)
- create(:labeled_issue, project: project_2, labels: [development], assignees: [johndoe])
-
- # because each issue without relative_position must be updated with
- # a different value, we have 8 extra queries per issue
- expect { list_issues(user: user, board: group_board, list: list3) }.not_to exceed_query_limit(control_count + (2 * 8 - 1))
- end
-
- it 'avoids N+1 database queries when adding a subgroup, project, and issue' do
- create(:project, group: sub_group_1)
- create(:labeled_issue, project: project, labels: [development])
- control_count = ActiveRecord::QueryRecorder.new { list_issues(user: user, board: group_board, list: list3) }.count
- project_2 = create(:project, group: group)
-
- 2.times do
- p = create(:project, group: sub_group_1)
- create(:labeled_issue, project: p, labels: [development])
- end
-
- create(:labeled_issue, project: project_2, labels: [development], assignees: [johndoe])
-
- expect { list_issues(user: user, board: group_board, list: list3) }.not_to exceed_query_limit(control_count + (2 * 8 - 1))
- end
-
- it 'does not query issues table more than once' do
- recorder = ActiveRecord::QueryRecorder.new { list_issues(user: user, board: board, list: list1) }
- query_count = recorder.occurrences.select { |query,| query.match?(/FROM "?issues"?/) }.each_value.first
-
- expect(query_count).to eq(1)
- end
-
- context 'when block_issue_repositioning feature flag is enabled' do
- before do
- stub_feature_flags(block_issue_repositioning: true)
- end
-
- it 'does not reposition issues with null position' do
- expect(Issue).not_to receive(:move_nulls_to_end)
-
- list_issues(user: user, board: group_board, list: list3)
- end
- end
- end
-
- context 'with invalid list id' do
- it 'returns a not found 404 response' do
- list_issues user: user, board: board, list: non_existing_record_id
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'when list id is missing' do
- it 'returns opened issues without board labels applied' do
- bug = create(:label, project: project, name: 'Bug')
- create(:issue, project: project)
- create(:labeled_issue, project: project, labels: [planning])
- create(:labeled_issue, project: project, labels: [development])
- create(:labeled_issue, project: project, labels: [bug])
-
- list_issues user: user, board: board
-
- expect(response).to match_response_schema('entities/issue_boards')
- expect(json_response['issues'].length).to eq 2
- end
- end
-
- context 'with unauthorized user' do
- let(:unauth_user) { create(:user) }
-
- it 'returns a forbidden 403 response' do
- list_issues user: unauth_user, board: board, list: list2
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
-
- context 'with external authorization' do
- before do
- sign_in(user)
- enable_external_authorization_service_check
- end
-
- it 'returns a 403 for group boards' do
- group = create(:group)
- group_board = create(:board, group: group)
-
- list_issues(user: user, board: group_board)
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
-
- it 'is successful for project boards' do
- project_board = create(:board, project: project)
-
- list_issues(user: user, board: project_board)
-
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
-
- describe 'PUT bulk_move' do
- let(:todo) { create(:group_label, group: group, name: 'Todo') }
- let(:development) { create(:group_label, group: group, name: 'Development') }
- let(:user) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
- let(:guest) { create(:group_member, :guest, user: create(:user), group: group ).user }
- let(:project) { create(:project, group: group) }
- let(:group) { create(:group) }
- let(:board) { create(:board, project: project) }
- let(:list1) { create(:list, board: board, label: todo, position: 0) }
- let(:list2) { create(:list, board: board, label: development, position: 1) }
- let(:issue1) { create(:labeled_issue, project: project, labels: [todo], author: user, relative_position: 10) }
- let(:issue2) { create(:labeled_issue, project: project, labels: [todo], author: user, relative_position: 20) }
- let(:issue3) { create(:labeled_issue, project: project, labels: [todo], author: user, relative_position: 30) }
- let(:issue4) { create(:labeled_issue, project: project, labels: [development], author: user, relative_position: 100) }
-
- let(:move_params) do
- {
- board_id: board.id,
- ids: [issue1.id, issue2.id, issue3.id],
- from_list_id: list1.id,
- to_list_id: list2.id,
- move_before_id: issue4.id,
- move_after_id: nil
- }
- end
-
- before do
- project.add_maintainer(user)
- project.add_guest(guest)
- end
-
- shared_examples 'move issues endpoint provider' do
- before do
- sign_in(signed_in_user)
- end
-
- it 'responds as expected' do
- put :bulk_move, params: move_issues_params
- expect(response).to have_gitlab_http_status(expected_status)
-
- if expected_status == 200
- expect(json_response).to include(
- 'count' => move_issues_params[:ids].size,
- 'success' => true
- )
-
- expect(json_response['issues'].pluck('id')).to match_array(move_issues_params[:ids])
- end
- end
-
- it 'moves issues as expected' do
- put :bulk_move, params: move_issues_params
- expect(response).to have_gitlab_http_status(expected_status)
-
- list_issues user: requesting_user, board: board, list: list2
- expect(response).to have_gitlab_http_status(:ok)
-
- expect(response).to match_response_schema('entities/issue_boards')
-
- responded_issues = json_response['issues']
- expect(responded_issues.length).to eq expected_issue_count
-
- ids_in_order = responded_issues.pluck('id')
- expect(ids_in_order).to eq(expected_issue_ids_in_order)
- end
- end
-
- context 'when items are moved to another list' do
- it_behaves_like 'move issues endpoint provider' do
- let(:signed_in_user) { user }
- let(:move_issues_params) { move_params }
- let(:requesting_user) { user }
- let(:expected_status) { 200 }
- let(:expected_issue_count) { 4 }
- let(:expected_issue_ids_in_order) { [issue4.id, issue1.id, issue2.id, issue3.id] }
- end
- end
-
- context 'when moving just one issue' do
- it_behaves_like 'move issues endpoint provider' do
- let(:signed_in_user) { user }
- let(:move_issues_params) do
- move_params.dup.tap do |hash|
- hash[:ids] = [issue2.id]
- end
- end
-
- let(:requesting_user) { user }
- let(:expected_status) { 200 }
- let(:expected_issue_count) { 2 }
- let(:expected_issue_ids_in_order) { [issue4.id, issue2.id] }
- end
- end
-
- context 'when user is not allowed to move issue' do
- it_behaves_like 'move issues endpoint provider' do
- let(:signed_in_user) { guest }
- let(:move_issues_params) do
- move_params.dup.tap do |hash|
- hash[:ids] = [issue2.id]
- end
- end
-
- let(:requesting_user) { user }
- let(:expected_status) { 403 }
- let(:expected_issue_count) { 1 }
- let(:expected_issue_ids_in_order) { [issue4.id] }
- end
- end
-
- context 'when issues should be moved visually above existing issue in list' do
- it_behaves_like 'move issues endpoint provider' do
- let(:signed_in_user) { user }
- let(:move_issues_params) do
- move_params.dup.tap do |hash|
- hash[:move_after_id] = issue4.id
- hash[:move_before_id] = nil
- end
- end
-
- let(:requesting_user) { user }
- let(:expected_status) { 200 }
- let(:expected_issue_count) { 4 }
- let(:expected_issue_ids_in_order) { [issue1.id, issue2.id, issue3.id, issue4.id] }
- end
- end
-
- context 'when destination list is empty' do
- before do
- # Remove issue from list
- issue4.labels -= [development]
- issue4.save!
- end
-
- it_behaves_like 'move issues endpoint provider' do
- let(:signed_in_user) { user }
- let(:move_issues_params) do
- move_params.dup.tap do |hash|
- hash[:move_before_id] = nil
- end
- end
-
- let(:requesting_user) { user }
- let(:expected_status) { 200 }
- let(:expected_issue_count) { 3 }
- let(:expected_issue_ids_in_order) { [issue1.id, issue2.id, issue3.id] }
- end
- end
-
- context 'when no position arguments are given' do
- it_behaves_like 'move issues endpoint provider' do
- let(:signed_in_user) { user }
- let(:move_issues_params) do
- move_params.dup.tap do |hash|
- hash[:move_before_id] = nil
- end
- end
-
- let(:requesting_user) { user }
- let(:expected_status) { 200 }
- let(:expected_issue_count) { 4 }
- let(:expected_issue_ids_in_order) { [issue1.id, issue2.id, issue3.id, issue4.id] }
- end
- end
-
- context 'when move_before_id and move_after_id are given' do
- let(:issue5) { create(:labeled_issue, project: project, labels: [development], author: user, relative_position: 90) }
-
- it_behaves_like 'move issues endpoint provider' do
- let(:signed_in_user) { user }
- let(:move_issues_params) do
- move_params.dup.tap do |hash|
- hash[:move_before_id] = issue5.id
- hash[:move_after_id] = issue4.id
- end
- end
-
- let(:requesting_user) { user }
- let(:expected_status) { 200 }
- let(:expected_issue_count) { 5 }
- let(:expected_issue_ids_in_order) { [issue5.id, issue1.id, issue2.id, issue3.id, issue4.id] }
- end
- end
-
- context 'when request contains too many issues' do
- it_behaves_like 'move issues endpoint provider' do
- let(:signed_in_user) { user }
- let(:move_issues_params) do
- move_params.dup.tap do |hash|
- hash[:ids] = (0..51).to_a
- end
- end
-
- let(:requesting_user) { user }
- let(:expected_status) { 422 }
- let(:expected_issue_count) { 1 }
- let(:expected_issue_ids_in_order) { [issue4.id] }
- end
- end
-
- context 'when request is malformed' do
- it_behaves_like 'move issues endpoint provider' do
- let(:signed_in_user) { user }
- let(:move_issues_params) do
- move_params.dup.tap do |hash|
- hash[:ids] = 'foobar'
- end
- end
-
- let(:requesting_user) { user }
- let(:expected_status) { 400 }
- let(:expected_issue_count) { 1 }
- let(:expected_issue_ids_in_order) { [issue4.id] }
- end
- end
- end
-
- def list_issues(user:, board:, list: nil)
- sign_in(user)
-
- params = {
- board_id: board.to_param,
- list_id: list.try(:to_param)
- }
-
- unless board.try(:parent).is_a?(Group)
- params[:namespace_id] = project.namespace.to_param
- params[:project_id] = project
- end
-
- get :index, params: params.compact
- end
- end
-
- describe 'POST create' do
- context 'when trying to create issue on an unauthorized project' do
- let(:unauthorized_project) { create(:project, :private) }
- let(:issue_params) { { project_id: unauthorized_project.id } }
-
- it 'creates the issue on the board\'s project' do
- expect do
- create_issue user: user, board: board, list: list1, title: 'New issue', additional_issue_params: issue_params
- end.to change(Issue, :count).by(1)
-
- created_issue = Issue.last
-
- expect(created_issue.project).to eq(project)
- expect(unauthorized_project.reload.issues.count).to eq(0)
- end
- end
-
- context 'with valid params' 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
- 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
- context 'when title is nil' do
- it 'returns an unprocessable entity 422 response' do
- create_issue user: user, board: board, list: list1, title: nil
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- end
- end
-
- context 'when list does not belongs to project board' do
- it 'returns a not found 404 response' do
- list = create(:list)
-
- create_issue user: user, board: board, list: list, title: 'New issue'
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'with invalid board id' do
- it 'returns a not found 404 response' do
- create_issue user: user, board: non_existing_record_id, list: list1, title: 'New issue'
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'with invalid list id' do
- it 'returns a not found 404 response' do
- create_issue user: user, board: board, list: non_existing_record_id, title: 'New issue'
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'with guest user' do
- context 'in open list' do
- it 'returns a successful 200 response' do
- open_list = board.lists.create!(list_type: :backlog)
- create_issue user: guest, board: board, list: open_list, title: 'New issue'
-
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
-
- context 'in label list' do
- it 'returns a forbidden 403 response' do
- create_issue user: guest, board: board, list: list1, title: 'New issue'
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
- end
-
- def create_issue(user:, board:, list:, title:, additional_issue_params: {})
- sign_in(user)
-
- post :create, params: {
- board_id: board.to_param,
- list_id: list.to_param,
- issue: { title: title, project_id: project.id }.merge(additional_issue_params)
- },
- format: :json
- end
- end
-
- describe 'PATCH update' do
- let!(:issue) { create(:labeled_issue, project: project, labels: [planning]) }
-
- context 'with valid params' do
- it 'returns a successful 200 response' do
- move user: user, board: board, issue: issue, from_list_id: list1.id, to_list_id: list2.id
-
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- it 'moves issue to the desired list' do
- move user: user, board: board, issue: issue, from_list_id: list1.id, to_list_id: list2.id
-
- expect(issue.reload.labels).to contain_exactly(development)
- end
- end
-
- context 'with invalid params' do
- it 'returns a unprocessable entity 422 response for invalid lists' do
- move user: user, board: board, issue: issue, from_list_id: nil, to_list_id: nil
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- end
-
- it 'returns a not found 404 response for invalid board id' do
- move user: user, board: non_existing_record_id, issue: issue, from_list_id: list1.id, to_list_id: list2.id
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
-
- it 'returns a not found 404 response for invalid issue id' do
- move user: user, board: board, issue: double(id: non_existing_record_id), from_list_id: list1.id, to_list_id: list2.id
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'with unauthorized user' do
- let(:guest) { create(:user) }
-
- before do
- project.add_guest(guest)
- end
-
- it 'returns a forbidden 403 response' do
- move user: guest, board: board, issue: issue, from_list_id: list1.id, to_list_id: list2.id
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
-
- def move(user:, board:, issue:, from_list_id:, to_list_id:)
- sign_in(user)
-
- patch :update, params: {
- namespace_id: project.namespace.to_param,
- project_id: project.id,
- board_id: board.to_param,
- id: issue.id,
- from_list_id: from_list_id,
- to_list_id: to_list_id
- },
- format: :json
- end
- end
-end
diff --git a/spec/controllers/boards/lists_controller_spec.rb b/spec/controllers/boards/lists_controller_spec.rb
deleted file mode 100644
index 95334974e66..00000000000
--- a/spec/controllers/boards/lists_controller_spec.rb
+++ /dev/null
@@ -1,333 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Boards::ListsController do
- let(:project) { create(:project) }
- let(:board) { create(:board, project: project) }
- let(:user) { create(:user) }
- let(:guest) { create(:user) }
-
- before do
- project.add_maintainer(user)
- project.add_guest(guest)
- end
-
- describe 'GET index' do
- before do
- create(:list, board: board)
- end
-
- it 'returns a successful 200 response' do
- read_board_list user: user, board: board
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.media_type).to eq 'application/json'
- end
-
- it 'returns a list of board lists' do
- read_board_list user: user, board: board
-
- expect(response).to match_response_schema('lists')
- expect(json_response.length).to eq 3
- end
-
- context 'when another user has list preferences' do
- before do
- board.lists.first.update_preferences_for(guest, collapsed: true)
- end
-
- it 'returns the complete list of board lists' do
- read_board_list user: user, board: board
-
- expect(json_response.length).to eq 3
- end
- end
-
- context 'with unauthorized user' do
- let(:unauth_user) { create(:user) }
-
- it 'returns a forbidden 403 response' do
- read_board_list user: unauth_user, board: board
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
-
- def read_board_list(user:, board:)
- sign_in(user)
-
- get :index, params: {
- namespace_id: project.namespace.to_param,
- project_id: project,
- board_id: board.to_param
- },
- format: :json
- end
- end
-
- describe 'POST create' do
- context 'with valid params' do
- let(:label) { create(:label, project: project, name: 'Development') }
-
- it 'returns a successful 200 response' do
- create_board_list user: user, board: board, label_id: label.id
-
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- it 'returns the created list' do
- create_board_list user: user, board: board, label_id: label.id
-
- expect(response).to match_response_schema('list')
- end
- end
-
- context 'with invalid params' do
- context 'when label is nil' do
- it 'returns an unprocessable entity 422 response' do
- create_board_list user: user, board: board, label_id: nil
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- expect(json_response['errors']).to eq(['Label not found'])
- end
- end
-
- context 'when label that does not belongs to project' do
- it 'returns an unprocessable entity 422 response' do
- label = create(:label, name: 'Development')
-
- create_board_list user: user, board: board, label_id: label.id
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- expect(json_response['errors']).to eq(['Label not found'])
- end
- end
- end
-
- context 'with unauthorized user' do
- it 'returns a forbidden 403 response' do
- label = create(:label, project: project, name: 'Development')
-
- create_board_list user: guest, board: board, label_id: label.id
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
-
- def create_board_list(user:, board:, label_id:)
- sign_in(user)
-
- post :create, params: {
- namespace_id: project.namespace.to_param,
- project_id: project,
- board_id: board.to_param,
- list: { label_id: label_id }
- },
- format: :json
- end
- end
-
- describe 'PATCH update' do
- let!(:planning) { create(:list, board: board, position: 0) }
- let!(:development) { create(:list, board: board, position: 1) }
-
- context 'with valid position' do
- it 'returns a successful 200 response' do
- move user: user, board: board, list: planning, position: 1
-
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- it 'moves the list to the desired position' do
- move user: user, board: board, list: planning, position: 1
-
- expect(planning.reload.position).to eq 1
- end
- end
-
- context 'with invalid position' do
- it 'returns an unprocessable entity 422 response' do
- move user: user, board: board, list: planning, position: 6
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- end
- end
-
- context 'with invalid list id' do
- it 'returns a not found 404 response' do
- move user: user, board: board, list: non_existing_record_id, position: 1
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'with unauthorized user' do
- it 'returns a 422 unprocessable entity response' do
- move user: guest, board: board, list: planning, position: 6
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- end
- end
-
- context 'with collapsed preference' do
- it 'saves collapsed preference for user' do
- save_setting user: user, board: board, list: planning, setting: { collapsed: true }
-
- expect(planning.preferences_for(user).collapsed).to eq(true)
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- it 'saves not collapsed preference for user' do
- save_setting user: user, board: board, list: planning, setting: { collapsed: false }
-
- expect(planning.preferences_for(user).collapsed).to eq(false)
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
-
- context 'with a list_type other than :label' do
- let!(:closed) { create(:closed_list, board: board, position: 2) }
-
- it 'saves collapsed preference for user' do
- save_setting user: user, board: board, list: closed, setting: { collapsed: true }
-
- expect(closed.preferences_for(user).collapsed).to eq(true)
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- it 'saves not collapsed preference for user' do
- save_setting user: user, board: board, list: closed, setting: { collapsed: false }
-
- expect(closed.preferences_for(user).collapsed).to eq(false)
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
-
- def move(user:, board:, list:, position:)
- sign_in(user)
-
- params = { namespace_id: project.namespace.to_param,
- project_id: project.id,
- board_id: board.to_param,
- id: list.to_param,
- list: { position: position },
- format: :json }
-
- patch :update, params: params, as: :json
- end
-
- def save_setting(user:, board:, list:, setting: {})
- sign_in(user)
-
- params = { namespace_id: project.namespace.to_param,
- project_id: project.id,
- board_id: board.to_param,
- id: list.to_param,
- list: setting,
- format: :json }
-
- patch :update, params: params, as: :json
- end
- end
-
- describe 'DELETE destroy' do
- let!(:planning) { create(:list, board: board, position: 0) }
-
- context 'with valid list id' do
- it 'returns a successful 200 response' do
- remove_board_list user: user, board: board, list: planning
-
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- it 'removes list from board' do
- expect { remove_board_list user: user, board: board, list: planning }.to change(board.lists, :size).by(-1)
- end
- end
-
- context 'with invalid list id' do
- it 'returns a not found 404 response' do
- remove_board_list user: user, board: board, list: non_existing_record_id
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'with unauthorized user' do
- it 'returns a forbidden 403 response' do
- remove_board_list user: guest, board: board, list: planning
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
-
- context 'with an error service response' do
- it 'returns an unprocessable entity response' do
- allow(Boards::Lists::DestroyService).to receive(:new)
- .and_return(double(execute: ServiceResponse.error(message: 'error')))
-
- remove_board_list user: user, board: board, list: planning
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- end
- end
-
- def remove_board_list(user:, board:, list:)
- sign_in(user)
-
- delete :destroy, params: {
- namespace_id: project.namespace.to_param,
- project_id: project,
- board_id: board.to_param,
- id: list.to_param
- },
- format: :json
- end
- end
-
- describe 'POST generate' do
- context 'when board lists is empty' do
- it 'returns a successful 200 response' do
- generate_default_lists user: user, board: board
-
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- it 'returns the defaults lists' do
- generate_default_lists user: user, board: board
-
- expect(response).to match_response_schema('lists')
- end
- end
-
- context 'when board lists is not empty' do
- it 'returns an unprocessable entity 422 response' do
- create(:list, board: board)
-
- generate_default_lists user: user, board: board
-
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- end
- end
-
- context 'with unauthorized user' do
- it 'returns a forbidden 403 response' do
- generate_default_lists user: guest, board: board
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
-
- def generate_default_lists(user:, board:)
- sign_in(user)
-
- post :generate, params: {
- namespace_id: project.namespace.to_param,
- project_id: project,
- board_id: board.to_param
- },
- format: :json
- end
- end
-end
diff --git a/spec/controllers/concerns/boards_responses_spec.rb b/spec/controllers/concerns/boards_responses_spec.rb
deleted file mode 100644
index 553a547d42c..00000000000
--- a/spec/controllers/concerns/boards_responses_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe BoardsResponses do
- let(:controller_class) do
- Class.new do
- include BoardsResponses
- end
- end
-
- subject(:controller) { controller_class.new }
-
- describe '#serialize_as_json' do
- let!(:board) { create(:board) }
-
- it 'serializes properly' do
- expected = { "id" => board.id }
-
- expect(subject.serialize_as_json(board)).to include(expected)
- end
- end
-end
diff --git a/spec/controllers/concerns/product_analytics_tracking_spec.rb b/spec/controllers/concerns/product_analytics_tracking_spec.rb
index 2e734d81ea0..28b79a10624 100644
--- a/spec/controllers/concerns/product_analytics_tracking_spec.rb
+++ b/spec/controllers/concerns/product_analytics_tracking_spec.rb
@@ -51,15 +51,21 @@ RSpec.describe ProductAnalyticsTracking, :snowplow do
end
end
- def expect_tracking(user: self.user)
+ def expect_redis_hll_tracking
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to have_received(:track_event)
.with('g_analytics_valuestream', values: instance_of(String))
+ end
+
+ def expect_snowplow_tracking(user)
+ context = Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: 'g_analytics_valuestream')
+ .to_context.to_json
expect_snowplow_event(
category: anything,
action: 'g_analytics_valuestream',
namespace: group,
- user: user
+ user: user,
+ context: [context]
)
end
@@ -77,7 +83,8 @@ RSpec.describe ProductAnalyticsTracking, :snowplow do
it 'tracks the event' do
get :index
- expect_tracking
+ expect_redis_hll_tracking
+ expect_snowplow_tracking(user)
end
context 'when FF is disabled' do
@@ -97,7 +104,8 @@ RSpec.describe ProductAnalyticsTracking, :snowplow do
get :index
- expect_tracking
+ expect_redis_hll_tracking
+ expect_snowplow_tracking(user)
end
it 'does not track the event if DNT is enabled' do
@@ -137,7 +145,8 @@ RSpec.describe ProductAnalyticsTracking, :snowplow do
get :show, params: { id: 1 }
- expect_tracking(user: nil)
+ expect_redis_hll_tracking
+ expect_snowplow_tracking(nil)
end
end
@@ -151,21 +160,24 @@ RSpec.describe ProductAnalyticsTracking, :snowplow do
it 'tracks the event when there is custom id' do
get :show, params: { id: 1 }
- expect_tracking(user: nil)
+ expect_redis_hll_tracking
+ expect_snowplow_tracking(nil)
end
- it 'does not track the HLL event when there is no custom id' do
- allow(controller).to receive(:get_custom_id).and_return(nil)
+ context 'when there is no custom_id set' do
+ before do
+ allow(controller).to receive(:get_custom_id).and_return(nil)
- get :show, params: { id: 2 }
+ get :show, params: { id: 2 }
+ end
- expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
- expect_snowplow_event(
- category: anything,
- action: 'g_analytics_valuestream',
- namespace: group,
- user: nil
- )
+ it 'does not track the HLL event' do
+ expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
+ end
+
+ it 'tracks Snowplow event' do
+ expect_snowplow_tracking(nil)
+ end
end
end
end
diff --git a/spec/controllers/concerns/send_file_upload_spec.rb b/spec/controllers/concerns/send_file_upload_spec.rb
index f9a6afb95ea..32304815bbb 100644
--- a/spec/controllers/concerns/send_file_upload_spec.rb
+++ b/spec/controllers/concerns/send_file_upload_spec.rb
@@ -96,9 +96,10 @@ RSpec.describe SendFileUpload do
expect(controller).to receive(:params).at_least(:once).and_return(width: '64')
expect(controller).to receive(:head).with(:ok)
- expect(Gitlab::Workhorse).to receive(:send_scaled_image).with(a_string_matching('^(/.+|https://.+)'), 64, 'image/png').and_return([
- Gitlab::Workhorse::SEND_DATA_HEADER, "send-scaled-img:faux"
- ])
+ expect(Gitlab::Workhorse).to receive(:send_scaled_image)
+ .with(a_string_matching('^(/.+|https://.+)'), 64, 'image/png')
+ .and_return([Gitlab::Workhorse::SEND_DATA_HEADER, "send-scaled-img:faux"])
+
expect(headers).to receive(:store).with(Gitlab::Workhorse::SEND_DATA_HEADER, "send-scaled-img:faux")
subject
diff --git a/spec/controllers/dashboard_controller_spec.rb b/spec/controllers/dashboard_controller_spec.rb
index aed310531e6..21810f64cb4 100644
--- a/spec/controllers/dashboard_controller_spec.rb
+++ b/spec/controllers/dashboard_controller_spec.rb
@@ -4,11 +4,14 @@ require 'spec_helper'
RSpec.describe DashboardController do
context 'signed in' do
- let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
- before do
+ before_all do
project.add_maintainer(user)
+ end
+
+ before do
sign_in(user)
end
@@ -30,6 +33,28 @@ RSpec.describe DashboardController do
end
it_behaves_like 'issuables requiring filter', :issues
+
+ it 'includes tasks in issue list' do
+ task = create(:work_item, :task, project: project, author: user)
+
+ get :issues, params: { author_id: user.id }
+
+ expect(assigns[:issues].map(&:id)).to include(task.id)
+ end
+
+ context 'when work_items is disabled' do
+ before do
+ stub_feature_flags(work_items: false)
+ end
+
+ it 'does not include tasks in issue list' do
+ task = create(:work_item, :task, project: project, author: user)
+
+ get :issues, params: { author_id: user.id }
+
+ expect(assigns[:issues].map(&:id)).not_to include(task.id)
+ end
+ end
end
describe 'GET merge requests' do
diff --git a/spec/controllers/groups/boards_controller_spec.rb b/spec/controllers/groups/boards_controller_spec.rb
index 6201cddecb0..4e441f86765 100644
--- a/spec/controllers/groups/boards_controller_spec.rb
+++ b/spec/controllers/groups/boards_controller_spec.rb
@@ -3,11 +3,14 @@
require 'spec_helper'
RSpec.describe Groups::BoardsController do
- let(:group) { create(:group) }
- let(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
- before do
+ before_all do
group.add_maintainer(user)
+ end
+
+ before do
sign_in(user)
end
@@ -57,46 +60,17 @@ RSpec.describe Groups::BoardsController do
end
end
- context 'when format is JSON' do
- it 'return an array with one group board' do
- create(:board, group: group)
-
- expect(Boards::VisitsFinder).not_to receive(:new)
-
- list_boards format: :json
-
- expect(response).to match_response_schema('boards')
- expect(json_response.length).to eq 1
- end
-
- context 'with unauthorized user' do
- before do
- expect(Ability).to receive(:allowed?).with(user, :log_in, :global).and_call_original
- allow(Ability).to receive(:allowed?).with(user, :read_cross_project, :global).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_issue_board, group).and_return(false)
- end
-
- it 'returns a not found 404 response' do
- list_boards format: :json
-
- expect(response).to have_gitlab_http_status(:not_found)
- expect(response.media_type).to eq 'application/json'
- end
- end
- end
-
it_behaves_like 'disabled when using an external authorization service' do
subject { list_boards }
end
- def list_boards(format: :html)
- get :index, params: { group_id: group }, format: format
+ def list_boards
+ get :index, params: { group_id: group }
end
end
describe 'GET show' do
- let!(:board) { create(:board, group: group) }
+ let_it_be(:board) { create(:board, group: group) }
context 'when format is HTML' do
it 'renders template' do
@@ -123,12 +97,12 @@ RSpec.describe Groups::BoardsController do
end
context 'when user is signed out' do
- let(:group) { create(:group, :public) }
+ let(:public_board) { create(:board, group: create(:group, :public)) }
it 'does not save visit' do
sign_out(user)
- expect { read_board board: board }.to change(BoardGroupRecentVisit, :count).by(0)
+ expect { read_board board: public_board }.to change(BoardGroupRecentVisit, :count).by(0)
expect(response).to render_template :show
expect(response.media_type).to eq 'text/html'
@@ -136,37 +110,11 @@ RSpec.describe Groups::BoardsController do
end
end
- context 'when format is JSON' do
- it 'returns project board' do
- expect(Boards::Visits::CreateService).not_to receive(:new)
-
- read_board board: board, format: :json
-
- expect(response).to match_response_schema('board')
- end
-
- context 'with unauthorized user' do
- before do
- expect(Ability).to receive(:allowed?).with(user, :log_in, :global).and_call_original
- allow(Ability).to receive(:allowed?).with(user, :read_cross_project, :global).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_group, group).and_return(false)
- end
-
- it 'returns a not found 404 response' do
- read_board board: board, format: :json
-
- expect(response).to have_gitlab_http_status(:not_found)
- expect(response.media_type).to eq 'application/json'
- end
- end
- end
-
context 'when board does not belong to group' do
it 'returns a not found 404 response' do
another_board = create(:board)
- read_board board: another_board
+ get :show, params: { group_id: group, id: another_board.to_param }
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -176,12 +124,8 @@ RSpec.describe Groups::BoardsController do
subject { read_board board: board }
end
- def read_board(board:, format: :html)
- get :show, params: {
- group_id: group,
- id: board.to_param
- },
- format: format
+ def read_board(board:)
+ get :show, params: { group_id: board.group, id: board.to_param }
end
end
end
diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb
index 77c62c0d930..6dbf0803892 100644
--- a/spec/controllers/groups/runners_controller_spec.rb
+++ b/spec/controllers/groups/runners_controller_spec.rb
@@ -8,9 +8,11 @@ RSpec.describe Groups::RunnersController do
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!(:project_runner) { create(:ci_runner, :project, projects: [project]) }
+ let!(:instance_runner) { create(:ci_runner, :instance) }
- let(:params_runner_project) { { group_id: group, id: runner_project } }
+ let(:params_runner_project) { { group_id: group, id: project_runner } }
+ let(:params_runner_instance) { { group_id: group, id: instance_runner } }
let(:params) { { group_id: group, id: runner } }
before do
@@ -70,8 +72,15 @@ RSpec.describe Groups::RunnersController do
expect(response).to render_template(:show)
end
+ it 'renders show with 200 status code instance runner' do
+ get :show, params: { group_id: group, id: instance_runner }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(:show)
+ end
+
it 'renders show with 200 status code project runner' do
- get :show, params: { group_id: group, id: runner_project }
+ get :show, params: { group_id: group, id: project_runner }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:show)
@@ -89,8 +98,14 @@ RSpec.describe Groups::RunnersController do
expect(response).to have_gitlab_http_status(:not_found)
end
+ it 'renders a 404 instance runner' do
+ get :show, params: { group_id: group, id: instance_runner }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
it 'renders a 404 project runner' do
- get :show, params: { group_id: group, id: runner_project }
+ get :show, params: { group_id: group, id: project_runner }
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -103,15 +118,21 @@ RSpec.describe Groups::RunnersController do
group.add_owner(user)
end
- it 'renders show with 200 status code' do
+ it 'renders edit with 200 status code' do
get :edit, params: { group_id: group, id: runner }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:edit)
end
- it 'renders show with 200 status code project runner' do
- get :edit, params: { group_id: group, id: runner_project }
+ it 'renders a 404 instance runner' do
+ get :edit, params: { group_id: group, id: instance_runner }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it 'renders edit with 200 status code project runner' do
+ get :edit, params: { group_id: group, id: project_runner }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:edit)
@@ -130,7 +151,7 @@ RSpec.describe Groups::RunnersController do
end
it 'renders a 404 project runner' do
- get :edit, params: { group_id: group, id: runner_project }
+ get :edit, params: { group_id: group, id: project_runner }
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -154,15 +175,26 @@ RSpec.describe Groups::RunnersController do
expect(runner.reload.description).to eq(new_desc)
end
+ it 'does not update the instance runner' do
+ new_desc = instance_runner.description.swapcase
+
+ expect do
+ post :update, params: params_runner_instance.merge(runner: { description: new_desc } )
+ end.to not_change { instance_runner.ensure_runner_queue_value }
+ .and not_change { instance_runner.description }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
it 'updates the project runner, ticks the queue, and redirects project runner' do
- new_desc = runner_project.description.swapcase
+ new_desc = project_runner.description.swapcase
expect do
post :update, params: params_runner_project.merge(runner: { description: new_desc } )
- end.to change { runner_project.ensure_runner_queue_value }
+ end.to change { project_runner.ensure_runner_queue_value }
expect(response).to have_gitlab_http_status(:found)
- expect(runner_project.reload.description).to eq(new_desc)
+ expect(project_runner.reload.description).to eq(new_desc)
end
end
@@ -182,15 +214,26 @@ RSpec.describe Groups::RunnersController do
expect(runner.reload.description).to eq(old_desc)
end
+ it 'rejects the update and responds 404 instance runner' do
+ old_desc = instance_runner.description
+
+ expect do
+ post :update, params: params_runner_instance.merge(runner: { description: old_desc.swapcase } )
+ end.not_to change { instance_runner.ensure_runner_queue_value }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(instance_runner.reload.description).to eq(old_desc)
+ end
+
it 'rejects the update and responds 404 project runner' do
- old_desc = runner_project.description
+ old_desc = project_runner.description
expect do
post :update, params: params_runner_project.merge(runner: { description: old_desc.swapcase } )
- end.not_to change { runner_project.ensure_runner_queue_value }
+ end.not_to change { project_runner.ensure_runner_queue_value }
expect(response).to have_gitlab_http_status(:not_found)
- expect(runner_project.reload.description).to eq(old_desc)
+ expect(project_runner.reload.description).to eq(old_desc)
end
end
end
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index c4e4eeec953..5bbe236077c 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -229,7 +229,7 @@ RSpec.describe GroupsController, factory_default: :keep do
sign_in(user)
expect do
- post :create, params: { group: { name: 'new_group', path: "new_group" } }
+ post :create, params: { group: { name: 'new_group', path: 'new_group' } }
end.to change { Group.count }.by(1)
expect(response).to have_gitlab_http_status(:found)
@@ -240,13 +240,31 @@ RSpec.describe GroupsController, factory_default: :keep do
sign_in(create(:admin))
expect do
- post :create, params: { group: { name: 'new_group', path: "new_group" } }
+ post :create, params: { group: { name: 'new_group', path: 'new_group' } }
end.to change { Group.count }.by(1)
expect(response).to have_gitlab_http_status(:found)
end
end
+ context 'when creating chat team' do
+ before do
+ stub_mattermost_setting(enabled: true)
+ end
+
+ it 'triggers Mattermost::CreateTeamService' do
+ sign_in(user)
+
+ expect_next_instance_of(::Mattermost::CreateTeamService) do |service|
+ expect(service).to receive(:execute).and_return({ name: 'test-chat-team', id: 1 })
+ end
+
+ post :create, params: { group: { name: 'new_group', path: 'new_group', create_chat_team: 1 } }
+
+ expect(response).to have_gitlab_http_status(:found)
+ end
+ end
+
context 'when creating subgroups' do
[true, false].each do |can_create_group_status|
context "and can_create_group is #{can_create_group_status}" do
diff --git a/spec/controllers/health_check_controller_spec.rb b/spec/controllers/health_check_controller_spec.rb
index 7f55c4407dd..47290b1d0d6 100644
--- a/spec/controllers/health_check_controller_spec.rb
+++ b/spec/controllers/health_check_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe HealthCheckController, :request_store do
+RSpec.describe HealthCheckController, :request_store, :use_clean_rails_memory_store_caching do
include StubENV
let(:xml_response) { Hash.from_xml(response.body)['hash'] }
@@ -93,12 +93,13 @@ RSpec.describe HealthCheckController, :request_store do
context 'when a service is down and an endpoint is accessed from whitelisted ip' do
before do
- allow(HealthCheck::Utils).to receive(:process_checks).with(['standard']).and_return('The server is on fire')
- allow(HealthCheck::Utils).to receive(:process_checks).with(['email']).and_return('Email is on fire')
+ allow(::HealthCheck).to receive(:include_error_in_response_body).and_return(true)
allow(Gitlab::RequestContext.instance).to receive(:client_ip).and_return(whitelisted_ip)
end
it 'supports failure plaintext response' do
+ expect(HealthCheck::Utils).to receive(:process_checks).with(['standard']).and_return('The server is on fire')
+
get :index
expect(response).to have_gitlab_http_status(:internal_server_error)
@@ -107,6 +108,8 @@ RSpec.describe HealthCheckController, :request_store do
end
it 'supports failure json response' do
+ expect(HealthCheck::Utils).to receive(:process_checks).with(['standard']).and_return('The server is on fire')
+
get :index, format: :json
expect(response).to have_gitlab_http_status(:internal_server_error)
@@ -116,6 +119,8 @@ RSpec.describe HealthCheckController, :request_store do
end
it 'supports failure xml response' do
+ expect(HealthCheck::Utils).to receive(:process_checks).with(['standard']).and_return('The server is on fire')
+
get :index, format: :xml
expect(response).to have_gitlab_http_status(:internal_server_error)
@@ -125,6 +130,8 @@ RSpec.describe HealthCheckController, :request_store do
end
it 'supports failure responses for specific checks' do
+ expect(HealthCheck::Utils).to receive(:process_checks).with(['email']).and_return('Email is on fire')
+
get :index, params: { checks: 'email' }, format: :json
expect(response).to have_gitlab_http_status(:internal_server_error)
diff --git a/spec/controllers/import/bulk_imports_controller_spec.rb b/spec/controllers/import/bulk_imports_controller_spec.rb
index 3be12717664..a0bb39f3e98 100644
--- a/spec/controllers/import/bulk_imports_controller_spec.rb
+++ b/spec/controllers/import/bulk_imports_controller_spec.rb
@@ -247,10 +247,10 @@ RSpec.describe Import::BulkImportsController do
"source_full_path" => "full_path",
"destination_slug" => "destination_name",
"destination_namespace" => "root" },
- { "source_type" => "group_entity2",
- "source_full_path" => "full_path2",
- "destination_slug" => "destination_name2",
- "destination_namespace" => "root" }]
+ { "source_type" => "group_entity",
+ "source_full_path" => "full_path",
+ "destination_slug" => "destination_name",
+ "destination_namespace" => "invalid-namespace" }]
end
before do
@@ -308,6 +308,21 @@ RSpec.describe Import::BulkImportsController do
expect(json_response).to match_array([{ "success" => true, "id" => bulk_import.id, "message" => nil }])
end
end
+
+ context 'when source type is project' do
+ let(:bulk_import_params) do
+ [{ "source_type" => "project_entity",
+ "source_full_path" => "full_path",
+ "destination_slug" => "destination_name",
+ "destination_namespace" => "root" }]
+ end
+
+ it 'returns 422' do
+ post :create, params: { bulk_import: bulk_import_params }
+
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
+ end
end
end
diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb
index 269eb62cae6..f3632e7370c 100644
--- a/spec/controllers/import/github_controller_spec.rb
+++ b/spec/controllers/import/github_controller_spec.rb
@@ -44,13 +44,6 @@ RSpec.describe Import::GithubController do
end
describe "GET callback" do
- before do
- allow(controller).to receive(:get_token).and_return(token)
- allow(controller).to receive(:oauth_options).and_return({})
-
- stub_omniauth_provider('github')
- end
-
context "when auth state param is missing from session" do
it "reports an error" do
get :callback
@@ -63,17 +56,31 @@ RSpec.describe Import::GithubController do
context "when auth state param is present in session" do
let(:valid_auth_state) { "secret-state" }
- before do
- session[:github_auth_state_key] = valid_auth_state
- end
+ context 'when remove_legacy_github_client feature is disabled' do
+ before do
+ stub_feature_flags(remove_legacy_github_client: false)
+ allow_next_instance_of(Gitlab::LegacyGithubImport::Client) do |client|
+ allow(client).to receive(:get_token).and_return(token)
+ end
+ session[:github_auth_state_key] = valid_auth_state
+ end
+
+ it "updates access token if state param is valid" do
+ token = "asdasd12345"
- it "updates access token if state param is valid" do
- token = "asdasd12345"
+ get :callback, params: { state: valid_auth_state }
- get :callback, params: { state: valid_auth_state }
+ expect(session[:github_access_token]).to eq(token)
+ expect(controller).to redirect_to(status_import_github_url)
+ end
+
+ it "includes namespace_id from query params if it is present" do
+ namespace_id = 1
+
+ get :callback, params: { state: valid_auth_state, namespace_id: namespace_id }
- expect(session[:github_access_token]).to eq(token)
- expect(controller).to redirect_to(status_import_github_url)
+ expect(controller).to redirect_to(status_import_github_url(namespace_id: namespace_id))
+ end
end
it "reports an error if state param is invalid" do
@@ -83,12 +90,31 @@ RSpec.describe Import::GithubController do
expect(flash[:alert]).to eq('Access denied to your GitHub account.')
end
- it "includes namespace_id from query params if it is present" do
- namespace_id = 1
+ context 'when remove_legacy_github_client feature is enabled' do
+ before do
+ stub_feature_flags(remove_legacy_github_client: true)
+ allow_next_instance_of(OAuth2::Client) do |client|
+ allow(client).to receive_message_chain(:auth_code, :get_token, :token).and_return(token)
+ end
+ session[:github_auth_state_key] = valid_auth_state
+ end
+
+ it "updates access token if state param is valid" do
+ token = "asdasd12345"
- get :callback, params: { state: valid_auth_state, namespace_id: namespace_id }
+ get :callback, params: { state: valid_auth_state }
+
+ expect(session[:github_access_token]).to eq(token)
+ expect(controller).to redirect_to(status_import_github_url)
+ end
- expect(controller).to redirect_to(status_import_github_url(namespace_id: namespace_id))
+ it "includes namespace_id from query params if it is present" do
+ namespace_id = 1
+
+ get :callback, params: { state: valid_auth_state, namespace_id: namespace_id }
+
+ expect(controller).to redirect_to(status_import_github_url(namespace_id: namespace_id))
+ end
end
end
end
@@ -218,7 +244,7 @@ RSpec.describe Import::GithubController do
it 'makes request to github search api' do
expect_next_instance_of(Octokit::Client) do |client|
- expect(client).to receive(:user).and_return(double(login: user_login))
+ expect(client).to receive(:user).and_return({ login: user_login })
expect(client).to receive(:search_repositories).with(search_query, { page: 1, per_page: 25 }).and_return({ items: [].to_enum })
end
@@ -234,7 +260,7 @@ RSpec.describe Import::GithubController 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(:user).and_return(double(login: user_login))
+ expect(client).to receive(:user).and_return({ login: user_login })
expect(client).to receive(:search_repositories).with(search_query, { page: 1, per_page: 25 }).and_return({ items: [].to_enum })
end
@@ -250,7 +276,7 @@ RSpec.describe Import::GithubController do
context 'when page is specified' do
it 'requests repos with specified page' do
expect_next_instance_of(Octokit::Client) do |client|
- expect(client).to receive(:user).and_return(double(login: user_login))
+ expect(client).to receive(:user).and_return({ login: user_login })
expect(client).to receive(:search_repositories).with(search_query, { page: 2, per_page: 25 }).and_return({ items: [].to_enum })
end
@@ -321,4 +347,37 @@ RSpec.describe Import::GithubController do
expect(json_response[0]['stats']).to include('imported')
end
end
+
+ describe "POST cancel" do
+ let_it_be(:project) { create(:project, :import_started, import_type: 'github', import_url: 'https://fake.url') }
+
+ context 'when project import was canceled' do
+ before do
+ allow(Import::Github::CancelProjectImportService)
+ .to receive(:new).with(project, user)
+ .and_return(double(execute: { status: :success, project: project }))
+ end
+
+ it 'returns success' do
+ post :cancel, params: { project_id: project.id }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when project import was not canceled' do
+ before do
+ allow(Import::Github::CancelProjectImportService)
+ .to receive(:new).with(project, user)
+ .and_return(double(execute: { status: :error, message: 'The import cannot be canceled because it is finished', http_status: :bad_request }))
+ end
+
+ it 'returns error' do
+ post :cancel, params: { project_id: project.id }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['errors']).to eq('The import cannot be canceled because it is finished')
+ end
+ end
+ end
end
diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
index 99e9644da66..8dee0490fd6 100644
--- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
+++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
@@ -35,6 +35,18 @@ RSpec.describe Profiles::PersonalAccessTokensController do
expect(created_token).not_to be_nil
expect(created_token.expires_at).to eq(expires_at)
end
+
+ it 'does not allow creation when personal access tokens are disabled' do
+ allow(::Gitlab::CurrentSettings).to receive_messages(personal_access_tokens_disabled?: true)
+
+ post :create, params: { personal_access_token: token_attributes }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it_behaves_like "#create access token" do
+ let(:url) { :create }
+ end
end
describe '#index' do
@@ -66,6 +78,14 @@ RSpec.describe Profiles::PersonalAccessTokensController do
)
end
+ it 'returns 404 when personal access tokens are disabled' do
+ allow(::Gitlab::CurrentSettings).to receive_messages(personal_access_tokens_disabled?: true)
+
+ get :index
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
context "access_token_pagination feature flag is enabled" do
before do
stub_feature_flags(access_token_pagination: true)
diff --git a/spec/controllers/profiles/preferences_controller_spec.rb b/spec/controllers/profiles/preferences_controller_spec.rb
index 7add3a72337..e2a216bb462 100644
--- a/spec/controllers/profiles/preferences_controller_spec.rb
+++ b/spec/controllers/profiles/preferences_controller_spec.rb
@@ -53,7 +53,8 @@ RSpec.describe Profiles::PreferencesController do
first_day_of_week: '1',
preferred_language: 'jp',
tab_width: '5',
- render_whitespace_in_code: 'true'
+ render_whitespace_in_code: 'true',
+ use_legacy_web_ide: 'true'
}.with_indifferent_access
expect(user).to receive(:assign_attributes).with(ActionController::Parameters.new(prefs).permit!)
diff --git a/spec/controllers/profiles/two_factor_auths_controller_spec.rb b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
index 33cba675777..1dd564427d3 100644
--- a/spec/controllers/profiles/two_factor_auths_controller_spec.rb
+++ b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
@@ -31,13 +31,26 @@ RSpec.describe Profiles::TwoFactorAuthsController do
shared_examples 'user must enter a valid current password' do
let(:current_password) { '123' }
- let(:redirect_path) { profile_two_factor_auth_path }
+ let(:error_message) { { message: _('You must provide a valid current password') } }
it 'requires the current password', :aggregate_failures do
go
- expect(response).to redirect_to(redirect_path)
- expect(flash[:alert]).to eq(_('You must provide a valid current password'))
+ expect(assigns[:error]).to eq(error_message)
+ expect(response).to render_template(:show)
+ end
+
+ it 'assigns qr_code' do
+ code = double('qr code')
+ expect(subject).to receive(:build_qr_code).and_return(code)
+
+ go
+ expect(assigns[:qr_code]).to eq(code)
+ end
+
+ it 'assigns account_string' do
+ go
+ expect(assigns[:account_string]).to eq("#{Gitlab.config.gitlab.host}:#{user.email}")
end
context 'when the user is on the last sign in attempt' do
@@ -58,8 +71,7 @@ RSpec.describe Profiles::TwoFactorAuthsController do
it 'does not require the current password', :aggregate_failures do
go
- expect(response).not_to redirect_to(redirect_path)
- expect(flash[:alert]).to be_nil
+ expect(assigns[:error]).not_to eq(error_message)
end
end
@@ -71,8 +83,7 @@ RSpec.describe Profiles::TwoFactorAuthsController do
it 'does not require the current password', :aggregate_failures do
go
- expect(response).not_to redirect_to(redirect_path)
- expect(flash[:alert]).to be_nil
+ expect(assigns[:error]).not_to eq(error_message)
end
end
@@ -84,8 +95,7 @@ RSpec.describe Profiles::TwoFactorAuthsController do
it 'does not require the current password', :aggregate_failures do
go
- expect(response).not_to redirect_to(redirect_path)
- expect(flash[:alert]).to be_nil
+ expect(assigns[:error]).not_to eq(error_message)
end
end
end
diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb
index 263f488ddbf..808e67eff3d 100644
--- a/spec/controllers/projects/artifacts_controller_spec.rb
+++ b/spec/controllers/projects/artifacts_controller_spec.rb
@@ -229,7 +229,7 @@ RSpec.describe Projects::ArtifactsController do
expect(response.body).to include(
'You must have developer or higher permissions in the associated project to view job logs when debug trace is enabled. ' \
'To disable debug trace, set the 'CI_DEBUG_TRACE' variable to 'false' in your pipeline configuration or CI/CD settings. ' \
- 'If you need to view this job log, a project maintainer must add you to the project with developer permissions or higher.'
+ 'If you need to view this job log, a project maintainer or owner must add you to the project with developer permissions or higher.'
)
end
end
diff --git a/spec/controllers/projects/autocomplete_sources_controller_spec.rb b/spec/controllers/projects/autocomplete_sources_controller_spec.rb
index a5274b6543e..7077aae6b45 100644
--- a/spec/controllers/projects/autocomplete_sources_controller_spec.rb
+++ b/spec/controllers/projects/autocomplete_sources_controller_spec.rb
@@ -5,37 +5,133 @@ require 'spec_helper'
RSpec.describe Projects::AutocompleteSourcesController do
let_it_be(:group, reload: true) { create(:group) }
let_it_be(:project) { create(:project, namespace: group) }
- let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:public_project) { create(:project, :public, group: group) }
+ let_it_be(:development) { create(:label, project: project, name: 'Development') }
+ let_it_be(:issue) { create(:labeled_issue, project: project, labels: [development]) }
let_it_be(:user) { create(:user) }
def members_by_username(username)
json_response.find { |member| member['username'] == username }
end
- describe 'GET members' do
+ describe 'GET commands' do
+ before do
+ group.add_owner(user)
+ end
+
+ context 'with a public project' do
+ shared_examples 'issuable commands' do
+ it 'returns empty array when no user logged in' do
+ get :commands, format: :json, params: { namespace_id: group.path, project_id: public_project.path, type: issuable_type, type_id: issuable_iid }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq([])
+ end
+
+ it 'raises an error when no target type specified' do
+ sign_in(user)
+
+ expect { get :commands, format: :json, params: { namespace_id: group.path, project_id: project.path } }
+ .to raise_error(ActionController::ParameterMissing)
+ end
+
+ it 'returns an array of commands' do
+ sign_in(user)
+
+ get :commands, format: :json, params: { namespace_id: group.path, project_id: public_project.path, type: issuable_type, type_id: issuable_iid }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_present
+ end
+ end
+
+ context 'with an issue' do
+ let(:issuable_type) { issue.class.name }
+ let(:issuable_iid) { issue.iid }
+
+ it_behaves_like 'issuable commands'
+ end
+
+ context 'with merge request' do
+ let(:merge_request) { create(:merge_request, target_project: public_project, source_project: public_project) }
+ let(:issuable_type) { merge_request.class.name }
+ let(:issuable_iid) { merge_request.iid }
+
+ it_behaves_like 'issuable commands'
+ end
+ end
+ end
+
+ describe 'GET labels' do
before do
group.add_owner(user)
sign_in(user)
end
- it 'returns an array of member object' do
- get :members, format: :json, params: { namespace_id: group.path, project_id: project.path, type: issue.class.name, type_id: issue.id }
+ it 'raises an error when no target type specified' do
+ expect { get :labels, format: :json, params: { namespace_id: group.path, project_id: project.path } }
+ .to raise_error(ActionController::ParameterMissing)
+ end
+
+ it 'returns an array of labels' do
+ get :labels, format: :json, params: { namespace_id: group.path, project_id: project.path, type: issue.class.name, type_id: issue.id }
+
+ expect(json_response).to be_a(Array)
+ expect(json_response.count).to eq(1)
+ expect(json_response[0]['title']).to eq('Development')
+ end
+ end
+
+ describe 'GET members' do
+ context 'when logged in' do
+ before do
+ group.add_owner(user)
+ sign_in(user)
+ end
+
+ it 'returns 400 when no target type specified' do
+ expect { get :members, format: :json, params: { namespace_id: group.path, project_id: project.path } }
+ .to raise_error(ActionController::ParameterMissing)
+ end
+
+ it 'returns an array of member object' do
+ get :members, format: :json, params: { namespace_id: group.path, project_id: project.path, type: issue.class.name, type_id: issue.id }
+
+ expect(members_by_username('all').symbolize_keys).to include(
+ username: 'all',
+ name: 'All Project and Group Members',
+ count: 1)
+
+ expect(members_by_username(group.full_path).symbolize_keys).to include(
+ type: group.class.name,
+ name: group.full_name,
+ avatar_url: group.avatar_url,
+ count: 1)
+
+ expect(members_by_username(user.username).symbolize_keys).to include(
+ type: user.class.name,
+ name: user.name,
+ avatar_url: user.avatar_url)
+ end
+ end
+
+ context 'when anonymous' do
+ it 'redirects to login page' do
+ get :members, format: :json, params: { namespace_id: group.path, project_id: project.path, type: issue.class.name, type_id: issue.id }
- expect(members_by_username('all').symbolize_keys).to include(
- username: 'all',
- name: 'All Project and Group Members',
- count: 1)
+ expect(response).to redirect_to new_user_session_path
+ end
- expect(members_by_username(group.full_path).symbolize_keys).to include(
- type: group.class.name,
- name: group.full_name,
- avatar_url: group.avatar_url,
- count: 1)
+ context 'with public project' do
+ it 'returns no members' do
+ get :members, format: :json, params: { namespace_id: group.path, project_id: public_project.path, type: issue.class.name, type_id: issue.id }
- expect(members_by_username(user.username).symbolize_keys).to include(
- type: user.class.name,
- name: user.name,
- avatar_url: user.avatar_url)
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_a(Array)
+ expect(json_response.count).to eq(1)
+ expect(json_response.first['count']).to eq(0)
+ end
+ end
end
end
@@ -88,7 +184,7 @@ RSpec.describe Projects::AutocompleteSourcesController do
it 'lists contacts' do
group.add_developer(user)
- get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path }
+ get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path, type: issue.class.name, type_id: issue.id }
emails = json_response.map { |contact_data| contact_data["email"] }
expect(emails).to match_array([contact_1.email, contact_2.email])
@@ -97,7 +193,7 @@ RSpec.describe Projects::AutocompleteSourcesController do
context 'when a user can not read contacts' do
it 'renders 404' do
- get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path }
+ get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path, type: issue.class.name, type_id: issue.id }
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -108,7 +204,7 @@ RSpec.describe Projects::AutocompleteSourcesController do
it 'renders 404' do
group.add_developer(user)
- get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path }
+ get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path, type: issue.class.name, type_id: issue.id }
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb
index cde3a8d4761..89d0669f47b 100644
--- a/spec/controllers/projects/boards_controller_spec.rb
+++ b/spec/controllers/projects/boards_controller_spec.rb
@@ -3,11 +3,14 @@
require 'spec_helper'
RSpec.describe Projects::BoardsController do
- let(:project) { create(:project) }
- let(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
- before do
+ before_all do
project.add_maintainer(user)
+ end
+
+ before do
sign_in(user)
end
@@ -16,77 +19,63 @@ RSpec.describe Projects::BoardsController do
expect { list_boards }.to change(project.boards, :count).by(1)
end
- it 'sets boards_endpoint instance variable to a boards path' do
+ it 'renders template' do
list_boards
- expect(assigns(:boards_endpoint)).to eq project_boards_path(project)
+ expect(response).to render_template :index
+ expect(response.media_type).to eq 'text/html'
end
- context 'when format is HTML' do
- it 'renders template' do
- list_boards
+ context 'when there are recently visited boards' do
+ let_it_be(:boards) { create_list(:board, 3, resource_parent: project) }
- expect(response).to render_template :index
- expect(response.media_type).to eq 'text/html'
+ before_all do
+ visit_board(boards[2], Time.current + 1.minute)
+ visit_board(boards[0], Time.current + 2.minutes)
+ visit_board(boards[1], Time.current + 5.minutes)
end
- context 'with unauthorized user' do
- before do
- expect(Ability).to receive(:allowed?).with(user, :log_in, :global).and_call_original
- allow(Ability).to receive(:allowed?).with(user, :read_project, project).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_issue_board, project).and_return(false)
- end
-
- it 'returns a not found 404 response' do
- list_boards
+ it 'redirects to latest visited board' do
+ list_boards
- expect(response).to have_gitlab_http_status(:not_found)
- expect(response.media_type).to eq 'text/html'
- end
+ expect(response).to redirect_to(
+ namespace_project_board_path(namespace_id: project.namespace, project_id: project, id: boards[1].id)
+ )
end
- context 'when user is signed out' do
- let(:project) { create(:project, :public) }
-
- it 'renders template' do
- sign_out(user)
+ def visit_board(board, time)
+ create(:board_project_recent_visit, project: project, board: board, user: user, updated_at: time)
+ end
+ end
- board = create(:board, project: project)
- create(:board_project_recent_visit, project: board.project, board: board, user: user)
+ context 'with unauthorized user' do
+ before do
+ expect(Ability).to receive(:allowed?).with(user, :log_in, :global).and_call_original
+ allow(Ability).to receive(:allowed?).with(user, :read_project, project).and_return(true)
+ allow(Ability).to receive(:allowed?).with(user, :read_issue_board, project).and_return(false)
+ end
- list_boards
+ it 'returns a not found 404 response' do
+ list_boards
- expect(response).to render_template :index
- expect(response.media_type).to eq 'text/html'
- end
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(response.media_type).to eq 'text/html'
end
end
- context 'when format is JSON' do
- it 'returns a list of project boards' do
- create_list(:board, 2, project: project)
-
- expect(Boards::VisitsFinder).not_to receive(:new)
-
- list_boards format: :json
+ context 'when user is signed out' do
+ let(:project) { create(:project, :public) }
- expect(response).to match_response_schema('boards')
- expect(json_response.length).to eq 2
- end
+ it 'renders template' do
+ sign_out(user)
- context 'with unauthorized user' do
- before do
- expect(Ability).to receive(:allowed?).with(user, :log_in, :global).and_call_original
- allow(Ability).to receive(:allowed?).with(user, :read_project, project).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_issue_board, project).and_return(false)
- end
+ board = create(:board, project: project)
+ create(:board_project_recent_visit, project: board.project, board: board, user: user)
- it 'returns a not found 404 response' do
- list_boards format: :json
+ list_boards
- expect(response).to have_gitlab_http_status(:not_found)
- expect(response.media_type).to eq 'application/json'
- end
+ expect(response).to render_template :index
+ expect(response.media_type).to eq 'text/html'
end
end
@@ -104,23 +93,16 @@ RSpec.describe Projects::BoardsController do
subject { list_boards }
end
- def list_boards(format: :html)
+ def list_boards
get :index, params: {
namespace_id: project.namespace,
project_id: project
- },
- format: format
+ }
end
end
describe 'GET show' do
- let!(:board) { create(:board, project: project) }
-
- it 'sets boards_endpoint instance variable to a boards path' do
- read_board board: board
-
- expect(assigns(:boards_endpoint)).to eq project_boards_path(project)
- end
+ let_it_be(:board) { create(:board, project: project) }
context 'when format is HTML' do
it 'renders template' do
@@ -146,12 +128,12 @@ RSpec.describe Projects::BoardsController do
end
context 'when user is signed out' do
- let(:project) { create(:project, :public) }
+ let(:public_board) { create(:board, project: create(:project, :public)) }
it 'does not save visit' do
sign_out(user)
- expect { read_board board: board }.to change(BoardProjectRecentVisit, :count).by(0)
+ expect { read_board board: public_board }.to change(BoardProjectRecentVisit, :count).by(0)
expect(response).to render_template :show
expect(response.media_type).to eq 'text/html'
@@ -159,48 +141,18 @@ RSpec.describe Projects::BoardsController do
end
end
- context 'when format is JSON' do
- it 'returns project board' do
- expect(Boards::Visits::CreateService).not_to receive(:new)
-
- read_board board: board, format: :json
-
- expect(response).to match_response_schema('board')
- end
-
- context 'with unauthorized user' do
- before do
- expect(Ability).to receive(:allowed?).with(user, :log_in, :global).and_call_original
- allow(Ability).to receive(:allowed?).with(user, :read_project, project).and_return(true)
- allow(Ability).to receive(:allowed?).with(user, :read_issue_board, project).and_return(false)
- end
-
- it 'returns a not found 404 response' do
- read_board board: board, format: :json
-
- expect(response).to have_gitlab_http_status(:not_found)
- expect(response.media_type).to eq 'application/json'
- end
- end
- end
-
context 'when board does not belong to project' do
it 'returns a not found 404 response' do
another_board = create(:board)
- read_board board: another_board
+ get :show, params: { namespace_id: project.namespace, project_id: project, id: another_board.to_param }
expect(response).to have_gitlab_http_status(:not_found)
end
end
- def read_board(board:, format: :html)
- get :show, params: {
- namespace_id: project.namespace,
- project_id: project,
- id: board.to_param
- },
- format: format
+ def read_board(board:)
+ get :show, params: { namespace_id: board.project.namespace, project_id: board.project, id: board.to_param }
end
end
end
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index 6ed6f7017e3..3751b89951c 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -67,11 +67,13 @@ RSpec.describe Projects::CompareController do
from: from_ref,
to: to_ref,
w: whitespace,
- page: page
+ page: page,
+ straight: straight
}
end
let(:whitespace) { nil }
+ let(:straight) { nil }
let(:page) { nil }
context 'when the refs exist in the same project' do
@@ -142,6 +144,58 @@ RSpec.describe Projects::CompareController do
end
end
+ context 'when comparing missing commits between source and target' do
+ let(:from_project_id) { nil }
+ let(:from_ref) { '5937ac0a7beb003549fc5fd26fc247adbce4a52e' }
+ let(:to_ref) { '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9' }
+ let(:page) { 1 }
+
+ context 'when comparing them in the other direction' do
+ let(:straight) { "false" }
+ let(:from_ref) { '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9' }
+ let(:to_ref) { '5937ac0a7beb003549fc5fd26fc247adbce4a52e' }
+
+ it 'the commits are there' do
+ show_request
+
+ expect(response).to be_successful
+ expect(assigns(:commits).length).to be >= 2
+ expect(assigns(:diffs).raw_diff_files.size).to be >= 2
+ expect(assigns(:diffs).diff_files.first).to be_present
+ end
+ end
+
+ context 'with straight mode true' do
+ let(:from_ref) { '5937ac0a7beb003549fc5fd26fc247adbce4a52e' }
+ let(:to_ref) { '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9' }
+
+ let(:straight) { "true" }
+
+ it 'the commits are empty, but the removed lines are visible as diffs' do
+ show_request
+
+ expect(response).to be_successful
+ expect(assigns(:commits).length).to be == 0
+ expect(assigns(:diffs).diff_files.size).to be >= 4
+ end
+ end
+
+ context 'with straight mode false' do
+ let(:from_ref) { '5937ac0a7beb003549fc5fd26fc247adbce4a52e' }
+ let(:to_ref) { '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9' }
+
+ let(:straight) { "false" }
+
+ it 'the additional commits are not visible in diffs and commits' do
+ show_request
+
+ expect(response).to be_successful
+ expect(assigns(:commits).length).to be == 0
+ expect(assigns(:diffs).diff_files.size).to be == 0
+ end
+ end
+ end
+
context 'when the refs exist in different projects but the user cannot see' do
let(:from_project_id) { private_fork.id }
let(:from_ref) { 'improve%2Fmore-awesome' }
@@ -450,10 +504,13 @@ RSpec.describe Projects::CompareController do
project_id: project,
from: from_ref,
to: to_ref,
+ straight: straight,
format: :json
}
end
+ let(:straight) { nil }
+
context 'when the source and target refs exist' do
let(:from_ref) { 'improve%2Fawesome' }
let(:to_ref) { 'feature' }
@@ -469,10 +526,43 @@ RSpec.describe Projects::CompareController do
escaped_to_ref = Addressable::URI.unescape(to_ref)
compare_service = CompareService.new(project, escaped_to_ref)
+ compare = compare_service.execute(project, escaped_from_ref, straight: false)
+
+ expect(CompareService).to receive(:new).with(project, escaped_to_ref).and_return(compare_service)
+ expect(compare_service).to receive(:execute).with(project, escaped_from_ref, straight: false).and_return(compare)
+
+ expect(compare).to receive(:commits).and_return(CommitCollection.new(project, [signature_commit, non_signature_commit]))
+ expect(non_signature_commit).to receive(:has_signature?).and_return(false)
+ end
+
+ it 'returns only the commit with a signature' do
+ signatures_request
+
+ expect(response).to have_gitlab_http_status(:ok)
+ signatures = json_response['signatures']
+
+ expect(signatures.size).to eq(1)
+ expect(signatures.first['commit_sha']).to eq(signature_commit.sha)
+ expect(signatures.first['html']).to be_present
+ end
+ end
+
+ context 'when the user has access to the project with straight compare' do
+ render_views
+
+ let(:signature_commit) { project.commit_by(oid: '0b4bc9a49b562e85de7cc9e834518ea6828729b9') }
+ let(:non_signature_commit) { build(:commit, project: project, safe_message: "message", sha: 'non_signature_commit') }
+ let(:straight) { "true" }
+
+ before do
+ escaped_from_ref = Addressable::URI.unescape(from_ref)
+ escaped_to_ref = Addressable::URI.unescape(to_ref)
+
+ compare_service = CompareService.new(project, escaped_to_ref)
compare = compare_service.execute(project, escaped_from_ref)
expect(CompareService).to receive(:new).with(project, escaped_to_ref).and_return(compare_service)
- expect(compare_service).to receive(:execute).with(project, escaped_from_ref).and_return(compare)
+ expect(compare_service).to receive(:execute).with(project, escaped_from_ref, straight: true).and_return(compare)
expect(compare).to receive(:commits).and_return(CommitCollection.new(project, [signature_commit, non_signature_commit]))
expect(non_signature_commit).to receive(:has_signature?).and_return(false)
diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb
index f5dd8abd67b..034e6104f99 100644
--- a/spec/controllers/projects/cycle_analytics_controller_spec.rb
+++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe Projects::CycleAnalyticsController do
let(:target_id) { 'p_analytics_valuestream' }
end
- it_behaves_like 'Snowplow event tracking' do
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
subject { get :show, params: request_params, format: :html }
let(:request_params) { { namespace_id: project.namespace, project_id: project } }
diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb
index 308146ce792..fd844808d81 100644
--- a/spec/controllers/projects/deploy_keys_controller_spec.rb
+++ b/spec/controllers/projects/deploy_keys_controller_spec.rb
@@ -72,13 +72,15 @@ RSpec.describe Projects::DeployKeysController do
end
describe 'POST create' do
+ let(:deploy_key_content) { attributes_for(:deploy_key)[:key] }
+
def create_params(title = 'my-key')
{
namespace_id: project.namespace.path,
project_id: project.path,
deploy_key: {
title: title,
- key: attributes_for(:deploy_key)[:key],
+ key: deploy_key_content,
deploy_keys_projects_attributes: { '0' => { can_push: '1' } }
}
}
@@ -96,13 +98,38 @@ RSpec.describe Projects::DeployKeysController do
expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
end
- context 'when the deploy key is invalid' do
+ context 'when the deploy key has an invalid title' do
it 'shows an alert with the validations errors' do
post :create, params: create_params(nil)
expect(flash[:alert]).to eq("Title can't be blank, Deploy keys projects deploy key title can't be blank")
end
end
+
+ context 'when the deploy key is not supported SSH public key' do
+ let(:deploy_key_content) { 'bogus ssh public key' }
+
+ it 'shows an alert with a help link' do
+ post :create, params: create_params
+
+ expect(assigns(:key).errors.count).to be > 1
+ expect(flash[:alert]).to eq('Deploy Key must be a <a target="_blank" rel="noopener noreferrer" ' \
+ 'href="/help/user/ssh#supported-ssh-key-types">supported SSH public key.</a>')
+ end
+ end
+
+ context 'when the deploy key already exists' do
+ before do
+ create(:deploy_key, title: 'my-key', key: deploy_key_content, projects: [project])
+ end
+
+ it 'shows an alert with the validations errors' do
+ post :create, params: create_params
+
+ expect(flash[:alert]).to eq("Fingerprint sha256 has already been taken, " \
+ "Deploy keys projects deploy key fingerprint sha256 has already been taken")
+ end
+ end
end
describe '/enable/:id' do
diff --git a/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb b/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb
index 55ab0f0eefa..2d39e0e5317 100644
--- a/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb
+++ b/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb
@@ -132,7 +132,7 @@ RSpec.describe Projects::DesignManagement::Designs::RawImagesController do
subject
expect(response.header['ETag']).to be_present
- expect(response.header['Cache-Control']).to eq("max-age=60, private")
+ expect(response.header['Cache-Control']).to eq("max-age=60, private, must-revalidate, stale-while-revalidate=60, stale-if-error=300, s-maxage=60")
end
end
diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb
index 9227c7dd70a..3dfc22927cf 100644
--- a/spec/controllers/projects/graphs_controller_spec.rb
+++ b/spec/controllers/projects/graphs_controller_spec.rb
@@ -90,7 +90,7 @@ RSpec.describe Projects::GraphsController do
let(:target_id) { 'p_analytics_repo' }
end
- it_behaves_like 'Snowplow event tracking' do
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
subject do
sign_in(user)
get :charts, params: request_params, format: :html
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index c48be8efb1b..0c3795540e0 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -1107,6 +1107,46 @@ RSpec.describe Projects::IssuesController do
end
end
+ context 'when create service return an unrecoverable error with http_status' do
+ let(:http_status) { 403 }
+
+ before do
+ allow_next_instance_of(::Issues::CreateService) do |create_service|
+ allow(create_service).to receive(:execute).and_return(
+ ServiceResponse.error(message: 'unrecoverable error', http_status: http_status)
+ )
+ end
+ end
+
+ it 'renders 403 and logs the error' do
+ expect(Gitlab::AppLogger).to receive(:warn).with(
+ message: 'Cannot create issue',
+ errors: ['unrecoverable error'],
+ http_status: http_status
+ )
+
+ post_new_issue
+
+ expect(response).to have_gitlab_http_status :forbidden
+ end
+
+ context 'when no render method is found for the returned http_status' do
+ let(:http_status) { nil }
+
+ it 'renders 404 and logs the error' do
+ expect(Gitlab::AppLogger).to receive(:warn).with(
+ message: 'Cannot create issue',
+ errors: ['unrecoverable error'],
+ http_status: http_status
+ )
+
+ post_new_issue
+
+ expect(response).to have_gitlab_http_status :not_found
+ end
+ end
+ end
+
it 'creates the issue successfully', :aggregate_failures do
issue = post_new_issue
@@ -1661,13 +1701,27 @@ RSpec.describe Projects::IssuesController do
end
it 'allows CSV export' do
- expect(IssuableExportCsvWorker).to receive(:perform_async).with(:issue, viewer.id, project.id, anything)
+ expect(IssuableExportCsvWorker).to receive(:perform_async)
+ .with(:issue, viewer.id, project.id, hash_including('issue_types' => Issue::TYPES_FOR_LIST))
request_csv
expect(response).to redirect_to(project_issues_path(project))
expect(controller).to set_flash[:notice].to match(/\AYour CSV export has started/i)
end
+
+ context 'when work_items is disabled' do
+ before do
+ stub_feature_flags(work_items: false)
+ end
+
+ it 'does not include tasks in CSV export' do
+ expect(IssuableExportCsvWorker).to receive(:perform_async)
+ .with(:issue, viewer.id, project.id, hash_including('issue_types' => Issue::TYPES_FOR_LIST.excluding('task')))
+
+ request_csv
+ end
+ end
end
context 'when not logged in' do
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 9c4baeae836..a41abd8c16d 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -77,7 +77,8 @@ RSpec.describe Projects::MergeRequestsController do
merge_request,
'json',
diff_head: true,
- view: 'inline'))
+ view: 'inline',
+ w: '0'))
end
context 'when diff files were cleaned' do
@@ -498,7 +499,7 @@ RSpec.describe Projects::MergeRequestsController do
context 'when a squash commit message is passed' do
let(:message) { 'My custom squash commit message' }
- it 'passes the same message to SquashService', :sidekiq_might_not_need_inline do
+ it 'passes the same message to SquashService', :sidekiq_inline do
params = { squash: '1',
squash_commit_message: message,
sha: merge_request.diff_head_sha }
@@ -790,7 +791,7 @@ RSpec.describe Projects::MergeRequestsController do
context 'with private builds' do
context 'for the target project member' do
- it 'does not respond with serialized pipelines', :sidekiq_might_not_need_inline do
+ it 'does not respond with serialized pipelines' do
expect(json_response['pipelines']).to be_empty
expect(json_response['count']['all']).to eq(0)
expect(response).to include_pagination_headers
@@ -800,7 +801,7 @@ RSpec.describe Projects::MergeRequestsController do
context 'for the source project member' do
let(:user) { fork_user }
- it 'responds with serialized pipelines', :sidekiq_might_not_need_inline do
+ it 'responds with serialized pipelines' do
expect(json_response['pipelines']).to be_present
expect(json_response['count']['all']).to eq(1)
expect(response).to include_pagination_headers
@@ -816,7 +817,7 @@ RSpec.describe Projects::MergeRequestsController do
end
context 'for the target project member' do
- it 'does not respond with serialized pipelines', :sidekiq_might_not_need_inline do
+ it 'does not respond with serialized pipelines' do
expect(json_response['pipelines']).to be_present
expect(json_response['count']['all']).to eq(1)
expect(response).to include_pagination_headers
@@ -826,7 +827,7 @@ RSpec.describe Projects::MergeRequestsController do
context 'for the source project member' do
let(:user) { fork_user }
- it 'responds with serialized pipelines', :sidekiq_might_not_need_inline do
+ it 'responds with serialized pipelines' do
expect(json_response['pipelines']).to be_present
expect(json_response['count']['all']).to eq(1)
expect(response).to include_pagination_headers
@@ -1855,13 +1856,13 @@ RSpec.describe Projects::MergeRequestsController do
create(:merge_request, source_project: forked, target_project: project, target_branch: 'master', head_pipeline: pipeline)
end
- it 'links to the environment on that project', :sidekiq_might_not_need_inline do
+ it 'links to the environment on that project' do
get_ci_environments_status
expect(json_response.first['url']).to match(/#{forked.full_path}/)
end
- context "when environment_target is 'merge_commit'", :sidekiq_might_not_need_inline do
+ context "when environment_target is 'merge_commit'" do
it 'returns nothing' do
get_ci_environments_status(environment_target: 'merge_commit')
@@ -1891,13 +1892,13 @@ RSpec.describe Projects::MergeRequestsController do
# we're trying to reduce the overall number of queries for this method.
# set a hard limit for now. https://gitlab.com/gitlab-org/gitlab-foss/issues/52287
- it 'keeps queries in check', :sidekiq_might_not_need_inline do
+ it 'keeps queries in check' do
control_count = ActiveRecord::QueryRecorder.new { get_ci_environments_status }.count
expect(control_count).to be <= 137
end
- it 'has no N+1 SQL issues for environments', :request_store, :sidekiq_might_not_need_inline, retry: 0 do
+ it 'has no N+1 SQL issues for environments', :request_store, retry: 0 do
# First run to insert test data from lets, which does take up some 30 queries
get_ci_environments_status
@@ -2144,7 +2145,7 @@ RSpec.describe Projects::MergeRequestsController do
sign_in(fork_owner)
end
- it 'returns 200', :sidekiq_might_not_need_inline do
+ it 'returns 200' do
expect_rebase_worker_for(fork_owner)
post_rebase
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index b62353784b3..28da7eff8fc 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -44,6 +44,26 @@ RSpec.describe Projects::MilestonesController do
end
end
+ describe "#create" do
+ it 'does not redirect without redirect_path' do
+ post :create, params: { namespace_id: project.namespace.id, project_id: project.id, milestone: { title: 'test' } }
+
+ expect(response).to redirect_to(project_milestone_path(project, project.milestones.last))
+ end
+
+ it 'redirects when given a redirect_path' do
+ post :create, params: { namespace_id: project.namespace.id, project_id: project.id, redirect_path: 'new_release', milestone: { title: 'test' } }
+
+ expect(response).to redirect_to(new_project_release_path(project))
+ end
+
+ it 'will not redirect when given a redirect_path with an error' do
+ post :create, params: { namespace_id: project.namespace.id, project_id: project.id, redirect_path: 'new_release', milestone: { title: nil } }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
describe "#index" do
context "as html" do
def render_index(project:, page:, search_title: '')
diff --git a/spec/controllers/projects/pages_domains_controller_spec.rb b/spec/controllers/projects/pages_domains_controller_spec.rb
index 691508d1e14..b29bbef0c40 100644
--- a/spec/controllers/projects/pages_domains_controller_spec.rb
+++ b/spec/controllers/projects/pages_domains_controller_spec.rb
@@ -63,9 +63,15 @@ RSpec.describe Projects::PagesDomainsController do
describe 'POST create' do
it "creates a new pages domain" do
- expect do
- post(:create, params: request_params.merge(pages_domain: pages_domain_params))
- end.to change { PagesDomain.count }.by(1)
+ expect { post(:create, params: request_params.merge(pages_domain: pages_domain_params)) }
+ .to change { PagesDomain.count }.by(1)
+ .and publish_event(PagesDomains::PagesDomainCreatedEvent)
+ .with(
+ project_id: project.id,
+ namespace_id: project.namespace.id,
+ root_namespace_id: project.root_namespace.id,
+ domain: pages_domain_params[:domain]
+ )
created_domain = PagesDomain.reorder(:id).last
@@ -106,6 +112,17 @@ RSpec.describe Projects::PagesDomainsController do
end.to change { pages_domain.reload.certificate }.to(pages_domain_params[:user_provided_certificate])
end
+ it 'publishes PagesDomainUpdatedEvent event' do
+ expect { patch(:update, params: params) }
+ .to publish_event(PagesDomains::PagesDomainUpdatedEvent)
+ .with(
+ project_id: project.id,
+ namespace_id: project.namespace.id,
+ root_namespace_id: project.root_namespace.id,
+ domain: pages_domain.domain
+ )
+ end
+
it 'redirects to the project page' do
patch(:update, params: params)
@@ -134,6 +151,11 @@ RSpec.describe Projects::PagesDomainsController do
expect(response).to render_template('show')
end
+
+ it 'does not publish PagesDomainUpdatedEvent event' do
+ expect { patch(:update, params: params) }
+ .to not_publish_event(PagesDomains::PagesDomainUpdatedEvent)
+ end
end
context 'when parameters include the domain' do
@@ -197,9 +219,15 @@ RSpec.describe Projects::PagesDomainsController do
describe 'DELETE destroy' do
it "deletes the pages domain" do
- expect do
- delete(:destroy, params: request_params.merge(id: pages_domain.domain))
- end.to change { PagesDomain.count }.by(-1)
+ expect { delete(:destroy, params: request_params.merge(id: pages_domain.domain)) }
+ .to change(PagesDomain, :count).by(-1)
+ .and publish_event(PagesDomains::PagesDomainDeletedEvent)
+ .with(
+ project_id: project.id,
+ namespace_id: project.namespace.id,
+ root_namespace_id: project.root_namespace.id,
+ domain: pages_domain.domain
+ )
expect(response).to redirect_to(project_pages_path(project))
end
@@ -216,6 +244,17 @@ RSpec.describe Projects::PagesDomainsController do
expect(response).to redirect_to(project_pages_domain_path(project, pages_domain))
end
+ it 'publishes PagesDomainUpdatedEvent event' do
+ expect { subject }
+ .to publish_event(PagesDomains::PagesDomainUpdatedEvent)
+ .with(
+ project_id: project.id,
+ namespace_id: project.namespace.id,
+ root_namespace_id: project.root_namespace.id,
+ domain: pages_domain.domain
+ )
+ end
+
it 'removes certificate' do
expect do
subject
@@ -245,6 +284,11 @@ RSpec.describe Projects::PagesDomainsController do
expect(pages_domain.key).to be_present
end
+ it 'does not publish PagesDomainUpdatedEvent event' do
+ expect { subject }
+ .to not_publish_event(PagesDomains::PagesDomainUpdatedEvent)
+ end
+
it 'redirects to show page with a flash message' do
subject
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index b9acaf65892..6e2de0c4d57 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -859,7 +859,7 @@ RSpec.describe Projects::PipelinesController do
let(:target_id) { ['p_analytics_pipelines', tab[:event]] }
end
- it_behaves_like 'Snowplow event tracking' do
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' 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] } }
diff --git a/spec/controllers/projects/prometheus/metrics_controller_spec.rb b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
index cd195b95100..327651b2058 100644
--- a/spec/controllers/projects/prometheus/metrics_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Projects::Prometheus::MetricsController do
let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:prometheus_project) }
+ let_it_be(:project) { create(:project, :with_prometheus_integration) }
let(:prometheus_adapter) { double('prometheus_adapter', can_query?: true) }
diff --git a/spec/controllers/projects/protected_branches_controller_spec.rb b/spec/controllers/projects/protected_branches_controller_spec.rb
index 4996bd90005..14728618633 100644
--- a/spec/controllers/projects/protected_branches_controller_spec.rb
+++ b/spec/controllers/projects/protected_branches_controller_spec.rb
@@ -4,26 +4,23 @@ require('spec_helper')
RSpec.describe Projects::ProtectedBranchesController do
let_it_be_with_reload(:project) { create(:project, :repository) }
- let_it_be(:maintainer) { create(:user) }
+ let_it_be_with_reload(:empty_project) { create(:project, :empty_repo) }
+ let_it_be(:maintainer) { create(:user, maintainer_projects: [project, empty_project]) }
let(:protected_branch) { create(:protected_branch, project: project) }
let(:project_params) { { namespace_id: project.namespace.to_param, project_id: project } }
let(:base_params) { project_params.merge(id: protected_branch.id) }
let(:user) { maintainer }
- before_all do
- project.add_maintainer(maintainer)
- end
-
before do
sign_in(user)
end
describe "GET #index" do
- let(:project) { create(:project_empty_repo, :public) }
+ it 'redirects to repository settings' do
+ get(:index, params: { namespace_id: empty_project.namespace.to_param, project_id: empty_project })
- it "redirects empty repo to projects page" do
- get(:index, params: { namespace_id: project.namespace.to_param, project_id: project })
+ expect(response).to redirect_to(project_settings_repository_path(empty_project))
end
end
@@ -42,6 +39,18 @@ RSpec.describe Projects::ProtectedBranchesController do
end.to change(ProtectedBranch, :count).by(1)
end
+ context 'when repository is empty' do
+ let(:project) { empty_project }
+
+ it 'creates the protected branch rule' do
+ expect do
+ post(:create, params: project_params.merge(protected_branch: create_params))
+ end.to change(ProtectedBranch, :count).by(1)
+
+ expect(response).to have_gitlab_http_status(:found)
+ end
+ end
+
context 'when a policy restricts rule creation' do
it "prevents creation of the protected branch rule" do
disallow(:create_protected_branch, an_instance_of(ProtectedBranch))
@@ -63,6 +72,17 @@ RSpec.describe Projects::ProtectedBranchesController do
expect(json_response["name"]).to eq('new_name')
end
+ context 'when repository is empty' do
+ let(:project) { empty_project }
+
+ it 'updates the protected branch rule' do
+ put(:update, params: base_params.merge(protected_branch: update_params))
+
+ expect(protected_branch.reload.name).to eq('new_name')
+ expect(json_response["name"]).to eq('new_name')
+ end
+ end
+
context 'when a policy restricts rule update' do
it "prevents update of the protected branch rule" do
disallow(:update_protected_branch, protected_branch)
@@ -83,6 +103,16 @@ RSpec.describe Projects::ProtectedBranchesController do
expect { ProtectedBranch.find(protected_branch.id) }.to raise_error(ActiveRecord::RecordNotFound)
end
+ context 'when repository is empty' do
+ let(:project) { empty_project }
+
+ it 'deletes the protected branch rule' do
+ delete(:destroy, params: base_params)
+
+ expect { ProtectedBranch.find(protected_branch.id) }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+
context 'when a policy restricts rule deletion' do
it "prevents deletion of the protected branch rule" do
disallow(:destroy_protected_branch, protected_branch)
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index e0d88fa799f..1c9aafacbd9 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -247,9 +247,11 @@ RSpec.describe Projects::RawController do
sign_in create(:user)
request_file
- expect(response.cache_control[:public]).to eq(true)
- expect(response.cache_control[:max_age]).to eq(60)
+ expect(response.headers['ETag']).to eq("\"bdd5aa537c1e1f6d1b66de4bac8a6132\"")
expect(response.cache_control[:no_store]).to be_nil
+ expect(response.header['Cache-Control']).to eq(
+ 'max-age=60, public, must-revalidate, stale-while-revalidate=60, stale-if-error=300, s-maxage=60'
+ )
end
context 'when a public project has private repo' do
@@ -260,7 +262,9 @@ RSpec.describe Projects::RawController do
sign_in user
request_file
- expect(response.header['Cache-Control']).to include('max-age=60, private')
+ expect(response.header['Cache-Control']).to eq(
+ 'max-age=60, private, must-revalidate, stale-while-revalidate=60, stale-if-error=300, s-maxage=60'
+ )
end
end
@@ -274,6 +278,21 @@ RSpec.describe Projects::RawController do
expect(response).to have_gitlab_http_status(:not_modified)
end
end
+
+ context 'when improve_blobs_cache_headers disabled' do
+ before do
+ stub_feature_flags(improve_blobs_cache_headers: false)
+ end
+
+ it 'uses weak etags with a restricted set of headers' do
+ sign_in create(:user)
+ request_file
+
+ expect(response.headers['ETag']).to eq("W/\"bdd5aa537c1e1f6d1b66de4bac8a6132\"")
+ expect(response.cache_control[:no_store]).to be_nil
+ expect(response.header['Cache-Control']).to eq('max-age=60, public')
+ end
+ end
end
end
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index b30610d98d7..b5797e374f3 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -231,7 +231,7 @@ RSpec.describe ProjectsController do
end
context "project with broken repo" do
- let_it_be(:empty_project) { create(:project_broken_repo, :public) }
+ let_it_be(:empty_project) { create(:project, :public) }
before do
sign_in(user)
@@ -246,8 +246,6 @@ RSpec.describe ProjectsController do
end
it "renders the empty project view" do
- allow(Project).to receive(:repo).and_raise(Gitlab::Git::Repository::NoRepository)
-
expect(response).to render_template('projects/no_repo')
end
end
@@ -299,14 +297,16 @@ RSpec.describe ProjectsController do
end
it "renders files even with invalid license" do
+ invalid_license = ::Gitlab::Git::DeclaredLicense.new(key: 'woozle', name: 'woozle wuzzle')
+
controller.instance_variable_set(:@project, public_project)
- expect(public_project.repository).to receive(:license_key).and_return('woozle wuzzle').at_least(:once)
+ expect(public_project.repository).to receive(:license).and_return(invalid_license).at_least(:once)
get_show
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template('_files')
- expect(response.body).to have_content('LICENSE') # would be 'MIT license' if stub not works
+ expect(response.body).to have_content('woozle wuzzle')
end
describe 'tracking events', :snowplow do
@@ -1233,26 +1233,6 @@ RSpec.describe ProjectsController do
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 14e88d469ba..a3b246fbedd 100644
--- a/spec/controllers/registrations/welcome_controller_spec.rb
+++ b/spec/controllers/registrations/welcome_controller_spec.rb
@@ -31,7 +31,6 @@ RSpec.describe Registrations::WelcomeController do
context 'when role and setup_for_company is set' do
before do
- stub_feature_flags(about_your_company_registration_flow: false)
user.update!(setup_for_company: false)
sign_in(user)
end
@@ -61,10 +60,6 @@ RSpec.describe Registrations::WelcomeController do
end
describe '#update' do
- before do
- stub_feature_flags(about_your_company_registration_flow: false)
- end
-
subject(:update) do
patch :update, params: { user: { role: 'software_developer', setup_for_company: 'false' } }
end
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index 4131bd148da..7ab66b04a6e 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -218,7 +218,7 @@ RSpec.describe SearchController do
end
end
- it_behaves_like 'Snowplow event tracking' do
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
subject { get :show, params: { group_id: namespace.id, scope: 'blobs', search: 'term' } }
let(:project) { nil }
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 0e0770fb94c..80cf060bc45 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -399,18 +399,30 @@ RSpec.describe SessionsController do
end
context 'when OTP is invalid' do
- before do
- authenticate_2fa(otp_attempt: 'invalid')
- end
+ let(:code) { 'invalid' }
it 'does not authenticate' do
+ authenticate_2fa(otp_attempt: code)
+
expect(subject.current_user).not_to eq user
end
it 'warns about invalid OTP code' do
+ authenticate_2fa(otp_attempt: code)
+
expect(controller).to set_flash.now[:alert]
.to(/Invalid two-factor code/)
end
+
+ it 'sends an email to the user informing about the attempt to sign in with a wrong OTP code' do
+ controller.request.remote_addr = '1.2.3.4'
+
+ expect_next_instance_of(NotificationService) do |instance|
+ expect(instance).to receive(:two_factor_otp_attempt_failed).with(user, '1.2.3.4')
+ end
+
+ authenticate_2fa(otp_attempt: code)
+ end
end
end
diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb
index c27e58634f6..e128db8d1c1 100644
--- a/spec/controllers/uploads_controller_spec.rb
+++ b/spec/controllers/uploads_controller_spec.rb
@@ -216,7 +216,7 @@ RSpec.describe UploadsController do
end
context 'for PDF files' do
- let(:filename) { 'git-cheat-sheet.pdf' }
+ let(:filename) { 'sample.pdf' }
let(:expected_disposition) { 'inline;' }
let(:note) { create(:note, :with_pdf_attachment, project: project) }