diff options
Diffstat (limited to 'spec/controllers')
44 files changed, 672 insertions, 241 deletions
diff --git a/spec/controllers/abuse_reports_controller_spec.rb b/spec/controllers/abuse_reports_controller_spec.rb deleted file mode 100644 index 11371108375..00000000000 --- a/spec/controllers/abuse_reports_controller_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe AbuseReportsController do - let(:reporter) { create(:user) } - let(:user) { create(:user) } - let(:attrs) do - attributes_for(:abuse_report) do |hash| - hash[:user_id] = user.id - end - end - - before do - sign_in(reporter) - end - - describe 'GET new' do - context 'when the user has already been deleted' do - it 'redirects the reporter to root_path' do - user_id = user.id - user.destroy! - - get :new, params: { user_id: user_id } - - expect(response).to redirect_to root_path - expect(flash[:alert]).to eq(_('Cannot create the abuse report. The user has been deleted.')) - end - end - - context 'when the user has already been blocked' do - it 'redirects the reporter to the user\'s profile' do - user.block - - get :new, params: { user_id: user.id } - - expect(response).to redirect_to user - expect(flash[:alert]).to eq(_('Cannot create the abuse report. This user has been blocked.')) - end - end - end - - describe 'POST create' do - context 'with valid attributes' do - it 'saves the abuse report' do - expect do - post :create, params: { abuse_report: attrs } - end.to change { AbuseReport.count }.by(1) - end - - it 'calls notify' do - expect_next_instance_of(AbuseReport) do |instance| - expect(instance).to receive(:notify) - end - - post :create, params: { abuse_report: attrs } - end - - it 'redirects back to root' do - post :create, params: { abuse_report: attrs } - - expect(response).to redirect_to root_path - end - end - - context 'with invalid attributes' do - it 'renders new' do - attrs.delete(:user_id) - post :create, params: { abuse_report: attrs } - - expect(response).to render_template(:new) - end - end - end -end diff --git a/spec/controllers/admin/instance_review_controller_spec.rb b/spec/controllers/admin/instance_review_controller_spec.rb index 2169be4e70c..342562618b2 100644 --- a/spec/controllers/admin/instance_review_controller_spec.rb +++ b/spec/controllers/admin/instance_review_controller_spec.rb @@ -23,7 +23,7 @@ RSpec.describe Admin::InstanceReviewController do stub_application_setting(usage_ping_enabled: true) stub_usage_data_connections stub_database_flavor_check - ::Gitlab::UsageData.data(force_refresh: true) + ::Gitlab::Usage::ServicePingReport.for(output: :all_metrics_values) subject end diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb index 08fb12c375e..74f352e8ec2 100644 --- a/spec/controllers/admin/runners_controller_spec.rb +++ b/spec/controllers/admin/runners_controller_spec.rb @@ -4,9 +4,10 @@ require 'spec_helper' RSpec.describe Admin::RunnersController do let_it_be(:runner) { create(:ci_runner) } + let_it_be(:user) { create(:admin) } before do - sign_in(create(:admin)) + sign_in(user) end describe '#index' do @@ -104,6 +105,10 @@ RSpec.describe Admin::RunnersController do describe '#destroy' do it 'destroys the runner' do + expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service| + expect(service).to receive(:execute).once.and_call_original + end + delete :destroy, params: { id: runner.id } expect(response).to have_gitlab_http_status(:found) diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb index 6ccba866ebb..533d3896ee6 100644 --- a/spec/controllers/autocomplete_controller_spec.rb +++ b/spec/controllers/autocomplete_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe AutocompleteController do let(:project) { create(:project) } - let(:user) { project.owner } + let(:user) { project.first_owner } context 'GET users' do let!(:user2) { create(:user) } diff --git a/spec/controllers/dashboard/projects_controller_spec.rb b/spec/controllers/dashboard/projects_controller_spec.rb index 743759d5023..b4a4ac56fce 100644 --- a/spec/controllers/dashboard/projects_controller_spec.rb +++ b/spec/controllers/dashboard/projects_controller_spec.rb @@ -97,14 +97,18 @@ RSpec.describe Dashboard::ProjectsController, :aggregate_failures do subject { get :starred, format: :json } let(:projects) { create_list(:project, 2, creator: user) } + let(:aimed_for_deletion_project) { create_list(:project, 2, :archived, creator: user, marked_for_deletion_at: 3.days.ago) } before do - allow(Kaminari.config).to receive(:default_per_page).and_return(1) - projects.each do |project| project.add_developer(user) create(:users_star_project, project_id: project.id, user_id: user.id) end + + aimed_for_deletion_project.each do |project| + project.add_developer(user) + create(:users_star_project, project_id: project.id, user_id: user.id) + end end it 'returns success' do @@ -113,10 +117,22 @@ RSpec.describe Dashboard::ProjectsController, :aggregate_failures do expect(response).to have_gitlab_http_status(:ok) end - it 'paginates the records' do + context "pagination" do + before do + allow(Kaminari.config).to receive(:default_per_page).and_return(1) + end + + it 'paginates the records' do + subject + + expect(assigns(:projects).count).to eq(1) + end + end + + it 'does not include projects aimed for deletion' do subject - expect(assigns(:projects).count).to eq(1) + expect(assigns(:projects).count).to eq(2) end end end diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb index f2328303102..c3f6c653376 100644 --- a/spec/controllers/explore/projects_controller_spec.rb +++ b/spec/controllers/explore/projects_controller_spec.rb @@ -73,6 +73,24 @@ RSpec.describe Explore::ProjectsController do expect(assigns(:projects)).to eq [project1, project2] end end + + context 'projects aimed for deletion' do + let(:project1) { create(:project, :public, updated_at: 3.days.ago) } + let(:project2) { create(:project, :public, updated_at: 1.day.ago) } + let(:aimed_for_deletion_project) { create(:project, :public, :archived, updated_at: 2.days.ago, marked_for_deletion_at: 2.days.ago) } + + before do + create(:trending_project, project: project1) + create(:trending_project, project: project2) + create(:trending_project, project: aimed_for_deletion_project) + end + + it 'does not list projects aimed for deletion' do + get :trending + + expect(assigns(:projects)).to eq [project2, project1] + end + end end describe 'GET #topic' do diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb index 578ce04721c..95f60156c40 100644 --- a/spec/controllers/graphql_controller_spec.rb +++ b/spec/controllers/graphql_controller_spec.rb @@ -124,6 +124,16 @@ RSpec.describe GraphqlController do post :execute end + + it 'calls the track jetbrains api when trackable method' do + agent = 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1' + request.env['HTTP_USER_AGENT'] = agent + + expect(Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter) + .to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user) + + post :execute + end end context 'when user uses an API token' do @@ -151,6 +161,16 @@ RSpec.describe GraphqlController do subject end + + it 'calls the track jetbrains api when trackable method' do + agent = 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1' + request.env['HTTP_USER_AGENT'] = agent + + expect(Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter) + .to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user) + + subject + end end context 'when user is not logged in' do diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb index 93c560b4753..710e983dfbd 100644 --- a/spec/controllers/groups/clusters_controller_spec.rb +++ b/spec/controllers/groups/clusters_controller_spec.rb @@ -103,7 +103,7 @@ RSpec.describe Groups::ClustersController do it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) } it { expect { go }.to be_allowed_for(:owner).of(group) } it { expect { go }.to be_allowed_for(:maintainer).of(group) } - it { expect { go }.to be_denied_for(:developer).of(group) } + it { expect { go }.to be_allowed_for(:developer).of(group) } it { expect { go }.to be_denied_for(:reporter).of(group) } it { expect { go }.to be_denied_for(:guest).of(group) } it { expect { go }.to be_denied_for(:user) } @@ -309,7 +309,8 @@ RSpec.describe Groups::ClustersController do .to receive(:expires_at_in_session).and_return(1.hour.since.to_i.to_s) allow_any_instance_of(GoogleApi::CloudPlatform::Client) .to receive(:projects_zones_clusters_create) do - OpenStruct.new( + double( + 'instance', self_link: 'projects/gcp-project-12345/zones/us-central1-a/operations/ope-123', status: 'RUNNING' ) @@ -673,7 +674,7 @@ RSpec.describe Groups::ClustersController do it('is denied for admin when admin mode is disabled') { expect { go }.to be_denied_for(:admin) } it { expect { go }.to be_allowed_for(:owner).of(group) } it { expect { go }.to be_allowed_for(:maintainer).of(group) } - it { expect { go }.to be_denied_for(:developer).of(group) } + it { expect { go }.to be_allowed_for(:developer).of(group) } it { expect { go }.to be_denied_for(:reporter).of(group) } it { expect { go }.to be_denied_for(:guest).of(group) } it { expect { go }.to be_denied_for(:user) } diff --git a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb index f438be534fa..57a83da3425 100644 --- a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb +++ b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb @@ -47,6 +47,24 @@ RSpec.describe Groups::DependencyProxyForContainersController do end end + shared_examples 'with invalid path' do + context 'with invalid image' do + let(:image) { '../path_traversal' } + + it 'raises an error' do + expect { subject }.to raise_error(Gitlab::Utils::PathTraversalAttackError, 'Invalid path') + end + end + + context 'with invalid tag' do + let(:tag) { 'latest%2f..%2f..%2fpath_traversal' } + + it 'raises an error' do + expect { subject }.to raise_error(Gitlab::Utils::PathTraversalAttackError, 'Invalid path') + end + end + end + shared_examples 'without permission' do context 'with invalid user' do before do @@ -164,8 +182,10 @@ RSpec.describe Groups::DependencyProxyForContainersController do end describe 'GET #manifest' do + let_it_be(:image) { 'alpine' } let_it_be(:tag) { 'latest' } - let_it_be(:manifest) { create(:dependency_proxy_manifest, file_name: "alpine:#{tag}.json", group: group) } + let_it_be(:file_name) { "#{image}:#{tag}.json" } + let_it_be(:manifest) { create(:dependency_proxy_manifest, file_name: file_name, group: group) } let(:pull_response) { { status: :success, manifest: manifest, from_cache: false } } @@ -235,6 +255,8 @@ RSpec.describe Groups::DependencyProxyForContainersController do context 'with workhorse response' do let(:pull_response) { { status: :success, manifest: nil, from_cache: false } } + it_behaves_like 'with invalid path' + it 'returns Workhorse send-dependency instructions', :aggregate_failures do subject @@ -246,7 +268,7 @@ RSpec.describe Groups::DependencyProxyForContainersController do "Authorization" => ["Bearer abcd1234"], "Accept" => ::ContainerRegistry::Client::ACCEPTED_TYPES ) - expect(url).to eq(DependencyProxy::Registry.manifest_url('alpine', tag)) + expect(url).to eq(DependencyProxy::Registry.manifest_url(image, tag)) expect(response.headers['Content-Type']).to eq('application/gzip') expect(response.headers['Content-Disposition']).to eq( ActionDispatch::Http::ContentDisposition.format(disposition: 'attachment', filename: manifest.file_name) @@ -277,7 +299,7 @@ RSpec.describe Groups::DependencyProxyForContainersController do it_behaves_like 'not found when disabled' def get_manifest(tag) - get :manifest, params: { group_id: group.to_param, image: 'alpine', tag: tag } + get :manifest, params: { group_id: group.to_param, image: image, tag: tag } end end @@ -440,6 +462,7 @@ RSpec.describe Groups::DependencyProxyForContainersController do end it_behaves_like 'a package tracking event', described_class.name, 'pull_manifest' + it_behaves_like 'with invalid path' context 'with no existing manifest' do it 'creates a manifest' do diff --git a/spec/controllers/groups/releases_controller_spec.rb b/spec/controllers/groups/releases_controller_spec.rb index 50701382945..582a77b1c50 100644 --- a/spec/controllers/groups/releases_controller_spec.rb +++ b/spec/controllers/groups/releases_controller_spec.rb @@ -6,14 +6,14 @@ RSpec.describe Groups::ReleasesController do let(:group) { create(:group) } let!(:project) { create(:project, :repository, :public, namespace: group) } let!(:private_project) { create(:project, :repository, :private, namespace: group) } - let(:developer) { create(:user) } + let(:guest) { create(:user) } let!(:release_1) { create(:release, project: project, tag: 'v1', released_at: Time.zone.parse('2020-02-15')) } let!(:release_2) { create(:release, project: project, tag: 'v2', released_at: Time.zone.parse('2020-02-20')) } let!(:private_release_1) { create(:release, project: private_project, tag: 'p1', released_at: Time.zone.parse('2020-03-01')) } let!(:private_release_2) { create(:release, project: private_project, tag: 'p2', released_at: Time.zone.parse('2020-03-05')) } before do - private_project.add_developer(developer) + group.add_guest(guest) end describe 'GET #index' do @@ -42,7 +42,7 @@ RSpec.describe Groups::ReleasesController do end it 'does not return any releases' do - expect(json_response.map {|r| r['tag'] } ).to match_array(%w(v2 v1)) + expect(json_response.map {|r| r['tag'] } ).to be_empty end it 'returns OK' do @@ -52,7 +52,7 @@ RSpec.describe Groups::ReleasesController do context 'the user is authorized' do it "returns all group's public and private project's releases as JSON, ordered by released_at" do - sign_in(developer) + sign_in(guest) subject diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb index a8830efe653..9f0615a96ae 100644 --- a/spec/controllers/groups/runners_controller_spec.rb +++ b/spec/controllers/groups/runners_controller_spec.rb @@ -190,6 +190,10 @@ RSpec.describe Groups::RunnersController do end it 'destroys the runner and redirects' do + expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service| + expect(service).to receive(:execute).once.and_call_original + end + delete :destroy, params: params expect(response).to have_gitlab_http_status(:found) diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index 62171528695..a82c5681911 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -132,6 +132,29 @@ RSpec.describe GroupsController, factory_default: :keep do end end end + + describe 'require_verification_for_namespace_creation experiment', :experiment do + before do + sign_in(owner) + stub_experiments(require_verification_for_namespace_creation: :candidate) + end + + it 'tracks a "start_create_group" event' do + expect(experiment(:require_verification_for_namespace_creation)).to track( + :start_create_group + ).on_next_instance.with_context(user: owner) + + get :new + end + + context 'when creating a sub-group' do + it 'does not track a "start_create_group" event' do + expect(experiment(:require_verification_for_namespace_creation)).not_to track(:start_create_group) + + get :new, params: { parent_id: group.id } + end + end + end end describe 'GET #activity' do diff --git a/spec/controllers/metrics_controller_spec.rb b/spec/controllers/metrics_controller_spec.rb index 4f74af295c6..9fa90dde997 100644 --- a/spec/controllers/metrics_controller_spec.rb +++ b/spec/controllers/metrics_controller_spec.rb @@ -67,12 +67,6 @@ RSpec.describe MetricsController, :request_store do expect(response.body).to match(/^prometheus_counter 1$/) end - it 'initializes the rails request SLIs' do - expect(Gitlab::Metrics::RailsSlis).to receive(:initialize_request_slis_if_needed!).and_call_original - - get :index - end - context 'prometheus metrics are disabled' do before do allow(Gitlab::Metrics).to receive(:prometheus_metrics_enabled?).and_return(false) diff --git a/spec/controllers/oauth/authorizations_controller_spec.rb b/spec/controllers/oauth/authorizations_controller_spec.rb index 98cc8d83e0c..e6553c027d6 100644 --- a/spec/controllers/oauth/authorizations_controller_spec.rb +++ b/spec/controllers/oauth/authorizations_controller_spec.rb @@ -4,7 +4,13 @@ require 'spec_helper' RSpec.describe Oauth::AuthorizationsController do let(:user) { create(:user) } - let!(:application) { create(:oauth_application, scopes: 'api read_user', redirect_uri: 'http://example.com') } + let(:application_scopes) { 'api read_user' } + + let!(:application) do + create(:oauth_application, scopes: application_scopes, + redirect_uri: 'http://example.com') + end + let(:params) do { response_type: "code", @@ -119,6 +125,92 @@ RSpec.describe Oauth::AuthorizationsController do expect(response).to have_gitlab_http_status(:ok) expect(response).to render_template('doorkeeper/authorizations/redirect') end + + context 'with gl_auth_type=login' do + let(:minimal_scope) { Gitlab::Auth::READ_USER_SCOPE.to_s } + + before do + params[:gl_auth_type] = 'login' + end + + shared_examples 'downgrades scopes' do + it 'downgrades the scopes' do + subject + + pre_auth = controller.send(:pre_auth) + + expect(pre_auth.scopes).to contain_exactly(minimal_scope) + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template('doorkeeper/authorizations/new') + # See: config/locales/doorkeeper.en.yml + expect(response.body).to include("Read the authenticated user's personal information") + expect(response.body).not_to include("Access the authenticated user's API") + end + end + + shared_examples 'adds read_user scope' do + it 'modifies the client.application.scopes' do + expect { subject } + .to change { application.reload.scopes }.to include(minimal_scope) + end + + it 'does not remove pre-existing scopes' do + subject + + expect(application.scopes).to include(*application_scopes.split(/ /)) + end + end + + context 'the application has all scopes' do + let(:application_scopes) { 'api read_api read_user' } + + include_examples 'downgrades scopes' + end + + context 'the application has api and read_user scopes' do + let(:application_scopes) { 'api read_user' } + + include_examples 'downgrades scopes' + end + + context 'the application has read_api and read_user scopes' do + let(:application_scopes) { 'read_api read_user' } + + include_examples 'downgrades scopes' + end + + context 'the application has only api scopes' do + let(:application_scopes) { 'api' } + + include_examples 'downgrades scopes' + include_examples 'adds read_user scope' + end + + context 'the application has only read_api scopes' do + let(:application_scopes) { 'read_api' } + + include_examples 'downgrades scopes' + include_examples 'adds read_user scope' + end + + context 'the application has scopes we do not handle' do + let(:application_scopes) { Gitlab::Auth::PROFILE_SCOPE.to_s } + + before do + params[:scope] = application_scopes + end + + it 'does not modify the scopes' do + subject + + pre_auth = controller.send(:pre_auth) + + expect(pre_auth.scopes).to contain_exactly(application_scopes) + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template('doorkeeper/authorizations/new') + end + end + end end end end diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb index 754b0ddfb94..f410c16b30b 100644 --- a/spec/controllers/projects/artifacts_controller_spec.rb +++ b/spec/controllers/projects/artifacts_controller_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe Projects::ArtifactsController do include RepoHelpers - let(:user) { project.owner } + let(:user) { project.first_owner } let_it_be(:project) { create(:project, :repository, :public) } let_it_be(:pipeline, reload: true) do diff --git a/spec/controllers/projects/autocomplete_sources_controller_spec.rb b/spec/controllers/projects/autocomplete_sources_controller_spec.rb index 865b31a28d7..79edc261809 100644 --- a/spec/controllers/projects/autocomplete_sources_controller_spec.rb +++ b/spec/controllers/projects/autocomplete_sources_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Projects::AutocompleteSourcesController do - let_it_be(:group) { create(:group) } + let_it_be(:group, reload: true) { create(:group) } let_it_be(:project) { create(:project, namespace: group) } let_it_be(:issue) { create(:issue, project: project) } let_it_be(:user) { create(:user) } @@ -69,4 +69,62 @@ RSpec.describe Projects::AutocompleteSourcesController do end end end + + describe 'GET contacts' do + let_it_be(:contact_1) { create(:contact, group: group) } + let_it_be(:contact_2) { create(:contact, group: group) } + + before do + sign_in(user) + end + + context 'when feature flag is enabled' do + context 'when a group has contact relations enabled' do + before do + create(:crm_settings, group: group, enabled: true) + end + + context 'when a user can read contacts' do + it 'lists contacts' do + group.add_developer(user) + + get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path } + + emails = json_response.map { |contact_data| contact_data["email"] } + expect(emails).to match_array([contact_1.email, contact_2.email]) + end + end + + context 'when a user can not read contacts' do + it 'renders 404' do + get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path } + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'when a group has contact relations disabled' do + it 'renders 404' do + group.add_developer(user) + + get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path } + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(customer_relations: false) + end + + it 'renders 404' do + get :contacts, format: :json, params: { namespace_id: group.path, project_id: project.path } + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end end diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb index 35878fe4c2d..39a373ed6b6 100644 --- a/spec/controllers/projects/avatars_controller_spec.rb +++ b/spec/controllers/projects/avatars_controller_spec.rb @@ -38,7 +38,7 @@ RSpec.describe Projects::AvatarsController do end it 'sets appropriate caching headers' do - sign_in(project.owner) + sign_in(project.first_owner) subject expect(response.cache_control[:public]).to eq(true) @@ -63,7 +63,7 @@ RSpec.describe Projects::AvatarsController do let(:project) { create(:project, :repository, avatar: fixture_file_upload("spec/fixtures/dk.png", "image/png")) } before do - sign_in(project.owner) + sign_in(project.first_owner) end it 'removes avatar from DB by calling destroy' do diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb index 242b2fd3ec6..d41e8d6169f 100644 --- a/spec/controllers/projects/badges_controller_spec.rb +++ b/spec/controllers/projects/badges_controller_spec.rb @@ -7,39 +7,100 @@ RSpec.describe Projects::BadgesController do let_it_be(:pipeline, reload: true) { create(:ci_empty_pipeline, project: project) } let_it_be(:user) { create(:user) } - shared_examples 'a badge resource' do |badge_type| - context 'when pipelines are public' do + shared_context 'renders badge irrespective of project access levels' do |badge_type| + context 'when project is public' do before do - project.update!(public_builds: true) + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) end - context 'when project is public' do - before do - project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - end + it "returns the #{badge_type} badge to unauthenticated users" do + get_badge(badge_type) - it "returns the #{badge_type} badge to unauthenticated users" do - get_badge(badge_type) + expect(response).to have_gitlab_http_status(:ok) + end + end - expect(response).to have_gitlab_http_status(:ok) - end + context 'when project is restricted' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + project.add_guest(user) + sign_in(user) end - context 'when project is restricted' do - before do - project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - project.add_guest(user) - sign_in(user) - end + it "returns the #{badge_type} badge to guest users" do + get_badge(badge_type) - it "returns the #{badge_type} badge to guest users" do - get_badge(badge_type) + expect(response).to have_gitlab_http_status(:ok) + end + end + end - expect(response).to have_gitlab_http_status(:ok) - end + shared_context 'when pipelines are public' do |badge_type| + before do + project.update!(public_builds: true) + end + + it_behaves_like 'renders badge irrespective of project access levels', badge_type + end + + shared_context 'when pipelines are not public' do |badge_type| + before do + project.update!(public_builds: false) + end + + context 'when project is public' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + end + + it 'returns 404 to unauthenticated users' do + get_badge(badge_type) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when project is restricted to the user' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + project.add_guest(user) + sign_in(user) + end + + it 'defaults to project permissions' do + get_badge(badge_type) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + shared_context 'customization' do |badge_type| + render_views + + before do + project.add_maintainer(user) + sign_in(user) + end + + context 'when key_text param is used' do + it 'sets custom key text' do + get_badge(badge_type, key_text: 'custom key text') + + expect(response.body).to include('custom key text') + end + end + + context 'when key_width param is used' do + it 'sets custom key width' do + get_badge(badge_type, key_width: '123') + + expect(response.body).to include('123') end end + end + shared_examples 'a badge resource' do |badge_type| context 'format' do before do project.add_maintainer(user) @@ -77,61 +138,11 @@ RSpec.describe Projects::BadgesController do end end - context 'when pipelines are not public' do - before do - project.update!(public_builds: false) - end - - context 'when project is public' do - before do - project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - end - - it 'returns 404 to unauthenticated users' do - get_badge(badge_type) - - expect(response).to have_gitlab_http_status(:not_found) - end - end - - context 'when project is restricted to the user' do - before do - project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - project.add_guest(user) - sign_in(user) - end - - it 'defaults to project permissions' do - get_badge(badge_type) - - expect(response).to have_gitlab_http_status(:not_found) - end - end - end - - context 'customization' do - render_views - - before do - project.add_maintainer(user) - sign_in(user) - end - - context 'when key_text param is used' do - it 'sets custom key text' do - get_badge(badge_type, key_text: 'custom key text') - - expect(response.body).to include('custom key text') - end - end - - context 'when key_width param is used' do - it 'sets custom key width' do - get_badge(badge_type, key_width: '123') + it_behaves_like 'customization', badge_type - expect(response.body).to include('123') - end - end + if [:pipeline, :coverage].include?(badge_type) + it_behaves_like 'when pipelines are public', badge_type + it_behaves_like 'when pipelines are not public', badge_type end end @@ -163,6 +174,13 @@ RSpec.describe Projects::BadgesController do it_behaves_like 'a badge resource', :coverage end + describe '#release' do + action = :release + + it_behaves_like 'a badge resource', action + it_behaves_like 'renders badge irrespective of project access levels', action + end + def get_badge(badge, args = {}) params = { namespace_id: project.namespace.to_param, diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index d9dedb04b0d..ea22e6b6f10 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -657,6 +657,36 @@ RSpec.describe Projects::BranchesController do end end + context 'sorting', :aggregate_failures do + let(:sort) { 'name_asc' } + + before do + get :index, format: :html, params: { + namespace_id: project.namespace, project_id: project, state: 'all', sort: sort + } + end + + it { expect(assigns[:sort]).to eq('name_asc') } + + context 'when sort is not provided' do + let(:sort) { nil } + + it 'uses a default sort without an error message' do + expect(assigns[:sort]).to eq('updated_desc') + expect(controller).not_to set_flash.now[:alert] + end + end + + context 'when sort is not supported' do + let(:sort) { 'unknown' } + + it 'uses a default sort and shows an error message' do + expect(assigns[:sort]).to eq('updated_desc') + expect(controller).to set_flash.now[:alert].to(/Unsupported sort/) + end + end + end + context 'when gitaly is not available' do before do allow_next_instance_of(Gitlab::GitalyClient::RefService) do |ref_service| diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb index 2a8feb09780..d0bef810ec8 100644 --- a/spec/controllers/projects/clusters_controller_spec.rb +++ b/spec/controllers/projects/clusters_controller_spec.rb @@ -101,7 +101,7 @@ RSpec.describe Projects::ClustersController do it { expect { go }.to be_allowed_for(:owner).of(project) } it { expect { go }.to be_allowed_for(:maintainer).of(project) } - it { expect { go }.to be_denied_for(:developer).of(project) } + it { expect { go }.to be_allowed_for(:developer).of(project) } it { expect { go }.to be_denied_for(:reporter).of(project) } it { expect { go }.to be_denied_for(:guest).of(project) } it { expect { go }.to be_denied_for(:user) } @@ -315,7 +315,8 @@ RSpec.describe Projects::ClustersController do .to receive(:expires_at_in_session).and_return(1.hour.since.to_i.to_s) allow_any_instance_of(GoogleApi::CloudPlatform::Client) .to receive(:projects_zones_clusters_create) do - OpenStruct.new( + double( + 'secure', self_link: 'projects/gcp-project-12345/zones/us-central1-a/operations/ope-123', status: 'RUNNING' ) @@ -711,7 +712,7 @@ RSpec.describe Projects::ClustersController do end it { expect { go }.to be_allowed_for(:owner).of(project) } it { expect { go }.to be_allowed_for(:maintainer).of(project) } - it { expect { go }.to be_denied_for(:developer).of(project) } + it { expect { go }.to be_allowed_for(:developer).of(project) } it { expect { go }.to be_denied_for(:reporter).of(project) } it { expect { go }.to be_denied_for(:guest).of(project) } it { expect { go }.to be_denied_for(:user) } diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb index 16bb33e95c8..72fee40a6e9 100644 --- a/spec/controllers/projects/commit_controller_spec.rb +++ b/spec/controllers/projects/commit_controller_spec.rb @@ -183,6 +183,18 @@ RSpec.describe Projects::CommitController do expect(assigns(:tags)).to eq([]) expect(assigns(:tags_limit_exceeded)).to be_truthy end + + context 'when commit is not found' do + it 'responds with 404' do + get(:branches, params: { + namespace_id: project.namespace, + project_id: project, + id: '11111111111111111111111111111111111111' + }) + + expect(response).to be_not_found + end + end end describe 'POST revert' do diff --git a/spec/controllers/projects/commits_controller_spec.rb b/spec/controllers/projects/commits_controller_spec.rb index fd840fafa61..c7f98406201 100644 --- a/spec/controllers/projects/commits_controller_spec.rb +++ b/spec/controllers/projects/commits_controller_spec.rb @@ -88,6 +88,26 @@ RSpec.describe Projects::CommitsController do expect(response).to be_successful end + + context 'when limit is a hash' do + it 'uses the default limit' do + expect_any_instance_of(Repository).to receive(:commits).with( + "master", + path: "README.md", + limit: described_class::COMMITS_DEFAULT_LIMIT, + offset: 0 + ).and_call_original + + get(:show, params: { + namespace_id: project.namespace, + project_id: project, + id: id, + limit: { 'broken' => 'value' } + }) + + expect(response).to be_successful + end + end end context "when the ref name ends in .atom" do @@ -131,6 +151,20 @@ RSpec.describe Projects::CommitsController do expect(response.media_type).to eq('text/html') end end + + context 'when the ref does not exist' do + before do + get(:show, params: { + namespace_id: project.namespace, + project_id: project, + id: 'unknown.atom' + }) + end + + it 'returns 404 page' do + expect(response).to be_not_found + end + end end end diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb index 48afd42e8ff..62b93a2728b 100644 --- a/spec/controllers/projects/compare_controller_spec.rb +++ b/spec/controllers/projects/compare_controller_spec.rb @@ -25,15 +25,25 @@ RSpec.describe Projects::CompareController do end describe 'GET index' do + let(:params) { { namespace_id: project.namespace, project_id: project } } + render_views before do - get :index, params: { namespace_id: project.namespace, project_id: project } + get :index, params: params end it 'returns successfully' do expect(response).to be_successful end + + context 'with incorrect parameters' do + let(:params) { super().merge(from: { invalid: :param }, to: { also: :invalid }) } + + it 'returns successfully' do + expect(response).to be_successful + end + end end describe 'GET show' do @@ -340,12 +350,13 @@ RSpec.describe Projects::CompareController do context 'when sending invalid params' do where(:from_ref, :to_ref, :from_project_id, :expected_redirect_params) do - '' | '' | '' | {} - 'main' | '' | '' | { from: 'main' } - '' | 'main' | '' | { to: 'main' } - '' | '' | '1' | { from_project_id: 1 } - 'main' | '' | '1' | { from: 'main', from_project_id: 1 } - '' | 'main' | '1' | { to: 'main', from_project_id: 1 } + '' | '' | '' | {} + 'main' | '' | '' | { from: 'main' } + '' | 'main' | '' | { to: 'main' } + '' | '' | '1' | { from_project_id: 1 } + 'main' | '' | '1' | { from: 'main', from_project_id: 1 } + '' | 'main' | '1' | { to: 'main', from_project_id: 1 } + ['a'] | ['b'] | ['c'] | {} end with_them do diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb index e53e53980b5..0f8f3b49e02 100644 --- a/spec/controllers/projects/forks_controller_spec.rb +++ b/spec/controllers/projects/forks_controller_spec.rb @@ -67,6 +67,18 @@ RSpec.describe Projects::ForksController do expect(assigns[:private_forks_count]).to eq(0) end end + + context 'when unsupported keys are provided' do + it 'ignores them' do + get :index, params: { + namespace_id: project.namespace, + project_id: project, + user: 'unsupported' + } + + expect(assigns[:forks]).to be_present + end + end end context 'when fork is internal' do diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb index d514c486f60..ea15d483c90 100644 --- a/spec/controllers/projects/group_links_controller_spec.rb +++ b/spec/controllers/projects/group_links_controller_spec.rb @@ -178,7 +178,7 @@ RSpec.describe Projects::GroupLinksController do context 'when `expires_at` is set' do it 'returns correct json response' do - expect(json_response).to eq({ "expires_in" => "about 1 month", "expires_soon" => false }) + expect(json_response).to eq({ "expires_in" => controller.helpers.time_ago_with_tooltip(expiry_date), "expires_soon" => false }) end end diff --git a/spec/controllers/projects/hooks_controller_spec.rb b/spec/controllers/projects/hooks_controller_spec.rb index 2ab18ccddbf..ebcf35a7ecd 100644 --- a/spec/controllers/projects/hooks_controller_spec.rb +++ b/spec/controllers/projects/hooks_controller_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe Projects::HooksController do let_it_be(:project) { create(:project) } - let(:user) { project.owner } + let(:user) { project.first_owner } before do sign_in(user) diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index d91c1b0d29a..bf0b833b311 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -502,10 +502,7 @@ RSpec.describe Projects::IssuesController do context 'with valid params' do it 'reorders issues and returns a successful 200 response' do - reorder_issue(issue1, - move_after_id: issue2.id, - move_before_id: issue3.id, - group_full_path: group.full_path) + reorder_issue(issue1, move_after_id: issue2.id, move_before_id: issue3.id) [issue1, issue2, issue3].map(&:reload) @@ -531,12 +528,10 @@ RSpec.describe Projects::IssuesController do end it 'returns a unprocessable entity 422 response for issues not in group' do - another_group = create(:group) + other_group_project = create(:project, group: create(:group)) + other_group_issue = create(:issue, project: other_group_project) - reorder_issue(issue1, - move_after_id: issue2.id, - move_before_id: issue3.id, - group_full_path: another_group.full_path) + reorder_issue(issue1, move_after_id: issue2.id, move_before_id: other_group_issue.id) expect(response).to have_gitlab_http_status(:unprocessable_entity) end @@ -555,15 +550,14 @@ RSpec.describe Projects::IssuesController do end end - def reorder_issue(issue, move_after_id: nil, move_before_id: nil, group_full_path: nil) + def reorder_issue(issue, move_after_id: nil, move_before_id: nil) put :reorder, params: { namespace_id: project.namespace.to_param, project_id: project, id: issue.iid, move_after_id: move_after_id, - move_before_id: move_before_id, - group_full_path: group_full_path + move_before_id: move_before_id }, format: :json end diff --git a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb index e07b7e4586a..366a1e587ab 100644 --- a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Projects::MergeRequests::ConflictsController do let(:project) { create(:project, :repository) } - let(:user) { project.owner } + let(:user) { project.first_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| diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb index df2023b7356..3c650988b4f 100644 --- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Projects::MergeRequests::CreationsController do let(:project) { create(:project, :repository) } - let(:user) { project.owner } + let(:user) { project.first_owner } let(:fork_project) { create(:forked_project_with_submodules) } let(:get_diff_params) do { diff --git a/spec/controllers/projects/merge_requests/drafts_controller_spec.rb b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb index 580211893dc..222bb977beb 100644 --- a/spec/controllers/projects/merge_requests/drafts_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb @@ -6,7 +6,7 @@ RSpec.describe Projects::MergeRequests::DraftsController do let(:project) { create(:project, :repository) } let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) } - let(:user) { project.owner } + let(:user) { project.first_owner } let(:user2) { create(:user) } let(:params) do diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 36b6df59ef5..2390687c3ea 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Projects::MergeRequestsController do 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(:user) { project.first_owner } let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: merge_request_source_project, allow_collaboration: false) } let(:merge_request_source_project) { project } @@ -57,19 +57,13 @@ RSpec.describe Projects::MergeRequestsController do merge_request.mark_as_unchecked! end - context 'check_mergeability_async_in_widget feature flag is disabled' do - before do - stub_feature_flags(check_mergeability_async_in_widget: false) + it 'checks mergeability asynchronously' do + expect_next_instance_of(MergeRequests::MergeabilityCheckService) do |service| + expect(service).not_to receive(:execute) + expect(service).to receive(:async_execute) end - it 'checks mergeability asynchronously' do - expect_next_instance_of(MergeRequests::MergeabilityCheckService) do |service| - expect(service).not_to receive(:execute) - expect(service).to receive(:async_execute) - end - - go - end + go end end @@ -449,7 +443,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: "Draft: #{merge_request.title}") post :merge, params: base_params end @@ -2084,6 +2078,20 @@ RSpec.describe Projects::MergeRequestsController do end end + context 'when source branch is protected from force push' do + before do + create(:protected_branch, project: project, name: merge_request.source_branch, allow_force_push: false) + end + + it 'returns 404' do + expect_rebase_worker_for(user).never + + post_rebase + + expect(response).to have_gitlab_http_status(:not_found) + end + end + context 'with a forked project' do let(:forked_project) { fork_project(project, fork_owner, repository: true) } let(:fork_owner) { create(:user) } diff --git a/spec/controllers/projects/mirrors_controller_spec.rb b/spec/controllers/projects/mirrors_controller_spec.rb index 7c5d14d3a22..7bc86d7c583 100644 --- a/spec/controllers/projects/mirrors_controller_spec.rb +++ b/spec/controllers/projects/mirrors_controller_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Projects::MirrorsController do shared_examples 'only admin is allowed when mirroring is disabled' do let(:subject_action) { raise 'subject_action is required' } - let(:user) { project.owner } + let(:user) { project.first_owner } let(:project_settings_path) { project_settings_repository_path(project, anchor: 'js-push-remote-settings') } context 'when project mirroring is enabled' do @@ -88,7 +88,7 @@ RSpec.describe Projects::MirrorsController do context 'when the current project is not a mirror' do it 'allows to create a remote mirror' do - sign_in(project.owner) + sign_in(project.first_owner) expect do do_put(project, remote_mirrors_attributes: { '0' => { 'enabled' => 1, 'url' => 'http://foo.com' } }) @@ -106,7 +106,7 @@ RSpec.describe Projects::MirrorsController do end it 'processes a successful update' do - sign_in(project.owner) + sign_in(project.first_owner) do_put(project, remote_mirrors_attributes: { '0' => ssh_mirror_attributes }) expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-push-remote-settings')) @@ -126,7 +126,7 @@ RSpec.describe Projects::MirrorsController do let(:project) { create(:project, :repository, :remote_mirror) } before do - sign_in(project.owner) + sign_in(project.first_owner) end context 'With valid URL for a push' do @@ -169,7 +169,7 @@ RSpec.describe Projects::MirrorsController do let(:cache) { SshHostKey.new(project: project, url: "ssh://example.com:22") } before do - sign_in(project.owner) + sign_in(project.first_owner) end context 'invalid URLs' do diff --git a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb index 707edeaeee3..a655c742973 100644 --- a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb +++ b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb @@ -52,18 +52,6 @@ RSpec.describe Projects::Packages::InfrastructureRegistryController do expect(assigns(:package_files)).to contain_exactly(terraform_module_package_file) end - - context 'with packages_installable_package_files disabled' do - before do - stub_feature_flags(packages_installable_package_files: false) - end - - it 'returns them' do - subject - - expect(assigns(:package_files)).to contain_exactly(package_file_pending_destruction, terraform_module_package_file) - end - end end end end diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 3fe709a0d44..4a51e2ed5a0 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -1169,7 +1169,7 @@ RSpec.describe Projects::PipelinesController do context 'when user has ability to delete pipeline' do before do - sign_in(project.owner) + sign_in(project.first_owner) end it 'deletes pipeline and redirects' do diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb index b625ce35d61..56415663109 100644 --- a/spec/controllers/projects/refs_controller_spec.rb +++ b/spec/controllers/projects/refs_controller_spec.rb @@ -47,6 +47,23 @@ RSpec.describe Projects::RefsController do expect(response).to be_not_found end + context 'when ref is incorrect' do + it 'returns 404 page' do + xhr_get(:json, id: '.') + + expect(response).to be_not_found + end + end + + context 'when offset has an invalid format' do + it 'renders JSON' do + xhr_get(:json, offset: { wrong: :format }) + + expect(response).to be_successful + expect(json_response).to be_kind_of(Array) + end + end + context 'when json is requested' do it 'renders JSON' do expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb index 1370ec9cc0b..928428b5caf 100644 --- a/spec/controllers/projects/repositories_controller_spec.rb +++ b/spec/controllers/projects/repositories_controller_spec.rb @@ -3,7 +3,37 @@ require "spec_helper" RSpec.describe Projects::RepositoriesController do - let(:project) { create(:project, :repository) } + let_it_be(:project) { create(:project, :repository) } + + describe 'POST create' do + let_it_be(:user) { create(:user) } + + let(:request) { post :create, params: { namespace_id: project.namespace, project_id: project } } + + before do + project.add_maintainer(user) + sign_in(user) + end + + context 'when repository does not exist' do + let!(:project) { create(:project) } + + it 'creates the repository' do + expect { request }.to change { project.repository.raw_repository.exists? }.from(false).to(true) + + expect(response).to be_redirect + end + end + + context 'when repository already exists' do + it 'does not raise an exception' do + expect(Gitlab::ErrorTracking).not_to receive(:track_exception) + request + + expect(response).to be_redirect + end + end + end describe "GET archive" do before do diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb index 70ff77d7ff0..246a37129d7 100644 --- a/spec/controllers/projects/runners_controller_spec.rb +++ b/spec/controllers/projects/runners_controller_spec.rb @@ -37,6 +37,10 @@ RSpec.describe Projects::RunnersController do describe '#destroy' do it 'destroys the runner' do + expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service| + expect(service).to receive(:execute).once.and_call_original + end + delete :destroy, params: params expect(response).to have_gitlab_http_status(:found) diff --git a/spec/controllers/projects/service_ping_controller_spec.rb b/spec/controllers/projects/service_ping_controller_spec.rb index e6afaadc75f..13b34290962 100644 --- a/spec/controllers/projects/service_ping_controller_spec.rb +++ b/spec/controllers/projects/service_ping_controller_spec.rb @@ -32,7 +32,7 @@ RSpec.describe Projects::ServicePingController do shared_examples 'counter is increased' do |counter| context 'when the authenticated user has access to the project' do - let(:user) { project.owner } + let(:user) { project.first_owner } it 'increments the usage counter' do expect do @@ -55,6 +55,33 @@ RSpec.describe Projects::ServicePingController do end context 'when web ide clientside preview is not enabled' do + let(:user) { project.first_owner } + + before do + stub_application_setting(web_ide_clientside_preview_enabled: false) + end + + it 'returns 404' do + subject + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + describe 'POST #web_ide_clientside_preview_success' do + subject { post :web_ide_clientside_preview_success, params: { namespace_id: project.namespace, project_id: project } } + + context 'when web ide clientside preview is enabled' do + before do + stub_application_setting(web_ide_clientside_preview_enabled: true) + end + + it_behaves_like 'counter is not increased' + it_behaves_like 'counter is increased', 'WEB_IDE_PREVIEWS_SUCCESS_COUNT' + end + + context 'when web ide clientside preview is not enabled' do let(:user) { project.owner } before do diff --git a/spec/controllers/projects/settings/repository_controller_spec.rb b/spec/controllers/projects/settings/repository_controller_spec.rb index 2bb93990c58..22287fea82c 100644 --- a/spec/controllers/projects/settings/repository_controller_spec.rb +++ b/spec/controllers/projects/settings/repository_controller_spec.rb @@ -33,6 +33,20 @@ RSpec.describe Projects::Settings::RepositoryController do expect(response).to redirect_to project_settings_repository_path(project) end + + context 'when project cleanup returns an error', :aggregate_failures do + it 'shows an error' do + expect(Projects::CleanupService) + .to receive(:enqueue) + .with(project, user, anything) + .and_return(status: :error, message: 'error message') + + put :cleanup, params: { namespace_id: project.namespace, project_id: project, project: { bfg_object_map: object_map } } + + expect(controller).to set_flash[:alert].to('error message') + expect(response).to redirect_to project_settings_repository_path(project) + end + end end describe 'POST create_deploy_token' do diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb index 9823c36cb86..f955f9d0248 100644 --- a/spec/controllers/projects/tags_controller_spec.rb +++ b/spec/controllers/projects/tags_controller_spec.rb @@ -17,6 +17,14 @@ RSpec.describe Projects::TagsController do expect(assigns(:tags).map(&:name)).to include('v1.1.0', 'v1.0.0') end + context 'default sort for tags' do + it 'sorts tags by recently updated' do + subject + + expect(assigns(:sort)).to eq('updated_desc') + end + end + context 'when Gitaly is unavailable' do where(:format) do [:html, :atom] @@ -31,6 +39,7 @@ RSpec.describe Projects::TagsController do get :index, params: { namespace_id: project.namespace.to_param, project_id: project }, format: format expect(assigns(:tags)).to eq([]) + expect(assigns(:releases)).to eq([]) expect(response).to have_gitlab_http_status(:service_unavailable) end end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 7ebd86640ad..08d1d88fcda 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -1202,6 +1202,26 @@ RSpec.describe ProjectsController do end end end + + context 'when input params are invalid' do + let(:request) { get :refs, params: { namespace_id: project.namespace, id: project, ref: { invalid: :format } } } + + it 'does not break' do + request + + expect(response).to have_gitlab_http_status(:success) + end + + context 'when "strong_parameters_for_project_controller" FF is disabled' do + before do + stub_feature_flags(strong_parameters_for_project_controller: false) + end + + it 'raises an exception' do + expect { request }.to raise_error(TypeError) + end + end + end end describe 'POST #preview_markdown' do diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index d5fe32ac094..af34ae2f69b 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -456,6 +456,28 @@ RSpec.describe RegistrationsController do subject end + + describe 'logged_out_marketing_header experiment', :experiment do + before do + stub_experiments(logged_out_marketing_header: :candidate) + end + + it 'tracks signed_up event' do + expect(experiment(:logged_out_marketing_header)).to track(:signed_up).on_next_instance + + subject + end + + context 'when registration fails' do + let_it_be(:user_params) { { user: base_user_params.merge({ username: '' }) } } + + it 'does not track signed_up event' do + expect(experiment(:logged_out_marketing_header)).not_to track(:signed_up) + + subject + end + end + end end describe '#destroy' do diff --git a/spec/controllers/repositories/git_http_controller_spec.rb b/spec/controllers/repositories/git_http_controller_spec.rb index 4a6e745cd63..fb2637238ec 100644 --- a/spec/controllers/repositories/git_http_controller_spec.rb +++ b/spec/controllers/repositories/git_http_controller_spec.rb @@ -29,7 +29,7 @@ RSpec.describe Repositories::GitHttpController do context 'when repository container is a project' do it_behaves_like Repositories::GitHttpController do let(:container) { project } - let(:user) { project.owner } + let(:user) { project.first_owner } let(:access_checker_class) { Gitlab::GitAccess } it_behaves_like 'handles unavailable Gitaly' @@ -103,7 +103,7 @@ RSpec.describe Repositories::GitHttpController do context 'when repository container is a project wiki' do it_behaves_like Repositories::GitHttpController do let(:container) { create(:project_wiki, :empty_repo, project: project) } - let(:user) { project.owner } + let(:user) { project.first_owner } let(:access_checker_class) { Gitlab::GitAccessWiki } end end diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index 58d34a5e5c1..0f1501d4c3c 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -397,9 +397,10 @@ RSpec.describe SearchController do expect(payload[:metadata]['meta.search.filters.confidential']).to eq('true') expect(payload[:metadata]['meta.search.filters.state']).to eq('true') expect(payload[:metadata]['meta.search.project_ids']).to eq(%w(456 789)) + expect(payload[:metadata]['meta.search.search_level']).to eq('multi-project') end - get :show, params: { scope: 'issues', search: 'hello world', group_id: '123', project_id: '456', project_ids: %w(456 789), confidential: true, state: true, force_search_results: true } + get :show, params: { scope: 'issues', search: 'hello world', group_id: '123', project_id: '456', project_ids: %w(456 789), search_level: 'multi-project', confidential: true, state: true, force_search_results: true } end it 'appends the default scope in meta.search.scope' do |