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/projects')
-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
16 files changed, 491 insertions, 158 deletions
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