diff options
Diffstat (limited to 'spec/controllers/projects')
23 files changed, 503 insertions, 286 deletions
diff --git a/spec/controllers/projects/alerting/notifications_controller_spec.rb b/spec/controllers/projects/alerting/notifications_controller_spec.rb index 33fd73c762a..b3d37723ccf 100644 --- a/spec/controllers/projects/alerting/notifications_controller_spec.rb +++ b/spec/controllers/projects/alerting/notifications_controller_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe Projects::Alerting::NotificationsController do let_it_be(:project) { create(:project) } let_it_be(:environment) { create(:environment, project: project) } + let(:params) { project_params } describe 'POST #create' do around do |example| @@ -20,7 +21,7 @@ RSpec.describe Projects::Alerting::NotificationsController do end def make_request - post :create, params: project_params, body: payload.to_json, as: :json + post :create, params: params, body: payload.to_json, as: :json end context 'when notification service succeeds' do @@ -53,26 +54,69 @@ RSpec.describe Projects::Alerting::NotificationsController do context 'bearer token' do context 'when set' do - it 'extracts bearer token' do - request.headers['HTTP_AUTHORIZATION'] = 'Bearer some token' + context 'when extractable' do + before do + request.headers['HTTP_AUTHORIZATION'] = 'Bearer some token' + end - expect(notify_service).to receive(:execute).with('some token') + it 'extracts bearer token' do + expect(notify_service).to receive(:execute).with('some token', nil) - make_request + make_request + end + + context 'with a corresponding integration' do + context 'with integration parameters specified' do + let_it_be_with_reload(:integration) { create(:alert_management_http_integration, project: project) } + let(:params) { project_params(endpoint_identifier: integration.endpoint_identifier, name: integration.name) } + + context 'the integration is active' do + it 'extracts and finds the integration' do + expect(notify_service).to receive(:execute).with('some token', integration) + + make_request + end + end + + context 'when the integration is inactive' do + before do + integration.update!(active: false) + end + + it 'does not find an integration' do + expect(notify_service).to receive(:execute).with('some token', nil) + + make_request + end + end + end + + context 'without integration parameters specified' do + let_it_be(:integration) { create(:alert_management_http_integration, :legacy, project: project) } + + it 'extracts and finds the legacy integration' do + expect(notify_service).to receive(:execute).with('some token', integration) + + make_request + end + end + end end - it 'pass nil if cannot extract a non-bearer token' do - request.headers['HTTP_AUTHORIZATION'] = 'some token' + context 'when inextractable' do + it 'passes nil for 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, nil) - make_request + make_request + end end end context 'when missing' do it 'passes nil' do - expect(notify_service).to receive(:execute).with(nil) + expect(notify_service).to receive(:execute).with(nil, nil) make_request end diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb index 16e9c845307..35878fe4c2d 100644 --- a/spec/controllers/projects/avatars_controller_spec.rb +++ b/spec/controllers/projects/avatars_controller_spec.rb @@ -3,14 +3,14 @@ require 'spec_helper' RSpec.describe Projects::AvatarsController do - let_it_be(:project) { create(:project, :repository) } + describe 'GET #show' do + let_it_be(:project) { create(:project, :public, :repository) } - before do - controller.instance_variable_set(:@project, project) - end + before do + controller.instance_variable_set(:@project, project) + end - describe 'GET #show' do - subject { get :show, params: { namespace_id: project.namespace, project_id: project } } + subject { get :show, params: { namespace_id: project.namespace, project_id: project.path } } context 'when repository has no avatar' do it 'shows 404' do @@ -37,6 +37,15 @@ RSpec.describe Projects::AvatarsController do expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq 'true' end + it 'sets appropriate caching headers' do + sign_in(project.owner) + subject + + expect(response.cache_control[:public]).to eq(true) + expect(response.cache_control[:max_age]).to eq(60) + expect(response.cache_control[:no_store]).to be_nil + end + it_behaves_like 'project cache control headers' end @@ -51,9 +60,16 @@ RSpec.describe Projects::AvatarsController do end describe 'DELETE #destroy' do + let(:project) { create(:project, :repository, avatar: fixture_file_upload("spec/fixtures/dk.png", "image/png")) } + + before do + sign_in(project.owner) + end + it 'removes avatar from DB by calling destroy' do - delete :destroy, params: { namespace_id: project.namespace.id, project_id: project.id } + delete :destroy, params: { namespace_id: project.namespace.path, project_id: project.path } + expect(response).to redirect_to(edit_project_path(project, anchor: 'js-general-project-settings')) expect(project.avatar.present?).to be_falsey expect(project).to be_valid end diff --git a/spec/controllers/projects/ci/lints_controller_spec.rb b/spec/controllers/projects/ci/lints_controller_spec.rb index 22f052e39b7..c4e040b0287 100644 --- a/spec/controllers/projects/ci/lints_controller_spec.rb +++ b/spec/controllers/projects/ci/lints_controller_spec.rb @@ -47,9 +47,9 @@ RSpec.describe Projects::Ci::LintsController do describe 'POST #create' do subject { post :create, params: params } - let(:format) { :html } - let(:params) { { namespace_id: project.namespace, project_id: project, content: content, format: format } } + let(:params) { { namespace_id: project.namespace, project_id: project, content: content, format: :json } } let(:remote_file_path) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' } + let(:parsed_body) { Gitlab::Json.parse(response.body) } let(:remote_file_content) do <<~HEREDOC @@ -72,17 +72,23 @@ RSpec.describe Projects::Ci::LintsController do HEREDOC end - shared_examples 'successful request with format json' do - context 'with format json' do - let(:format) { :json } - let(:parsed_body) { Gitlab::Json.parse(response.body) } + shared_examples 'returns a successful validation' do + before do + subject + end - it 'renders json' do - expect(response).to have_gitlab_http_status :ok - expect(response.content_type).to eq 'application/json' - expect(parsed_body).to include('errors', 'warnings', 'jobs', 'valid') - expect(parsed_body).to match_schema('entities/lint_result_entity') - end + it 'returns successfully' do + expect(response).to have_gitlab_http_status :ok + end + + it 'renders json' do + expect(response.content_type).to eq 'application/json' + expect(parsed_body).to include('errors', 'warnings', 'jobs', 'valid') + expect(parsed_body).to match_schema('entities/lint_result_entity') + end + + it 'retrieves project' do + expect(assigns(:project)).to eq(project) end end @@ -92,25 +98,7 @@ RSpec.describe Projects::Ci::LintsController do project.add_developer(user) end - shared_examples 'returns a successful validation' do - before do - subject - end - - it 'returns successfully' do - expect(response).to have_gitlab_http_status :ok - end - - it 'renders show page' do - expect(response).to render_template :show - end - - it 'retrieves project' do - expect(assigns(:project)).to eq(project) - end - - it_behaves_like 'successful request with format json' - end + it_behaves_like 'returns a successful validation' context 'using legacy validation (YamlProcessor)' do it_behaves_like 'returns a successful validation' @@ -135,20 +123,6 @@ RSpec.describe Projects::Ci::LintsController do subject end - - context 'when dry_run feature flag is disabled' do - before do - stub_feature_flags(ci_lint_creates_pipeline_with_dry_run: false) - end - - it_behaves_like 'returns a successful validation' - - it 'runs validations through YamlProcessor' do - expect(Gitlab::Ci::YamlProcessor).to receive(:new).and_call_original - - subject - end - end end end @@ -166,27 +140,23 @@ RSpec.describe Projects::Ci::LintsController do subject end + it_behaves_like 'returns a successful validation' + it 'assigns result with errors' do - expect(assigns[:result].errors).to match_array([ + expect(parsed_body['errors']).to match_array([ 'jobs rubocop config should implement a script: or a trigger: keyword', 'jobs config should contain at least one visible job' ]) end - it 'render show page' do - expect(response).to render_template :show - end - - it_behaves_like 'successful request with format json' - context 'with dry_run mode' do subject { post :create, params: params.merge(dry_run: 'true') } it 'assigns result with errors' do - expect(assigns[:result].errors).to eq(['jobs rubocop config should implement a script: or a trigger: keyword']) + expect(parsed_body['errors']).to eq(['jobs rubocop config should implement a script: or a trigger: keyword']) end - it_behaves_like 'successful request with format json' + it_behaves_like 'returns a successful validation' end end @@ -200,14 +170,6 @@ RSpec.describe Projects::Ci::LintsController do it 'responds with 404' do expect(response).to have_gitlab_http_status(:not_found) end - - context 'with format json' do - let(:format) { :json } - - it 'responds with 404' do - expect(response).to have_gitlab_http_status :not_found - end - end end end end diff --git a/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb b/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb new file mode 100644 index 00000000000..1bf6ff95c44 --- /dev/null +++ b/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::Ci::PipelineEditorController do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:user) { create(:user) } + + before do + sign_in(user) + end + + describe 'GET #show' do + context 'with enough privileges' do + before do + project.add_developer(user) + + get :show, params: { namespace_id: project.namespace, project_id: project } + end + + it { expect(response).to have_gitlab_http_status(:ok) } + + it 'renders show page' do + expect(response).to render_template :show + end + end + + context 'without enough privileges' do + before do + project.add_reporter(user) + + get :show, params: { namespace_id: project.namespace, project_id: project } + end + + it 'responds with 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when ci_pipeline_editor_page feature flag is disabled' do + before do + stub_feature_flags(ci_pipeline_editor_page: false) + project.add_developer(user) + + get :show, params: { namespace_id: project.namespace, project_id: project } + end + + it 'responds with 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + end +end diff --git a/spec/controllers/projects/cycle_analytics/events_controller_spec.rb b/spec/controllers/projects/cycle_analytics/events_controller_spec.rb index c5b72ff2b3b..f940da7ea35 100644 --- a/spec/controllers/projects/cycle_analytics/events_controller_spec.rb +++ b/spec/controllers/projects/cycle_analytics/events_controller_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Projects::CycleAnalytics::EventsController do project.add_maintainer(user) end - describe 'cycle analytics not set up flag' do + describe 'value stream analytics not set up flag' do context 'with no data' do it 'is empty' do get_issue diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb index e956065972f..24c2d568d9a 100644 --- a/spec/controllers/projects/cycle_analytics_controller_spec.rb +++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb @@ -32,7 +32,7 @@ RSpec.describe Projects::CycleAnalyticsController do end end - describe 'cycle analytics not set up flag' do + describe 'value stream analytics not set up flag' do context 'with no data' do it 'is true' do get(:show, diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb index 029b4210f19..5e09a50aa36 100644 --- a/spec/controllers/projects/imports_controller_spec.rb +++ b/spec/controllers/projects/imports_controller_spec.rb @@ -7,10 +7,21 @@ RSpec.describe Projects::ImportsController do let(:project) { create(:project) } before do - sign_in(user) + sign_in(user) if user end describe 'GET #show' do + context 'when user is not authenticated and the project is public' do + let(:user) { nil } + let(:project) { create(:project, :public) } + + it 'returns 404 response' do + get :show, params: { namespace_id: project.namespace.to_param, project_id: project } + + expect(response).to have_gitlab_http_status(:not_found) + end + end + context 'when the user has maintainer rights' do before do project.add_maintainer(user) diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index f956baa0e22..26e1842468b 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -52,14 +52,14 @@ RSpec.describe Projects::IssuesController do get :index, params: { namespace_id: project.namespace, project_id: project } expect(response).to redirect_to(project_issues_path(new_project)) - expect(response).to have_gitlab_http_status(:found) + expect(response).to have_gitlab_http_status(:moved_permanently) end it 'redirects from an old issue correctly' do get :show, params: { namespace_id: project.namespace, project_id: project, id: issue } expect(response).to redirect_to(project_issue_path(new_project, issue)) - expect(response).to have_gitlab_http_status(:found) + expect(response).to have_gitlab_http_status(:moved_permanently) end end end @@ -1869,7 +1869,7 @@ RSpec.describe Projects::IssuesController do } expect(response).to redirect_to(designs_project_issue_path(new_project, issue)) - expect(response).to have_gitlab_http_status(:found) + expect(response).to have_gitlab_http_status(:moved_permanently) end end end diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb index 91770a00081..bda1f1a3b1c 100644 --- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb @@ -383,6 +383,7 @@ RSpec.describe Projects::MergeRequests::DiffsController do environment: nil, merge_request: merge_request, diff_view: :inline, + merge_ref_head_diff: nil, pagination_data: { current_page: nil, next_page: nil, @@ -454,6 +455,31 @@ RSpec.describe Projects::MergeRequests::DiffsController do it_behaves_like 'successful request' end + context 'with paths param' do + let(:example_file_path) { "README" } + let(:file_path_option) { { paths: [example_file_path] } } + + subject do + go(file_path_option) + end + + it_behaves_like 'serializes diffs with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiffBatch } + let(:expected_options) do + collection_arguments(current_page: 1, total_pages: 1) + end + end + + it_behaves_like 'successful request' + + it 'filters down the response to the expected file path' do + subject + + expect(json_response["diff_files"].size).to eq(1) + expect(json_response["diff_files"].first["file_path"]).to eq(example_file_path) + end + end + context 'with default params' do subject { go } diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index ee194e5ff2f..f159f0e6099 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -6,14 +6,10 @@ RSpec.describe Projects::MergeRequestsController do include ProjectForksHelper include Gitlab::Routing - let(:project) { create(:project, :repository) } - let(:user) { project.owner } + let_it_be_with_refind(:project) { create(:project, :repository) } + let_it_be_with_reload(:project_public_with_private_builds) { create(:project, :repository, :public, :builds_private) } + let(:user) { project.owner } let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) } - let(:merge_request_with_conflicts) do - create(:merge_request, source_branch: 'conflict-resolvable', target_branch: 'conflict-start', source_project: project, merge_status: :unchecked) do |mr| - mr.mark_as_unmergeable - end - end before do sign_in(user) @@ -99,7 +95,8 @@ RSpec.describe Projects::MergeRequestsController do project, merge_request, 'json', - diff_head: true)) + diff_head: true, + view: 'inline')) end end @@ -107,7 +104,7 @@ RSpec.describe Projects::MergeRequestsController do render_views it 'renders merge request page' do - merge_request.merge_request_diff.destroy + merge_request.merge_request_diff.destroy! go(format: :html) @@ -147,7 +144,7 @@ RSpec.describe Projects::MergeRequestsController do let(:new_project) { create(:project) } before do - project.route.destroy + project.route.destroy! new_project.redirect_routes.create!(path: project.full_path) new_project.add_developer(user) end @@ -161,7 +158,7 @@ RSpec.describe Projects::MergeRequestsController do } expect(response).to redirect_to(project_merge_request_path(new_project, merge_request)) - expect(response).to have_gitlab_http_status(:found) + expect(response).to have_gitlab_http_status(:moved_permanently) end it 'redirects from an old merge request commits correctly' do @@ -173,7 +170,7 @@ RSpec.describe Projects::MergeRequestsController do } expect(response).to redirect_to(commits_project_merge_request_path(new_project, merge_request)) - expect(response).to have_gitlab_http_status(:found) + expect(response).to have_gitlab_http_status(:moved_permanently) end end end @@ -359,12 +356,11 @@ RSpec.describe Projects::MergeRequestsController do end context 'there is no source project' do - let(:project) { create(:project, :repository) } let(:forked_project) { fork_project_with_submodules(project) } let!(:merge_request) { create(:merge_request, source_project: forked_project, source_branch: 'add-submodule-version-bump', target_branch: 'master', target_project: project) } before do - forked_project.destroy + forked_project.destroy! end it 'closes MR without errors' do @@ -435,7 +431,7 @@ RSpec.describe Projects::MergeRequestsController do context 'when the merge request is not mergeable' do before do - merge_request.update(title: "WIP: #{merge_request.title}") + merge_request.update!(title: "WIP: #{merge_request.title}") post :merge, params: base_params end @@ -475,7 +471,7 @@ RSpec.describe Projects::MergeRequestsController do context 'when squash is passed as 1' do it 'updates the squash attribute on the MR to true' do - merge_request.update(squash: false) + merge_request.update!(squash: false) merge_with_sha(squash: '1') expect(merge_request.reload.squash_on_merge?).to be_truthy @@ -484,7 +480,7 @@ RSpec.describe Projects::MergeRequestsController do context 'when squash is passed as 0' do it 'updates the squash attribute on the MR to false' do - merge_request.update(squash: true) + merge_request.update!(squash: true) merge_with_sha(squash: '0') expect(merge_request.reload.squash_on_merge?).to be_falsey @@ -547,7 +543,7 @@ RSpec.describe Projects::MergeRequestsController do context 'and head pipeline is not the current one' do before do - head_pipeline.update(sha: 'not_current_sha') + head_pipeline.update!(sha: 'not_current_sha') end it 'returns :failed' do @@ -667,9 +663,9 @@ RSpec.describe Projects::MergeRequestsController do end context "when the user is owner" do - let(:owner) { create(:user) } - let(:namespace) { create(:namespace, owner: owner) } - let(:project) { create(:project, :repository, namespace: namespace) } + let_it_be(:owner) { create(:user) } + let_it_be(:namespace) { create(:namespace, owner: owner) } + let_it_be(:project) { create(:project, :repository, namespace: namespace) } before do sign_in owner @@ -765,7 +761,7 @@ RSpec.describe Projects::MergeRequestsController do end context 'with private builds on a public project' do - let(:project) { create(:project, :repository, :public, :builds_private) } + let(:project) { project_public_with_private_builds } context 'for a project owner' do it 'responds with serialized pipelines' do @@ -813,7 +809,7 @@ RSpec.describe Projects::MergeRequestsController do context 'with public builds' do let(:forked_project) do fork_project(project, fork_user, repository: true).tap do |new_project| - new_project.project_feature.update(builds_access_level: ProjectFeature::ENABLED) + new_project.project_feature.update!(builds_access_level: ProjectFeature::ENABLED) end end @@ -855,7 +851,7 @@ RSpec.describe Projects::MergeRequestsController do end describe 'GET exposed_artifacts' do - let(:merge_request) do + let_it_be(:merge_request) do create(:merge_request, :with_merge_request_pipeline, target_project: project, @@ -993,7 +989,7 @@ RSpec.describe Projects::MergeRequestsController do end describe 'GET coverage_reports' do - let(:merge_request) do + let_it_be(:merge_request) do create(:merge_request, :with_merge_request_pipeline, target_project: project, @@ -1123,7 +1119,7 @@ RSpec.describe Projects::MergeRequestsController do end describe 'GET terraform_reports' do - let(:merge_request) do + let_it_be(:merge_request) do create(:merge_request, :with_merge_request_pipeline, target_project: project, @@ -1271,7 +1267,7 @@ RSpec.describe Projects::MergeRequestsController do end describe 'GET test_reports' do - let(:merge_request) do + let_it_be(:merge_request) do create(:merge_request, :with_diffs, :with_merge_request_pipeline, @@ -1382,7 +1378,7 @@ RSpec.describe Projects::MergeRequestsController do end describe 'GET accessibility_reports' do - let(:merge_request) do + let_it_be(:merge_request) do create(:merge_request, :with_diffs, :with_merge_request_pipeline, @@ -1419,7 +1415,7 @@ RSpec.describe Projects::MergeRequestsController do end context 'permissions on a public project with private CI/CD' do - let(:project) { create(:project, :repository, :public, :builds_private) } + let(:project) { project_public_with_private_builds } let(:accessibility_comparison) { { status: :parsed, data: { summary: 1 } } } context 'while signed out' do @@ -1505,7 +1501,7 @@ RSpec.describe Projects::MergeRequestsController do describe 'POST remove_wip' do before do merge_request.title = merge_request.wip_title - merge_request.save + merge_request.save! post :remove_wip, params: { @@ -1626,7 +1622,7 @@ RSpec.describe Projects::MergeRequestsController do it 'links to the environment on that project', :sidekiq_might_not_need_inline do get_ci_environments_status - expect(json_response.first['url']).to match /#{forked.full_path}/ + expect(json_response.first['url']).to match(/#{forked.full_path}/) end context "when environment_target is 'merge_commit'", :sidekiq_might_not_need_inline do @@ -1653,7 +1649,7 @@ RSpec.describe Projects::MergeRequestsController do get_ci_environments_status(environment_target: 'merge_commit') expect(response).to have_gitlab_http_status(:ok) - expect(json_response.first['url']).to match /#{project.full_path}/ + expect(json_response.first['url']).to match(/#{project.full_path}/) end end end @@ -1773,7 +1769,7 @@ RSpec.describe Projects::MergeRequestsController do context 'with project member visibility on a public project' do let(:user) { create(:user) } - let(:project) { create(:project, :repository, :public, :builds_private) } + let(:project) { project_public_with_private_builds } it 'returns pipeline data to project members' do project.add_developer(user) @@ -1999,4 +1995,21 @@ RSpec.describe Projects::MergeRequestsController do expect(assigns(:noteable)).not_to be_nil end end + + describe 'POST export_csv' do + subject { post :export_csv, params: { namespace_id: project.namespace, project_id: project } } + + it 'redirects to the merge request index' do + subject + + expect(response).to redirect_to(project_merge_requests_path(project)) + expect(response.flash[:notice]).to match(/\AYour CSV export has started/i) + end + + it 'enqueues an IssuableExportCsvWorker worker' do + expect(IssuableExportCsvWorker).to receive(:perform_async).with(:merge_request, user.id, project.id, anything) + + subject + end + end end diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb index 8c59b2b378f..d76432f71b3 100644 --- a/spec/controllers/projects/notes_controller_spec.rb +++ b/spec/controllers/projects/notes_controller_spec.rb @@ -113,6 +113,8 @@ RSpec.describe Projects::NotesController do end it 'returns the first page of notes' do + expect(Gitlab::EtagCaching::Middleware).to receive(:skip!) + get :index, params: request_params expect(json_response['notes'].count).to eq(page_1.count) @@ -122,6 +124,8 @@ RSpec.describe Projects::NotesController do end it 'returns the second page of notes' do + expect(Gitlab::EtagCaching::Middleware).to receive(:skip!) + request.headers['X-Last-Fetched-At'] = page_1_boundary get :index, params: request_params @@ -133,6 +137,8 @@ RSpec.describe Projects::NotesController do end it 'returns the final page of notes' do + expect(Gitlab::EtagCaching::Middleware).to receive(:skip!) + request.headers['X-Last-Fetched-At'] = page_2_boundary get :index, params: request_params @@ -142,6 +148,19 @@ RSpec.describe Projects::NotesController do expect(json_response['last_fetched_at']).to eq(microseconds(Time.zone.now)) expect(response.headers['Poll-Interval'].to_i).to be > 1 end + + it 'returns an empty page of notes' do + expect(Gitlab::EtagCaching::Middleware).not_to receive(:skip!) + + request.headers['X-Last-Fetched-At'] = microseconds(Time.zone.now) + + get :index, params: request_params + + expect(json_response['notes']).to be_empty + expect(json_response['more']).to be_falsy + expect(json_response['last_fetched_at']).to eq(microseconds(Time.zone.now)) + expect(response.headers['Poll-Interval'].to_i).to be > 1 + end end context 'feature flag disabled' do diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb index b3921164c81..43cf1a16051 100644 --- a/spec/controllers/projects/raw_controller_spec.rb +++ b/spec/controllers/projects/raw_controller_spec.rb @@ -33,11 +33,6 @@ RSpec.describe Projects::RawController do it_behaves_like 'project cache control headers' it_behaves_like 'content disposition headers' - it_behaves_like 'uncached response' do - before do - subject - end - end end context 'image header' do @@ -225,6 +220,32 @@ RSpec.describe Projects::RawController do end end end + + describe 'caching' do + def request_file + get(:show, params: { namespace_id: project.namespace, project_id: project, id: 'master/README.md' }) + end + + it 'sets appropriate caching headers' do + sign_in create(:user) + request_file + + expect(response.cache_control[:public]).to eq(true) + expect(response.cache_control[:max_age]).to eq(60) + expect(response.cache_control[:no_store]).to be_nil + end + + context 'when If-None-Match header is set' do + it 'returns a 304 status' do + request_file + + request.headers['If-None-Match'] = response.headers['ETag'] + request_file + + expect(response).to have_gitlab_http_status(:not_modified) + end + end + end end def execute_raw_requests(requests:, project:, file_path:, **params) diff --git a/spec/controllers/projects/registry/repositories_controller_spec.rb b/spec/controllers/projects/registry/repositories_controller_spec.rb index 098fa9bac2c..9b803edd463 100644 --- a/spec/controllers/projects/registry/repositories_controller_spec.rb +++ b/spec/controllers/projects/registry/repositories_controller_spec.rb @@ -50,18 +50,17 @@ RSpec.describe Projects::Registry::RepositoriesController do tags: %w[rc1 latest]) end - it 'successfully renders container repositories' do - expect(Gitlab::Tracking).not_to receive(:event) - + it 'successfully renders container repositories', :snowplow do go_to_index + expect_no_snowplow_event expect(response).to have_gitlab_http_status(:ok) end - it 'tracks the event' do - expect(Gitlab::Tracking).to receive(:event).with(anything, 'list_repositories', {}) - + it 'tracks the event', :snowplow do go_to_index(format: :json) + + expect_snowplow_event(category: anything, action: 'list_repositories') end it 'creates a root container repository' do @@ -132,11 +131,12 @@ RSpec.describe Projects::Registry::RepositoriesController do expect(response).to have_gitlab_http_status(:no_content) end - it 'tracks the event' do - expect(Gitlab::Tracking).to receive(:event).with(anything, 'delete_repository', {}) + it 'tracks the event', :snowplow do allow(DeleteContainerRepositoryWorker).to receive(:perform_async).with(user.id, repository.id) delete_repository(repository) + + expect_snowplow_event(category: anything, action: 'delete_repository') end end end diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb index 59df9e78a3c..5bff89b4308 100644 --- a/spec/controllers/projects/registry/tags_controller_spec.rb +++ b/spec/controllers/projects/registry/tags_controller_spec.rb @@ -39,10 +39,10 @@ RSpec.describe Projects::Registry::TagsController do expect(response).to include_pagination_headers end - it 'tracks the event' do - expect(Gitlab::Tracking).to receive(:event).with(anything, 'list_tags', {}) - + it 'tracks the event', :snowplow do get_tags + + expect_snowplow_event(category: anything, action: 'list_tags') end end @@ -109,7 +109,7 @@ RSpec.describe Projects::Registry::TagsController do it 'tracks the event' do expect_delete_tags(%w[test.]) - expect(controller).to receive(:track_event).with(:delete_tag, {}) + expect(controller).to receive(:track_event).with(:delete_tag) destroy_tag('test.') end @@ -148,11 +148,11 @@ RSpec.describe Projects::Registry::TagsController do bulk_destroy_tags(tags) end - it 'tracks the event' do + it 'tracks the event', :snowplow do expect_delete_tags(tags) - expect(Gitlab::Tracking).to receive(:event).with(anything, 'delete_tag_bulk', {}) - bulk_destroy_tags(tags) + + expect_snowplow_event(category: anything, action: 'delete_tag_bulk') end end end diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb index 420d818daeb..07fb03b39c6 100644 --- a/spec/controllers/projects/releases_controller_spec.rb +++ b/spec/controllers/projects/releases_controller_spec.rb @@ -201,102 +201,7 @@ RSpec.describe Projects::ReleasesController do end end - context 'GET #downloads' do - subject do - get :downloads, params: { namespace_id: project.namespace, project_id: project, tag: tag, filepath: filepath } - end - - before do - sign_in(user) - end - - let(:release) { create(:release, project: project, tag: tag ) } - let!(:link) { create(:release_link, release: release, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', url: 'https://downloads.example.com/bin/gitlab-linux-amd64') } - let(:tag) { 'v11.9.0-rc2' } - - context 'valid filepath' do - let(:filepath) { CGI.escape('/binaries/linux-amd64') } - - it 'redirects to the asset direct link' do - subject - - expect(response).to redirect_to('https://downloads.example.com/bin/gitlab-linux-amd64') - end - - it 'redirects with a status of 302' do - subject - - expect(response).to have_gitlab_http_status(:redirect) - end - end - - context 'invalid filepath' do - let(:filepath) { CGI.escape('/binaries/win32') } - - it 'is not found' do - subject - - expect(response).to have_gitlab_http_status(:not_found) - end - end - end - - context 'GET #downloads' do - subject do - get :downloads, params: { - namespace_id: project.namespace, - project_id: project, - tag: tag, - filepath: filepath - } - end - - before do - sign_in(user) - end - - let(:release) { create(:release, project: project, tag: tag ) } - let(:tag) { 'v11.9.0-rc2' } - let(:db_filepath) { '/binaries/linux-amd64' } - let!(:link) do - create :release_link, - release: release, - name: 'linux-amd64 binaries', - filepath: db_filepath, - url: 'https://downloads.example.com/bin/gitlab-linux-amd64' - end - - context 'valid filepath' do - let(:filepath) { CGI.escape('/binaries/linux-amd64') } - - it 'redirects to the asset direct link' do - subject - - expect(response).to redirect_to(link.url) - end - end - - context 'invalid filepath' do - let(:filepath) { CGI.escape('/binaries/win32') } - - it 'is not found' do - subject - - expect(response).to have_gitlab_http_status(:not_found) - end - end - - context 'ignores filepath extension' do - let(:db_filepath) { '/binaries/linux-amd64.json' } - let(:filepath) { CGI.escape(db_filepath) } - - it 'redirects to the asset direct link' do - subject - - expect(response).to redirect_to(link.url) - end - end - end + # `GET #downloads` is addressed in spec/requests/projects/releases_controller_spec.rb private diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb index 97eea7c7e9d..e7f4a8a1422 100644 --- a/spec/controllers/projects/repositories_controller_spec.rb +++ b/spec/controllers/projects/repositories_controller_spec.rb @@ -122,7 +122,9 @@ RSpec.describe Projects::RepositoriesController do expect(response).to have_gitlab_http_status(:ok) expect(response.header['ETag']).to be_present - expect(response.header['Cache-Control']).to include('max-age=60, private') + expect(response.cache_control[:public]).to eq(false) + expect(response.cache_control[:max_age]).to eq(60) + expect(response.cache_control[:no_store]).to be_nil end context 'when project is public' do diff --git a/spec/controllers/projects/settings/operations_controller_spec.rb b/spec/controllers/projects/settings/operations_controller_spec.rb index 9fc9da1265e..46f69eaf96a 100644 --- a/spec/controllers/projects/settings/operations_controller_spec.rb +++ b/spec/controllers/projects/settings/operations_controller_spec.rb @@ -166,23 +166,22 @@ RSpec.describe Projects::Settings::OperationsController do context 'updating each incident management setting' do let(:new_incident_management_settings) { {} } - shared_examples 'a gitlab tracking event' do |params, event_key| - it "creates a gitlab tracking event #{event_key}" do + shared_examples 'a gitlab tracking event' do |params, event_key, **args| + it "creates a gitlab tracking event #{event_key}", :snowplow do new_incident_management_settings = params - expect(Gitlab::Tracking).to receive(:event) - .with('IncidentManagement::Settings', event_key, any_args) - patch :update, params: project_params(project, incident_management_setting_attributes: new_incident_management_settings) project.reload + + expect_snowplow_event(category: 'IncidentManagement::Settings', action: event_key, **args) end end it_behaves_like 'a gitlab tracking event', { create_issue: '1' }, 'enabled_issue_auto_creation_on_alerts' it_behaves_like 'a gitlab tracking event', { create_issue: '0' }, 'disabled_issue_auto_creation_on_alerts' - it_behaves_like 'a gitlab tracking event', { issue_template_key: 'template' }, 'enabled_issue_template_on_alerts' - it_behaves_like 'a gitlab tracking event', { issue_template_key: nil }, 'disabled_issue_template_on_alerts' + it_behaves_like 'a gitlab tracking event', { issue_template_key: 'template' }, 'enabled_issue_template_on_alerts', label: "Template name", property: "template" + it_behaves_like 'a gitlab tracking event', { issue_template_key: nil }, 'disabled_issue_template_on_alerts', label: "Template name", property: "" it_behaves_like 'a gitlab tracking event', { send_email: '1' }, 'enabled_sending_emails' it_behaves_like 'a gitlab tracking event', { send_email: '0' }, 'disabled_sending_emails' it_behaves_like 'a gitlab tracking event', { pagerduty_active: '1' }, 'enabled_pagerduty_webhook' diff --git a/spec/controllers/projects/settings/repository_controller_spec.rb b/spec/controllers/projects/settings/repository_controller_spec.rb index d93f23ae142..394f1ff28f2 100644 --- a/spec/controllers/projects/settings/repository_controller_spec.rb +++ b/spec/controllers/projects/settings/repository_controller_spec.rb @@ -23,13 +23,15 @@ RSpec.describe Projects::Settings::RepositoryController do describe 'PUT cleanup' do let(:object_map) { fixture_file_upload('spec/fixtures/bfg_object_map.txt') } - it 'enqueues a RepositoryCleanupWorker' do - allow(RepositoryCleanupWorker).to receive(:perform_async) + it 'enqueues a project cleanup' do + expect(Projects::CleanupService) + .to receive(:enqueue) + .with(project, user, anything) + .and_return(status: :success) - put :cleanup, params: { namespace_id: project.namespace, project_id: project, project: { object_map: object_map } } + put :cleanup, params: { namespace_id: project.namespace, project_id: project, project: { bfg_object_map: object_map } } expect(response).to redirect_to project_settings_repository_path(project) - expect(RepositoryCleanupWorker).to have_received(:perform_async).once end end diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb index 6b394fab14c..f9221c5a4ef 100644 --- a/spec/controllers/projects/snippets_controller_spec.rb +++ b/spec/controllers/projects/snippets_controller_spec.rb @@ -180,16 +180,6 @@ RSpec.describe Projects::SnippetsController do end end - describe 'GET #show as JSON' do - it 'renders the blob from the repository' do - project_snippet = create(:project_snippet, :public, :repository, project: project, author: user) - - get :show, params: { namespace_id: project.namespace, project_id: project, id: project_snippet.to_param }, format: :json - - expect(assigns(:blob)).to eq(project_snippet.blobs.first) - end - end - describe "GET #show for embeddable content" do let(:project_snippet) { create(:project_snippet, :repository, snippet_permission, project: project, author: user) } let(:extra_params) { {} } diff --git a/spec/controllers/projects/static_site_editor_controller_spec.rb b/spec/controllers/projects/static_site_editor_controller_spec.rb index 6ea730cbf27..867b2b51039 100644 --- a/spec/controllers/projects/static_site_editor_controller_spec.rb +++ b/spec/controllers/projects/static_site_editor_controller_spec.rb @@ -105,7 +105,8 @@ RSpec.describe Projects::StaticSiteEditorController do foo: 'bar' } }, - a_boolean: true + a_boolean: true, + a_nil: nil } end @@ -130,6 +131,10 @@ RSpec.describe Projects::StaticSiteEditorController do it 'serializes data values which are hashes to JSON' do expect(assigns_data[:a_hash]).to eq('{"a_deeper_hash":{"foo":"bar"}}') end + + it 'serializes data values which are nil to an empty string' do + expect(assigns_data[:a_nil]).to eq('') + end end end end diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb index 57760088183..efb57494f82 100644 --- a/spec/controllers/projects/tags_controller_spec.rb +++ b/spec/controllers/projects/tags_controller_spec.rb @@ -9,18 +9,75 @@ RSpec.describe Projects::TagsController do let(:user) { create(:user) } describe 'GET index' do - before do - get :index, params: { namespace_id: project.namespace.to_param, project_id: project } - end + subject { get :index, params: { namespace_id: project.namespace.to_param, project_id: project } } it 'returns the tags for the page' do + subject + expect(assigns(:tags).map(&:name)).to include('v1.1.0', 'v1.0.0') end it 'returns releases matching those tags' do + subject + expect(assigns(:releases)).to include(release) expect(assigns(:releases)).not_to include(invalid_release) end + + context '@tag_pipeline_status' do + context 'when no pipelines exist' do + it 'is empty' do + subject + + expect(assigns(:tag_pipeline_statuses)).to be_empty + end + end + + context 'when multiple tags exist' do + before do + create(:ci_pipeline, + project: project, + ref: 'v1.1.0', + sha: project.commit('v1.1.0').sha, + status: :running) + create(:ci_pipeline, + project: project, + ref: 'v1.0.0', + sha: project.commit('v1.0.0').sha, + status: :success) + end + + it 'all relevant commit statuses are received' do + subject + + expect(assigns(:tag_pipeline_statuses)['v1.1.0'].group).to eq("running") + expect(assigns(:tag_pipeline_statuses)['v1.0.0'].group).to eq("success") + end + end + + context 'when a tag has multiple pipelines' do + before do + create(:ci_pipeline, + project: project, + ref: 'v1.0.0', + sha: project.commit('v1.0.0').sha, + status: :running, + created_at: 6.months.ago) + create(:ci_pipeline, + project: project, + ref: 'v1.0.0', + sha: project.commit('v1.0.0').sha, + status: :success, + created_at: 2.months.ago) + end + + it 'chooses the latest to determine status' do + subject + + expect(assigns(:tag_pipeline_statuses)['v1.0.0'].group).to eq("success") + end + end + end end describe 'GET show' do @@ -70,7 +127,8 @@ RSpec.describe Projects::TagsController do end let(:release_description) { nil } - let(:request) do + + subject(:request) do post(:create, params: { namespace_id: project.namespace.to_param, project_id: project, @@ -81,7 +139,7 @@ RSpec.describe Projects::TagsController do end it 'creates tag' do - request + subject expect(response).to have_gitlab_http_status(:found) expect(project.repository.find_tag('1.0')).to be_present @@ -92,7 +150,7 @@ RSpec.describe Projects::TagsController do let(:release_description) { 'some release description' } it 'creates tag and release' do - request + subject expect(response).to have_gitlab_http_status(:found) expect(project.repository.find_tag('1.0')).to be_present @@ -118,7 +176,7 @@ RSpec.describe Projects::TagsController do expect(service).to receive(:execute).and_call_original end - request + subject aggregate_failures do expect(response).to have_gitlab_http_status(:found) diff --git a/spec/controllers/projects/templates_controller_spec.rb b/spec/controllers/projects/templates_controller_spec.rb index 40632e0dea7..01593f4133c 100644 --- a/spec/controllers/projects/templates_controller_spec.rb +++ b/spec/controllers/projects/templates_controller_spec.rb @@ -5,35 +5,84 @@ require 'spec_helper' 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' } - let(:file_path_2) { '.gitlab/merge_request_templates/merge_request_template.md' } - let!(:file_1) { project.repository.create_file(user, file_path_1, 'issue content', message: 'message', branch_name: 'master') } - let!(:file_2) { project.repository.create_file(user, file_path_2, 'merge request content', message: 'message', branch_name: 'master') } + let(:issue_template_path_1) { '.gitlab/issue_templates/issue_template_1.md' } + let(:issue_template_path_2) { '.gitlab/issue_templates/issue_template_2.md' } + let(:merge_request_template_path_1) { '.gitlab/merge_request_templates/merge_request_template_1.md' } + let(:merge_request_template_path_2) { '.gitlab/merge_request_templates/merge_request_template_2.md' } + let!(:issue_template_file_1) { project.repository.create_file(user, issue_template_path_1, 'issue content 1', message: 'message 1', branch_name: 'master') } + let!(:issue_template_file_2) { project.repository.create_file(user, issue_template_path_2, 'issue content 2', message: 'message 2', branch_name: 'master') } + let!(:merge_request_template_file_1) { project.repository.create_file(user, merge_request_template_path_1, 'merge request content 1', message: 'message 1', branch_name: 'master') } + let!(:merge_request_template_file_2) { project.repository.create_file(user, merge_request_template_path_2, 'merge request content 2', message: 'message 2', branch_name: 'master') } + let(:expected_issue_template_1) { { 'key' => 'issue_template_1', 'name' => 'issue_template_1', 'content' => 'issue content 1' } } + let(:expected_issue_template_2) { { 'key' => 'issue_template_2', 'name' => 'issue_template_2', 'content' => 'issue content 2' } } + let(:expected_merge_request_template_1) { { 'key' => 'merge_request_template_1', 'name' => 'merge_request_template_1', 'content' => 'merge request content 1' } } + let(:expected_merge_request_template_2) { { 'key' => 'merge_request_template_2', 'name' => 'merge_request_template_2', 'content' => 'merge request content 2' } } + + describe '#index' do + before do + project.add_developer(user) + sign_in(user) + end + + shared_examples 'templates request' do + it 'returns the templates' do + get(:index, params: { namespace_id: project.namespace, template_type: template_type, project_id: project }, format: :json) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to match(expected_templates) + end + + it 'fails for user with no access' do + other_user = create(:user) + sign_in(other_user) + + get(:index, params: { namespace_id: project.namespace, template_type: template_type, project_id: project }, format: :json) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when querying for issue templates' do + it_behaves_like 'templates request' do + let(:template_type) { 'issue' } + let(:expected_templates) { [expected_issue_template_1, expected_issue_template_2] } + end + end + + context 'when querying for merge_request templates' do + it_behaves_like 'templates request' do + let(:template_type) { 'merge_request' } + let(:expected_templates) { [expected_merge_request_template_1, expected_merge_request_template_2] } + end + end + end describe '#show' do shared_examples 'renders issue templates as json' do + let(:expected_issue_template) { expected_issue_template_2 } + it do - get(:show, params: { namespace_id: project.namespace, template_type: 'issue', key: 'issue_template', project_id: project }, format: :json) + get(:show, params: { namespace_id: project.namespace, template_type: 'issue', key: 'issue_template_2', project_id: project }, format: :json) expect(response).to have_gitlab_http_status(:ok) - expect(json_response['name']).to eq('issue_template') - expect(json_response['content']).to eq('issue content') + expect(json_response).to match(expected_issue_template) end end shared_examples 'renders merge request templates as json' do + let(:expected_merge_request_template) { expected_merge_request_template_2 } + it do - get(:show, params: { namespace_id: project.namespace, template_type: 'merge_request', key: 'merge_request_template', project_id: project }, format: :json) + get(:show, params: { namespace_id: project.namespace, template_type: 'merge_request', key: 'merge_request_template_2', project_id: project }, format: :json) expect(response).to have_gitlab_http_status(:ok) - expect(json_response['name']).to eq('merge_request_template') - expect(json_response['content']).to eq('merge request content') + expect(json_response).to match(expected_merge_request_template) end end shared_examples 'renders 404 when requesting an issue template' do it do - get(:show, params: { namespace_id: project.namespace, template_type: 'issue', key: 'issue_template', project_id: project }, format: :json) + get(:show, params: { namespace_id: project.namespace, template_type: 'issue', key: 'issue_template_1', project_id: project }, format: :json) expect(response).to have_gitlab_http_status(:not_found) end @@ -41,21 +90,23 @@ RSpec.describe Projects::TemplatesController do shared_examples 'renders 404 when requesting a merge request template' do it do - get(:show, params: { namespace_id: project.namespace, template_type: 'merge_request', key: 'merge_request_template', project_id: project }, format: :json) + get(:show, params: { namespace_id: project.namespace, template_type: 'merge_request', key: 'merge_request_template_1', project_id: project }, format: :json) expect(response).to have_gitlab_http_status(:not_found) end end - shared_examples 'renders 404 when params are invalid' do + shared_examples 'raises error when template type is invalid' do it 'does not route when the template type is invalid' do expect do - get(:show, params: { namespace_id: project.namespace, template_type: 'invalid_type', key: 'issue_template', project_id: project }, format: :json) + get(:show, params: { namespace_id: project.namespace, template_type: 'invalid_type', key: 'issue_template_1', project_id: project }, format: :json) end.to raise_error(ActionController::UrlGenerationError) end + end + shared_examples 'renders 404 when params are invalid' do it 'renders 404 when the format type is invalid' do - get(:show, params: { namespace_id: project.namespace, template_type: 'issue', key: 'issue_template', project_id: project }, format: :html) + get(:show, params: { namespace_id: project.namespace, template_type: 'issue', key: 'issue_template_1', project_id: project }, format: :html) expect(response).to have_gitlab_http_status(:not_found) end @@ -74,7 +125,6 @@ RSpec.describe Projects::TemplatesController do include_examples 'renders 404 when requesting an issue template' include_examples 'renders 404 when requesting a merge request template' - include_examples 'renders 404 when params are invalid' end context 'when user is a member of the project' do @@ -85,7 +135,11 @@ RSpec.describe Projects::TemplatesController do include_examples 'renders issue templates as json' include_examples 'renders merge request templates as json' - include_examples 'renders 404 when params are invalid' + + context 'when params are invalid' do + include_examples 'raises error when template type is invalid' + include_examples 'renders 404 when params are invalid' + end end context 'when user is a guest of the project' do @@ -96,7 +150,6 @@ RSpec.describe Projects::TemplatesController do include_examples 'renders issue templates as json' include_examples 'renders 404 when requesting a merge request template' - include_examples 'renders 404 when params are invalid' end end @@ -111,8 +164,8 @@ RSpec.describe Projects::TemplatesController do get(:names, params: { namespace_id: project.namespace, template_type: template_type, project_id: project }, format: :json) expect(response).to have_gitlab_http_status(:ok) - expect(json_response.size).to eq(1) - expect(json_response[0]['name']).to eq(expected_template_name) + expect(json_response.size).to eq(2) + expect(json_response).to match(expected_template_names) end it 'fails for user with no access' do @@ -128,14 +181,14 @@ RSpec.describe Projects::TemplatesController do context 'when querying for issue templates' do it_behaves_like 'template names request' do let(:template_type) { 'issue' } - let(:expected_template_name) { 'issue_template' } + let(:expected_template_names) { [{ 'name' => 'issue_template_1' }, { 'name' => 'issue_template_2' }] } end end context 'when querying for merge_request templates' do it_behaves_like 'template names request' do let(:template_type) { 'merge_request' } - let(:expected_template_name) { 'merge_request_template' } + let(:expected_template_names) { [{ 'name' => 'merge_request_template_1' }, { 'name' => 'merge_request_template_2' }] } end end end diff --git a/spec/controllers/projects/terraform_controller_spec.rb b/spec/controllers/projects/terraform_controller_spec.rb new file mode 100644 index 00000000000..1978b9494fa --- /dev/null +++ b/spec/controllers/projects/terraform_controller_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::TerraformController do + let_it_be(:project) { create(:project) } + + describe 'GET index' do + subject { get :index, params: { namespace_id: project.namespace, project_id: project } } + + context 'when user is authorized' do + let(:user) { project.creator } + + before do + sign_in(user) + subject + end + + it 'renders content' do + expect(response).to be_successful + end + end + + context 'when user is unauthorized' do + let(:user) { create(:user) } + + before do + project.add_guest(user) + sign_in(user) + subject + end + + it 'shows 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + end +end |