diff options
Diffstat (limited to 'spec/requests/projects')
13 files changed, 442 insertions, 304 deletions
diff --git a/spec/requests/projects/environments_controller_spec.rb b/spec/requests/projects/environments_controller_spec.rb index 5cdf507abef..0890b0c45da 100644 --- a/spec/requests/projects/environments_controller_spec.rb +++ b/spec/requests/projects/environments_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Projects::EnvironmentsController do - let_it_be(:project) { create(:project, :repository) } + let_it_be_with_refind(:project) { create(:project, :repository) } let(:environment) { create(:environment, name: 'production', project: project) } diff --git a/spec/requests/projects/google_cloud/configuration_controller_spec.rb b/spec/requests/projects/google_cloud/configuration_controller_spec.rb new file mode 100644 index 00000000000..08d4ad2f9ba --- /dev/null +++ b/spec/requests/projects/google_cloud/configuration_controller_spec.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Mock Types +MockGoogleOAuth2Credentials = Struct.new(:app_id, :app_secret) + +RSpec.describe Projects::GoogleCloud::ConfigurationController do + let_it_be(:project) { create(:project, :public) } + let_it_be(:url) { project_google_cloud_configuration_path(project) } + + let_it_be(:user_guest) { create(:user) } + let_it_be(:user_developer) { create(:user) } + let_it_be(:user_maintainer) { create(:user) } + + let_it_be(:unauthorized_members) { [user_guest, user_developer] } + let_it_be(:authorized_members) { [user_maintainer] } + + before do + project.add_guest(user_guest) + project.add_developer(user_developer) + project.add_maintainer(user_maintainer) + end + + context 'when accessed by unauthorized members' do + it 'returns not found on GET request' do + unauthorized_members.each do |unauthorized_member| + sign_in(unauthorized_member) + + get url + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'admin_project_google_cloud!', + label: 'error_access_denied', + property: 'invalid_user', + project: project, + user: unauthorized_member + ) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'when accessed by authorized members' do + it 'returns successful' do + authorized_members.each do |authorized_member| + sign_in(authorized_member) + + get url + + expect(response).to be_successful + expect(response).to render_template('projects/google_cloud/configuration/index') + end + end + + context 'but gitlab instance is not configured for google oauth2' do + it 'returns forbidden' do + unconfigured_google_oauth2 = MockGoogleOAuth2Credentials.new('', '') + allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for) + .with('google_oauth2') + .and_return(unconfigured_google_oauth2) + + authorized_members.each do |authorized_member| + sign_in(authorized_member) + + get url + + expect(response).to have_gitlab_http_status(:forbidden) + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'google_oauth2_enabled!', + label: 'error_access_denied', + extra: { reason: 'google_oauth2_not_configured', + config: unconfigured_google_oauth2 }, + project: project, + user: authorized_member + ) + end + end + end + + context 'but feature flag is disabled' do + before do + stub_feature_flags(incubation_5mp_google_cloud: false) + end + + it 'returns not found' do + authorized_members.each do |authorized_member| + sign_in(authorized_member) + + get url + + expect(response).to have_gitlab_http_status(:not_found) + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'feature_flag_enabled!', + label: 'error_access_denied', + property: 'feature_flag_not_enabled', + project: project, + user: authorized_member + ) + end + end + end + + context 'but google oauth2 token is not valid' do + it 'does not return revoke oauth url' do + allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client| + allow(client).to receive(:validate_token).and_return(false) + end + + authorized_members.each do |authorized_member| + sign_in(authorized_member) + + get url + + expect(response).to be_successful + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'configuration#index', + label: 'success', + extra: { + configurationUrl: project_google_cloud_configuration_path(project), + deploymentsUrl: project_google_cloud_deployments_path(project), + databasesUrl: project_google_cloud_databases_path(project), + serviceAccounts: [], + createServiceAccountUrl: project_google_cloud_service_accounts_path(project), + emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg'), + configureGcpRegionsUrl: project_google_cloud_gcp_regions_path(project), + gcpRegions: [], + revokeOauthUrl: nil + }, + project: project, + user: authorized_member + ) + end + end + end + end +end diff --git a/spec/requests/projects/google_cloud/databases_controller_spec.rb b/spec/requests/projects/google_cloud/databases_controller_spec.rb new file mode 100644 index 00000000000..c9335f8f317 --- /dev/null +++ b/spec/requests/projects/google_cloud/databases_controller_spec.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Mock Types +MockGoogleOAuth2Credentials = Struct.new(:app_id, :app_secret) + +RSpec.describe Projects::GoogleCloud::DatabasesController do + let_it_be(:project) { create(:project, :public) } + let_it_be(:url) { project_google_cloud_databases_path(project) } + + let_it_be(:user_guest) { create(:user) } + let_it_be(:user_developer) { create(:user) } + let_it_be(:user_maintainer) { create(:user) } + + let_it_be(:unauthorized_members) { [user_guest, user_developer] } + let_it_be(:authorized_members) { [user_maintainer] } + + before do + project.add_guest(user_guest) + project.add_developer(user_developer) + project.add_maintainer(user_maintainer) + end + + context 'when accessed by unauthorized members' do + it 'returns not found on GET request' do + unauthorized_members.each do |unauthorized_member| + sign_in(unauthorized_member) + + get url + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'admin_project_google_cloud!', + label: 'error_access_denied', + property: 'invalid_user', + project: project, + user: unauthorized_member + ) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'when accessed by authorized members' do + it 'returns successful' do + authorized_members.each do |authorized_member| + sign_in(authorized_member) + + get url + + expect(response).to be_successful + expect(response).to render_template('projects/google_cloud/databases/index') + end + end + + context 'but gitlab instance is not configured for google oauth2' do + it 'returns forbidden' do + unconfigured_google_oauth2 = MockGoogleOAuth2Credentials.new('', '') + allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for) + .with('google_oauth2') + .and_return(unconfigured_google_oauth2) + + authorized_members.each do |authorized_member| + sign_in(authorized_member) + + get url + + expect(response).to have_gitlab_http_status(:forbidden) + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'google_oauth2_enabled!', + label: 'error_access_denied', + extra: { reason: 'google_oauth2_not_configured', + config: unconfigured_google_oauth2 }, + project: project, + user: authorized_member + ) + end + end + end + + context 'but feature flag is disabled' do + before do + stub_feature_flags(incubation_5mp_google_cloud: false) + end + + it 'returns not found' do + authorized_members.each do |authorized_member| + sign_in(authorized_member) + + get url + + expect(response).to have_gitlab_http_status(:not_found) + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'feature_flag_enabled!', + label: 'error_access_denied', + property: 'feature_flag_not_enabled', + project: project, + user: authorized_member + ) + end + end + end + + context 'but google oauth2 token is not valid' do + it 'does not return revoke oauth url' do + allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client| + allow(client).to receive(:validate_token).and_return(false) + end + + authorized_members.each do |authorized_member| + sign_in(authorized_member) + + get url + + expect(response).to be_successful + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'databases#index', + label: 'success', + extra: { + configurationUrl: project_google_cloud_configuration_path(project), + deploymentsUrl: project_google_cloud_deployments_path(project), + databasesUrl: project_google_cloud_databases_path(project) + }, + project: project, + user: authorized_member + ) + end + end + end + end +end diff --git a/spec/requests/projects/google_cloud/deployments_controller_spec.rb b/spec/requests/projects/google_cloud/deployments_controller_spec.rb index 7bd9609a7dc..9e854e01516 100644 --- a/spec/requests/projects/google_cloud/deployments_controller_spec.rb +++ b/spec/requests/projects/google_cloud/deployments_controller_spec.rb @@ -9,10 +9,9 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do let_it_be(:user_guest) { create(:user) } let_it_be(:user_developer) { create(:user) } let_it_be(:user_maintainer) { create(:user) } - let_it_be(:user_creator) { project.creator } let_it_be(:unauthorized_members) { [user_guest, user_developer] } - let_it_be(:authorized_members) { [user_maintainer, user_creator] } + let_it_be(:authorized_members) { [user_maintainer] } let_it_be(:urls_list) { %W[#{project_google_cloud_deployments_cloud_run_path(project)} #{project_google_cloud_deployments_cloud_storage_path(project)}] } @@ -32,7 +31,7 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'admin_project_google_cloud!', - label: 'access_denied', + label: 'error_access_denied', property: 'invalid_user', project: project, user: nil @@ -51,7 +50,7 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'admin_project_google_cloud!', - label: 'access_denied', + label: 'error_access_denied', property: 'invalid_user', project: project, user: nil @@ -87,15 +86,15 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do end end - it 'redirects to google_cloud home on enable service error' do + it 'redirects to google cloud deployments on enable service error' do get url - expect(response).to redirect_to(project_google_cloud_index_path(project)) + expect(response).to redirect_to(project_google_cloud_deployments_path(project)) # since GPC_PROJECT_ID is not set, enable cloud run service should return an error expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'deployments#cloud_run', - label: 'enable_cloud_run_error', + label: 'error_enable_cloud_run', extra: { message: 'No GCP projects found. Configure a service account or GCP_PROJECT_ID ci variable.', status: :error }, project: project, @@ -103,7 +102,7 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do ) end - it 'redirects to gcp_error' do + it 'redirects to google cloud deployments with error' do mock_gcp_error = Google::Apis::ClientError.new('some_error') allow_next_instance_of(GoogleCloud::EnableCloudRunService) do |service| @@ -112,11 +111,11 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do get url - expect(response).to render_template(:gcp_error) + expect(response).to redirect_to(project_google_cloud_deployments_path(project)) expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'deployments#cloud_run', - label: 'gcp_error', + label: 'error_gcp', extra: mock_gcp_error, project: project, user: user_maintainer @@ -124,7 +123,7 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do end context 'GCP_PROJECT_IDs are defined' do - it 'redirects to google_cloud home on generate pipeline error' do + it 'redirects to google_cloud deployments on generate pipeline error' do allow_next_instance_of(GoogleCloud::EnableCloudRunService) do |enable_cloud_run_service| allow(enable_cloud_run_service).to receive(:execute).and_return({ status: :success }) end @@ -135,11 +134,11 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do get url - expect(response).to redirect_to(project_google_cloud_index_path(project)) + expect(response).to redirect_to(project_google_cloud_deployments_path(project)) expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'deployments#cloud_run', - label: 'generate_pipeline_error', + label: 'error_generate_pipeline', extra: { status: :error }, project: project, user: user_maintainer @@ -162,7 +161,7 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'deployments#cloud_run', - label: 'cloud_run_success', + label: 'success', extra: { "title": "Enable deployments to Cloud Run", "description": "This merge request includes a Cloud Run deployment job in the pipeline definition (.gitlab-ci.yml).\n\nThe `deploy-to-cloud-run` job:\n* Requires the following environment variables\n * `GCP_PROJECT_ID`\n * `GCP_SERVICE_ACCOUNT_KEY`\n* Job definition can be found at: https://gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library\n\nThis pipeline definition has been committed to the branch ``.\nYou may modify the pipeline definition further or accept the changes as-is if suitable.\n", "source_project_id": project.id, diff --git a/spec/requests/projects/google_cloud/gcp_regions_controller_spec.rb b/spec/requests/projects/google_cloud/gcp_regions_controller_spec.rb index 56474b6520d..f88273080d5 100644 --- a/spec/requests/projects/google_cloud/gcp_regions_controller_spec.rb +++ b/spec/requests/projects/google_cloud/gcp_regions_controller_spec.rb @@ -6,8 +6,8 @@ RSpec.describe Projects::GoogleCloud::GcpRegionsController do let_it_be(:project) { create(:project, :public, :repository) } let_it_be(:repository) { project.repository } - let(:user_guest) { create(:user) } - let(:user_maintainer) { create(:user) } + let_it_be(:user_guest) { create(:user) } + let_it_be(:user_maintainer) { create(:user) } RSpec.shared_examples "should track not_found event" do it "tracks event" do @@ -15,7 +15,7 @@ RSpec.describe Projects::GoogleCloud::GcpRegionsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'admin_project_google_cloud!', - label: 'access_denied', + label: 'error_access_denied', property: 'invalid_user', project: project, user: nil @@ -29,7 +29,7 @@ RSpec.describe Projects::GoogleCloud::GcpRegionsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'admin_project_google_cloud!', - label: 'access_denied', + label: 'error_access_denied', property: 'invalid_user', project: project, user: nil @@ -43,7 +43,7 @@ RSpec.describe Projects::GoogleCloud::GcpRegionsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'feature_flag_enabled!', - label: 'access_denied', + label: 'error_access_denied', property: 'feature_flag_not_enabled', project: project, user: user_maintainer @@ -57,7 +57,7 @@ RSpec.describe Projects::GoogleCloud::GcpRegionsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'google_oauth2_enabled!', - label: 'access_denied', + label: 'error_access_denied', extra: { reason: 'google_oauth2_not_configured', config: config }, project: project, user: user_maintainer @@ -144,8 +144,8 @@ RSpec.describe Projects::GoogleCloud::GcpRegionsController do sign_in(user_maintainer) end - it 'redirects to google cloud index' do - is_expected.to redirect_to(project_google_cloud_index_path(project)) + it 'redirects to google cloud configurations' do + is_expected.to redirect_to(project_google_cloud_configuration_path(project)) end end end diff --git a/spec/requests/projects/google_cloud/revoke_oauth_controller_spec.rb b/spec/requests/projects/google_cloud/revoke_oauth_controller_spec.rb index 07590d3710e..36441a184cb 100644 --- a/spec/requests/projects/google_cloud/revoke_oauth_controller_spec.rb +++ b/spec/requests/projects/google_cloud/revoke_oauth_controller_spec.rb @@ -47,13 +47,13 @@ RSpec.describe Projects::GoogleCloud::RevokeOauthController do post url expect(request.session[GoogleApi::CloudPlatform::Client.session_key_for_token]).to be_nil - expect(response).to redirect_to(project_google_cloud_index_path(project)) + expect(response).to redirect_to(project_google_cloud_configuration_path(project)) expect(flash[:notice]).to eq('Google OAuth2 token revocation requested') expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'revoke_oauth#create', - label: 'create', - property: 'success', + label: 'success', + property: '{}', project: project, user: user ) @@ -70,13 +70,13 @@ RSpec.describe Projects::GoogleCloud::RevokeOauthController do post url expect(request.session[GoogleApi::CloudPlatform::Client.session_key_for_token]).to be_nil - expect(response).to redirect_to(project_google_cloud_index_path(project)) + expect(response).to redirect_to(project_google_cloud_configuration_path(project)) expect(flash[:alert]).to eq('Google OAuth2 token revocation request failed') expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'revoke_oauth#create', - label: 'create', - property: 'failed', + label: 'error', + property: '{}', project: project, user: user ) diff --git a/spec/requests/projects/google_cloud/service_accounts_controller_spec.rb b/spec/requests/projects/google_cloud/service_accounts_controller_spec.rb index 4b32965e2b0..ae2519855db 100644 --- a/spec/requests/projects/google_cloud/service_accounts_controller_spec.rb +++ b/spec/requests/projects/google_cloud/service_accounts_controller_spec.rb @@ -8,13 +8,15 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do describe 'GET index', :snowplow do let_it_be(:url) { "#{project_google_cloud_service_accounts_path(project)}" } - let(:user_guest) { create(:user) } - let(:user_developer) { create(:user) } - let(:user_maintainer) { create(:user) } - let(:user_creator) { project.creator } + let_it_be(:user_guest) { create(:user) } + let_it_be(:user_developer) { create(:user) } + let_it_be(:user_maintainer) { create(:user) } + let_it_be(:user_creator) { project.creator } - let(:unauthorized_members) { [user_guest, user_developer] } - let(:authorized_members) { [user_maintainer, user_creator] } + let_it_be(:unauthorized_members) { [user_guest, user_developer] } + let_it_be(:authorized_members) { [user_maintainer, user_creator] } + + let_it_be(:google_client_error) { Google::Apis::ClientError.new('client-error') } before do project.add_guest(user_guest) @@ -30,7 +32,7 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'admin_project_google_cloud!', - label: 'access_denied', + label: 'error_access_denied', property: 'invalid_user', project: project, user: nil @@ -53,7 +55,7 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'admin_project_google_cloud!', - label: 'access_denied', + label: 'error_access_denied', property: 'invalid_user', project: project, user: unauthorized_member @@ -71,7 +73,7 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do expect_snowplow_event( category: 'Projects::GoogleCloud', action: 'admin_project_google_cloud!', - label: 'access_denied', + label: 'error_access_denied', property: 'invalid_user', project: project, user: unauthorized_member @@ -116,7 +118,7 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do end end - it 'renders no_gcp_projects' do + it 'flashes error and redirects to google cloud configurations' do authorized_members.each do |authorized_member| allow_next_instance_of(BranchesFinder) do |branches_finder| allow(branches_finder).to receive(:execute).and_return([]) @@ -130,7 +132,16 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do get url - expect(response).to render_template('projects/google_cloud/errors/no_gcp_projects') + expect(response).to redirect_to(project_google_cloud_configuration_path(project)) + expect(flash[:warning]).to eq('No Google Cloud projects - You need at least one Google Cloud project') + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'service_accounts#index', + label: 'error_form', + property: 'no_gcp_projects', + project: project, + user: authorized_member + ) end end end @@ -171,7 +182,7 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do post url, params: { gcp_project: 'prj1', ref: 'env1' } - expect(response).to redirect_to(project_google_cloud_index_path(project)) + expect(response).to redirect_to(project_google_cloud_configuration_path(project)) end end end @@ -181,29 +192,47 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do before do allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client| allow(client).to receive(:validate_token).and_return(true) - allow(client).to receive(:list_projects).and_raise(Google::Apis::ClientError.new('')) - allow(client).to receive(:create_service_account).and_raise(Google::Apis::ClientError.new('')) - allow(client).to receive(:create_service_account_key).and_raise(Google::Apis::ClientError.new('')) + allow(client).to receive(:list_projects).and_raise(google_client_error) + allow(client).to receive(:create_service_account).and_raise(google_client_error) + allow(client).to receive(:create_service_account_key).and_raise(google_client_error) end end - it 'renders gcp_error template on GET' do + it 'GET flashes error and redirects to -/google_cloud/configurations' do authorized_members.each do |authorized_member| sign_in(authorized_member) get url - expect(response).to render_template(:gcp_error) + expect(response).to redirect_to(project_google_cloud_configuration_path(project)) + expect(flash[:warning]).to eq('Google Cloud Error - client-error') + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'service_accounts#index', + label: 'error_gcp', + extra: google_client_error, + project: project, + user: authorized_member + ) end end - it 'renders gcp_error template on POST' do + it 'POST flashes error and redirects to -/google_cloud/configurations' do authorized_members.each do |authorized_member| sign_in(authorized_member) post url, params: { gcp_project: 'prj1', environment: 'env1' } - expect(response).to render_template(:gcp_error) + expect(response).to redirect_to(project_google_cloud_configuration_path(project)) + expect(flash[:warning]).to eq('Google Cloud Error - client-error') + expect_snowplow_event( + category: 'Projects::GoogleCloud', + action: 'service_accounts#create', + label: 'error_gcp', + extra: google_client_error, + project: project, + user: authorized_member + ) end end end diff --git a/spec/requests/projects/google_cloud_controller_spec.rb b/spec/requests/projects/google_cloud_controller_spec.rb deleted file mode 100644 index d0814990989..00000000000 --- a/spec/requests/projects/google_cloud_controller_spec.rb +++ /dev/null @@ -1,178 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -# Mock Types -MockGoogleOAuth2Credentials = Struct.new(:app_id, :app_secret) - -RSpec.describe Projects::GoogleCloudController do - let_it_be(:project) { create(:project, :public) } - - describe 'GET index', :snowplow do - let_it_be(:url) { "#{project_google_cloud_index_path(project)}" } - - context 'when a public request is made' do - it 'returns not found' do - get url - - expect(response).to have_gitlab_http_status(:not_found) - expect_snowplow_event( - category: 'Projects::GoogleCloud', - action: 'admin_project_google_cloud!', - label: 'access_denied', - property: 'invalid_user', - project: project, - user: nil) - end - end - - context 'when a project.guest makes request' do - let(:user) { create(:user) } - - it 'returns not found' do - project.add_guest(user) - sign_in(user) - - get url - - expect(response).to have_gitlab_http_status(:not_found) - expect_snowplow_event( - category: 'Projects::GoogleCloud', - action: 'admin_project_google_cloud!', - label: 'access_denied', - property: 'invalid_user', - project: project, - user: user - ) - end - end - - context 'when project.developer makes request' do - let(:user) { create(:user) } - - it 'returns not found' do - project.add_developer(user) - sign_in(user) - - get url - - expect(response).to have_gitlab_http_status(:not_found) - expect_snowplow_event( - category: 'Projects::GoogleCloud', - action: 'admin_project_google_cloud!', - label: 'access_denied', - property: 'invalid_user', - project: project, - user: user - ) - end - end - - context 'when project.maintainer makes request' do - let(:user) { create(:user) } - - it 'returns successful' do - project.add_maintainer(user) - sign_in(user) - - get url - - expect(response).to be_successful - end - end - - context 'when project.creator makes request' do - let(:user) { project.creator } - - it 'returns successful' do - sign_in(user) - - get url - - expect(response).to be_successful - end - end - - describe 'when authorized user makes request' do - let(:user) { project.creator } - - context 'but gitlab instance is not configured for google oauth2' do - it 'returns forbidden' do - unconfigured_google_oauth2 = MockGoogleOAuth2Credentials.new('', '') - allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for) - .with('google_oauth2') - .and_return(unconfigured_google_oauth2) - - sign_in(user) - - get url - - expect(response).to have_gitlab_http_status(:forbidden) - expect_snowplow_event( - category: 'Projects::GoogleCloud', - action: 'google_oauth2_enabled!', - label: 'access_denied', - extra: { reason: 'google_oauth2_not_configured', - config: unconfigured_google_oauth2 }, - project: project, - user: user - ) - end - end - - context 'but feature flag is disabled' do - before do - stub_feature_flags(incubation_5mp_google_cloud: false) - end - - it 'returns not found' do - sign_in(user) - - get url - - expect(response).to have_gitlab_http_status(:not_found) - expect_snowplow_event( - category: 'Projects::GoogleCloud', - action: 'feature_flag_enabled!', - label: 'access_denied', - property: 'feature_flag_not_enabled', - project: project, - user: user - ) - end - end - - context 'but google oauth2 token is not valid' do - it 'does not return revoke oauth url' do - allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client| - allow(client).to receive(:validate_token).and_return(false) - end - - sign_in(user) - - get url - - expect(response).to be_successful - expect_snowplow_event( - category: 'Projects::GoogleCloud', - action: 'google_cloud#index', - label: 'index', - extra: { - screen: 'home', - serviceAccounts: [], - createServiceAccountUrl: project_google_cloud_service_accounts_path(project), - enableCloudRunUrl: project_google_cloud_deployments_cloud_run_path(project), - enableCloudStorageUrl: project_google_cloud_deployments_cloud_storage_path(project), - emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg'), - configureGcpRegionsUrl: project_google_cloud_gcp_regions_path(project), - gcpRegions: [], - revokeOauthUrl: nil - }, - project: project, - user: user - ) - end - end - end - end -end diff --git a/spec/requests/projects/harbor/artifacts_controller_spec.rb b/spec/requests/projects/harbor/artifacts_controller_spec.rb new file mode 100644 index 00000000000..310fbcf0a0f --- /dev/null +++ b/spec/requests/projects/harbor/artifacts_controller_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::Harbor::ArtifactsController do + it_behaves_like 'a harbor artifacts controller', anonymous_status_code: '302' do + let_it_be(:container) { create(:project) } + let_it_be(:harbor_integration) { create(:harbor_integration, project: container) } + end +end diff --git a/spec/requests/projects/harbor/repositories_controller_spec.rb b/spec/requests/projects/harbor/repositories_controller_spec.rb index cdb5a696d7e..751becaa20a 100644 --- a/spec/requests/projects/harbor/repositories_controller_spec.rb +++ b/spec/requests/projects/harbor/repositories_controller_spec.rb @@ -3,67 +3,8 @@ require 'spec_helper' RSpec.describe Projects::Harbor::RepositoriesController do - let_it_be(:project, reload: true) { create(:project) } - let_it_be(:user) { create(:user) } - - shared_examples 'responds with 404 status' do - it 'returns 404' do - subject - - expect(response).to have_gitlab_http_status(:not_found) - end - end - - shared_examples 'responds with 200 status' do - it 'renders the index template' do - subject - - expect(response).to have_gitlab_http_status(:ok) - expect(response).to render_template(:index) - end - end - - before do - stub_feature_flags(harbor_registry_integration: true) - project.add_developer(user) - sign_in(user) - end - - describe 'GET #index' do - subject do - get project_harbor_registry_index_path(project) - response - end - - context 'with harbor registry feature flag enabled' do - it_behaves_like 'responds with 200 status' - end - - context 'with harbor registry feature flag disabled' do - before do - stub_feature_flags(harbor_registry_integration: false) - end - - it_behaves_like 'responds with 404 status' - end - end - - describe 'GET #show' do - subject do - get project_harbor_registry_path(project, 1) - response - end - - context 'with harbor registry feature flag enabled' do - it_behaves_like 'responds with 200 status' - end - - context 'with harbor registry feature flag disabled' do - before do - stub_feature_flags(harbor_registry_integration: false) - end - - it_behaves_like 'responds with 404 status' - end + it_behaves_like 'a harbor repositories controller', anonymous_status_code: '302' do + let_it_be(:container, reload: true) { create(:project) } + let_it_be(:harbor_integration) { create(:harbor_integration, project: container) } end end diff --git a/spec/requests/projects/harbor/tags_controller_spec.rb b/spec/requests/projects/harbor/tags_controller_spec.rb new file mode 100644 index 00000000000..119d1c746ac --- /dev/null +++ b/spec/requests/projects/harbor/tags_controller_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::Harbor::TagsController do + it_behaves_like 'a harbor tags controller', anonymous_status_code: '302' do + let_it_be(:container) { create(:project) } + let_it_be(:harbor_integration) { create(:harbor_integration, project: container) } + end +end diff --git a/spec/requests/projects/issues_controller_spec.rb b/spec/requests/projects/issues_controller_spec.rb index 248e3e3a92b..de1d55ff5be 100644 --- a/spec/requests/projects/issues_controller_spec.rb +++ b/spec/requests/projects/issues_controller_spec.rb @@ -50,22 +50,6 @@ RSpec.describe Projects::IssuesController do a_hash_including('id' => discussion_2.id.to_s) ]) end - - context 'when paginated_issue_discussions is disabled' do - before do - stub_feature_flags(paginated_issue_discussions: false) - end - - it 'returns all discussions and ignores per_page param' do - get_discussions(per_page: 2) - - discussions = Gitlab::Json.parse(response.body) - notes = discussions.flat_map { |d| d['notes'] } - - expect(discussions.count).to eq(4) - expect(notes.count).to eq(5) - end - end end end diff --git a/spec/requests/projects/pipelines_controller_spec.rb b/spec/requests/projects/pipelines_controller_spec.rb new file mode 100644 index 00000000000..1c6b1039aee --- /dev/null +++ b/spec/requests/projects/pipelines_controller_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::PipelinesController do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :repository) } + let_it_be(:pipeline) { create(:ci_pipeline, project: project) } + + before_all do + create(:ci_build, pipeline: pipeline, stage: 'build') + create(:ci_bridge, pipeline: pipeline, stage: 'build') + create(:generic_commit_status, pipeline: pipeline, stage: 'build') + + project.add_developer(user) + end + + before do + login_as(user) + end + + describe "GET stages.json" do + it 'does not execute N+1 queries' do + request_build_stage + + control_count = ActiveRecord::QueryRecorder.new do + request_build_stage + end.count + + create(:ci_build, pipeline: pipeline, stage: 'build') + + expect { request_build_stage }.not_to exceed_query_limit(control_count) + + expect(response).to have_gitlab_http_status(:ok) + end + + context 'with retried builds' do + it 'does not execute N+1 queries' do + create(:ci_build, :retried, :failed, pipeline: pipeline, stage: 'build') + + request_build_stage(retried: true) + + control_count = ActiveRecord::QueryRecorder.new do + request_build_stage(retried: true) + end.count + + create(:ci_build, :retried, :failed, pipeline: pipeline, stage: 'build') + + expect { request_build_stage(retried: true) }.not_to exceed_query_limit(control_count) + + expect(response).to have_gitlab_http_status(:ok) + end + end + + def request_build_stage(params = {}) + get stage_namespace_project_pipeline_path( + params.merge( + namespace_id: project.namespace.to_param, + project_id: project.to_param, + id: pipeline.id, + stage: 'build', + format: :json + ) + ) + end + end +end |