summaryrefslogtreecommitdiff
path: root/spec/controllers/projects
diff options
context:
space:
mode:
Diffstat (limited to 'spec/controllers/projects')
-rw-r--r--spec/controllers/projects/alert_management_controller_spec.rb2
-rw-r--r--spec/controllers/projects/alerting/notifications_controller_spec.rb109
-rw-r--r--spec/controllers/projects/artifacts_controller_spec.rb7
-rw-r--r--spec/controllers/projects/autocomplete_sources_controller_spec.rb2
-rw-r--r--spec/controllers/projects/avatars_controller_spec.rb2
-rw-r--r--spec/controllers/projects/badges_controller_spec.rb42
-rw-r--r--spec/controllers/projects/blame_controller_spec.rb2
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb18
-rw-r--r--spec/controllers/projects/boards_controller_spec.rb2
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb105
-rw-r--r--spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb146
-rw-r--r--spec/controllers/projects/ci/lints_controller_spec.rb2
-rw-r--r--spec/controllers/projects/clusters/applications_controller_spec.rb2
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb9
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb2
-rw-r--r--spec/controllers/projects/commits_controller_spec.rb2
-rw-r--r--spec/controllers/projects/compare_controller_spec.rb2
-rw-r--r--spec/controllers/projects/cycle_analytics/events_controller_spec.rb2
-rw-r--r--spec/controllers/projects/cycle_analytics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/deploy_keys_controller_spec.rb2
-rw-r--r--spec/controllers/projects/deployments_controller_spec.rb2
-rw-r--r--spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb2
-rw-r--r--spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb2
-rw-r--r--spec/controllers/projects/discussions_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments/prometheus_api_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments/sample_metrics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb59
-rw-r--r--spec/controllers/projects/error_tracking/projects_controller_spec.rb2
-rw-r--r--spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb2
-rw-r--r--spec/controllers/projects/error_tracking_controller_spec.rb2
-rw-r--r--spec/controllers/projects/find_file_controller_spec.rb2
-rw-r--r--spec/controllers/projects/forks_controller_spec.rb2
-rw-r--r--spec/controllers/projects/grafana_api_controller_spec.rb2
-rw-r--r--spec/controllers/projects/graphs_controller_spec.rb51
-rw-r--r--spec/controllers/projects/group_links_controller_spec.rb2
-rw-r--r--spec/controllers/projects/hooks_controller_spec.rb2
-rw-r--r--spec/controllers/projects/import/jira_controller_spec.rb245
-rw-r--r--spec/controllers/projects/imports_controller_spec.rb2
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb11
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb196
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb2
-rw-r--r--spec/controllers/projects/logs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/mattermosts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/conflicts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/content_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/drafts_controller_spec.rb455
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb34
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb4
-rw-r--r--spec/controllers/projects/mirrors_controller_spec.rb2
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb8
-rw-r--r--spec/controllers/projects/pages_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pages_domains_controller_spec.rb2
-rw-r--r--spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pipeline_schedules_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb115
-rw-r--r--spec/controllers/projects/pipelines_settings_controller_spec.rb2
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb2
-rw-r--r--spec/controllers/projects/prometheus/alerts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/prometheus/metrics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/protected_branches_controller_spec.rb2
-rw-r--r--spec/controllers/projects/protected_tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb2
-rw-r--r--spec/controllers/projects/refs_controller_spec.rb4
-rw-r--r--spec/controllers/projects/registry/repositories_controller_spec.rb4
-rw-r--r--spec/controllers/projects/registry/tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects/releases/evidences_controller_spec.rb63
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb2
-rw-r--r--spec/controllers/projects/repositories_controller_spec.rb2
-rw-r--r--spec/controllers/projects/runners_controller_spec.rb2
-rw-r--r--spec/controllers/projects/serverless/functions_controller_spec.rb2
-rw-r--r--spec/controllers/projects/service_hook_logs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/services_controller_spec.rb42
-rw-r--r--spec/controllers/projects/settings/access_tokens_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/integrations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/operations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/repository_controller_spec.rb2
-rw-r--r--spec/controllers/projects/snippets_controller_spec.rb2
-rw-r--r--spec/controllers/projects/stages_controller_spec.rb2
-rw-r--r--spec/controllers/projects/starrers_controller_spec.rb2
-rw-r--r--spec/controllers/projects/static_site_editor_controller_spec.rb2
-rw-r--r--spec/controllers/projects/tags/releases_controller_spec.rb4
-rw-r--r--spec/controllers/projects/tags_controller_spec.rb68
-rw-r--r--spec/controllers/projects/templates_controller_spec.rb2
-rw-r--r--spec/controllers/projects/todos_controller_spec.rb2
-rw-r--r--spec/controllers/projects/tree_controller_spec.rb2
-rw-r--r--spec/controllers/projects/uploads_controller_spec.rb2
-rw-r--r--spec/controllers/projects/usage_ping_controller_spec.rb2
-rw-r--r--spec/controllers/projects/variables_controller_spec.rb2
-rw-r--r--spec/controllers/projects/web_ide_terminals_controller_spec.rb304
-rw-r--r--spec/controllers/projects/wikis_controller_spec.rb282
93 files changed, 1742 insertions, 779 deletions
diff --git a/spec/controllers/projects/alert_management_controller_spec.rb b/spec/controllers/projects/alert_management_controller_spec.rb
index b84376db33d..6a1952f949b 100644
--- a/spec/controllers/projects/alert_management_controller_spec.rb
+++ b/spec/controllers/projects/alert_management_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AlertManagementController do
+RSpec.describe Projects::AlertManagementController do
let_it_be(:project) { create(:project) }
let_it_be(:role) { :developer }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/alerting/notifications_controller_spec.rb b/spec/controllers/projects/alerting/notifications_controller_spec.rb
index 9d26c2278b1..33fd73c762a 100644
--- a/spec/controllers/projects/alerting/notifications_controller_spec.rb
+++ b/spec/controllers/projects/alerting/notifications_controller_spec.rb
@@ -2,90 +2,101 @@
require 'spec_helper'
-describe Projects::Alerting::NotificationsController do
+RSpec.describe Projects::Alerting::NotificationsController do
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
describe 'POST #create' do
- let(:service_response) { ServiceResponse.success }
- let(:notify_service) { instance_double(Projects::Alerting::NotifyService, execute: service_response) }
-
around do |example|
ForgeryProtection.with_forgery_protection { example.run }
end
- before do
- allow(Projects::Alerting::NotifyService).to receive(:new).and_return(notify_service)
- end
+ shared_examples 'process alert payload' do |notify_service_class|
+ let(:service_response) { ServiceResponse.success }
+ let(:notify_service) { instance_double(notify_service_class, execute: service_response) }
- def make_request(body = {})
- post :create, params: project_params, body: body.to_json, as: :json
- end
+ before do
+ allow(notify_service_class).to receive(:new).and_return(notify_service)
+ end
- context 'when notification service succeeds' do
- let(:payload) do
- {
- title: 'Alert title',
- hosts: 'https://gitlab.com'
- }
+ def make_request
+ post :create, params: project_params, body: payload.to_json, as: :json
end
- let(:permitted_params) { ActionController::Parameters.new(payload).permit! }
+ context 'when notification service succeeds' do
+ let(:permitted_params) { ActionController::Parameters.new(payload).permit! }
- it 'responds with ok' do
- make_request
+ it 'responds with ok' do
+ make_request
- expect(response).to have_gitlab_http_status(:ok)
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ end
- it 'does not pass excluded parameters to the notify service' do
- make_request(payload)
+ it 'does not pass excluded parameters to the notify service' do
+ make_request
- expect(Projects::Alerting::NotifyService)
- .to have_received(:new)
- .with(project, nil, permitted_params)
+ expect(notify_service_class)
+ .to have_received(:new)
+ .with(project, nil, permitted_params)
+ end
end
- end
- context 'when notification service fails' do
- let(:service_response) { ServiceResponse.error(message: 'Unauthorized', http_status: :unauthorized) }
+ context 'when notification service fails' do
+ let(:service_response) { ServiceResponse.error(message: 'Unauthorized', http_status: :unauthorized) }
- it 'responds with the service response' do
- make_request
+ it 'responds with the service response' do
+ make_request
- expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
end
- end
- context 'bearer token' do
- context 'when set' do
- it 'extracts bearer token' do
- request.headers['HTTP_AUTHORIZATION'] = 'Bearer some token'
+ context 'bearer token' do
+ context 'when set' do
+ it 'extracts bearer token' do
+ request.headers['HTTP_AUTHORIZATION'] = 'Bearer some token'
- expect(notify_service).to receive(:execute).with('some token')
+ expect(notify_service).to receive(:execute).with('some token')
- make_request
- end
+ make_request
+ end
- it 'pass nil if cannot extract a non-bearer token' do
- request.headers['HTTP_AUTHORIZATION'] = 'some token'
+ it 'pass nil if cannot extract a non-bearer token' do
+ request.headers['HTTP_AUTHORIZATION'] = 'some token'
- expect(notify_service).to receive(:execute).with(nil)
+ expect(notify_service).to receive(:execute).with(nil)
- make_request
+ make_request
+ end
end
- end
- context 'when missing' do
- it 'passes nil' do
- expect(notify_service).to receive(:execute).with(nil)
+ context 'when missing' do
+ it 'passes nil' do
+ expect(notify_service).to receive(:execute).with(nil)
- make_request
+ make_request
+ end
end
end
end
+
+ context 'generic alert payload' do
+ it_behaves_like 'process alert payload', Projects::Alerting::NotifyService do
+ let(:payload) { { title: 'Alert title' } }
+ end
+ end
+
+ context 'Prometheus alert payload' do
+ include PrometheusHelpers
+
+ it_behaves_like 'process alert payload', Projects::Prometheus::Alerts::NotifyService do
+ let(:payload) { prometheus_alert_payload }
+ end
+ end
end
+ private
+
def project_params(opts = {})
opts.reverse_merge(namespace_id: project.namespace, project_id: project)
end
diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb
index 4c815a5b40c..69ab9873b90 100644
--- a/spec/controllers/projects/artifacts_controller_spec.rb
+++ b/spec/controllers/projects/artifacts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ArtifactsController do
+RSpec.describe Projects::ArtifactsController do
include RepoHelpers
let(:user) { project.owner }
@@ -371,10 +371,9 @@ describe Projects::ArtifactsController do
end
context 'when the artifact is zip' do
- let!(:artifact) { create(:ci_job_artifact, :lsif, job: job, file_path: Rails.root.join("spec/fixtures/#{file_name}")) }
+ let!(:artifact) { create(:ci_job_artifact, :lsif, job: job) }
let(:path) { 'lsif/main.go.json' }
- let(:file_name) { 'lsif.json.zip' }
- let(:archive_matcher) { file_name }
+ let(:archive_matcher) { 'lsif.json.zip' }
let(:query_params) { super().merge(file_type: :lsif, path: path) }
it_behaves_like 'a valid file' do
diff --git a/spec/controllers/projects/autocomplete_sources_controller_spec.rb b/spec/controllers/projects/autocomplete_sources_controller_spec.rb
index d35192b2ccb..865b31a28d7 100644
--- a/spec/controllers/projects/autocomplete_sources_controller_spec.rb
+++ b/spec/controllers/projects/autocomplete_sources_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AutocompleteSourcesController do
+RSpec.describe Projects::AutocompleteSourcesController do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, namespace: group) }
let_it_be(:issue) { create(:issue, project: project) }
diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb
index 54c2397625f..16e9c845307 100644
--- a/spec/controllers/projects/avatars_controller_spec.rb
+++ b/spec/controllers/projects/avatars_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AvatarsController do
+RSpec.describe Projects::AvatarsController do
let_it_be(:project) { create(:project, :repository) }
before do
diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb
index 4ae29ba7f54..7e7a630921f 100644
--- a/spec/controllers/projects/badges_controller_spec.rb
+++ b/spec/controllers/projects/badges_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BadgesController do
+RSpec.describe Projects::BadgesController do
let(:project) { pipeline.project }
let!(:pipeline) { create(:ci_empty_pipeline) }
let(:user) { create(:user) }
@@ -54,7 +54,7 @@ describe Projects::BadgesController do
context 'when style param is set to `flat`' do
it 'renders the `flat` badge layout' do
- get_badge(badge_type, 'flat')
+ get_badge(badge_type, style: 'flat')
expect(response).to render_template('projects/badges/badge')
end
@@ -62,7 +62,7 @@ describe Projects::BadgesController do
context 'when style param is set to an invalid type' do
it 'renders the `flat` (default) badge layout' do
- get_badge(badge_type, 'xxx')
+ get_badge(badge_type, style: 'xxx')
expect(response).to render_template('projects/badges/badge')
end
@@ -70,7 +70,7 @@ describe Projects::BadgesController do
context 'when style param is set to `flat-square`' do
it 'renders the `flat-square` badge layout' do
- get_badge(badge_type, 'flat-square')
+ get_badge(badge_type, style: 'flat-square')
expect(response).to render_template('projects/badges/badge_flat-square')
end
@@ -102,12 +102,37 @@ describe Projects::BadgesController do
end
it 'defaults to project permissions' do
- get_badge(:coverage)
+ get_badge(badge_type)
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
+
+ context 'customization' do
+ render_views
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ end
+
+ context 'when key_text param is used' do
+ it 'sets custom key text' do
+ get_badge(badge_type, key_text: 'custom key text')
+
+ expect(response.body).to include('custom key text')
+ end
+ end
+
+ context 'when key_width param is used' do
+ it 'sets custom key width' do
+ get_badge(badge_type, key_width: '123')
+
+ expect(response.body).to include('123')
+ end
+ end
+ end
end
describe '#pipeline' do
@@ -118,13 +143,12 @@ describe Projects::BadgesController do
it_behaves_like 'a badge resource', :coverage
end
- def get_badge(badge, style = nil)
+ def get_badge(badge, args = {})
params = {
namespace_id: project.namespace.to_param,
project_id: project,
- ref: pipeline.ref,
- style: style
- }
+ ref: pipeline.ref
+ }.merge(args.slice(:style, :key_text, :key_width))
get badge, params: params, format: :svg
end
diff --git a/spec/controllers/projects/blame_controller_spec.rb b/spec/controllers/projects/blame_controller_spec.rb
index ac8394e3cd4..bf475f6135a 100644
--- a/spec/controllers/projects/blame_controller_spec.rb
+++ b/spec/controllers/projects/blame_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BlameController do
+RSpec.describe Projects::BlameController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index ad04c6e61e8..9fee97f938c 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BlobController do
+RSpec.describe Projects::BlobController do
include ProjectForksHelper
let(:project) { create(:project, :public, :repository) }
@@ -378,6 +378,22 @@ describe Projects::BlobController do
expect(response).to redirect_to(after_delete_path)
end
+
+ context 'when a validation failure occurs' do
+ let(:failure_path) { project_blob_path(project, default_params[:id]) }
+
+ render_views
+
+ it 'redirects to a valid page' do
+ expect_next_instance_of(Files::DeleteService) do |instance|
+ expect(instance).to receive(:validate!).and_raise(Commits::CreateService::ValidationError, "validation error")
+ end
+
+ delete :destroy, params: default_params
+
+ expect(response).to redirect_to(failure_path)
+ end
+ end
end
context 'if deleted file is the last one in a subdirectory' do
diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb
index 6634801939b..dad932f9cdf 100644
--- a/spec/controllers/projects/boards_controller_spec.rb
+++ b/spec/controllers/projects/boards_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BoardsController do
+RSpec.describe Projects::BoardsController do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index 174d8904481..625fc5bddda 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -2,14 +2,13 @@
require 'spec_helper'
-describe Projects::BranchesController do
+RSpec.describe Projects::BranchesController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:developer) { create(:user) }
before do
- project.add_maintainer(user)
- project.add_developer(user)
+ project.add_developer(developer)
allow(project).to receive(:branches).and_return(['master', 'foo/bar/baz'])
allow(project).to receive(:tags).and_return(['v1.0.0', 'v2.0.0'])
@@ -21,7 +20,7 @@ describe Projects::BranchesController do
context "on creation of a new branch" do
before do
- sign_in(user)
+ sign_in(developer)
post :create,
params: {
@@ -80,7 +79,7 @@ describe Projects::BranchesController do
let(:issue) { create(:issue, project: project) }
before do
- sign_in(user)
+ sign_in(developer)
end
it 'redirects' do
@@ -97,7 +96,7 @@ describe Projects::BranchesController do
end
it 'posts a system note' do
- expect(SystemNoteService).to receive(:new_issue_branch).with(issue, project, user, "1-feature-branch", branch_project: project)
+ expect(SystemNoteService).to receive(:new_issue_branch).with(issue, project, developer, "1-feature-branch", branch_project: project)
post :create,
params: {
@@ -136,14 +135,14 @@ describe Projects::BranchesController do
context 'user can update issue' do
before do
- confidential_issue_project.add_reporter(user)
+ confidential_issue_project.add_reporter(developer)
end
context 'issue is under the specified project' do
let(:issue) { create(:issue, project: confidential_issue_project) }
it 'posts a system note' do
- expect(SystemNoteService).to receive(:new_issue_branch).with(issue, confidential_issue_project, user, "1-feature-branch", branch_project: project)
+ expect(SystemNoteService).to receive(:new_issue_branch).with(issue, confidential_issue_project, developer, "1-feature-branch", branch_project: project)
create_branch_with_confidential_issue_project
end
@@ -264,7 +263,7 @@ describe Projects::BranchesController do
describe 'POST create with JSON format' do
before do
- sign_in(user)
+ sign_in(developer)
end
context 'with valid params' do
@@ -305,7 +304,7 @@ describe Projects::BranchesController do
render_views
before do
- sign_in(user)
+ sign_in(developer)
end
it 'returns 303' do
@@ -325,7 +324,7 @@ describe Projects::BranchesController do
render_views
before do
- sign_in(user)
+ sign_in(developer)
post :destroy,
format: format,
@@ -436,7 +435,7 @@ describe Projects::BranchesController do
context 'when user is allowed to push' do
before do
- sign_in(user)
+ sign_in(developer)
end
it 'redirects to branches' do
@@ -454,7 +453,7 @@ describe Projects::BranchesController do
context 'when user is not allowed to push' do
before do
- sign_in(developer)
+ sign_in(user)
end
it 'responds with status 404' do
@@ -469,7 +468,7 @@ describe Projects::BranchesController do
render_views
before do
- sign_in(user)
+ sign_in(developer)
end
context 'when rendering a JSON format' do
@@ -487,6 +486,82 @@ describe Projects::BranchesController do
end
end
+ context 'when a branch has multiple pipelines' do
+ it 'chooses the latest to determine status' do
+ sha = project.repository.create_file(developer, generate(:branch), 'content', message: 'message', branch_name: 'master')
+ create(:ci_pipeline,
+ project: project,
+ user: developer,
+ ref: "master",
+ sha: sha,
+ status: :running,
+ created_at: 6.months.ago)
+ create(:ci_pipeline,
+ project: project,
+ user: developer,
+ ref: "master",
+ sha: sha,
+ status: :success,
+ created_at: 2.months.ago)
+
+ get :index,
+ format: :html,
+ params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ state: 'all'
+ }
+
+ expect(controller.instance_variable_get(:@branch_pipeline_statuses)["master"].group).to eq("success")
+ end
+ end
+
+ context 'when multiple branches exist' do
+ it 'all relevant commit statuses are received' do
+ master_sha = project.repository.create_file(developer, generate(:branch), 'content', message: 'message', branch_name: 'master')
+ create(:ci_pipeline,
+ project: project,
+ user: developer,
+ ref: "master",
+ sha: master_sha,
+ status: :running,
+ created_at: 6.months.ago)
+ test_sha = project.repository.create_file(developer, generate(:branch), 'content', message: 'message', branch_name: 'test')
+ create(:ci_pipeline,
+ project: project,
+ user: developer,
+ ref: "test",
+ sha: test_sha,
+ status: :success,
+ created_at: 2.months.ago)
+
+ get :index,
+ format: :html,
+ params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ state: 'all'
+ }
+
+ expect(controller.instance_variable_get(:@branch_pipeline_statuses)["master"].group).to eq("running")
+ expect(controller.instance_variable_get(:@branch_pipeline_statuses)["test"].group).to eq("success")
+ end
+ end
+
+ context 'when a branch contains no pipelines' do
+ it 'no commit statuses are received' do
+ get :index,
+ format: :html,
+ params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ state: 'all'
+ }
+
+ expect(controller.instance_variable_get(:@branch_pipeline_statuses)).to be_blank
+ end
+ end
+
# We need :request_store because Gitaly only counts the queries whenever
# `RequestStore.active?` in GitalyClient.enforce_gitaly_request_limits
# And the main goal of this test is making sure TooManyInvocationsError
@@ -564,7 +639,7 @@ describe Projects::BranchesController do
describe 'GET diverging_commit_counts' do
before do
- sign_in(user)
+ sign_in(developer)
end
it 'returns the commit counts behind and ahead of default branch' do
diff --git a/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb b/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb
index ac31045678f..252ad6ec9c4 100644
--- a/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb
+++ b/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb
@@ -2,34 +2,27 @@
require 'spec_helper'
-describe Projects::Ci::DailyBuildGroupReportResultsController do
+RSpec.describe Projects::Ci::DailyBuildGroupReportResultsController do
describe 'GET index' do
let(:project) { create(:project, :public, :repository) }
let(:ref_path) { 'refs/heads/master' }
let(:param_type) { 'coverage' }
let(:start_date) { '2019-12-10' }
let(:end_date) { '2020-03-09' }
-
- def create_daily_coverage(group_name, coverage, date)
- create(
- :ci_daily_build_group_report_result,
- project: project,
- ref_path: ref_path,
- group_name: group_name,
- data: { 'coverage' => coverage },
- date: date
- )
- end
-
- def csv_response
- CSV.parse(response.body)
- end
+ let(:allowed_to_read) { true }
+ let(:user) { create(:user) }
before do
create_daily_coverage('rspec', 79.0, '2020-03-09')
+ create_daily_coverage('rspec', 77.0, '2020-03-08')
create_daily_coverage('karma', 81.0, '2019-12-10')
- create_daily_coverage('rspec', 67.0, '2019-12-09')
- create_daily_coverage('karma', 71.0, '2019-12-09')
+ create_daily_coverage('minitest', 67.0, '2019-12-09')
+ create_daily_coverage('mocha', 71.0, '2019-12-09')
+
+ sign_in(user)
+
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?).with(user, :read_build_report_results, project).and_return(allowed_to_read)
get :index, params: {
namespace_id: project.namespace,
@@ -38,43 +31,126 @@ describe Projects::Ci::DailyBuildGroupReportResultsController do
param_type: param_type,
start_date: start_date,
end_date: end_date,
- format: :csv
+ format: format
}
end
- it 'serves the results in CSV' do
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.headers['Content-Type']).to eq('text/csv; charset=utf-8')
+ shared_examples_for 'validating param_type' do
+ context 'when given param_type is invalid' do
+ let(:param_type) { 'something_else' }
- expect(csv_response).to eq([
- %w[date group_name coverage],
- ['2020-03-09', 'rspec', '79.0'],
- ['2019-12-10', 'karma', '81.0']
- ])
+ it 'responds with 422 error' do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
+ end
end
- context 'when given date range spans more than 90 days' do
- let(:start_date) { '2019-12-09' }
- let(:end_date) { '2020-03-09' }
+ shared_examples_for 'ensuring policy' do
+ context 'when user is not allowed to read build report results' do
+ let(:allowed_to_read) { false }
+
+ it 'responds with 404 error' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
- it 'limits the result to 90 days from the given start_date' do
+ context 'when format is CSV' do
+ let(:format) { :csv }
+
+ it 'serves the results in CSV' do
expect(response).to have_gitlab_http_status(:ok)
expect(response.headers['Content-Type']).to eq('text/csv; charset=utf-8')
expect(csv_response).to eq([
%w[date group_name coverage],
['2020-03-09', 'rspec', '79.0'],
+ ['2020-03-08', 'rspec', '77.0'],
['2019-12-10', 'karma', '81.0']
])
end
+
+ context 'when given date range spans more than 90 days' do
+ let(:start_date) { '2019-12-09' }
+ let(:end_date) { '2020-03-09' }
+
+ it 'limits the result to 90 days from the given start_date' do
+ expect(csv_response).to eq([
+ %w[date group_name coverage],
+ ['2020-03-09', 'rspec', '79.0'],
+ ['2020-03-08', 'rspec', '77.0'],
+ ['2019-12-10', 'karma', '81.0']
+ ])
+ end
+ end
+
+ it_behaves_like 'validating param_type'
+ it_behaves_like 'ensuring policy'
end
- context 'when given param_type is invalid' do
- let(:param_type) { 'something_else' }
+ context 'when format is JSON' do
+ let(:format) { :json }
+
+ it 'serves the results in JSON' do
+ expect(response).to have_gitlab_http_status(:ok)
- it 'responds with 422 error' do
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ expect(json_response).to eq([
+ {
+ 'group_name' => 'rspec',
+ 'data' => [
+ { 'date' => '2020-03-09', 'coverage' => 79.0 },
+ { 'date' => '2020-03-08', 'coverage' => 77.0 }
+ ]
+ },
+ {
+ 'group_name' => 'karma',
+ 'data' => [
+ { 'date' => '2019-12-10', 'coverage' => 81.0 }
+ ]
+ }
+ ])
end
+
+ context 'when given date range spans more than 90 days' do
+ let(:start_date) { '2019-12-09' }
+ let(:end_date) { '2020-03-09' }
+
+ it 'limits the result to 90 days from the given start_date' do
+ expect(json_response).to eq([
+ {
+ 'group_name' => 'rspec',
+ 'data' => [
+ { 'date' => '2020-03-09', 'coverage' => 79.0 },
+ { 'date' => '2020-03-08', 'coverage' => 77.0 }
+ ]
+ },
+ {
+ 'group_name' => 'karma',
+ 'data' => [
+ { 'date' => '2019-12-10', 'coverage' => 81.0 }
+ ]
+ }
+ ])
+ end
+ end
+
+ it_behaves_like 'validating param_type'
+ it_behaves_like 'ensuring policy'
end
end
+
+ def create_daily_coverage(group_name, coverage, date)
+ create(
+ :ci_daily_build_group_report_result,
+ project: project,
+ ref_path: ref_path,
+ group_name: group_name,
+ data: { 'coverage' => coverage },
+ date: date
+ )
+ end
+
+ def csv_response
+ CSV.parse(response.body)
+ end
end
diff --git a/spec/controllers/projects/ci/lints_controller_spec.rb b/spec/controllers/projects/ci/lints_controller_spec.rb
index f45b1d7ddd8..eb92385fc83 100644
--- a/spec/controllers/projects/ci/lints_controller_spec.rb
+++ b/spec/controllers/projects/ci/lints_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Ci::LintsController do
+RSpec.describe Projects::Ci::LintsController do
include StubRequests
let(:project) { create(:project, :repository) }
diff --git a/spec/controllers/projects/clusters/applications_controller_spec.rb b/spec/controllers/projects/clusters/applications_controller_spec.rb
index 6de3593be28..b50814b4790 100644
--- a/spec/controllers/projects/clusters/applications_controller_spec.rb
+++ b/spec/controllers/projects/clusters/applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Clusters::ApplicationsController do
+RSpec.describe Projects::Clusters::ApplicationsController do
include AccessMatchersForController
def current_application
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index 698a3773d59..5645e25b741 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ClustersController do
+RSpec.describe Projects::ClustersController do
include AccessMatchersForController
include GoogleApi::CloudPlatformHelpers
include KubernetesHelpers
@@ -41,6 +41,13 @@ describe Projects::ClustersController do
expect(response).to match_response_schema('cluster_list')
end
+ it 'sets the polling interval header for json requests' do
+ go(format: :json)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers['Poll-Interval']).to eq("10000")
+ end
+
context 'when page is specified' do
let(:last_page) { project.clusters.page.total_pages }
let(:total_count) { project.clusters.page.total_count }
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index c8ddd181d10..706bf787b2d 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CommitController do
+RSpec.describe Projects::CommitController do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/commits_controller_spec.rb b/spec/controllers/projects/commits_controller_spec.rb
index 1977e92e42b..557002acbc0 100644
--- a/spec/controllers/projects/commits_controller_spec.rb
+++ b/spec/controllers/projects/commits_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CommitsController do
+RSpec.describe Projects::CommitsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index d1a4a9a0058..6aa4bfe235b 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CompareController do
+RSpec.describe Projects::CompareController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/cycle_analytics/events_controller_spec.rb b/spec/controllers/projects/cycle_analytics/events_controller_spec.rb
index 942e095d669..408ce51d34b 100644
--- a/spec/controllers/projects/cycle_analytics/events_controller_spec.rb
+++ b/spec/controllers/projects/cycle_analytics/events_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CycleAnalytics::EventsController do
+RSpec.describe Projects::CycleAnalytics::EventsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb
index 65eee7b8ead..8feb964cdde 100644
--- a/spec/controllers/projects/cycle_analytics_controller_spec.rb
+++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CycleAnalyticsController do
+RSpec.describe Projects::CycleAnalyticsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb
index 9d41e2f59cb..821f7fca73d 100644
--- a/spec/controllers/projects/deploy_keys_controller_spec.rb
+++ b/spec/controllers/projects/deploy_keys_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DeployKeysController do
+RSpec.describe Projects::DeployKeysController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:admin) { create(:admin) }
diff --git a/spec/controllers/projects/deployments_controller_spec.rb b/spec/controllers/projects/deployments_controller_spec.rb
index 37dcfa78772..85dd86d91e9 100644
--- a/spec/controllers/projects/deployments_controller_spec.rb
+++ b/spec/controllers/projects/deployments_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DeploymentsController do
+RSpec.describe Projects::DeploymentsController do
include ApiHelpers
let(:user) { create(:user) }
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 30d2b79a92f..f664604ac15 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
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DesignManagement::Designs::RawImagesController do
+RSpec.describe Projects::DesignManagement::Designs::RawImagesController do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb b/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb
index 6bfec1b314e..96ecbaf55b6 100644
--- a/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb
+++ b/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DesignManagement::Designs::ResizedImageController do
+RSpec.describe Projects::DesignManagement::Designs::ResizedImageController do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/discussions_controller_spec.rb b/spec/controllers/projects/discussions_controller_spec.rb
index b2e4a3b7b0d..f2efd40afdb 100644
--- a/spec/controllers/projects/discussions_controller_spec.rb
+++ b/spec/controllers/projects/discussions_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DiscussionsController do
+RSpec.describe Projects::DiscussionsController do
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.source_project }
diff --git a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
index fb8da52930c..17952aa0683 100644
--- a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
+++ b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Environments::PrometheusApiController do
+RSpec.describe Projects::Environments::PrometheusApiController do
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/environments/sample_metrics_controller_spec.rb b/spec/controllers/projects/environments/sample_metrics_controller_spec.rb
index 19b07a2ccc4..14e3ded76f2 100644
--- a/spec/controllers/projects/environments/sample_metrics_controller_spec.rb
+++ b/spec/controllers/projects/environments/sample_metrics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Environments::SampleMetricsController do
+RSpec.describe Projects::Environments::SampleMetricsController do
include StubENV
let_it_be(:project) { create(:project) }
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 56fff2771ec..cca4b597f4c 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::EnvironmentsController do
+RSpec.describe Projects::EnvironmentsController do
include MetricsDashboardHelpers
let_it_be(:project) { create(:project) }
@@ -354,6 +354,19 @@ describe Projects::EnvironmentsController do
expect(response).to redirect_to(environment_metrics_path(environment))
end
+ context 'with anonymous user and public dashboard visibility' do
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ it 'redirects successfully' do
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+
+ get :metrics_redirect, params: { namespace_id: project.namespace, project_id: project }
+
+ expect(response).to redirect_to(environment_metrics_path(environment))
+ end
+ end
+
context 'when there are no environments' do
let(:environment) { }
@@ -422,6 +435,19 @@ describe Projects::EnvironmentsController do
get :metrics, params: environment_params
end
end
+
+ context 'with anonymous user and public dashboard visibility' do
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ it 'returns success' do
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+
+ get :metrics, params: environment_params
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
end
describe 'GET #additional_metrics' do
@@ -497,6 +523,26 @@ describe Projects::EnvironmentsController do
get :metrics, params: environment_params
end
end
+
+ context 'with anonymous user and public dashboard visibility' do
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ it 'does not fail' do
+ allow(environment)
+ .to receive(:additional_metrics)
+ .and_return({
+ success: true,
+ data: {},
+ last_update: 42
+ })
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+
+ additional_metrics(window_params)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
end
describe 'GET #metrics_dashboard' do
@@ -673,6 +719,17 @@ describe Projects::EnvironmentsController do
it_behaves_like 'dashboard can be specified'
it_behaves_like 'dashboard can be embedded'
+ context 'with anonymous user and public dashboard visibility' do
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ before do
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+ end
+
+ it_behaves_like 'the default dashboard'
+ end
+
context 'permissions' do
before do
allow(controller).to receive(:can?).and_return true
diff --git a/spec/controllers/projects/error_tracking/projects_controller_spec.rb b/spec/controllers/projects/error_tracking/projects_controller_spec.rb
index 1737528b597..67947d1c9d9 100644
--- a/spec/controllers/projects/error_tracking/projects_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ErrorTracking::ProjectsController do
+RSpec.describe Projects::ErrorTracking::ProjectsController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb b/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
index 27d49147e99..7c080504c31 100644
--- a/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ErrorTracking::StackTracesController do
+RSpec.describe Projects::ErrorTracking::StackTracesController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb
index 6be979418ad..5ea885e4fd6 100644
--- a/spec/controllers/projects/error_tracking_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ErrorTrackingController do
+RSpec.describe Projects::ErrorTrackingController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/find_file_controller_spec.rb b/spec/controllers/projects/find_file_controller_spec.rb
index 4d8933f3aaf..a6c71cff74b 100644
--- a/spec/controllers/projects/find_file_controller_spec.rb
+++ b/spec/controllers/projects/find_file_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::FindFileController do
+RSpec.describe Projects::FindFileController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb
index e362790cd3c..4c0fd7b8954 100644
--- a/spec/controllers/projects/forks_controller_spec.rb
+++ b/spec/controllers/projects/forks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ForksController do
+RSpec.describe Projects::ForksController do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:forked_project) { Projects::ForkService.new(project, user, name: 'Some name').execute }
diff --git a/spec/controllers/projects/grafana_api_controller_spec.rb b/spec/controllers/projects/grafana_api_controller_spec.rb
index 8502bd1ab0a..baee9705127 100644
--- a/spec/controllers/projects/grafana_api_controller_spec.rb
+++ b/spec/controllers/projects/grafana_api_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GrafanaApiController do
+RSpec.describe Projects::GrafanaApiController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb
index e589815c45d..12cef6bea09 100644
--- a/spec/controllers/projects/graphs_controller_spec.rb
+++ b/spec/controllers/projects/graphs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GraphsController do
+RSpec.describe Projects::GraphsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
@@ -42,23 +42,42 @@ describe Projects::GraphsController do
expect(response).to render_template(:charts)
end
- it 'sets the daily coverage options' do
- Timecop.freeze do
+ context 'when anonymous users can read build report results' do
+ it 'sets the daily coverage options' do
+ Timecop.freeze do
+ get(:charts, params: { namespace_id: project.namespace.path, project_id: project.path, id: 'master' })
+
+ expect(assigns[:daily_coverage_options]).to eq(
+ base_params: {
+ start_date: Date.current - 90.days,
+ end_date: Date.current,
+ ref_path: project.repository.expand_ref('master'),
+ param_type: 'coverage'
+ },
+ download_path: namespace_project_ci_daily_build_group_report_results_path(
+ namespace_id: project.namespace,
+ project_id: project,
+ format: :csv
+ ),
+ graph_api_path: namespace_project_ci_daily_build_group_report_results_path(
+ namespace_id: project.namespace,
+ project_id: project,
+ format: :json
+ )
+ )
+ end
+ end
+ end
+
+ context 'when anonymous users cannot read build report results' do
+ before do
+ project.update_column(:public_builds, false)
+
get(:charts, params: { namespace_id: project.namespace.path, project_id: project.path, id: 'master' })
+ end
- expect(assigns[:daily_coverage_options]).to eq(
- base_params: {
- start_date: Time.current.to_date - 90.days,
- end_date: Time.current.to_date,
- ref_path: project.repository.expand_ref('master'),
- param_type: 'coverage'
- },
- download_path: namespace_project_ci_daily_build_group_report_results_path(
- namespace_id: project.namespace,
- project_id: project,
- format: :csv
- )
- )
+ it 'does not set daily coverage options' do
+ expect(assigns[:daily_coverage_options]).to be_nil
end
end
end
diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb
index 28999257957..762ef795f6e 100644
--- a/spec/controllers/projects/group_links_controller_spec.rb
+++ b/spec/controllers/projects/group_links_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GroupLinksController do
+RSpec.describe Projects::GroupLinksController do
let(:group) { create(:group, :private) }
let(:group2) { create(:group, :private) }
let(:project) { create(:project, :private, group: group2) }
diff --git a/spec/controllers/projects/hooks_controller_spec.rb b/spec/controllers/projects/hooks_controller_spec.rb
index e97f602d9ab..440e6b2a74c 100644
--- a/spec/controllers/projects/hooks_controller_spec.rb
+++ b/spec/controllers/projects/hooks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HooksController do
+RSpec.describe Projects::HooksController do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/import/jira_controller_spec.rb b/spec/controllers/projects/import/jira_controller_spec.rb
index d1b0a086576..b82735a56b3 100644
--- a/spec/controllers/projects/import/jira_controller_spec.rb
+++ b/spec/controllers/projects/import/jira_controller_spec.rb
@@ -2,230 +2,101 @@
require 'spec_helper'
-describe Projects::Import::JiraController do
+RSpec.describe Projects::Import::JiraController do
include JiraServiceHelper
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:jira_project_key) { 'Test' }
- context 'with anonymous user' do
- before do
- stub_feature_flags(jira_issue_import: true)
- end
+ def ensure_correct_config
+ sign_in(user)
+ project.add_maintainer(user)
+ stub_feature_flags(jira_issue_import: true)
+ stub_jira_service_test
+ end
- context 'get show' do
- it 'redirects to issues page' do
- get :show, params: { namespace_id: project.namespace, project_id: project }
+ shared_examples 'redirect with error' do |error|
+ it 'redirects to project issues path' do
+ subject
- expect(response).to redirect_to(new_user_session_path)
- end
+ expect(response).to redirect_to(project_issues_path(project))
end
- context 'post import' do
- it 'redirects to issues page' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: jira_project_key }
+ it 'renders a correct error' do
+ subject
- expect(response).to redirect_to(new_user_session_path)
- end
+ expect(flash[:notice]).to eq(error)
end
end
- context 'with logged in user' do
- before do
- sign_in(user)
- project.add_maintainer(user)
- end
+ shared_examples 'template with no message' do
+ it 'does not set any message' do
+ subject
- context 'when feature flag not enabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
+ expect(flash).to be_empty
+ end
- context 'get show' do
- it 'redirects to issues page' do
- get :show, params: { namespace_id: project.namespace, project_id: project }
+ it 'renders show template' do
+ subject
- expect(response).to redirect_to(project_issues_path(project))
- end
- end
+ expect(response).to render_template(template)
+ end
+ end
- context 'post import' do
- it 'redirects to issues page' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: jira_project_key }
+ shared_examples 'users without permissions' do
+ context 'with anonymous user' do
+ it 'redirects to new user page' do
+ subject
- expect(response).to redirect_to(project_issues_path(project))
- end
+ expect(response).to redirect_to(new_user_session_path)
end
end
- context 'when feature flag enabled' do
+ context 'when loged user is a developer' do
before do
- stub_feature_flags(jira_issue_import: true)
- stub_feature_flags(jira_issue_import_vue: false)
+ create(:jira_service, project: project)
stub_jira_service_test
- end
-
- context 'when Jira service is enabled for the project' do
- let_it_be(:jira_service) { create(:jira_service, project: project) }
-
- context 'when user is developer' do
- let_it_be(:dev) { create(:user) }
-
- before do
- sign_in(dev)
- project.add_developer(dev)
- end
-
- context 'get show' do
- before do
- get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
- end
-
- it 'does not query Jira service' do
- expect(project).not_to receive(:jira_service)
- end
-
- it 'renders show template' do
- expect(response).to render_template(:show)
- expect(assigns(:jira_projects)).not_to be_present
- end
- end
-
- context 'post import' do
- it 'returns 404' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: jira_project_key }
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'when issues disabled' do
- let_it_be(:disabled_issues_project) { create(:project, :public, :issues_disabled) }
-
- context 'get show' do
- it 'returs 404' do
- get :show, params: { namespace_id: project.namespace.to_param, project_id: disabled_issues_project }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'post import' do
- it 'returs 404' do
- post :import, params: { namespace_id: disabled_issues_project.namespace, project_id: disabled_issues_project, jira_project_key: jira_project_key }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'when running Jira import first time' do
- context 'get show' do
- before do
- allow(JIRA::Resource::Project).to receive(:all).and_return(jira_projects)
-
- expect(project.jira_imports).to be_empty
-
- get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
- end
-
- context 'when no projects have been retrieved from Jira' do
- let(:jira_projects) { [] }
-
- it 'render an error message' do
- expect(flash[:alert]).to eq('No projects have been returned from Jira. Please check your Jira configuration.')
- expect(response).to render_template(:show)
- end
- end
-
- context 'when projects retrieved from Jira' do
- let(:jira_projects) { [double(name: 'FOO project', key: 'FOO')] }
-
- it 'renders show template' do
- expect(response).to render_template(:show)
- end
- end
- end
+ sign_in(user)
+ project.add_developer(user)
+ end
- context 'post import' do
- context 'when Jira project key is empty' do
- it 'redirects back to show with an error' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: '' }
+ it_behaves_like 'redirect with error', 'You do not have permissions to run the import.'
+ end
+ end
- expect(response).to redirect_to(project_import_jira_path(project))
- expect(flash[:alert]).to eq('No Jira project key has been provided.')
- end
- end
+ describe 'GET #show' do
+ let(:template) { 'show' }
- context 'when everything is ok' do
- it 'creates import state' do
- expect(project.latest_jira_import).to be_nil
+ subject { get :show, params: { namespace_id: project.namespace, project_id: project } }
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: jira_project_key }
+ it_behaves_like 'users without permissions'
- project.reload
+ context 'jira service configuration' do
+ before do
+ sign_in(user)
+ project.add_maintainer(user)
+ stub_feature_flags(jira_issue_import: true)
+ end
- jira_import = project.latest_jira_import
- expect(project.import_type).to eq 'jira'
- expect(jira_import.status).to eq 'scheduled'
- expect(jira_import.jira_project_key).to eq jira_project_key
- expect(response).to redirect_to(project_import_jira_path(project))
- end
- end
- end
+ context 'when Jira service is not enabled for the project' do
+ it 'does not query Jira service' do
+ expect(project).not_to receive(:jira_service)
end
- context 'when import state is scheduled' do
- let_it_be(:jira_import_state) { create(:jira_import_state, :scheduled, project: project) }
-
- context 'get show' do
- it 'renders import status' do
- get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
-
- jira_import = project.latest_jira_import
- expect(jira_import.status).to eq 'scheduled'
- expect(flash.now[:notice]).to eq 'Import scheduled'
- end
- end
+ it_behaves_like 'template with no message'
+ end
- context 'post import' do
- it 'uses the existing import data' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: 'New Project' }
+ context 'when Jira service is not configured correctly for the project' do
+ let_it_be(:jira_service) { create(:jira_service, project: project) }
- expect(flash[:notice]).to eq('Jira import is already running.')
- expect(response).to redirect_to(project_import_jira_path(project))
- end
- end
+ before do
+ WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo')
+ .to_raise(JIRA::HTTPError.new(double(message: 'Some failure.')))
end
- context 'when Jira import ran before' do
- let_it_be(:jira_import_state) { create(:jira_import_state, :finished, project: project, jira_project_key: jira_project_key) }
-
- context 'get show' do
- it 'renders import status' do
- allow(JIRA::Resource::Project).to receive(:all).and_return([])
- get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
-
- expect(project.latest_jira_import.status).to eq 'finished'
- expect(flash.now[:notice]).to eq 'Import finished'
- end
- end
-
- context 'post import' do
- it 'uses the existing import data' do
- post :import, params: { namespace_id: project.namespace, project_id: project, jira_project_key: 'New Project' }
-
- project.reload
- expect(project.latest_jira_import.status).to eq 'scheduled'
- expect(project.jira_imports.size).to eq 2
- expect(project.jira_imports.first.jira_project_key).to eq jira_project_key
- expect(project.jira_imports.last.jira_project_key).to eq 'New Project'
- expect(response).to redirect_to(project_import_jira_path(project))
- end
- end
- end
+ it_behaves_like 'template with no message'
end
end
end
diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb
index bdc81efe3bc..29cfd1c352e 100644
--- a/spec/controllers/projects/imports_controller_spec.rb
+++ b/spec/controllers/projects/imports_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ImportsController do
+RSpec.describe Projects::ImportsController do
let(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 96f11f11dc4..bcd1a53bd47 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::IssuesController do
+RSpec.describe Projects::IssuesController do
include ProjectForksHelper
include_context 'includes Spam constants'
@@ -332,8 +332,7 @@ describe Projects::IssuesController do
end
before do
- allow(controller).to receive(:find_routable!)
- .with(Project, project.full_path, any_args).and_return(project)
+ allow(controller).to receive(:find_routable!).and_return(project)
allow(project).to receive(:default_branch).and_return(master_branch)
allow_next_instance_of(Issues::RelatedBranchesService) do |service|
allow(service).to receive(:execute).and_return(related_branches)
@@ -536,7 +535,7 @@ describe Projects::IssuesController do
before do
stub_application_setting(recaptcha_enabled: true)
expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
end
@@ -851,7 +850,7 @@ describe Projects::IssuesController do
context 'when recaptcha is not verified' do
before do
expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
end
@@ -1103,7 +1102,7 @@ describe Projects::IssuesController do
context 'when captcha is not verified' do
before do
expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(REQUIRE_RECAPTCHA)
+ expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
end
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index ef1253edda5..44dcb0caab2 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::JobsController, :clean_gitlab_redis_shared_state do
+RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
include ApiHelpers
include HttpIOHelpers
@@ -1225,4 +1225,198 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
get :terminal_websocket_authorize, params: params.merge(extra_params)
end
end
+
+ describe 'GET #proxy_websocket_authorize' do
+ let_it_be(:owner) { create(:owner) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:project) { create(:project, :private, :repository, namespace: owner.namespace) }
+ let(:user) { maintainer }
+ let(:pipeline) { create(:ci_pipeline, project: project, source: :webide, config_source: :webide_source, user: user) }
+ let(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) }
+ let(:extra_params) { { id: job.id } }
+ let(:path) { :proxy_websocket_authorize }
+ let(:render_method) { :channel_websocket }
+ let(:expected_data) do
+ {
+ 'Channel' => {
+ 'Subprotocols' => ["terminal.gitlab.com"],
+ 'Url' => 'wss://localhost/proxy/build/default_port/',
+ 'Header' => {
+ 'Authorization' => [nil]
+ },
+ 'MaxSessionTime' => nil,
+ 'CAPem' => nil
+ }
+ }.to_json
+ end
+
+ before do
+ stub_feature_flags(build_service_proxy: true)
+ allow(job).to receive(:has_terminal?).and_return(true)
+
+ project.add_maintainer(maintainer)
+ project.add_developer(developer)
+ project.add_reporter(reporter)
+ project.add_guest(guest)
+
+ sign_in(user)
+ end
+
+ context 'access rights' do
+ before do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+
+ make_request
+ end
+
+ context 'with admin' do
+ let(:user) { admin }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'with owner' do
+ let(:user) { owner }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with maintainer' do
+ let(:user) { maintainer }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with developer' do
+ let(:user) { developer }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with reporter' do
+ let(:user) { reporter }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with guest' do
+ let(:user) { guest }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with non member' do
+ let(:user) { create(:user) }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'when pipeline is not from a webide source' do
+ context 'with admin' do
+ let(:user) { admin }
+ let(:pipeline) { create(:ci_pipeline, project: project, source: :chat, user: user) }
+
+ before do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+ make_request
+ end
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'when workhorse signature is valid' do
+ before do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+ end
+
+ context 'and the id is valid' do
+ it 'returns the proxy data for the service running in the job' do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers["Content-Type"]).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ expect(response.body).to eq(expected_data)
+ end
+ end
+
+ context 'and the id is invalid' do
+ let(:extra_params) { { id: non_existing_record_id } }
+
+ it 'returns 404' do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'with invalid workhorse signature' do
+ it 'aborts with an exception' do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_raise(JWT::DecodeError)
+
+ expect { make_request }.to raise_error(JWT::DecodeError)
+ end
+ end
+
+ context 'when feature flag :build_service_proxy is disabled' do
+ let(:user) { admin }
+
+ it 'returns 404' do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+ stub_feature_flags(build_service_proxy: false)
+
+ make_request
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ it 'converts the url scheme into wss' do
+ allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
+
+ expect(job.runner_session_url).to start_with('https://')
+ expect(Gitlab::Workhorse).to receive(:channel_websocket).with(a_hash_including(url: "wss://localhost/proxy/build/default_port/"))
+
+ make_request
+ end
+
+ def make_request
+ params = {
+ namespace_id: project.namespace.to_param,
+ project_id: project
+ }
+
+ get path, params: params.merge(extra_params)
+ end
+ end
end
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index c6098f5934d..f213d104747 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::LabelsController do
+RSpec.describe Projects::LabelsController do
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/logs_controller_spec.rb b/spec/controllers/projects/logs_controller_spec.rb
index e86a42b03c8..1eb5a6fcc12 100644
--- a/spec/controllers/projects/logs_controller_spec.rb
+++ b/spec/controllers/projects/logs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::LogsController do
+RSpec.describe Projects::LogsController do
include KubernetesHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb
index 693176d0cfc..001f2564698 100644
--- a/spec/controllers/projects/mattermosts_controller_spec.rb
+++ b/spec/controllers/projects/mattermosts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MattermostsController do
+RSpec.describe Projects::MattermostsController do
let!(:project) { create(:project) }
let!(:user) { create(:user) }
diff --git a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
index 8e4ac64f7b0..5f636bd4340 100644
--- a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::ConflictsController do
+RSpec.describe Projects::MergeRequests::ConflictsController do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
diff --git a/spec/controllers/projects/merge_requests/content_controller_spec.rb b/spec/controllers/projects/merge_requests/content_controller_spec.rb
index 72eedc837a4..7fb20b4666a 100644
--- a/spec/controllers/projects/merge_requests/content_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/content_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::ContentController do
+RSpec.describe Projects::MergeRequests::ContentController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request, target_project: project, source_project: project) }
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index db25ad62019..091a44130a1 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::CreationsController do
+RSpec.describe Projects::MergeRequests::CreationsController do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:fork_project) { create(:forked_project_with_submodules) }
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
index 3d9193e3e33..02b4c2d1da9 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::DiffsController do
+RSpec.describe Projects::MergeRequests::DiffsController do
include ProjectForksHelper
shared_examples '404 for unexistent diffable' do
diff --git a/spec/controllers/projects/merge_requests/drafts_controller_spec.rb b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb
new file mode 100644
index 00000000000..7d74e872d29
--- /dev/null
+++ b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb
@@ -0,0 +1,455 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Projects::MergeRequests::DraftsController do
+ include RepoHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
+ let(:user) { project.owner }
+ let(:user2) { create(:user) }
+
+ let(:params) do
+ {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ merge_request_id: merge_request.iid
+ }
+ end
+
+ before do
+ sign_in(user)
+ stub_licensed_features(multiple_merge_request_assignees: true)
+ stub_commonmark_sourcepos_disabled
+ end
+
+ describe 'GET #index' do
+ let!(:draft_note) { create(:draft_note, merge_request: merge_request, author: user) }
+
+ it 'list merge request draft notes for current user' do
+ get :index, params: params
+
+ expect(json_response.first['merge_request_id']).to eq(merge_request.id)
+ expect(json_response.first['author']['id']).to eq(user.id)
+ expect(json_response.first['note_html']).not_to be_empty
+ end
+ end
+
+ describe 'POST #create' do
+ def create_draft_note(draft_overrides: {}, overrides: {})
+ post_params = params.merge({
+ draft_note: {
+ note: 'This is a unpublished comment'
+ }.merge(draft_overrides)
+ }.merge(overrides))
+
+ post :create, params: post_params
+ end
+
+ context 'without permissions' do
+ let(:project) { create(:project, :private) }
+
+ before do
+ sign_in(user2)
+ end
+
+ it 'does not allow draft note creation' do
+ expect { create_draft_note }.to change { DraftNote.count }.by(0)
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ it 'creates a draft note' do
+ expect { create_draft_note }.to change { DraftNote.count }.by(1)
+ end
+
+ it 'creates draft note with position' do
+ diff_refs = project.commit(sample_commit.id).try(:diff_refs)
+
+ position = Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 14,
+ diff_refs: diff_refs
+ )
+
+ create_draft_note(draft_overrides: { position: position.to_json })
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['position']).to be_present
+ expect(json_response['file_hash']).to be_present
+ expect(json_response['file_identifier_hash']).to be_present
+ expect(json_response['line_code']).to match(/\w+_\d+_\d+/)
+ expect(json_response['note_html']).to eq('<p dir="auto">This is a unpublished comment</p>')
+ end
+
+ it 'creates a draft note with quick actions' do
+ create_draft_note(draft_overrides: { note: "#{user2.to_reference}\n/assign #{user.to_reference}" })
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['note_html']).to match(/#{user2.to_reference}/)
+ expect(json_response['references']['commands']).to match(/Assigns/)
+ expect(json_response['references']['users']).to include(user2.username)
+ end
+
+ context 'in a thread' do
+ let(:discussion) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project).discussion }
+
+ it 'creates draft note as a reply' do
+ expect do
+ create_draft_note(overrides: { in_reply_to_discussion_id: discussion.reply_id })
+ end.to change { DraftNote.count }.by(1)
+
+ draft_note = DraftNote.last
+
+ expect(draft_note).to be_valid
+ expect(draft_note.discussion_id).to eq(discussion.reply_id)
+ end
+
+ it 'creates a draft note that will resolve a thread' do
+ expect do
+ create_draft_note(
+ overrides: { in_reply_to_discussion_id: discussion.reply_id },
+ draft_overrides: { resolve_discussion: true }
+ )
+ end.to change { DraftNote.count }.by(1)
+
+ draft_note = DraftNote.last
+
+ expect(draft_note).to be_valid
+ expect(draft_note.discussion_id).to eq(discussion.reply_id)
+ expect(draft_note.resolve_discussion).to eq(true)
+ end
+
+ it 'cannot create more than one draft note per thread' do
+ expect do
+ create_draft_note(
+ overrides: { in_reply_to_discussion_id: discussion.reply_id },
+ draft_overrides: { resolve_discussion: true }
+ )
+ end.to change { DraftNote.count }.by(1)
+
+ expect do
+ create_draft_note(
+ overrides: { in_reply_to_discussion_id: discussion.reply_id },
+ draft_overrides: { resolve_discussion: true, note: 'A note' }
+ )
+ end.to change { DraftNote.count }.by(0)
+ end
+ end
+
+ context 'commit_id is present' do
+ let(:commit) { project.commit(sample_commit.id) }
+
+ let(:position) do
+ Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 14,
+ diff_refs: commit.diff_refs
+ )
+ end
+
+ before do
+ create_draft_note(draft_overrides: { commit_id: commit_id, position: position.to_json })
+ end
+
+ context 'value is a commit sha' do
+ let(:commit_id) { commit.id }
+
+ it 'creates the draft note with commit ID' do
+ expect(DraftNote.last.commit_id).to eq(commit_id)
+ end
+ end
+
+ context 'value is "undefined"' do
+ let(:commit_id) { 'undefined' }
+
+ it 'creates the draft note with nil commit ID' do
+ expect(DraftNote.last.commit_id).to be_nil
+ end
+ end
+ end
+ end
+
+ describe 'PUT #update' do
+ let(:draft) { create(:draft_note, merge_request: merge_request, author: user) }
+
+ def update_draft_note(overrides = {})
+ put_params = params.merge({
+ id: draft.id,
+ draft_note: {
+ note: 'This is an updated unpublished comment'
+ }.merge(overrides)
+ })
+
+ put :update, params: put_params
+ end
+
+ context 'without permissions' do
+ before do
+ sign_in(user2)
+ project.add_developer(user2)
+ end
+
+ it 'does not allow editing draft note belonging to someone else' do
+ update_draft_note
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(draft.reload.note).not_to eq('This is an updated unpublished comment')
+ end
+ end
+
+ it 'updates the draft' do
+ expect(draft.note).not_to be_empty
+
+ expect { update_draft_note }.not_to change { DraftNote.count }
+
+ draft.reload
+
+ expect(draft.note).to eq('This is an updated unpublished comment')
+ expect(json_response['note_html']).not_to be_empty
+ end
+ end
+
+ describe 'POST #publish' do
+ context 'without permissions' do
+ shared_examples_for 'action that does not allow publishing draft note' do
+ it 'does not allow publishing draft note' do
+ expect { action }
+ .to not_change { Note.count }
+ .and not_change { DraftNote.count }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ before do
+ sign_in(user2)
+ end
+
+ context 'when note belongs to someone else' do
+ before do
+ project.add_developer(user2)
+ end
+
+ it_behaves_like 'action that does not allow publishing draft note' do
+ let!(:draft) { create(:draft_note, merge_request: merge_request, author: user) }
+ let(:action) { post :publish, params: params.merge(id: draft.id) }
+ end
+ end
+
+ context 'when merge request discussion is locked' do
+ let(:project) { create(:project, :public, :merge_requests_public, :repository) }
+
+ before do
+ create(:draft_note, merge_request: merge_request, author: user2)
+ merge_request.update!(discussion_locked: true)
+ end
+
+ it_behaves_like 'action that does not allow publishing draft note' do
+ let(:action) { post :publish, params: params }
+ end
+ end
+ end
+
+ context 'when PublishService errors' do
+ it 'returns message and 500 response' do
+ create(:draft_note, merge_request: merge_request, author: user)
+ error_message = "Something went wrong"
+
+ expect_next_instance_of(DraftNotes::PublishService) do |service|
+ allow(service).to receive(:execute).and_return({ message: error_message, status: :error })
+ end
+
+ post :publish, params: params
+
+ expect(response).to have_gitlab_http_status(:error)
+ expect(json_response["message"]).to include(error_message)
+ end
+ end
+
+ it 'publishes draft notes with position' do
+ diff_refs = project.commit(sample_commit.id).try(:diff_refs)
+
+ position = Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 14,
+ diff_refs: diff_refs
+ )
+
+ draft = create(:draft_note_on_text_diff, merge_request: merge_request, author: user, position: position)
+
+ expect { post :publish, params: params }.to change { Note.count }.by(1)
+ .and change { DraftNote.count }.by(-1)
+
+ note = merge_request.notes.reload.last
+
+ expect(note.note).to eq(draft.note)
+ expect(note.position).to eq(draft.position)
+ end
+
+ it 'does nothing if there are no draft notes' do
+ expect { post :publish, params: params }.to change { Note.count }.by(0).and change { DraftNote.count }.by(0)
+ end
+
+ it 'publishes a draft note with quick actions and applies them' do
+ project.add_developer(user2)
+ create(:draft_note, merge_request: merge_request, author: user,
+ note: "/assign #{user2.to_reference}")
+
+ expect(merge_request.assignees).to be_empty
+
+ expect { post :publish, params: params }.to change { Note.count }.by(1)
+ .and change { DraftNote.count }.by(-1)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(merge_request.reload.assignee_ids).to match_array([user2.id])
+ expect(Note.last.system?).to be true
+ end
+
+ it 'publishes all draft notes for an MR' do
+ draft_params = { merge_request: merge_request, author: user }
+
+ drafts = create_list(:draft_note, 4, draft_params)
+
+ note = create(:discussion_note_on_merge_request, noteable: merge_request, project: project)
+ draft_reply = create(:draft_note, draft_params.merge(discussion_id: note.discussion_id))
+
+ diff_note = create(:diff_note_on_merge_request, noteable: merge_request, project: project)
+ diff_draft_reply = create(:draft_note, draft_params.merge(discussion_id: diff_note.discussion_id))
+
+ expect { post :publish, params: params }.to change { Note.count }.by(6)
+ .and change { DraftNote.count }.by(-6)
+
+ expect(response).to have_gitlab_http_status(:ok)
+
+ notes = merge_request.notes.reload
+
+ expect(notes.pluck(:note)).to include(*drafts.map(&:note))
+ expect(note.discussion.notes.last.note).to eq(draft_reply.note)
+ expect(diff_note.discussion.notes.last.note).to eq(diff_draft_reply.note)
+ end
+
+ it 'can publish just a single draft note' do
+ draft_params = { merge_request: merge_request, author: user }
+
+ drafts = create_list(:draft_note, 4, draft_params)
+
+ expect { post :publish, params: params.merge(id: drafts.first.id) }.to change { Note.count }.by(1)
+ .and change { DraftNote.count }.by(-1)
+ end
+
+ context 'when publishing drafts in a thread' do
+ let(:note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) }
+
+ def create_reply(discussion_id, resolves: false)
+ create(:draft_note,
+ merge_request: merge_request,
+ author: user,
+ discussion_id: discussion_id,
+ resolve_discussion: resolves
+ )
+ end
+
+ it 'resolves a thread if the draft note resolves it' do
+ draft_reply = create_reply(note.discussion_id, resolves: true)
+
+ post :publish, params: params
+
+ discussion = note.discussion
+
+ expect(discussion.notes.last.note).to eq(draft_reply.note)
+ expect(discussion.resolved?).to eq(true)
+ expect(discussion.resolved_by.id).to eq(user.id)
+ end
+
+ it 'unresolves a thread if the draft note unresolves it' do
+ note.discussion.resolve!(user)
+ expect(note.discussion.resolved?).to eq(true)
+
+ draft_reply = create_reply(note.discussion_id, resolves: false)
+
+ post :publish, params: params
+
+ discussion = note.discussion
+
+ expect(discussion.notes.last.note).to eq(draft_reply.note)
+ expect(discussion.resolved?).to eq(false)
+ end
+ end
+ end
+
+ describe 'DELETE #destroy' do
+ let(:draft) { create(:draft_note, merge_request: merge_request, author: user) }
+
+ def create_draft
+ create(:draft_note, merge_request: merge_request, author: user)
+ end
+
+ context 'without permissions' do
+ before do
+ sign_in(user2)
+ project.add_developer(user2)
+ end
+
+ it 'does not allow destroying a draft note belonging to someone else' do
+ draft = create(:draft_note, merge_request: merge_request, author: user)
+
+ expect { post :destroy, params: params.merge(id: draft.id) }
+ .not_to change { DraftNote.count }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ it 'destroys the draft note when ID is given' do
+ draft = create_draft
+
+ expect { delete :destroy, params: params.merge(id: draft.id) }.to change { DraftNote.count }.by(-1)
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ context 'without permissions' do
+ before do
+ sign_in(user2)
+ end
+
+ it 'does not allow editing draft note belonging to someone else' do
+ draft = create_draft
+
+ expect { delete :destroy, params: params.merge(id: draft.id) }.to change { DraftNote.count }.by(0)
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ describe 'DELETE #discard' do
+ it 'deletes all DraftNotes belonging to a user in a Merge Request' do
+ create_list(:draft_note, 6, merge_request: merge_request, author: user)
+
+ expect { delete :discard, params: params }.to change { DraftNote.count }.by(-6)
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ context 'without permissions' do
+ before do
+ sign_in(user2)
+ project.add_developer(user2)
+ end
+
+ it 'does not destroys a draft note belonging to someone else' do
+ create(:draft_note, merge_request: merge_request, author: user)
+
+ expect { post :discard, params: params }
+ .not_to change { DraftNote.count }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 7d9e42fcc2d..382593fd7cb 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequestsController do
+RSpec.describe Projects::MergeRequestsController do
include ProjectForksHelper
include Gitlab::Routing
@@ -1183,15 +1183,19 @@ describe Projects::MergeRequestsController do
subject
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response).to match(
- a_hash_including(
- 'tfplan.json' => hash_including(
- 'create' => 0,
- 'delete' => 0,
- 'update' => 1
+
+ pipeline.builds.each do |build|
+ expect(json_response).to match(
+ a_hash_including(
+ build.id.to_s => hash_including(
+ 'create' => 0,
+ 'delete' => 0,
+ 'update' => 1,
+ 'job_name' => build.options.dig(:artifacts, :name).to_s
+ )
)
)
- )
+ end
end
end
@@ -1409,20 +1413,6 @@ describe Projects::MergeRequestsController do
end
end
- context 'when feature flag is disabled' do
- let(:accessibility_comparison) { { status: :parsed, data: { summary: 1 } } }
-
- before do
- stub_feature_flags(accessibility_report_view: false)
- end
-
- it 'returns 204 HTTP status' do
- subject
-
- expect(response).to have_gitlab_http_status(:no_content)
- end
- end
-
context 'when pipeline has jobs with accessibility reports' do
before do
allow_any_instance_of(MergeRequest)
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index ee61ef73b45..0c7391c1b9c 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MilestonesController do
+RSpec.describe Projects::MilestonesController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:milestone) { create(:milestone, project: project) }
@@ -145,7 +145,7 @@ describe Projects::MilestonesController do
delete :destroy, params: { namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid }, format: :js
expect(response).to be_successful
- expect(Event.recent.first.action).to eq(Event::DESTROYED)
+ expect(Event.recent.first).to be_destroyed_action
expect { Milestone.find(milestone.id) }.to raise_exception(ActiveRecord::RecordNotFound)
issue.reload
diff --git a/spec/controllers/projects/mirrors_controller_spec.rb b/spec/controllers/projects/mirrors_controller_spec.rb
index 8cd940978c0..7c5d14d3a22 100644
--- a/spec/controllers/projects/mirrors_controller_spec.rb
+++ b/spec/controllers/projects/mirrors_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MirrorsController do
+RSpec.describe Projects::MirrorsController do
include ReactiveCachingHelpers
shared_examples 'only admin is allowed when mirroring is disabled' do
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 39594ff287d..b3a83723189 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::NotesController do
+RSpec.describe Projects::NotesController do
include ProjectForksHelper
let(:user) { create(:user) }
@@ -37,7 +37,7 @@ describe Projects::NotesController do
project.add_developer(user)
end
- it 'passes last_fetched_at from headers to NotesFinder' do
+ it 'passes last_fetched_at from headers to NotesFinder and MergeIntoNotesService' do
last_fetched_at = 3.hours.ago.to_i
request.headers['X-Last-Fetched-At'] = last_fetched_at
@@ -46,6 +46,10 @@ describe Projects::NotesController do
.with(anything, hash_including(last_fetched_at: last_fetched_at))
.and_call_original
+ expect(ResourceEvents::MergeIntoNotesService).to receive(:new)
+ .with(anything, anything, hash_including(last_fetched_at: last_fetched_at))
+ .and_call_original
+
get :index, params: request_params
end
diff --git a/spec/controllers/projects/pages_controller_spec.rb b/spec/controllers/projects/pages_controller_spec.rb
index 102c0b6b048..1fa8838b548 100644
--- a/spec/controllers/projects/pages_controller_spec.rb
+++ b/spec/controllers/projects/pages_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PagesController do
+RSpec.describe Projects::PagesController do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
diff --git a/spec/controllers/projects/pages_domains_controller_spec.rb b/spec/controllers/projects/pages_domains_controller_spec.rb
index 40a6f77f0d6..691508d1e14 100644
--- a/spec/controllers/projects/pages_domains_controller_spec.rb
+++ b/spec/controllers/projects/pages_domains_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PagesDomainsController do
+RSpec.describe Projects::PagesDomainsController do
let(:user) { create(:user) }
let(:project) { create(:project) }
let!(:pages_domain) { create(:pages_domain, project: project) }
diff --git a/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
index 6a53e8f3dbf..8a344a72120 100644
--- a/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
+++ b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PerformanceMonitoring::DashboardsController do
+RSpec.describe Projects::PerformanceMonitoring::DashboardsController do
let_it_be(:user) { create(:user) }
let_it_be(:namespace) { create(:namespace) }
let!(:project) { create(:project, :repository, name: 'dashboard-project', namespace: namespace) }
diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
index 635980ba93b..27a3e95896a 100644
--- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb
+++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelineSchedulesController do
+RSpec.describe Projects::PipelineSchedulesController do
include AccessMatchersForController
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index b3d8fb94fb3..ca09d2b1428 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelinesController do
+RSpec.describe Projects::PipelinesController do
include ApiHelpers
let_it_be(:user) { create(:user) }
@@ -26,10 +26,6 @@ describe Projects::PipelinesController do
context 'when using persisted stages', :request_store do
render_views
- before do
- stub_feature_flags(ci_pipeline_persisted_stages: true)
- end
-
it 'returns serialized pipelines' do
expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original
@@ -66,46 +62,6 @@ describe Projects::PipelinesController do
end
end
- context 'when using legacy stages', :request_store do
- before do
- stub_feature_flags(ci_pipeline_persisted_stages: false)
- end
-
- it 'returns JSON with serialized pipelines' do
- get_pipelines_index_json
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('pipeline')
-
- expect(json_response).to include('pipelines')
- expect(json_response['pipelines'].count).to eq 6
- expect(json_response['count']['all']).to eq '6'
- expect(json_response['count']['running']).to eq '2'
- expect(json_response['count']['pending']).to eq '1'
- expect(json_response['count']['finished']).to eq '3'
-
- json_response.dig('pipelines', 0, 'details', 'stages').tap do |stages|
- expect(stages.count).to eq 3
- end
- end
-
- it 'does not execute N+1 queries' do
- get_pipelines_index_json
-
- control_count = ActiveRecord::QueryRecorder.new do
- get_pipelines_index_json
- end.count
-
- create_all_pipeline_types
-
- # There appears to be one extra query for Pipelines#has_warnings? for some reason
- expect { get_pipelines_index_json }.not_to exceed_query_limit(control_count + 1)
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['pipelines'].count).to eq 12
- end
- end
-
it 'does not include coverage data for the pipelines' do
get_pipelines_index_json
@@ -215,6 +171,40 @@ describe Projects::PipelinesController do
end
end
+ context 'filter by status' do
+ context 'when pipelines with the status exists' do
+ it 'returns matched pipelines' do
+ get_pipelines_index_json(status: 'success')
+
+ check_pipeline_response(returned: 1, all: 1, running: 0, pending: 0, finished: 1)
+ end
+
+ context 'when filter by unrelated scope' do
+ it 'returns empty list' do
+ get_pipelines_index_json(status: 'success', scope: 'running')
+
+ check_pipeline_response(returned: 0, all: 1, running: 0, pending: 0, finished: 1)
+ end
+ end
+ end
+
+ context 'when no pipeline with the status exists' do
+ it 'returns empty list' do
+ get_pipelines_index_json(status: 'manual')
+
+ check_pipeline_response(returned: 0, all: 0, running: 0, pending: 0, finished: 0)
+ end
+ end
+
+ context 'when invalid status' do
+ it 'returns all list' do
+ get_pipelines_index_json(status: 'invalid-status')
+
+ check_pipeline_response(returned: 6, all: 6, running: 2, pending: 1, finished: 3)
+ end
+ end
+ end
+
def get_pipelines_index_json(params = {})
get :index, params: {
namespace_id: project.namespace,
@@ -548,6 +538,39 @@ describe Projects::PipelinesController do
end
end
+ describe 'GET dag.json' do
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+
+ before do
+ create_build('build', 1, 'build')
+ create_build('test', 2, 'test', scheduling_type: 'dag').tap do |job|
+ create(:ci_build_need, build: job, name: 'build')
+ end
+ end
+
+ it 'returns the pipeline with DAG serialization' do
+ get :dag, params: { namespace_id: project.namespace, project_id: project, id: pipeline }, format: :json
+
+ expect(response).to have_gitlab_http_status(:ok)
+
+ expect(json_response.fetch('stages')).not_to be_empty
+
+ build_stage = json_response['stages'].first
+ expect(build_stage.fetch('name')).to eq 'build'
+ expect(build_stage.fetch('groups').first.fetch('jobs'))
+ .to eq [{ 'name' => 'build', 'scheduling_type' => 'stage' }]
+
+ test_stage = json_response['stages'].last
+ expect(test_stage.fetch('name')).to eq 'test'
+ expect(test_stage.fetch('groups').first.fetch('jobs'))
+ .to eq [{ 'name' => 'test', 'scheduling_type' => 'dag', 'needs' => ['build'] }]
+ end
+
+ def create_build(stage, stage_idx, name, params = {})
+ create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name, **params)
+ end
+ end
+
describe 'GET stages.json' do
let(:pipeline) { create(:ci_pipeline, project: project) }
@@ -685,7 +708,7 @@ describe Projects::PipelinesController do
end
shared_examples 'creates a pipeline' do
- it do
+ specify do
expect { post_request }.to change { project.ci_pipelines.count }.by(1)
pipeline = project.ci_pipelines.last
diff --git a/spec/controllers/projects/pipelines_settings_controller_spec.rb b/spec/controllers/projects/pipelines_settings_controller_spec.rb
index 789b2104d3c..ad631b7c3da 100644
--- a/spec/controllers/projects/pipelines_settings_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_settings_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelinesSettingsController do
+RSpec.describe Projects::PipelinesSettingsController do
let_it_be(:user) { create(:user) }
let_it_be(:project_auto_devops) { create(:project_auto_devops) }
let(:project) { project_auto_devops.project }
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index f354bba902a..7457e4c5023 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::ProjectMembersController do
+RSpec.describe Projects::ProjectMembersController do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
let(:project) { create(:project, :public) }
diff --git a/spec/controllers/projects/prometheus/alerts_controller_spec.rb b/spec/controllers/projects/prometheus/alerts_controller_spec.rb
index e936cb5916e..6e3148231bd 100644
--- a/spec/controllers/projects/prometheus/alerts_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/alerts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::AlertsController do
+RSpec.describe Projects::Prometheus::AlertsController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
diff --git a/spec/controllers/projects/prometheus/metrics_controller_spec.rb b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
index 36f694cda29..c7c3be20f29 100644
--- a/spec/controllers/projects/prometheus/metrics_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::MetricsController do
+RSpec.describe Projects::Prometheus::MetricsController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:prometheus_project) }
diff --git a/spec/controllers/projects/protected_branches_controller_spec.rb b/spec/controllers/projects/protected_branches_controller_spec.rb
index 262f77a7328..09eb1a45c73 100644
--- a/spec/controllers/projects/protected_branches_controller_spec.rb
+++ b/spec/controllers/projects/protected_branches_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::ProtectedBranchesController do
+RSpec.describe Projects::ProtectedBranchesController do
let(:project) { create(:project, :repository) }
let(:protected_branch) { create(:protected_branch, project: project) }
let(:project_params) { { namespace_id: project.namespace.to_param, project_id: project } }
diff --git a/spec/controllers/projects/protected_tags_controller_spec.rb b/spec/controllers/projects/protected_tags_controller_spec.rb
index a900947d82e..2c2240cb0d0 100644
--- a/spec/controllers/projects/protected_tags_controller_spec.rb
+++ b/spec/controllers/projects/protected_tags_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::ProtectedTagsController do
+RSpec.describe Projects::ProtectedTagsController do
describe "GET #index" do
let(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index 4a684dcfbc6..5f10343eb76 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RawController do
+RSpec.describe Projects::RawController do
include RepoHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb
index b043e7f2538..a6a4aff7ce9 100644
--- a/spec/controllers/projects/refs_controller_spec.rb
+++ b/spec/controllers/projects/refs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RefsController do
+RSpec.describe Projects::RefsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
@@ -73,7 +73,7 @@ describe Projects::RefsController do
cache_key = "projects/#{project.id}/logs/#{project.commit.id}/#{path}/25"
expect(Rails.cache.fetch(cache_key)).to eq(['logs', 50])
- expect(response.headers['More-Logs-Offset']).to eq(50)
+ expect(response.headers['More-Logs-Offset']).to eq("50")
end
end
end
diff --git a/spec/controllers/projects/registry/repositories_controller_spec.rb b/spec/controllers/projects/registry/repositories_controller_spec.rb
index badb84f9b50..098fa9bac2c 100644
--- a/spec/controllers/projects/registry/repositories_controller_spec.rb
+++ b/spec/controllers/projects/registry/repositories_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Registry::RepositoriesController do
+RSpec.describe Projects::Registry::RepositoriesController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
@@ -46,7 +46,7 @@ describe Projects::Registry::RepositoriesController do
context 'when root container repository is not created' do
context 'when there are tags for this repository' do
before do
- stub_container_registry_tags(repository: project.full_path,
+ stub_container_registry_tags(repository: :any,
tags: %w[rc1 latest])
end
diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb
index 5ab32b7d81d..6adee35b60a 100644
--- a/spec/controllers/projects/registry/tags_controller_spec.rb
+++ b/spec/controllers/projects/registry/tags_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Registry::TagsController do
+RSpec.describe Projects::Registry::TagsController do
let(:user) { create(:user) }
let(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/releases/evidences_controller_spec.rb b/spec/controllers/projects/releases/evidences_controller_spec.rb
index d3808087681..d5a9665d6a5 100644
--- a/spec/controllers/projects/releases/evidences_controller_spec.rb
+++ b/spec/controllers/projects/releases/evidences_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Releases::EvidencesController do
+RSpec.describe Projects::Releases::EvidencesController do
let!(:project) { create(:project, :repository, :public) }
let_it_be(:private_project) { create(:project, :repository, :private) }
let_it_be(:developer) { create(:user) }
@@ -31,8 +31,8 @@ describe Projects::Releases::EvidencesController do
end
describe 'GET #show' do
- let_it_be(:tag_name) { "v1.1.0-evidence" }
- let!(:release) { create(:release, :with_evidence, project: project, tag: tag_name) }
+ let(:tag_name) { "v1.1.0-evidence" }
+ let!(:release) { create(:release, project: project, tag: tag_name) }
let(:evidence) { release.evidences.first }
let(:tag) { CGI.escape(release.tag) }
let(:format) { :json }
@@ -48,6 +48,8 @@ describe Projects::Releases::EvidencesController do
end
before do
+ ::Releases::CreateEvidenceService.new(release).execute
+
sign_in(user)
end
@@ -84,14 +86,9 @@ describe Projects::Releases::EvidencesController do
end
context 'when release is associated to a milestone which includes an issue' do
- let_it_be(:project) { create(:project, :repository, :public) }
- let_it_be(:issue) { create(:issue, project: project) }
- let_it_be(:milestone) { create(:milestone, project: project, issues: [issue]) }
- let_it_be(:release) { create(:release, project: project, tag: tag_name, milestones: [milestone]) }
-
- before do
- create(:evidence, release: release)
- end
+ let(:issue) { create(:issue, project: project) }
+ let(:milestone) { create(:milestone, project: project, issues: [issue]) }
+ let(:release) { create(:release, project: project, tag: tag_name, milestones: [milestone]) }
shared_examples_for 'does not show the issue in evidence' do
it do
@@ -111,7 +108,9 @@ describe Projects::Releases::EvidencesController do
end
end
- shared_examples_for 'safely expose evidence' do
+ context 'when user is non-project member' do
+ let(:user) { create(:user) }
+
it_behaves_like 'does not show the issue in evidence'
context 'when the issue is confidential' do
@@ -127,28 +126,50 @@ describe Projects::Releases::EvidencesController do
end
context 'when project is private' do
- let!(:project) { create(:project, :repository, :private) }
+ let(:project) { create(:project, :repository, :private) }
it_behaves_like 'evidence not found'
end
context 'when project restricts the visibility of issues to project members only' do
- let!(:project) { create(:project, :repository, :issues_private) }
+ let(:project) { create(:project, :repository, :issues_private) }
it_behaves_like 'evidence not found'
end
end
- context 'when user is non-project member' do
- let(:user) { create(:user) }
-
- it_behaves_like 'safely expose evidence'
- end
-
context 'when user is auditor', if: Gitlab.ee? do
let(:user) { create(:user, :auditor) }
- it_behaves_like 'safely expose evidence'
+ it_behaves_like 'does not show the issue in evidence'
+
+ context 'when the issue is confidential' do
+ let(:issue) { create(:issue, :confidential, project: project) }
+
+ it_behaves_like 'does not show the issue in evidence'
+ end
+
+ context 'when the user is the author of the confidential issue' do
+ let(:issue) { create(:issue, :confidential, project: project, author: user) }
+
+ it_behaves_like 'does not show the issue in evidence'
+ end
+
+ context 'when project is private' do
+ let(:project) { create(:project, :repository, :private) }
+
+ it 'returns evidence ' do
+ subject
+
+ expect(json_response).to eq(evidence.summary)
+ end
+ end
+
+ context 'when project restricts the visibility of issues to project members only' do
+ let(:project) { create(:project, :repository, :issues_private) }
+
+ it_behaves_like 'evidence not found'
+ end
end
context 'when external authorization control is enabled' do
diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb
index 45f4433ed0a..96c38c1b726 100644
--- a/spec/controllers/projects/releases_controller_spec.rb
+++ b/spec/controllers/projects/releases_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ReleasesController do
+RSpec.describe Projects::ReleasesController do
let!(:project) { create(:project, :repository, :public) }
let_it_be(:private_project) { create(:project, :repository, :private) }
let_it_be(:developer) { create(:user) }
diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb
index 42032b4cad0..97eea7c7e9d 100644
--- a/spec/controllers/projects/repositories_controller_spec.rb
+++ b/spec/controllers/projects/repositories_controller_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Projects::RepositoriesController do
+RSpec.describe Projects::RepositoriesController do
let(:project) { create(:project, :repository) }
describe "GET archive" do
diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb
index 1893180fe9b..66f20bd50c4 100644
--- a/spec/controllers/projects/runners_controller_spec.rb
+++ b/spec/controllers/projects/runners_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RunnersController do
+RSpec.describe Projects::RunnersController do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:runner) { create(:ci_runner, :project, projects: [project]) }
diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb
index 203e1e49994..3071d0b7f54 100644
--- a/spec/controllers/projects/serverless/functions_controller_spec.rb
+++ b/spec/controllers/projects/serverless/functions_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Serverless::FunctionsController do
+RSpec.describe Projects::Serverless::FunctionsController do
include KubernetesHelpers
include ReactiveCachingHelpers
diff --git a/spec/controllers/projects/service_hook_logs_controller_spec.rb b/spec/controllers/projects/service_hook_logs_controller_spec.rb
index a5130cd6e32..97fb31f0546 100644
--- a/spec/controllers/projects/service_hook_logs_controller_spec.rb
+++ b/spec/controllers/projects/service_hook_logs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ServiceHookLogsController do
+RSpec.describe Projects::ServiceHookLogsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:service) { create(:drone_ci_service, project: project) }
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index c669119fa4e..04c74dfdefe 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ServicesController do
+RSpec.describe Projects::ServicesController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:service) { create(:jira_service, project: project) }
@@ -134,24 +134,50 @@ describe Projects::ServicesController do
describe 'PUT #update' do
describe 'as HTML' do
let(:service_params) { { active: true } }
+ let(:params) { project_params(service: service_params) }
+
+ let(:message) { 'Jira activated.' }
+ let(:redirect_url) { project_settings_integrations_path(project) }
before do
- put :update, params: project_params(service: service_params)
+ put :update, params: params
+ end
+
+ shared_examples 'service update' do
+ it 'redirects to the correct url with a flash message' do
+ expect(response).to redirect_to(redirect_url)
+ expect(flash[:notice]).to eq(message)
+ end
end
context 'when param `active` is set to true' do
- it 'activates the service and redirects to integrations paths' do
- expect(response).to redirect_to(project_settings_integrations_path(project))
- expect(flash[:notice]).to eq 'Jira activated.'
+ let(:params) { project_params(service: service_params, redirect_to: redirect) }
+
+ context 'when redirect_to param is present' do
+ let(:redirect) { '/redirect_here' }
+ let(:redirect_url) { redirect }
+
+ it_behaves_like 'service update'
+ end
+
+ context 'when redirect_to is an external domain' do
+ let(:redirect) { 'http://examle.com' }
+
+ it_behaves_like 'service update'
+ end
+
+ context 'when redirect_to param is an empty string' do
+ let(:redirect) { '' }
+
+ it_behaves_like 'service update'
end
end
context 'when param `active` is set to false' do
let(:service_params) { { active: false } }
+ let(:message) { 'Jira settings saved, but not activated.' }
- it 'does not activate the service but saves the settings' do
- expect(flash[:notice]).to eq 'Jira settings saved, but not activated.'
- end
+ it_behaves_like 'service update'
end
end
diff --git a/spec/controllers/projects/settings/access_tokens_controller_spec.rb b/spec/controllers/projects/settings/access_tokens_controller_spec.rb
index 884a5bc2836..4743ab2b7c1 100644
--- a/spec/controllers/projects/settings/access_tokens_controller_spec.rb
+++ b/spec/controllers/projects/settings/access_tokens_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::Settings::AccessTokensController do
+RSpec.describe Projects::Settings::AccessTokensController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index 6891af54eb4..8498ff49826 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::Settings::CiCdController do
+RSpec.describe Projects::Settings::CiCdController do
let_it_be(:user) { create(:user) }
let_it_be(:project_auto_devops) { create(:project_auto_devops) }
let(:project) { project_auto_devops.project }
diff --git a/spec/controllers/projects/settings/integrations_controller_spec.rb b/spec/controllers/projects/settings/integrations_controller_spec.rb
index 5d9fe3da912..0652786c787 100644
--- a/spec/controllers/projects/settings/integrations_controller_spec.rb
+++ b/spec/controllers/projects/settings/integrations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Settings::IntegrationsController do
+RSpec.describe Projects::Settings::IntegrationsController do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/settings/operations_controller_spec.rb b/spec/controllers/projects/settings/operations_controller_spec.rb
index c9afff0b73d..6b440e910ad 100644
--- a/spec/controllers/projects/settings/operations_controller_spec.rb
+++ b/spec/controllers/projects/settings/operations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Settings::OperationsController do
+RSpec.describe Projects::Settings::OperationsController do
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project) }
diff --git a/spec/controllers/projects/settings/repository_controller_spec.rb b/spec/controllers/projects/settings/repository_controller_spec.rb
index fb9cdd860dc..46dba691bc4 100644
--- a/spec/controllers/projects/settings/repository_controller_spec.rb
+++ b/spec/controllers/projects/settings/repository_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Settings::RepositoryController do
+RSpec.describe Projects::Settings::RepositoryController do
let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index b5f4929d8ce..8bbfaa8d327 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::SnippetsController do
+RSpec.describe Projects::SnippetsController do
include Gitlab::Routing
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/stages_controller_spec.rb b/spec/controllers/projects/stages_controller_spec.rb
index c38e3d2544f..dcf8607ae18 100644
--- a/spec/controllers/projects/stages_controller_spec.rb
+++ b/spec/controllers/projects/stages_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::StagesController do
+RSpec.describe Projects::StagesController do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/controllers/projects/starrers_controller_spec.rb b/spec/controllers/projects/starrers_controller_spec.rb
index 5774ff7c576..66888fa3024 100644
--- a/spec/controllers/projects/starrers_controller_spec.rb
+++ b/spec/controllers/projects/starrers_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::StarrersController do
+RSpec.describe Projects::StarrersController do
let(:user_1) { create(:user, name: 'John') }
let(:user_2) { create(:user, name: 'Michael') }
let(:private_user) { create(:user, name: 'Michael Douglas', private_profile: true) }
diff --git a/spec/controllers/projects/static_site_editor_controller_spec.rb b/spec/controllers/projects/static_site_editor_controller_spec.rb
index 7b470254de1..384218504b9 100644
--- a/spec/controllers/projects/static_site_editor_controller_spec.rb
+++ b/spec/controllers/projects/static_site_editor_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::StaticSiteEditorController do
+RSpec.describe Projects::StaticSiteEditorController do
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/tags/releases_controller_spec.rb b/spec/controllers/projects/tags/releases_controller_spec.rb
index cb12e074732..b3d4d944440 100644
--- a/spec/controllers/projects/tags/releases_controller_spec.rb
+++ b/spec/controllers/projects/tags/releases_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Tags::ReleasesController do
+RSpec.describe Projects::Tags::ReleasesController do
let!(:project) { create(:project, :repository) }
let!(:user) { create(:user) }
let!(:release) { create(:release, project: project) }
@@ -16,7 +16,7 @@ describe Projects::Tags::ReleasesController do
describe 'GET #edit' do
it 'initializes a new release' do
tag_id = release.tag
- project.releases.destroy_all # rubocop: disable DestroyAll
+ project.releases.destroy_all # rubocop: disable Cop/DestroyAll
response = get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: tag_id }
diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb
index 15ef1c65c53..122d1b072d0 100644
--- a/spec/controllers/projects/tags_controller_spec.rb
+++ b/spec/controllers/projects/tags_controller_spec.rb
@@ -2,10 +2,11 @@
require 'spec_helper'
-describe Projects::TagsController do
+RSpec.describe Projects::TagsController do
let(:project) { create(:project, :public, :repository) }
let!(:release) { create(:release, project: project) }
let!(:invalid_release) { create(:release, project: project, tag: 'does-not-exist') }
+ let(:user) { create(:user) }
describe 'GET index' do
before do
@@ -61,4 +62,69 @@ describe Projects::TagsController do
end
end
end
+
+ describe 'POST #create' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ let(:release_description) { nil }
+ let(:request) do
+ post(:create, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ tag_name: '1.0',
+ ref: 'master',
+ release_description: release_description
+ })
+ end
+
+ it 'creates tag' do
+ request
+
+ expect(response).to have_gitlab_http_status(:found)
+ expect(project.repository.find_tag('1.0')).to be_present
+ end
+
+ # TODO: remove this with the release creation moved to it's own form https://gitlab.com/gitlab-org/gitlab/-/issues/214245
+ context 'when release description is set' do
+ let(:release_description) { 'some release description' }
+
+ it 'creates tag and release' do
+ request
+
+ expect(response).to have_gitlab_http_status(:found)
+ expect(project.repository.find_tag('1.0')).to be_present
+
+ release = project.releases.find_by_tag!('1.0')
+
+ expect(release).to be_present
+ expect(release.description).to eq(release_description)
+ end
+
+ it 'passes the last pipeline for evidence creation', :sidekiq_inline do
+ sha = project.repository.commit('master').sha
+ create(:ci_empty_pipeline, sha: sha, project: project) # old pipeline
+ pipeline = create(:ci_empty_pipeline, sha: sha, project: project)
+
+ # simulating pipeline creation by new tag
+ expect_any_instance_of(Repository).to receive(:add_tag).and_wrap_original do |m, *args|
+ create(:ci_empty_pipeline, sha: sha, project: project)
+ m.call(*args)
+ end
+
+ expect_next_instance_of(Releases::CreateEvidenceService, anything, pipeline: pipeline) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+
+ request
+
+ release = project.releases.find_by_tag!('1.0')
+
+ expect(release).to be_present
+ expect(release.description).to eq(release_description)
+ end
+ end
+ end
end
diff --git a/spec/controllers/projects/templates_controller_spec.rb b/spec/controllers/projects/templates_controller_spec.rb
index fcd9b4aa8bd..40632e0dea7 100644
--- a/spec/controllers/projects/templates_controller_spec.rb
+++ b/spec/controllers/projects/templates_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::TemplatesController do
+RSpec.describe Projects::TemplatesController do
let(:project) { create(:project, :repository, :private) }
let(:user) { create(:user) }
let(:file_path_1) { '.gitlab/issue_templates/issue_template.md' }
diff --git a/spec/controllers/projects/todos_controller_spec.rb b/spec/controllers/projects/todos_controller_spec.rb
index b7d40d2a452..e1e1e455094 100644
--- a/spec/controllers/projects/todos_controller_spec.rb
+++ b/spec/controllers/projects/todos_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::TodosController do
+RSpec.describe Projects::TodosController do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb
index 96838383540..f6ec04d4dd7 100644
--- a/spec/controllers/projects/tree_controller_spec.rb
+++ b/spec/controllers/projects/tree_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::TreeController do
+RSpec.describe Projects::TreeController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/uploads_controller_spec.rb b/spec/controllers/projects/uploads_controller_spec.rb
index bb5415ee62c..dda58f06a37 100644
--- a/spec/controllers/projects/uploads_controller_spec.rb
+++ b/spec/controllers/projects/uploads_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UploadsController do
+RSpec.describe Projects::UploadsController do
include WorkhorseHelpers
let(:model) { create(:project, :public) }
diff --git a/spec/controllers/projects/usage_ping_controller_spec.rb b/spec/controllers/projects/usage_ping_controller_spec.rb
index a68967c228f..9ace072d561 100644
--- a/spec/controllers/projects/usage_ping_controller_spec.rb
+++ b/spec/controllers/projects/usage_ping_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UsagePingController do
+RSpec.describe Projects::UsagePingController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/variables_controller_spec.rb b/spec/controllers/projects/variables_controller_spec.rb
index 21e106660d0..8bb4c2dae4b 100644
--- a/spec/controllers/projects/variables_controller_spec.rb
+++ b/spec/controllers/projects/variables_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::VariablesController do
+RSpec.describe Projects::VariablesController do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/web_ide_terminals_controller_spec.rb b/spec/controllers/projects/web_ide_terminals_controller_spec.rb
new file mode 100644
index 00000000000..2ae5899c258
--- /dev/null
+++ b/spec/controllers/projects/web_ide_terminals_controller_spec.rb
@@ -0,0 +1,304 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::WebIdeTerminalsController do
+ let_it_be(:owner) { create(:owner) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:project) { create(:project, :private, :repository, namespace: owner.namespace) }
+ let(:pipeline) { create(:ci_pipeline, project: project, source: :webide, config_source: :webide_source, user: user) }
+ let(:job) { create(:ci_build, pipeline: pipeline, user: user, project: project) }
+ let(:user) { maintainer }
+
+ before do
+ project.add_maintainer(maintainer)
+ project.add_developer(developer)
+ project.add_reporter(reporter)
+ project.add_guest(guest)
+
+ sign_in(user)
+ end
+
+ shared_examples 'terminal access rights' do
+ context 'with admin' do
+ let(:user) { admin }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'with owner' do
+ let(:user) { owner }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with maintainer' do
+ let(:user) { maintainer }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with developer' do
+ let(:user) { developer }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with reporter' do
+ let(:user) { reporter }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with guest' do
+ let(:user) { guest }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with non member' do
+ let(:user) { create(:user) }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ shared_examples 'when pipeline is not from a webide source' do
+ context 'with admin' do
+ let(:user) { admin }
+ let(:pipeline) { create(:ci_pipeline, project: project, source: :chat, user: user) }
+
+ it 'returns 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ describe 'GET show' do
+ before do
+ get(:show, params: { namespace_id: project.namespace.to_param, project_id: project, id: job.id })
+ end
+
+ it_behaves_like 'terminal access rights'
+ it_behaves_like 'when pipeline is not from a webide source'
+ end
+
+ describe 'POST check_config' do
+ let(:result) { { status: :success } }
+
+ before do
+ allow_next_instance_of(::Ci::WebIdeConfigService) do |instance|
+ allow(instance).to receive(:execute).and_return(result)
+ end
+
+ post :check_config, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ branch: 'master'
+ }
+ end
+
+ it_behaves_like 'terminal access rights'
+
+ context 'when invalid config file' do
+ let(:user) { admin }
+ let(:result) { { status: :error } }
+
+ it 'returns 422', :enable_admin_mode do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
+ end
+ end
+
+ describe 'POST create' do
+ let(:branch) { 'master' }
+
+ subject do
+ post :create, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ branch: branch
+ }
+ end
+
+ context 'when terminal job is created successfully' do
+ let(:build) { create(:ci_build, project: project) }
+ let(:pipeline) { build.pipeline }
+
+ before do
+ allow_next_instance_of(::Ci::CreateWebIdeTerminalService) do |instance|
+ allow(instance).to receive(:execute).and_return(status: :success, pipeline: pipeline)
+ end
+ end
+
+ context 'access rights' do
+ before do
+ subject
+ end
+
+ it_behaves_like 'terminal access rights'
+ end
+
+ it 'increases the web ide terminal counter' do
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:increment_terminals_count)
+
+ subject
+ end
+ end
+
+ shared_examples 'web ide terminal usage counter' do
+ it 'does not increase', :enable_admin_mode do
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).not_to receive(:increment_terminals_count)
+
+ subject
+ end
+ end
+
+ context 'when branch does not exist' do
+ let(:user) { admin }
+ let(:branch) { 'foobar' }
+
+ it 'returns 400', :enable_admin_mode do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it_behaves_like 'web ide terminal usage counter'
+ end
+
+ context 'when there is an error creating the job' do
+ let(:user) { admin }
+
+ before do
+ allow_next_instance_of(::Ci::CreateWebIdeTerminalService) do |instance|
+ allow(instance).to receive(:execute).and_return(status: :error, message: 'foobar')
+ end
+ end
+
+ it 'returns 400', :enable_admin_mode do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it_behaves_like 'web ide terminal usage counter'
+ end
+
+ context 'when the current build is nil' do
+ let(:user) { admin }
+
+ before do
+ allow(pipeline).to receive(:builds).and_return([])
+ allow_next_instance_of(::Ci::CreateWebIdeTerminalService) do |instance|
+ allow(instance).to receive(:execute).and_return(status: :success, pipeline: pipeline)
+ end
+ end
+
+ it 'returns 400', :enable_admin_mode do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+
+ it_behaves_like 'web ide terminal usage counter'
+ end
+ end
+
+ describe 'POST cancel' do
+ let(:job) { create(:ci_build, :running, pipeline: pipeline, user: user, project: project) }
+
+ before do
+ post(:cancel, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: job.id
+ })
+ end
+
+ it_behaves_like 'terminal access rights'
+ it_behaves_like 'when pipeline is not from a webide source'
+
+ context 'when job is not cancelable' do
+ let!(:job) { create(:ci_build, :failed, pipeline: pipeline, user: user) }
+
+ it 'returns 422' do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
+ end
+ end
+
+ describe 'POST retry' do
+ let(:status) { :failed }
+ let(:job) { create(:ci_build, status, pipeline: pipeline, user: user, project: project) }
+
+ before do
+ post(:retry, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: job.id
+ })
+ end
+
+ it_behaves_like 'terminal access rights'
+ it_behaves_like 'when pipeline is not from a webide source'
+
+ context 'when job is not retryable' do
+ let(:status) { :running }
+
+ it 'returns 422' do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
+ end
+
+ context 'when job is cancelled' do
+ let(:status) { :canceled }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when job fails' do
+ let(:status) { :failed }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'when job is successful' do
+ let(:status) { :success }
+
+ it 'returns 200' do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/wikis_controller_spec.rb b/spec/controllers/projects/wikis_controller_spec.rb
index b4bbf76ce18..4e58822b613 100644
--- a/spec/controllers/projects/wikis_controller_spec.rb
+++ b/spec/controllers/projects/wikis_controller_spec.rb
@@ -2,283 +2,9 @@
require 'spec_helper'
-describe Projects::WikisController do
- let_it_be(:project) { create(:project, :public, :repository) }
- let(:user) { project.owner }
- let(:project_wiki) { ProjectWiki.new(project, user) }
- let(:wiki) { project_wiki.wiki }
- let(:wiki_title) { 'page title test' }
-
- before do
- create_page(wiki_title, 'hello world')
-
- sign_in(user)
- end
-
- after do
- destroy_page(wiki_title)
- end
-
- describe 'GET #new' do
- subject { get :new, params: { namespace_id: project.namespace, project_id: project } }
-
- it 'redirects to #show and appends a `random_title` param' do
- subject
-
- expect(response).to have_gitlab_http_status(:found)
- expect(Rails.application.routes.recognize_path(response.redirect_url)).to include(
- controller: 'projects/wikis',
- action: 'show'
- )
- expect(response.redirect_url).to match(/\?random_title=true\Z/)
- end
- end
-
- describe 'GET #pages' do
- subject { get :pages, params: { namespace_id: project.namespace, project_id: project, id: wiki_title } }
-
- it 'does not load the pages content' do
- expect(controller).to receive(:load_wiki).and_return(project_wiki)
-
- expect(project_wiki).to receive(:list_pages).twice.and_call_original
-
- subject
- end
- end
-
- describe 'GET #history' do
- before do
- allow(controller)
- .to receive(:can?)
- .with(any_args)
- .and_call_original
-
- # The :create_wiki permission is irrelevant to reading history.
- expect(controller)
- .not_to receive(:can?)
- .with(anything, :create_wiki, any_args)
-
- allow(controller)
- .to receive(:can?)
- .with(anything, :read_wiki, any_args)
- .and_return(allow_read_wiki)
- end
-
- shared_examples 'fetching history' do |expected_status|
- before do
- get :history, params: { namespace_id: project.namespace, project_id: project, id: wiki_title }
- end
-
- it "returns status #{expected_status}" do
- expect(response).to have_gitlab_http_status(expected_status)
- end
- end
-
- it_behaves_like 'fetching history', :ok do
- let(:allow_read_wiki) { true }
-
- it 'assigns @page_versions' do
- expect(assigns(:page_versions)).to be_present
- end
- end
-
- it_behaves_like 'fetching history', :not_found do
- let(:allow_read_wiki) { false }
- end
- end
-
- describe 'GET #show' do
- render_views
-
- let(:random_title) { nil }
-
- subject { get :show, params: { namespace_id: project.namespace, project_id: project, id: id, random_title: random_title } }
-
- context 'when page exists' do
- let(:id) { wiki_title }
-
- it 'limits the retrieved pages for the sidebar' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(assigns(:page).title).to eq(wiki_title)
- expect(assigns(:sidebar_wiki_entries)).to contain_exactly(an_instance_of(WikiPage))
- expect(assigns(:sidebar_limited)).to be(false)
- end
-
- context 'when page content encoding is invalid' do
- it 'sets flash error' do
- allow(controller).to receive(:valid_encoding?).and_return(false)
-
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(flash[:notice]).to eq(_('The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.'))
- end
- end
- end
-
- context 'when the page does not exist' do
- let(:id) { 'does not exist' }
-
- before do
- subject
- end
-
- it 'builds a new wiki page with the id as the title' do
- expect(assigns(:page).title).to eq(id)
- end
-
- context 'when a random_title param is present' do
- let(:random_title) { true }
-
- it 'builds a new wiki page with no title' do
- expect(assigns(:page).title).to be_empty
- end
- end
- end
-
- context 'when page is a file' do
- include WikiHelpers
-
- let(:id) { upload_file_to_wiki(project, user, file_name) }
-
- context 'when file is an image' do
- let(:file_name) { 'dk.png' }
-
- it 'delivers the image' do
- subject
-
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
-
- context 'when file is a svg' do
- let(:file_name) { 'unsanitized.svg' }
-
- it 'delivers the image' do
- subject
-
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
- end
-
- it_behaves_like 'project cache control headers'
- end
-
- context 'when file is a pdf' do
- let(:file_name) { 'git-cheat-sheet.pdf' }
-
- it 'sets the content type to sets the content response headers' do
- subject
-
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
-
- it_behaves_like 'project cache control headers'
- end
- end
- end
-
- describe 'POST #preview_markdown' do
- it 'renders json in a correct format' do
- post :preview_markdown, params: { namespace_id: project.namespace, project_id: project, id: 'page/path', text: '*Markdown* text' }
-
- expect(json_response.keys).to match_array(%w(body references))
- end
- end
-
- describe 'GET #edit' do
- subject { get(:edit, params: { namespace_id: project.namespace, project_id: project, id: wiki_title }) }
-
- context 'when page content encoding is invalid' do
- it 'redirects to show' do
- allow(controller).to receive(:valid_encoding?).and_return(false)
-
- subject
-
- expect(response).to redirect_to_wiki(project, project_wiki.list_pages.first)
- end
- end
-
- context 'when the page has nil content' do
- let(:page) { create(:wiki_page) }
-
- it 'redirects to show' do
- allow(page).to receive(:content).and_return(nil)
- allow(controller).to receive(:find_page).and_return(page)
-
- subject
-
- expect(response).to redirect_to_wiki(project, page)
- end
- end
-
- context 'when page content encoding is valid' do
- render_views
-
- it 'shows the edit page' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.body).to include(s_('Wiki|Edit Page'))
- end
- end
- end
-
- describe 'PATCH #update' do
- let(:new_title) { 'New title' }
- let(:new_content) { 'New content' }
-
- subject do
- patch(:update,
- params: {
- namespace_id: project.namespace,
- project_id: project,
- id: wiki_title,
- wiki: { title: new_title, content: new_content }
- })
- end
-
- context 'when page content encoding is invalid' do
- it 'redirects to show' do
- allow(controller).to receive(:valid_encoding?).and_return(false)
-
- subject
- expect(response).to redirect_to_wiki(project, project_wiki.list_pages.first)
- end
- end
-
- context 'when page content encoding is valid' do
- render_views
-
- it 'updates the page' do
- subject
-
- wiki_page = project_wiki.list_pages(load_content: true).first
-
- expect(wiki_page.title).to eq new_title
- expect(wiki_page.content).to eq new_content
- end
- end
- end
-
- def create_page(name, content)
- wiki.write_page(name, :markdown, content, commit_details(name))
- end
-
- def commit_details(name)
- Gitlab::Git::Wiki::CommitDetails.new(user.id, user.username, user.name, user.email, "created page #{name}")
- end
-
- def destroy_page(title, dir = '')
- page = wiki.page(title: title, dir: dir)
- project_wiki.delete_page(page, "test commit")
- end
-
- def redirect_to_wiki(project, page)
- redirect_to(controller.project_wiki_path(project, page))
+RSpec.describe Projects::WikisController do
+ it_behaves_like 'wiki controller actions' do
+ let(:container) { create(:project, :public, :repository, namespace: user.namespace) }
+ let(:routing_params) { { namespace_id: container.namespace, project_id: container } }
end
end