diff options
Diffstat (limited to 'spec/controllers/projects')
19 files changed, 416 insertions, 369 deletions
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb index 53efcc65066..cc807098498 100644 --- a/spec/controllers/projects/blob_controller_spec.rb +++ b/spec/controllers/projects/blob_controller_spec.rb @@ -366,8 +366,8 @@ RSpec.describe Projects::BlobController do it_behaves_like 'tracking unique hll events' do subject(:request) { put :update, params: default_params } - let(:target_id) { 'g_edit_by_sfe' } - let(:expected_type) { instance_of(Integer) } + let(:target_event) { 'g_edit_by_sfe' } + let(:expected_value) { instance_of(Integer) } end end @@ -516,8 +516,8 @@ RSpec.describe Projects::BlobController do subject(:request) { post :create, params: default_params } it_behaves_like 'tracking unique hll events' do - let(:target_id) { 'g_edit_by_sfe' } - let(:expected_type) { instance_of(Integer) } + let(:target_event) { 'g_edit_by_sfe' } + let(:expected_value) { instance_of(Integer) } end it 'redirects to blob' do @@ -525,24 +525,5 @@ RSpec.describe Projects::BlobController do expect(response).to redirect_to(project_blob_path(project, 'master/docs/EXAMPLE_FILE')) end - - context 'when code_quality_walkthrough param is present' do - let(:default_params) { super().merge(code_quality_walkthrough: true) } - - it 'redirects to the pipelines page' do - request - - expect(response).to redirect_to(project_pipelines_path(project, code_quality_walkthrough: true)) - end - - it 'creates an "commit_created" experiment tracking event' do - experiment = double(track: true) - expect(controller).to receive(:experiment).with(:code_quality_walkthrough, namespace: project.root_ancestor).and_return(experiment) - - request - - expect(experiment).to have_received(:track).with(:commit_created) - 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 index d55aad20689..37406d704f1 100644 --- a/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb +++ b/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb @@ -36,17 +36,5 @@ RSpec.describe Projects::Ci::PipelineEditorController do expect(response).to have_gitlab_http_status(:not_found) end end - - describe 'pipeline_editor_walkthrough experiment' do - before do - project.add_developer(user) - end - - subject(:action) { show_request } - - it_behaves_like 'tracks assignment and records the subject', :pipeline_editor_walkthrough, :namespace do - subject { project.namespace } - end - end end end diff --git a/spec/controllers/projects/ci/secure_files_controller_spec.rb b/spec/controllers/projects/ci/secure_files_controller_spec.rb new file mode 100644 index 00000000000..1138897bcc6 --- /dev/null +++ b/spec/controllers/projects/ci/secure_files_controller_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::Ci::SecureFilesController do + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + + subject(:show_request) { get :show, params: { namespace_id: project.namespace, project_id: project } } + + describe 'GET #show' do + context 'with enough privileges' do + before do + sign_in(user) + project.add_developer(user) + show_request + 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 + sign_in(user) + project.add_reporter(user) + show_request + end + + it 'responds with 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'an unauthenticated user' do + before do + show_request + end + + it 'redirects to sign in' do + expect(response).to have_gitlab_http_status(:found) + expect(response).to redirect_to('/users/sign_in') + end + end + end +end diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb index d0bef810ec8..44bdc958805 100644 --- a/spec/controllers/projects/clusters_controller_spec.rb +++ b/spec/controllers/projects/clusters_controller_spec.rb @@ -26,6 +26,10 @@ RSpec.describe Projects::ClustersController do let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) } + include_examples ':certificate_based_clusters feature flag index responses' do + let(:subject) { go } + end + it 'lists available clusters and renders html' do go @@ -118,6 +122,10 @@ RSpec.describe Projects::ClustersController do } end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { go } + end + describe 'functionality for new cluster' do context 'when omniauth has been configured' do let(:key) { 'secret-key' } @@ -264,6 +272,10 @@ RSpec.describe Projects::ClustersController do post :create_gcp, params: params.merge(namespace_id: project.namespace, project_id: project) end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { go } + end + describe 'functionality' do context 'when access token is valid' do before do @@ -360,6 +372,10 @@ RSpec.describe Projects::ClustersController do post :create_user, params: params.merge(namespace_id: project.namespace, project_id: project) end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { go } + end + describe 'functionality' do context 'when creates a cluster' do it 'creates a new cluster' do @@ -477,6 +493,10 @@ RSpec.describe Projects::ClustersController do post :create_aws, params: params.merge(namespace_id: project.namespace, project_id: project) end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { post_create_aws } + end + it 'creates a new cluster' do expect(ClusterProvisionWorker).to receive(:perform_async) expect { post_create_aws }.to change { Clusters::Cluster.count } @@ -548,6 +568,10 @@ RSpec.describe Projects::ClustersController do .and_return(double(execute: double)) end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { go } + end + it 'updates the associated role with the supplied ARN' do go @@ -603,6 +627,10 @@ RSpec.describe Projects::ClustersController do } end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { go } + end + it 'deletes the namespaces associated with the cluster' do expect { go }.to change { Clusters::KubernetesNamespace.count } @@ -640,6 +668,10 @@ RSpec.describe Projects::ClustersController do format: :json end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { go } + end + describe 'functionality' do it "responds with matching schema" do go @@ -685,6 +717,10 @@ RSpec.describe Projects::ClustersController do } end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { go } + end + describe 'functionality' do render_views @@ -749,6 +785,10 @@ RSpec.describe Projects::ClustersController do } end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { go } + end + it "updates and redirects back to show page" do go @@ -842,6 +882,10 @@ RSpec.describe Projects::ClustersController do } end + include_examples ':certificate_based_clusters feature flag controller responses' do + let(:subject) { go } + end + describe 'functionality' do context 'when cluster is provided by GCP' do context 'when cluster is created' do diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 0fcdeb2edde..fdfc21887a6 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Projects::EnvironmentsController do include MetricsDashboardHelpers include KubernetesHelpers - let_it_be(:project) { create(:project) } + let_it_be(:project) { create(:project, :repository) } let_it_be(:maintainer) { create(:user, name: 'main-dos').tap { |u| project.add_maintainer(u) } } let_it_be(:reporter) { create(:user, name: 'repo-dos').tap { |u| project.add_reporter(u) } } @@ -55,11 +55,11 @@ RSpec.describe Projects::EnvironmentsController do let(:environments) { json_response['environments'] } context 'with default parameters' do - before do - get :index, params: environment_params(format: :json) - end + subject { get :index, params: environment_params(format: :json) } it 'responds with a flat payload describing available environments' do + subject + expect(environments.count).to eq 3 expect(environments.first).to include('name' => 'production', 'name_without_type' => 'production') expect(environments.second).to include('name' => 'staging/review-1', 'name_without_type' => 'review-1') @@ -69,9 +69,28 @@ RSpec.describe Projects::EnvironmentsController do end it 'sets the polling interval header' do + subject + expect(response).to have_gitlab_http_status(:ok) expect(response.headers['Poll-Interval']).to eq("3000") end + + context 'validates latest deployment' do + let_it_be(:test_environment) do + create(:environment, project: project, name: 'staging/review-4', state: :available) + end + + before do + create_list(:deployment, 2, :success, environment: test_environment, project: project) + end + + it 'responds with the latest deployment for the environment' do + subject + + environment = environments.find { |env| env['id'] == test_environment.id } + expect(environment['last_deployment']['id']).to eq(test_environment.deployments.last.id) + end + end end context 'when a folder-based nested structure is requested' do diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb index 822778779eb..b4f21e070c6 100644 --- a/spec/controllers/projects/error_tracking_controller_spec.rb +++ b/spec/controllers/projects/error_tracking_controller_spec.rb @@ -50,9 +50,7 @@ RSpec.describe Projects::ErrorTrackingController do let(:external_url) { 'http://example.com' } context 'no data' do - let(:permitted_params) do - ActionController::Parameters.new({}).permit! - end + let(:permitted_params) { permit_index_parameters!({}) } before do expect(ErrorTracking::ListIssuesService) @@ -75,9 +73,7 @@ RSpec.describe Projects::ErrorTrackingController do let(:search_term) { 'something' } let(:sort) { 'last_seen' } let(:params) { project_params(format: :json, search_term: search_term, sort: sort, cursor: cursor) } - let(:permitted_params) do - ActionController::Parameters.new(search_term: search_term, sort: sort, cursor: cursor).permit! - end + let(:permitted_params) { permit_index_parameters!(search_term: search_term, sort: sort, cursor: cursor) } before do expect(ErrorTracking::ListIssuesService) @@ -114,7 +110,7 @@ RSpec.describe Projects::ErrorTrackingController do context 'without extra params' do before do expect(ErrorTracking::ListIssuesService) - .to receive(:new).with(project, user, {}) + .to receive(:new).with(project, user, permit_index_parameters!({})) .and_return(list_issues_service) end @@ -179,6 +175,15 @@ RSpec.describe Projects::ErrorTrackingController do end end end + + private + + def permit_index_parameters!(params) + ActionController::Parameters.new( + **params, + tracking_event: :error_tracking_view_list + ).permit! + end end describe 'GET #issue_details' do @@ -188,7 +193,8 @@ RSpec.describe Projects::ErrorTrackingController do let(:permitted_params) do ActionController::Parameters.new( - { issue_id: issue_id.to_s } + issue_id: issue_id.to_s, + tracking_event: :error_tracking_view_details ).permit! end diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb index 0f8f3b49e02..962ef93dc72 100644 --- a/spec/controllers/projects/forks_controller_spec.rb +++ b/spec/controllers/projects/forks_controller_spec.rb @@ -199,15 +199,6 @@ RSpec.describe Projects::ForksController do expect(json_response['namespaces'][1]['id']).to eq(group.id) end - it 'responds with group only when fork_project_form feature flag is disabled' do - stub_feature_flags(fork_project_form: false) - do_request - - expect(response).to have_gitlab_http_status(:ok) - expect(json_response['namespaces'].length).to eq(1) - expect(json_response['namespaces'][0]['id']).to eq(group.id) - end - context 'N+1 queries' do before do create(:fork_network, root_project: project) diff --git a/spec/controllers/projects/incidents_controller_spec.rb b/spec/controllers/projects/incidents_controller_spec.rb index 460821634b0..20cf0dcfd3a 100644 --- a/spec/controllers/projects/incidents_controller_spec.rb +++ b/spec/controllers/projects/incidents_controller_spec.rb @@ -43,6 +43,7 @@ RSpec.describe Projects::IncidentsController do expect(response).to have_gitlab_http_status(:ok) expect(response).to render_template(:index) + expect(Gon.features).to include('incidentEscalations' => true) end context 'when user is unauthorized' do diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index bf0b833b311..9d3711d8a96 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -72,7 +72,21 @@ RSpec.describe Projects::IssuesController do project.add_developer(user) end - it_behaves_like "issuables list meta-data", :issue + context 'when issues_full_text_search is disabled' do + before do + stub_feature_flags(issues_full_text_search: false) + end + + it_behaves_like 'issuables list meta-data', :issue + end + + context 'when issues_full_text_search is enabled' do + before do + stub_feature_flags(issues_full_text_search: true) + end + + it_behaves_like 'issuables list meta-data', :issue + end it_behaves_like 'set sort order from user preference' do let(:sorting_param) { 'updated_asc' } @@ -605,11 +619,11 @@ RSpec.describe Projects::IssuesController do end end - context 'when the SpamVerdictService disallows' do + context 'when an issue is identified as spam' 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(CONDITIONAL_ALLOW) + allow_next_instance_of(Spam::AkismetService) do |akismet_service| + allow(akismet_service).to receive(:spam?).and_return(true) end end @@ -926,8 +940,8 @@ RSpec.describe Projects::IssuesController do context 'when an issue is identified as spam' 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(CONDITIONAL_ALLOW) + allow_next_instance_of(Spam::AkismetService) do |akismet_service| + allow(akismet_service).to receive(:spam?).and_return(true) end end @@ -1004,6 +1018,7 @@ RSpec.describe Projects::IssuesController do end it 'returns 200 status' do + update_verified_issue expect(response).to have_gitlab_http_status(:ok) end @@ -1051,35 +1066,6 @@ RSpec.describe Projects::IssuesController do .not_to exceed_query_limit(control_count + 2 * labels.count) end - context 'real-time sidebar feature flag' do - let_it_be(:project) { create(:project, :public) } - let_it_be(:issue) { create(:issue, project: project) } - - context 'when enabled' do - before do - stub_feature_flags(real_time_issue_sidebar: true) - end - - it 'pushes the correct value to the frontend' do - go(id: issue.to_param) - - expect(Gon.features).to include('realTimeIssueSidebar' => true) - end - end - - context 'when disabled' do - before do - stub_feature_flags(real_time_issue_sidebar: false) - end - - it 'pushes the correct value to the frontend' do - go(id: issue.to_param) - - expect(Gon.features).to include('realTimeIssueSidebar' => false) - end - end - end - it 'logs the view with Gitlab::Search::RecentIssues' do sign_in(user) recent_issues_double = instance_double(::Gitlab::Search::RecentIssues, log_view: nil) @@ -1260,11 +1246,11 @@ RSpec.describe Projects::IssuesController do end end - context 'when SpamVerdictService requires recaptcha' do + context 'when an issue is identified as spam and requires recaptcha' 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(CONDITIONAL_ALLOW) + allow_next_instance_of(Spam::AkismetService) do |akismet_service| + allow(akismet_service).to receive(:spam?).and_return(true) 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 a5c59b7e22d..367781c0e76 100644 --- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb @@ -220,29 +220,6 @@ RSpec.describe Projects::MergeRequests::DiffsController do end end - context "with the :default_merge_ref_for_diffs flag on" do - let(:diffable_merge_ref) { true } - - subject do - go(diff_head: true, - diff_id: merge_request.merge_request_diff.id, - start_sha: merge_request.merge_request_diff.start_commit_sha) - end - - it "correctly generates the right diff between versions" do - MergeRequests::MergeToRefService.new(project: project, current_user: merge_request.author).execute(merge_request) - - expect_next_instance_of(CompareService) do |service| - expect(service).to receive(:execute).with( - project, - merge_request.merge_request_diff.head_commit_sha, - straight: true) - end - - subject - end - end - context 'with diff_head param passed' do before do allow(merge_request).to receive(:diffable_merge_ref?) @@ -259,6 +236,23 @@ RSpec.describe Projects::MergeRequests::DiffsController do expect(response).to have_gitlab_http_status(:ok) end + + context 'when diff_id and start_sha are set' do + it 'correctly generates the right diff between versions' do + MergeRequests::MergeToRefService.new(project: project, current_user: merge_request.author).execute(merge_request) + + expect_next_instance_of(CompareService) do |service| + expect(service).to receive(:execute).with( + project, + merge_request.merge_request_diff.head_commit_sha, + straight: true) + end + + go(diff_head: true, + diff_id: merge_request.merge_request_diff.id, + start_sha: merge_request.merge_request_diff.start_commit_sha) + end + end end context 'the merge request cannot be compared with head' do diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 2390687c3ea..f6db809c2e3 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -68,6 +68,18 @@ RSpec.describe Projects::MergeRequestsController do end describe 'as html' do + it 'sets the endpoint_metadata_url' do + go + + expect(assigns["endpoint_metadata_url"]).to eq( + diffs_metadata_project_json_merge_request_path( + project, + merge_request, + 'json', + diff_head: true, + view: 'inline')) + end + context 'when diff files were cleaned' do render_views @@ -85,23 +97,6 @@ RSpec.describe Projects::MergeRequestsController do end end - context 'with `default_merge_ref_for_diffs` feature flag enabled' do - before do - stub_feature_flags(default_merge_ref_for_diffs: true) - go - end - - it 'adds the diff_head parameter' do - expect(assigns["endpoint_metadata_url"]).to eq( - diffs_metadata_project_json_merge_request_path( - project, - merge_request, - 'json', - diff_head: true, - view: 'inline')) - end - end - context 'when diff is missing' do render_views diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 4a51e2ed5a0..8fae82d54a2 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -292,12 +292,8 @@ RSpec.describe Projects::PipelinesController do subject { project.namespace } - context 'code_quality_walkthrough experiment' do - it_behaves_like 'tracks assignment and records the subject', :code_quality_walkthrough, :namespace - end - - context 'ci_runner_templates experiment' do - it_behaves_like 'tracks assignment and records the subject', :ci_runner_templates, :namespace + context 'runners_availability_section experiment' do + it_behaves_like 'tracks assignment and records the subject', :runners_availability_section, :namespace end end @@ -936,6 +932,33 @@ RSpec.describe Projects::PipelinesController do expect(response).to have_gitlab_http_status(:not_found) end end + + context 'when access denied' do + it 'returns an error' do + sign_in(create(:user)) + + post_retry + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when service returns an error' do + before do + service_response = ServiceResponse.error(message: 'some error', http_status: 404) + allow_next_instance_of(::Ci::RetryPipelineService) do |service| + allow(service).to receive(:check_access).and_return(service_response) + end + end + + it 'does not retry' do + post_retry + + expect(response).to have_gitlab_http_status(:not_found) + expect(response.body).to include('some error') + expect(::Ci::RetryPipelineWorker).not_to have_received(:perform_async).with(pipeline.id, user.id) + end + end end describe 'POST cancel.json' do diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index d8ef95cf11a..20a114bbe8c 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -147,137 +147,6 @@ RSpec.describe Projects::ProjectMembersController do end end - describe 'POST create' do - let_it_be(:project_user) { create(:user) } - - before do - sign_in(user) - end - - context 'when user does not have enough rights' do - before do - project.add_developer(user) - end - - it 'returns 404', :aggregate_failures do - post :create, params: { - namespace_id: project.namespace, - project_id: project, - user_ids: project_user.id, - access_level: Gitlab::Access::GUEST - } - - expect(response).to have_gitlab_http_status(:not_found) - expect(project.users).not_to include project_user - end - end - - context 'when user has enough rights' do - before do - project.add_maintainer(user) - end - - it 'adds user to members', :aggregate_failures, :snowplow do - post :create, params: { - namespace_id: project.namespace, - project_id: project, - user_ids: project_user.id, - access_level: Gitlab::Access::GUEST - } - - expect(controller).to set_flash.to 'Users were successfully added.' - expect(response).to redirect_to(project_project_members_path(project)) - expect(project.users).to include project_user - expect_snowplow_event( - category: 'Members::CreateService', - action: 'create_member', - label: 'project-members-page', - property: 'existing_user', - user: user - ) - end - - it 'adds no user to members', :aggregate_failures do - expect_next_instance_of(Members::CreateService) do |instance| - expect(instance).to receive(:execute).and_return(status: :failure, message: 'Message') - end - - post :create, params: { - namespace_id: project.namespace, - project_id: project, - user_ids: '', - access_level: Gitlab::Access::GUEST - } - - expect(controller).to set_flash.to 'Message' - expect(response).to redirect_to(project_project_members_path(project)) - end - end - - context 'adding project bot' do - let_it_be(:project_bot) { create(:user, :project_bot) } - - before do - project.add_maintainer(user) - - unrelated_project = create(:project) - unrelated_project.add_maintainer(project_bot) - end - - it 'returns error', :aggregate_failures do - post :create, params: { - namespace_id: project.namespace, - project_id: project, - user_ids: project_bot.id, - access_level: Gitlab::Access::GUEST - } - - expect(flash[:alert]).to include('project bots cannot be added to other groups / projects') - expect(response).to redirect_to(project_project_members_path(project)) - end - end - - context 'access expiry date' do - before do - project.add_maintainer(user) - end - - subject do - post :create, params: { - namespace_id: project.namespace, - project_id: project, - user_ids: project_user.id, - access_level: Gitlab::Access::GUEST, - expires_at: expires_at - } - end - - context 'when set to a date in the past' do - let(:expires_at) { 2.days.ago } - - it 'does not add user to members', :aggregate_failures do - subject - - expect(flash[:alert]).to include('Expires at cannot be a date in the past') - expect(response).to redirect_to(project_project_members_path(project)) - expect(project.users).not_to include project_user - end - end - - context 'when set to a date in the future' do - let(:expires_at) { 5.days.from_now } - - it 'adds user to members', :aggregate_failures do - subject - - expect(controller).to set_flash.to 'Users were successfully added.' - expect(response).to redirect_to(project_project_members_path(project)) - expect(project.users).to include project_user - end - end - end - end - describe 'PUT update' do let_it_be(:requester) { create(:project_member, :access_request, project: project) } @@ -603,99 +472,6 @@ RSpec.describe Projects::ProjectMembersController do end end - describe 'POST apply_import' do - let_it_be(:another_project) { create(:project, :private) } - let_it_be(:member) { create(:user) } - - before do - project.add_maintainer(user) - another_project.add_guest(member) - sign_in(user) - end - - shared_context 'import applied' do - before do - post(:apply_import, params: { - namespace_id: project.namespace, - project_id: project, - source_project_id: another_project.id - }) - end - end - - context 'when user can admin source project members' do - before do - another_project.add_maintainer(user) - end - - include_context 'import applied' - - it 'imports source project members', :aggregate_failures do - expect(project.team_members).to include member - expect(controller).to set_flash.to 'Successfully imported' - expect(response).to redirect_to( - project_project_members_path(project) - ) - end - end - - context "when user can't admin source project members" do - before do - another_project.add_developer(user) - end - - include_context 'import applied' - - it 'does not import team members' do - expect(project.team_members).not_to include member - end - - it 'responds with not found' do - expect(response).to have_gitlab_http_status(:not_found) - end - end - end - - describe 'POST create' do - let_it_be(:stranger) { create(:user) } - - context 'when creating owner' do - before do - project.add_maintainer(user) - sign_in(user) - end - - it 'does not create a member' do - expect do - post :create, params: { - user_ids: stranger.id, - namespace_id: project.namespace, - access_level: Member::OWNER, - project_id: project - } - end.to change { project.members.count }.by(0) - end - end - - context 'when create maintainer' do - before do - project.add_maintainer(user) - sign_in(user) - end - - it 'creates a member' do - expect do - post :create, params: { - user_ids: stranger.id, - namespace_id: project.namespace, - access_level: Member::MAINTAINER, - project_id: project - } - end.to change { project.members.count }.by(1) - end - end - end - describe 'POST resend_invite' do let_it_be(:member) { create(:project_member, project: project) } diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb index 120020273f9..9dd18e58109 100644 --- a/spec/controllers/projects/releases_controller_spec.rb +++ b/spec/controllers/projects/releases_controller_spec.rb @@ -222,6 +222,168 @@ RSpec.describe Projects::ReleasesController do end end + describe 'GET #latest_permalink' do + # Uses default order_by=released_at parameter. + subject do + get :latest_permalink, params: { namespace_id: project.namespace, project_id: project } + end + + before do + sign_in(user) + end + + let(:release) { create(:release, project: project) } + let(:tag) { CGI.escape(release.tag) } + + context 'when user is a guest' do + let(:project) { private_project } + let(:user) { guest } + + it 'proceeds with the redirect' do + subject + + expect(response).to have_gitlab_http_status(:redirect) + end + end + + context 'when user is an external user for the project' do + let(:project) { private_project } + let(:user) { create(:user) } + + it 'behaves like not found' do + subject + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when there are no releases for the project' do + let(:project) { create(:project, :repository, :public) } + let(:user) { developer } + + before do + project.releases.destroy_all # rubocop: disable Cop/DestroyAll + end + + it 'behaves like not found' do + subject + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'multiple releases' do + let(:user) { developer } + + it 'redirects to the latest release' do + create(:release, project: project, released_at: 1.day.ago) + latest_release = create(:release, project: project, released_at: Time.current) + + subject + + expect(response).to redirect_to("#{project_releases_path(project)}/#{latest_release.tag}") + end + end + + context 'suffix path redirection' do + let(:user) { developer } + let(:suffix_path) { 'downloads/zips/helm-hello-world.zip' } + let!(:latest_release) { create(:release, project: project, released_at: Time.current) } + + subject do + get :latest_permalink, params: { + namespace_id: project.namespace, + project_id: project, + suffix_path: suffix_path + } + end + + it 'redirects to the latest release with suffix path and format' do + subject + + expect(response).to redirect_to( + "#{project_releases_path(project)}/#{latest_release.tag}/#{suffix_path}") + end + + context 'suffix path abuse' do + let(:suffix_path) { 'downloads/zips/../../../../../../../robots.txt'} + + it 'raises attack error' do + expect do + subject + end.to raise_error(Gitlab::Utils::PathTraversalAttackError) + end + end + + context 'url parameters' do + let(:suffix_path) { 'downloads/zips/helm-hello-world.zip' } + + subject do + get :latest_permalink, params: { + namespace_id: project.namespace, + project_id: project, + suffix_path: suffix_path, + order_by: 'released_at', + param_1: 1, + param_2: 2 + } + end + + it 'carries over query parameters without order_by parameter in the redirect' do + subject + + expect(response).to redirect_to( + "#{project_releases_path(project)}/#{latest_release.tag}/#{suffix_path}?param_1=1¶m_2=2") + end + end + end + + context 'order_by parameter' do + let!(:latest_release) { create(:release, project: project, released_at: Time.current, tag: 'latest') } + + shared_examples_for 'redirects to latest release ordered by using released_at' do + it do + expect(Release).to receive(:order_released_desc).and_call_original + + subject + + expect(response).to redirect_to("#{project_releases_path(project)}/#{latest_release.tag}") + end + end + + before do + create(:release, project: project, released_at: 1.day.ago, tag: 'alpha') + create(:release, project: project, released_at: 2.days.ago, tag: 'beta') + end + + context 'invalid parameter' do + let(:user) { developer } + + subject do + get :latest_permalink, params: { + namespace_id: project.namespace, + project_id: project, + order_by: 'unsupported' + } + end + + it_behaves_like 'redirects to latest release ordered by using released_at' + end + + context 'valid parameter' do + subject do + get :latest_permalink, params: { + namespace_id: project.namespace, + project_id: project, + order_by: 'released_at' + } + end + + it_behaves_like 'redirects to latest release ordered by using released_at' + end + end + end + # `GET #downloads` is addressed in spec/requests/projects/releases_controller_spec.rb private diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb index 246a37129d7..57d1695b842 100644 --- a/spec/controllers/projects/runners_controller_spec.rb +++ b/spec/controllers/projects/runners_controller_spec.rb @@ -37,7 +37,7 @@ RSpec.describe Projects::RunnersController do describe '#destroy' do it 'destroys the runner' do - expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service| + expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service| expect(service).to receive(:execute).once.and_call_original end diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb index 860bbc1c5cc..f8cee09006c 100644 --- a/spec/controllers/projects/serverless/functions_controller_spec.rb +++ b/spec/controllers/projects/serverless/functions_controller_spec.rb @@ -39,9 +39,24 @@ RSpec.describe Projects::Serverless::FunctionsController do project_id: project.to_param) end + shared_examples_for 'behind :deprecated_serverless feature flag' do + before do + stub_feature_flags(deprecated_serverless: false) + end + + it 'returns 404' do + action + expect(response).to have_gitlab_http_status(:not_found) + end + end + describe 'GET #index' do let(:expected_json) { { 'knative_installed' => knative_state, 'functions' => functions } } + it_behaves_like 'behind :deprecated_serverless feature flag' do + let(:action) { get :index, params: params({ format: :json }) } + end + context 'when cache is being read' do let(:knative_state) { 'checking' } let(:functions) { [] } @@ -147,6 +162,10 @@ RSpec.describe Projects::Serverless::FunctionsController do end describe 'GET #show' do + it_behaves_like 'behind :deprecated_serverless feature flag' do + let(:action) { get :show, params: params({ format: :json, environment_id: "*", id: "foo" }) } + end + context 'with function that does not exist' do it 'returns 404' do get :show, params: params({ format: :json, environment_id: "*", id: "foo" }) @@ -239,6 +258,10 @@ RSpec.describe Projects::Serverless::FunctionsController do end describe 'GET #metrics' do + it_behaves_like 'behind :deprecated_serverless feature flag' do + let(:action) { get :metrics, params: params({ format: :json, environment_id: "*", id: "foo" }) } + end + context 'invalid data' do it 'has a bad function name' do get :metrics, params: params({ format: :json, environment_id: "*", id: "foo" }) diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb index f3c7b501faa..35e5422d072 100644 --- a/spec/controllers/projects/services_controller_spec.rb +++ b/spec/controllers/projects/services_controller_spec.rb @@ -353,7 +353,16 @@ RSpec.describe Projects::ServicesController do it 'does not modify integration' do expect { put :update, params: project_params.merge(service: integration_params) } - .not_to change { project.prometheus_integration.reload.attributes } + .not_to change { prometheus_integration_as_data } + end + + def prometheus_integration_as_data + pi = project.prometheus_integration.reload + attrs = pi.attributes.except('encrypted_properties', + 'encrypted_properties_iv', + 'encrypted_properties_tmp') + + [attrs, pi.encrypted_properties_tmp] end end diff --git a/spec/controllers/projects/tags/releases_controller_spec.rb b/spec/controllers/projects/tags/releases_controller_spec.rb index b3d4d944440..1d2385f54f9 100644 --- a/spec/controllers/projects/tags/releases_controller_spec.rb +++ b/spec/controllers/projects/tags/releases_controller_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe Projects::Tags::ReleasesController do let!(:project) { create(:project, :repository) } let!(:user) { create(:user) } - let!(:release) { create(:release, project: project) } + let!(:release) { create(:release, project: project, tag: "v1.1.0") } let!(:tag) { release.tag } before do @@ -27,7 +27,7 @@ RSpec.describe Projects::Tags::ReleasesController do end it 'retrieves an existing release' do - response = get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: release.tag } + response = get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: tag } release = assigns(:release) expect(release).not_to be_nil diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb index f955f9d0248..d0971e96910 100644 --- a/spec/controllers/projects/tags_controller_spec.rb +++ b/spec/controllers/projects/tags_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Projects::TagsController do let(:project) { create(:project, :public, :repository) } - let!(:release) { create(:release, project: project) } + let!(:release) { create(:release, project: project, tag: "v1.1.0") } let!(:invalid_release) { create(:release, project: project, tag: 'does-not-exist') } let(:user) { create(:user) } |