diff options
Diffstat (limited to 'spec/controllers/projects')
14 files changed, 493 insertions, 405 deletions
diff --git a/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb b/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb index 3bb841c7c9f..1351ba35a71 100644 --- a/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb +++ b/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb @@ -7,26 +7,58 @@ RSpec.describe Projects::Analytics::CycleAnalytics::StagesController do let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } - let(:params) { { namespace_id: group, project_id: project, value_stream_id: 'default' } } + let(:params) do + { + namespace_id: group, + project_id: project, + value_stream_id: Analytics::CycleAnalytics::Stages::BaseService::DEFAULT_VALUE_STREAM_NAME + } + end before do sign_in(user) end - describe 'GET index' do - context 'when user is member of the project' do + shared_examples 'project-level value stream analytics endpoint' do + before do + project.add_developer(user) + end + + it 'succeeds' do + get action, params: params + + expect(response).to have_gitlab_http_status(:ok) + end + end + + shared_examples 'project-level value stream analytics request error examples' do + context 'when invalid value stream id is given' do before do - project.add_developer(user) + params[:value_stream_id] = 1 end - it 'succeeds' do - get :index, params: params + it 'renders 404' do + get action, params: params - expect(response).to have_gitlab_http_status(:ok) + expect(response).to have_gitlab_http_status(:not_found) end + end + context 'when user is not member of the project' do + it 'renders 404' do + get action, params: params + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + describe 'GET index' do + let(:action) { :index } + + it_behaves_like 'project-level value stream analytics endpoint' do it 'exposes the default stages' do - get :index, params: params + get action, params: params expect(json_response['stages'].size).to eq(Gitlab::Analytics::CycleAnalytics::DefaultStages.all.size) end @@ -37,31 +69,109 @@ RSpec.describe Projects::Analytics::CycleAnalytics::StagesController do expect(list_service).to receive(:allowed?).and_return(false) end - get :index, params: params + get action, params: params expect(response).to have_gitlab_http_status(:forbidden) end end end - context 'when invalid value stream id is given' do - before do - params[:value_stream_id] = 1 + it_behaves_like 'project-level value stream analytics request error examples' + end + + describe 'GET median' do + let(:action) { :median } + + before do + params[:id] = 'issue' + end + + it_behaves_like 'project-level value stream analytics endpoint' do + it 'returns the median' do + result = 2 + + expect_next_instance_of(Gitlab::Analytics::CycleAnalytics::Median) do |instance| + expect(instance).to receive(:seconds).and_return(result) + end + + get action, params: params + + expect(json_response['value']).to eq(result) end + end - it 'renders 404' do - get :index, params: params + it_behaves_like 'project-level value stream analytics request error examples' + end - expect(response).to have_gitlab_http_status(:not_found) + describe 'GET average' do + let(:action) { :average } + + before do + params[:id] = 'issue' + end + + it_behaves_like 'project-level value stream analytics endpoint' do + it 'returns the average' do + result = 2 + + expect_next_instance_of(Gitlab::Analytics::CycleAnalytics::Average) do |instance| + expect(instance).to receive(:seconds).and_return(result) + end + + get action, params: params + + expect(json_response['value']).to eq(result) end end - context 'when user is not member of the project' do - it 'renders 404' do - get :index, params: params + it_behaves_like 'project-level value stream analytics request error examples' + end - expect(response).to have_gitlab_http_status(:not_found) + describe 'GET count' do + let(:action) { :count } + + before do + params[:id] = 'issue' + end + + it_behaves_like 'project-level value stream analytics endpoint' do + it 'returns the count' do + count = 2 + + expect_next_instance_of(Gitlab::Analytics::CycleAnalytics::DataCollector) do |instance| + expect(instance).to receive(:count).and_return(count) + end + + get action, params: params + + expect(json_response['count']).to eq(count) end end + + it_behaves_like 'project-level value stream analytics request error examples' + end + + describe 'GET records' do + let(:action) { :records } + + before do + params[:id] = 'issue' + end + + it_behaves_like 'project-level value stream analytics endpoint' do + it 'returns the records' do + result = Issue.none.page(1) + + expect_next_instance_of(Gitlab::Analytics::CycleAnalytics::RecordsFetcher) do |instance| + expect(instance).to receive(:serialized_records).and_yield(result).and_return([]) + end + + get action, params: params + + expect(json_response).to eq([]) + end + end + + it_behaves_like 'project-level value stream analytics request error examples' end end diff --git a/spec/controllers/projects/clusters/applications_controller_spec.rb b/spec/controllers/projects/clusters/applications_controller_spec.rb deleted file mode 100644 index cc6170252c1..00000000000 --- a/spec/controllers/projects/clusters/applications_controller_spec.rb +++ /dev/null @@ -1,215 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Projects::Clusters::ApplicationsController do - include AccessMatchersForController - - def current_application - Clusters::Cluster::APPLICATIONS[application] - end - - shared_examples 'a secure endpoint' do - it 'is allowed for admin when admin mode enabled', :enable_admin_mode do - expect { subject }.to be_allowed_for(:admin) - end - it 'is denied for admin when admin mode disabled' do - expect { subject }.to be_denied_for(:admin) - end - it { expect { subject }.to be_allowed_for(:owner).of(project) } - it { expect { subject }.to be_allowed_for(:maintainer).of(project) } - it { expect { subject }.to be_denied_for(:developer).of(project) } - it { expect { subject }.to be_denied_for(:reporter).of(project) } - it { expect { subject }.to be_denied_for(:guest).of(project) } - it { expect { subject }.to be_denied_for(:user) } - it { expect { subject }.to be_denied_for(:external) } - end - - describe 'POST create' do - subject do - post :create, params: params.merge(namespace_id: project.namespace, project_id: project) - end - - let(:cluster) { create(:cluster, :project, :provided_by_gcp) } - let(:project) { cluster.project } - let(:application) { 'ingress' } - let(:params) { { application: application, id: cluster.id } } - - describe 'functionality' do - let(:user) { create(:user) } - - before do - project.add_maintainer(user) - sign_in(user) - end - - it 'schedule an application installation' do - expect(ClusterInstallAppWorker).to receive(:perform_async).with(application, anything).once - - expect { subject }.to change { current_application.count } - expect(response).to have_gitlab_http_status(:no_content) - expect(cluster.application_ingress).to be_scheduled - end - - context 'when cluster do not exists' do - before do - cluster.destroy! - end - - it 'return 404' do - expect { subject }.not_to change { current_application.count } - expect(response).to have_gitlab_http_status(:not_found) - end - end - - context 'when application is unknown' do - let(:application) { 'unkwnown-app' } - - it 'return 404' do - is_expected.to have_gitlab_http_status(:not_found) - end - end - - context 'when application is already installing' do - before do - create(:clusters_applications_ingress, :installing, cluster: cluster) - end - - it 'returns 400' do - is_expected.to have_gitlab_http_status(:bad_request) - end - end - end - - describe 'security' do - before do - allow(ClusterInstallAppWorker).to receive(:perform_async) - end - - it_behaves_like 'a secure endpoint' - end - end - - describe 'PATCH update' do - subject do - patch :update, params: params.merge(namespace_id: project.namespace, project_id: project) - end - - let(:cluster) { create(:cluster, :project, :provided_by_gcp) } - let(:project) { cluster.project } - let!(:application) { create(:clusters_applications_knative, :installed, cluster: cluster) } - let(:application_name) { application.name } - let(:params) { { application: application_name, id: cluster.id, hostname: "new.example.com" } } - - describe 'functionality' do - let(:user) { create(:user) } - - before do - project.add_maintainer(user) - sign_in(user) - end - - context "when cluster and app exists" do - it "schedules an application update" do - expect(ClusterPatchAppWorker).to receive(:perform_async).with(application.name, anything).once - - is_expected.to have_gitlab_http_status(:no_content) - - expect(cluster.application_knative).to be_scheduled - end - end - - context 'when cluster do not exists' do - before do - cluster.destroy! - end - - it { is_expected.to have_gitlab_http_status(:not_found) } - end - - context 'when application is unknown' do - let(:application_name) { 'unkwnown-app' } - - it { is_expected.to have_gitlab_http_status(:not_found) } - end - - context 'when application is already scheduled' do - before do - application.make_scheduled! - end - - it { is_expected.to have_gitlab_http_status(:bad_request) } - end - end - - describe 'security' do - before do - allow(ClusterPatchAppWorker).to receive(:perform_async) - end - - it_behaves_like 'a secure endpoint' - end - end - - describe 'DELETE destroy' do - subject do - delete :destroy, params: params.merge(namespace_id: project.namespace, project_id: project) - end - - let(:cluster) { create(:cluster, :project, :provided_by_gcp) } - let(:project) { cluster.project } - let!(:application) { create(:clusters_applications_prometheus, :installed, cluster: cluster) } - let(:application_name) { application.name } - let(:params) { { application: application_name, id: cluster.id } } - let(:worker_class) { Clusters::Applications::UninstallWorker } - - describe 'functionality' do - let(:user) { create(:user) } - - before do - project.add_maintainer(user) - sign_in(user) - end - - context "when cluster and app exists" do - it "schedules an application update" do - expect(worker_class).to receive(:perform_async).with(application.name, application.id).once - - is_expected.to have_gitlab_http_status(:no_content) - - expect(cluster.application_prometheus).to be_scheduled - end - end - - context 'when cluster do not exists' do - before do - cluster.destroy! - end - - it { is_expected.to have_gitlab_http_status(:not_found) } - end - - context 'when application is unknown' do - let(:application_name) { 'unkwnown-app' } - - it { is_expected.to have_gitlab_http_status(:not_found) } - end - - context 'when application is already scheduled' do - before do - application.make_scheduled! - end - - it { is_expected.to have_gitlab_http_status(:bad_request) } - end - end - - describe 'security' do - before do - allow(worker_class).to receive(:perform_async) - end - - it_behaves_like 'a secure endpoint' - end - end -end diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 4cb90edb742..7103d7df5c5 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -200,11 +200,27 @@ RSpec.describe Projects::EnvironmentsController do end describe 'PATCH #update' do - it 'responds with a 302' do - patch_params = environment_params.merge(environment: { external_url: 'https://git.gitlab.com' }) - patch :update, params: patch_params + subject { patch :update, params: params } - expect(response).to have_gitlab_http_status(:found) + context "when environment params are valid" do + let(:params) { environment_params.merge(environment: { external_url: 'https://git.gitlab.com' }) } + + it 'returns ok and the path to the newly created environment' do + subject + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['path']).to eq("/#{project.full_path}/-/environments/#{environment.id}") + end + end + + context "when environment params are invalid" do + let(:params) { environment_params.merge(environment: { name: '/foo/', external_url: '/git.gitlab.com' }) } + + it 'returns bad request' do + subject + + expect(response).to have_gitlab_http_status(:bad_request) + end end end @@ -786,6 +802,31 @@ RSpec.describe Projects::EnvironmentsController do end end + describe 'POST #create' do + subject { post :create, params: params } + + context "when environment params are valid" do + let(:params) { { namespace_id: project.namespace, project_id: project, environment: { name: 'foo', external_url: 'https://foo.example.com' } } } + + it 'returns ok and the path to the newly created environment' do + subject + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['path']).to eq("/#{project.full_path}/-/environments/#{json_response['environment']['id']}") + end + end + + context "when environment params are invalid" do + let(:params) { { namespace_id: project.namespace, project_id: project, environment: { name: 'foo/', external_url: '/foo.example.com' } } } + + it 'returns bad request' do + subject + + expect(response).to have_gitlab_http_status(:bad_request) + end + end + end + def environment_params(opts = {}) opts.reverse_merge(namespace_id: project.namespace, project_id: project, 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 7c080504c31..19b6b597a84 100644 --- a/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb +++ b/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb @@ -40,7 +40,7 @@ RSpec.describe Projects::ErrorTracking::StackTracesController do context 'service result is successful' do let(:service_response) { { status: :success, latest_event: error_event } } - let(:error_event) { build(:error_tracking_error_event) } + let(:error_event) { build(:error_tracking_sentry_error_event) } it 'responds with success' do expect(response).to have_gitlab_http_status(:ok) diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb index 5ea885e4fd6..822778779eb 100644 --- a/spec/controllers/projects/error_tracking_controller_spec.rb +++ b/spec/controllers/projects/error_tracking_controller_spec.rb @@ -95,7 +95,7 @@ RSpec.describe Projects::ErrorTrackingController do get :index, params: params end - let(:error) { build(:error_tracking_error) } + let(:error) { build(:error_tracking_sentry_error) } it 'returns a list of errors' do expect(response).to have_gitlab_http_status(:ok) @@ -126,7 +126,7 @@ RSpec.describe Projects::ErrorTrackingController do .and_return(external_url) end - let(:error) { build(:error_tracking_error) } + let(:error) { build(:error_tracking_sentry_error) } it 'returns a list of errors' do get :index, params: project_params(format: :json) @@ -221,7 +221,7 @@ RSpec.describe Projects::ErrorTrackingController do get :details, params: issue_params(issue_id: issue_id, format: :json) end - let(:error) { build(:detailed_error_tracking_error) } + let(:error) { build(:error_tracking_sentry_detailed_error) } it 'returns an error' do expected_error = error.as_json.except('first_release_version').merge( diff --git a/spec/controllers/projects/feature_flags_controller_spec.rb b/spec/controllers/projects/feature_flags_controller_spec.rb index f809dd31b3b..e038b247eff 100644 --- a/spec/controllers/projects/feature_flags_controller_spec.rb +++ b/spec/controllers/projects/feature_flags_controller_spec.rb @@ -652,7 +652,7 @@ RSpec.describe Projects::FeatureFlagsController do version: 'new_version_flag', strategies_attributes: [{ name: 'flexibleRollout', - parameters: { groupId: 'default', rollout: '15', stickiness: 'DEFAULT' }, + parameters: { groupId: 'default', rollout: '15', stickiness: 'default' }, scopes_attributes: [{ environment_scope: 'production' }] }] } @@ -666,7 +666,7 @@ RSpec.describe Projects::FeatureFlagsController do strategy_json = json_response['strategies'].first expect(strategy_json['name']).to eq('flexibleRollout') - expect(strategy_json['parameters']).to eq({ 'groupId' => 'default', 'rollout' => '15', 'stickiness' => 'DEFAULT' }) + expect(strategy_json['parameters']).to eq({ 'groupId' => 'default', 'rollout' => '15', 'stickiness' => 'default' }) expect(strategy_json['scopes'].count).to eq(1) scope_json = strategy_json['scopes'].first @@ -938,7 +938,7 @@ RSpec.describe Projects::FeatureFlagsController do it 'creates a flexibleRollout strategy' do put_request(new_version_flag, strategies_attributes: [{ name: 'flexibleRollout', - parameters: { groupId: 'default', rollout: '30', stickiness: 'DEFAULT' } + parameters: { groupId: 'default', rollout: '30', stickiness: 'default' } }]) expect(response).to have_gitlab_http_status(:ok) @@ -948,7 +948,7 @@ RSpec.describe Projects::FeatureFlagsController do expect(strategy_json['parameters']).to eq({ 'groupId' => 'default', 'rollout' => '30', - 'stickiness' => 'DEFAULT' + 'stickiness' => 'default' }) expect(strategy_json['scopes']).to eq([]) end diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 922ecb6052a..0c29280316a 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -1464,7 +1464,7 @@ RSpec.describe Projects::IssuesController do } end - it 'updates issue' do + it 'updates issue', :enable_admin_mode do post_spam expect(issue.submittable_as_spam?).to be_falsey end diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb index a7a36d3a074..e9e7c3c3bb3 100644 --- a/spec/controllers/projects/jobs_controller_spec.rb +++ b/spec/controllers/projects/jobs_controller_spec.rb @@ -868,64 +868,85 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'POST cancel' do - before do - project.add_developer(user) - sign_in(user) - end + context 'when user is authorized to cancel the build' do + before do + project.add_developer(user) + sign_in(user) + end - context 'when continue url is present' do - let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) } + context 'when continue url is present' do + let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) } - context 'when continue to is a safe url' do - let(:url) { '/test' } + context 'when continue to is a safe url' do + let(:url) { '/test' } - before do - post_cancel(continue: { to: url }) - end + before do + post_cancel(continue: { to: url }) + end - it 'redirects to the continue url' do - expect(response).to have_gitlab_http_status(:found) - expect(response).to redirect_to(url) + it 'redirects to the continue url' do + expect(response).to have_gitlab_http_status(:found) + expect(response).to redirect_to(url) + end + + it 'transits to canceled' do + expect(job.reload).to be_canceled + end end - it 'transits to canceled' do - expect(job.reload).to be_canceled + context 'when continue to is not a safe url' do + let(:url) { 'http://example.com' } + + it 'raises an error' do + expect { cancel_with_redirect(url) }.to raise_error + end end end - context 'when continue to is not a safe url' do - let(:url) { 'http://example.com' } + context 'when continue url is not present' do + before do + post_cancel + end + + context 'when job is cancelable' do + let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) } + + it 'redirects to the builds page' do + expect(response).to have_gitlab_http_status(:found) + expect(response).to redirect_to(builds_namespace_project_pipeline_path(id: pipeline.id)) + end + + it 'transits to canceled' do + expect(job.reload).to be_canceled + end + end + + context 'when job is not cancelable' do + let(:job) { create(:ci_build, :canceled, pipeline: pipeline) } - it 'raises an error' do - expect { cancel_with_redirect(url) }.to raise_error + it 'returns unprocessable_entity' do + expect(response).to have_gitlab_http_status(:unprocessable_entity) + end end end end - context 'when continue url is not present' do + context 'when user is not authorized to cancel the build' do + let!(:job) { create(:ci_build, :cancelable, pipeline: pipeline) } + before do + project.add_reporter(user) + sign_in(user) + post_cancel end - context 'when job is cancelable' do - let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) } - - it 'redirects to the builds page' do - expect(response).to have_gitlab_http_status(:found) - expect(response).to redirect_to(builds_namespace_project_pipeline_path(id: pipeline.id)) - end - - it 'transits to canceled' do - expect(job.reload).to be_canceled - end + it 'responds with not_found' do + expect(response).to have_gitlab_http_status(:not_found) end - context 'when job is not cancelable' do - let(:job) { create(:ci_build, :canceled, pipeline: pipeline) } - - it 'returns unprocessable_entity' do - expect(response).to have_gitlab_http_status(:unprocessable_entity) - end + it 'does not transit to canceled' do + expect(job.reload).not_to be_canceled end end @@ -938,43 +959,60 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do describe 'POST unschedule' do before do - project.add_developer(user) + create(:protected_branch, :developers_can_merge, name: 'master', project: project) + end - create(:protected_branch, :developers_can_merge, - name: 'master', project: project) + context 'when user is authorized to unschedule the build' do + before do + project.add_developer(user) + sign_in(user) - sign_in(user) + post_unschedule + end - post_unschedule - end + context 'when job is scheduled' do + let(:job) { create(:ci_build, :scheduled, pipeline: pipeline) } - context 'when job is scheduled' do - let(:job) { create(:ci_build, :scheduled, pipeline: pipeline) } + it 'redirects to the unscheduled job page' do + expect(response).to have_gitlab_http_status(:found) + expect(response).to redirect_to(namespace_project_job_path(id: job.id)) + end - it 'redirects to the unscheduled job page' do - expect(response).to have_gitlab_http_status(:found) - expect(response).to redirect_to(namespace_project_job_path(id: job.id)) + it 'transits to manual' do + expect(job.reload).to be_manual + end end - it 'transits to manual' do - expect(job.reload).to be_manual + context 'when job is not scheduled' do + let(:job) { create(:ci_build, pipeline: pipeline) } + + it 'renders unprocessable_entity' do + expect(response).to have_gitlab_http_status(:unprocessable_entity) + end end end - context 'when job is not scheduled' do - let(:job) { create(:ci_build, pipeline: pipeline) } + context 'when user is not authorized to unschedule the build' do + let(:job) { create(:ci_build, :scheduled, pipeline: pipeline) } - it 'renders unprocessable_entity' do - expect(response).to have_gitlab_http_status(:unprocessable_entity) + before do + project.add_reporter(user) + sign_in(user) + + post_unschedule + end + + it 'responds with not_found' do + expect(response).to have_gitlab_http_status(:not_found) + end + + it 'does not transit to scheduled' do + expect(job.reload).not_to be_manual end end def post_unschedule - post :unschedule, params: { - namespace_id: project.namespace, - project_id: project, - id: job.id - } + post :unschedule, params: { namespace_id: project.namespace, project_id: project, id: job.id } 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 707d074b5c1..3d7636b1f30 100644 --- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe Projects::MergeRequests::DiffsController do include ProjectForksHelper + include TrackingHelpers shared_examples '404 for unexistent diffable' do context 'when diffable does not exists' do @@ -141,6 +142,24 @@ RSpec.describe Projects::MergeRequests::DiffsController do end describe 'GET diffs_metadata' do + shared_examples_for 'serializes diffs metadata with expected arguments' do + it 'returns success' do + subject + + expect(response).to have_gitlab_http_status(:ok) + end + + it 'serializes paginated merge request diff collection' do + expect_next_instance_of(DiffsMetadataSerializer) do |instance| + expect(instance).to receive(:represent) + .with(an_instance_of(collection), expected_options) + .and_call_original + end + + subject + end + end + def go(extra_params = {}) params = { namespace_id: project.namespace.to_param, @@ -179,32 +198,25 @@ RSpec.describe Projects::MergeRequests::DiffsController do end context 'with valid diff_id' do - it 'returns success' do - go(diff_id: merge_request.merge_request_diff.id) - - expect(response).to have_gitlab_http_status(:ok) - end - - it 'serializes diffs metadata with expected arguments' do - expected_options = { - environment: nil, - merge_request: merge_request, - merge_request_diff: merge_request.merge_request_diff, - merge_request_diffs: merge_request.merge_request_diffs, - start_version: nil, - start_sha: nil, - commit: nil, - latest_diff: true, - only_context_commits: false - } + subject { go(diff_id: merge_request.merge_request_diff.id) } - expect_next_instance_of(DiffsMetadataSerializer) do |instance| - expect(instance).to receive(:represent) - .with(an_instance_of(Gitlab::Diff::FileCollection::MergeRequestDiff), expected_options) - .and_call_original + it_behaves_like 'serializes diffs metadata with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiff } + let(:expected_options) do + { + environment: nil, + merge_request: merge_request, + merge_request_diff: merge_request.merge_request_diff, + merge_request_diffs: merge_request.merge_request_diffs, + start_version: nil, + start_sha: nil, + commit: nil, + latest_diff: true, + only_context_commits: false, + allow_tree_conflicts: true, + merge_ref_head_diff: false + } end - - go(diff_id: merge_request.merge_request_diff.id) end end @@ -261,62 +273,75 @@ RSpec.describe Projects::MergeRequests::DiffsController do end context 'with MR regular diff params' do - it 'returns success' do - go + subject { go } - expect(response).to have_gitlab_http_status(:ok) + it_behaves_like 'serializes diffs metadata with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiff } + let(:expected_options) do + { + environment: nil, + merge_request: merge_request, + merge_request_diff: merge_request.merge_request_diff, + merge_request_diffs: merge_request.merge_request_diffs, + start_version: nil, + start_sha: nil, + commit: nil, + latest_diff: true, + only_context_commits: false, + allow_tree_conflicts: true, + merge_ref_head_diff: nil + } + end end + end - it 'serializes diffs metadata with expected arguments' do - expected_options = { - environment: nil, - merge_request: merge_request, - merge_request_diff: merge_request.merge_request_diff, - merge_request_diffs: merge_request.merge_request_diffs, - start_version: nil, - start_sha: nil, - commit: nil, - latest_diff: true, - only_context_commits: false - } + context 'with commit param' do + subject { go(commit_id: merge_request.diff_head_sha) } - expect_next_instance_of(DiffsMetadataSerializer) do |instance| - expect(instance).to receive(:represent) - .with(an_instance_of(Gitlab::Diff::FileCollection::MergeRequestDiff), expected_options) - .and_call_original + it_behaves_like 'serializes diffs metadata with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::Commit } + let(:expected_options) do + { + environment: nil, + merge_request: merge_request, + merge_request_diff: nil, + merge_request_diffs: merge_request.merge_request_diffs, + start_version: nil, + start_sha: nil, + commit: merge_request.diff_head_commit, + latest_diff: nil, + only_context_commits: false, + allow_tree_conflicts: true, + merge_ref_head_diff: nil + } end - - go end end - context 'with commit param' do - it 'returns success' do - go(commit_id: merge_request.diff_head_sha) + context 'when display_merge_conflicts_in_diff is disabled' do + subject { go } - expect(response).to have_gitlab_http_status(:ok) + before do + stub_feature_flags(display_merge_conflicts_in_diff: false) end - it 'serializes diffs metadata with expected arguments' do - expected_options = { - environment: nil, - merge_request: merge_request, - merge_request_diff: nil, - merge_request_diffs: merge_request.merge_request_diffs, - start_version: nil, - start_sha: nil, - commit: merge_request.diff_head_commit, - latest_diff: nil, - only_context_commits: false - } - - expect_next_instance_of(DiffsMetadataSerializer) do |instance| - expect(instance).to receive(:represent) - .with(an_instance_of(Gitlab::Diff::FileCollection::Commit), expected_options) - .and_call_original + it_behaves_like 'serializes diffs metadata with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiff } + let(:expected_options) do + { + environment: nil, + merge_request: merge_request, + merge_request_diff: merge_request.merge_request_diff, + merge_request_diffs: merge_request.merge_request_diffs, + start_version: nil, + start_sha: nil, + commit: nil, + latest_diff: true, + only_context_commits: false, + allow_tree_conflicts: false, + merge_ref_head_diff: nil + } end - - go(commit_id: merge_request.diff_head_sha) end end end @@ -423,7 +448,7 @@ RSpec.describe Projects::MergeRequests::DiffsController do context 'when DNT is enabled' do before do - request.headers['DNT'] = '1' + stub_do_not_track('1') end it 'does not track any mr_diffs event' do @@ -471,6 +496,7 @@ RSpec.describe Projects::MergeRequests::DiffsController do merge_request: merge_request, diff_view: :inline, merge_ref_head_diff: nil, + allow_tree_conflicts: true, pagination_data: { total_pages: nil }.merge(pagination_data) @@ -589,6 +615,21 @@ RSpec.describe Projects::MergeRequests::DiffsController do it_behaves_like 'successful request' end + context 'when display_merge_conflicts_in_diff is disabled' do + before do + stub_feature_flags(display_merge_conflicts_in_diff: false) + end + + subject { go } + + it_behaves_like 'serializes diffs with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiffBatch } + let(:expected_options) { collection_arguments(total_pages: 20).merge(allow_tree_conflicts: false) } + end + + it_behaves_like 'successful request' + end + it_behaves_like 'forked project with submodules' it_behaves_like 'cached diff collection' diff --git a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb index dc5a022eb7b..fc741d0f3f6 100644 --- a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb +++ b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb @@ -18,9 +18,9 @@ RSpec.describe Projects::Packages::InfrastructureRegistryController do it_behaves_like 'returning response status', :ok - context 'when the feature is disabled' do + context 'when the packages registry is not available' do before do - stub_feature_flags(infrastructure_registry_page: false) + stub_config(packages: { enabled: false }) end it_behaves_like 'returning response status', :not_found @@ -34,9 +34,9 @@ RSpec.describe Projects::Packages::InfrastructureRegistryController do it_behaves_like 'returning response status', :ok - context 'when the feature is disabled' do + context 'when the packages registry is not available' do before do - stub_feature_flags(infrastructure_registry_page: false) + stub_config(packages: { enabled: false }) end it_behaves_like 'returning response status', :not_found diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index 9ed43a251a2..be5c1f0d428 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -93,13 +93,12 @@ RSpec.describe Projects::ProjectMembersController do let_it_be(:invited_member) { create(:project_member, :invited, project: project) } before do - project.add_maintainer(user) sign_in(user) end context 'when user has `admin_project_member` permissions' do before do - allow(controller.helpers).to receive(:can_manage_project_members?).with(project).and_return(true) + project.add_maintainer(user) end it 'lists invited members' do @@ -110,10 +109,6 @@ RSpec.describe Projects::ProjectMembersController do end context 'when user does not have `admin_project_member` permissions' do - before do - allow(controller.helpers).to receive(:can_manage_project_members?).with(project).and_return(false) - end - it 'does not list invited members' do get :index, params: { namespace_id: project.namespace, project_id: project } @@ -127,13 +122,12 @@ RSpec.describe Projects::ProjectMembersController do before do project.request_access(access_requester_user) - project.add_maintainer(user) sign_in(user) end context 'when user has `admin_project_member` permissions' do before do - allow(controller.helpers).to receive(:can_manage_project_members?).with(project).and_return(true) + project.add_maintainer(user) end it 'lists access requests' do @@ -144,10 +138,6 @@ RSpec.describe Projects::ProjectMembersController do end context 'when user does not have `admin_project_member` permissions' do - before do - allow(controller.helpers).to receive(:can_manage_project_members?).with(project).and_return(false) - end - it 'does not list access requests' do get :index, params: { namespace_id: project.namespace, project_id: project } diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb index 5dee36ee7c2..2c25c7e20ea 100644 --- a/spec/controllers/projects/raw_controller_spec.rb +++ b/spec/controllers/projects/raw_controller_spec.rb @@ -33,15 +33,25 @@ RSpec.describe Projects::RawController do end context 'regular filename' do - let(:filepath) { 'master/README.md' } + let(:filepath) { 'master/CONTRIBUTING.md' } it 'delivers ASCII file' do + allow(Gitlab::Workhorse).to receive(:send_git_blob).and_call_original + subject expect(response).to have_gitlab_http_status(:ok) expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8') expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq 'true' expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') + + expect(Gitlab::Workhorse).to have_received(:send_git_blob) do |repository, blob| + expected_blob = project.repository.blob_at('master', 'CONTRIBUTING.md') + + expect(repository).to eq(project.repository) + expect(blob.id).to eq(expected_blob.id) + expect(blob).to be_truncated + end end it_behaves_like 'project cache control headers' diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb index baf3bde83bd..419b5c7e101 100644 --- a/spec/controllers/projects/services_controller_spec.rb +++ b/spec/controllers/projects/services_controller_spec.rb @@ -174,6 +174,8 @@ RSpec.describe Projects::ServicesController do let(:redirect_url) { edit_project_service_path(project, integration) } before do + stub_jira_integration_test + put :update, params: params end @@ -222,12 +224,48 @@ RSpec.describe Projects::ServicesController do end end - context 'when param `inherit_from_id` is set to some value' do - let(:instance_service) { create(:jira_integration, :instance) } - let(:integration_params) { { inherit_from_id: instance_service.id } } + context 'when param `inherit_from_id` is set to an instance integration' do + let(:instance_integration) { create(:jira_integration, :instance, url: 'http://instance.com', password: 'instance') } + let(:integration_params) { { inherit_from_id: instance_integration.id, url: 'http://custom.com', password: 'custom' } } + + it 'ignores submitted params and inherits instance settings' do + expect(integration.reload).to have_attributes( + inherit_from_id: instance_integration.id, + url: instance_integration.url, + password: instance_integration.password + ) + end + end + + context 'when param `inherit_from_id` is set to a group integration' do + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } + let_it_be(:jira_integration) { create(:jira_integration, project: project) } - it 'sets inherit_from_id to value' do - expect(integration.reload.inherit_from_id).to eq(instance_service.id) + let(:group_integration) { create(:jira_integration, group: group, project: nil, url: 'http://group.com', password: 'group') } + let(:integration_params) { { inherit_from_id: group_integration.id, url: 'http://custom.com', password: 'custom' } } + + it 'ignores submitted params and inherits group settings' do + expect(integration.reload).to have_attributes( + inherit_from_id: group_integration.id, + url: group_integration.url, + password: group_integration.password + ) + end + end + + context 'when param `inherit_from_id` is set to an unrelated group' do + let_it_be(:group) { create(:group) } + + let(:group_integration) { create(:jira_integration, group: group, project: nil, url: 'http://group.com', password: 'group') } + let(:integration_params) { { inherit_from_id: group_integration.id, url: 'http://custom.com', password: 'custom' } } + + it 'ignores the param and saves the submitted settings' do + expect(integration.reload).to have_attributes( + inherit_from_id: nil, + url: 'http://custom.com', + password: 'custom' + ) end end end @@ -239,22 +277,39 @@ RSpec.describe Projects::ServicesController do end context 'when update succeeds' do - let(:integration_params) { { url: 'http://example.com' } } + let(:integration_params) { { url: 'http://example.com', password: 'password' } } - it 'returns JSON response with no errors' do + it 'returns success response' do expect(response).to be_successful - expect(json_response).to include('active' => true, 'errors' => {}) + expect(json_response).to include( + 'active' => true, + 'errors' => {} + ) + end + end + + context 'when update fails with missing password' do + let(:integration_params) { { url: 'http://example.com' } } + + it 'returns JSON response errors' do + expect(response).not_to be_successful + expect(json_response).to include( + 'active' => true, + 'errors' => { + 'password' => ["can't be blank"] + } + ) end end - context 'when update fails' do - let(:integration_params) { { url: '' } } + context 'when update fails with invalid URL' do + let(:integration_params) { { url: '', password: 'password' } } it 'returns JSON response with errors' do expect(response).to have_gitlab_http_status(:unprocessable_entity) expect(json_response).to include( 'active' => true, - 'errors' => { 'url' => ['must be a valid URL', %(can't be blank)] } + 'errors' => { 'url' => ['must be a valid URL', "can't be blank"] } ) end end diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb index 1a6c0974f08..a388fc4620f 100644 --- a/spec/controllers/projects/snippets_controller_spec.rb +++ b/spec/controllers/projects/snippets_controller_spec.rb @@ -110,7 +110,7 @@ RSpec.describe Projects::SnippetsController do } end - it 'updates the snippet' do + it 'updates the snippet', :enable_admin_mode do mark_as_spam expect(snippet.reload).not_to be_submittable_as_spam @@ -181,6 +181,24 @@ RSpec.describe Projects::SnippetsController do end end end + + context 'when the project snippet is public' do + let_it_be(:project_snippet_public) { create(:project_snippet, :public, :repository, project: project, author: user) } + + context 'when attempting to access from a different project route' do + subject { get action, params: { namespace_id: project.namespace, project_id: 42, id: project_snippet_public.to_param } } + + before do + sign_in(user) + end + + it 'responds with status 404' do + subject + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end end end |