diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-14 12:09:21 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-14 12:09:21 +0300 |
commit | 1fc72cb8765dab466da8555b70eb744a53a74a80 (patch) | |
tree | c74b37a2056ff89781aee51b2b9ff5c0560a2fb4 /spec/requests | |
parent | 4fc8a5035217a603a5af54aab09bb7c1bfea7626 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/requests')
3 files changed, 174 insertions, 233 deletions
diff --git a/spec/requests/api/admin/migrations_spec.rb b/spec/requests/api/admin/migrations_spec.rb new file mode 100644 index 00000000000..fc464300b56 --- /dev/null +++ b/spec/requests/api/admin/migrations_spec.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe API::Admin::Migrations, feature_category: :database do + let(:admin) { create(:admin) } + + describe 'POST /admin/migrations/:version/mark' do + let(:database) { :main } + let(:params) { { database: database } } + let(:connection) { ApplicationRecord.connection } + let(:path) { "/admin/migrations/#{version}/mark" } + let(:version) { 1 } + + subject(:mark) do + post api(path, admin, admin_mode: true), params: params + end + + context 'when the migration exists' do + before do + double = instance_double( + Database::MarkMigrationService, + execute: ServiceResponse.success) + + allow(Database::MarkMigrationService) + .to receive(:new) + .with(connection: connection, version: version) + .and_return(double) + end + + it_behaves_like "POST request permissions for admin mode" + + it 'marks the migration as successful' do + mark + + expect(response).to have_gitlab_http_status(:created) + end + end + + context 'when the migration does not exist' do + let(:version) { 123 } + + it 'returns 404' do + mark + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when the migration was already executed' do + let(:version) { connection.migration_context.current_version } + + it 'returns 422' do + mark + + expect(response).to have_gitlab_http_status(:unprocessable_entity) + end + end + + context 'when multiple database is enabled' do + let(:ci_model) { Ci::ApplicationRecord } + let(:database) { :ci } + + before do + skip_if_multiple_databases_not_setup(:ci) + end + + it 'uses the correct connection' do + expect(Database::MarkMigrationService) + .to receive(:new) + .with(connection: ci_model.connection, version: version) + .and_call_original + + mark + end + + context 'when the database name does not exist' do + let(:database) { :wrong_database } + + it 'returns bad request', :aggregate_failures do + mark + + expect(response).to have_gitlab_http_status(:bad_request) + expect(response.body).to include('database does not have a valid value') + end + end + end + end +end diff --git a/spec/requests/api/error_tracking/collector_spec.rb b/spec/requests/api/error_tracking/collector_spec.rb deleted file mode 100644 index 6a3e71bc859..00000000000 --- a/spec/requests/api/error_tracking/collector_spec.rb +++ /dev/null @@ -1,233 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe API::ErrorTracking::Collector, feature_category: :error_tracking do - let_it_be(:project) { create(:project, :private) } - let_it_be(:setting) { create(:project_error_tracking_setting, :integrated, project: project) } - let_it_be(:client_key) { create(:error_tracking_client_key, project: project) } - - RSpec.shared_examples 'not found' do - it 'reponds with 404' do - subject - - expect(response).to have_gitlab_http_status(:not_found) - end - end - - RSpec.shared_examples 'bad request' do - it 'responds with 400' do - subject - - expect(response).to have_gitlab_http_status(:bad_request) - end - end - - RSpec.shared_examples 'successful request' do - it 'writes to the database and returns OK', :aggregate_failures do - expect { subject }.to change { ErrorTracking::ErrorEvent.count }.by(1) - expect(response).to have_gitlab_http_status(:ok) - end - end - - describe "POST /error_tracking/collector/api/:id/envelope" do - let_it_be(:raw_event) { fixture_file('error_tracking/event.txt') } - let_it_be(:url) { "/error_tracking/collector/api/#{project.id}/envelope" } - - let(:params) { raw_event } - let(:headers) { { 'X-Sentry-Auth' => "Sentry sentry_key=#{client_key.public_key}" } } - - subject { post api(url), params: params, headers: headers } - - it_behaves_like 'successful request' - - context 'intergrated error tracking feature flag is disabled' do - before do - stub_feature_flags(integrated_error_tracking: false) - end - - it_behaves_like 'not found' - end - - context 'error tracking feature is disabled' do - before do - setting.update!(enabled: false) - end - - it_behaves_like 'not found' - end - - context 'integrated error tracking is disabled' do - before do - setting.update!(integrated: false) - end - - it_behaves_like 'not found' - end - - context 'auth headers are missing' do - let(:headers) { {} } - - it_behaves_like 'bad request' - end - - context 'public key is wrong' do - let(:headers) { { 'X-Sentry-Auth' => "Sentry sentry_key=glet_1fedb514e17f4b958435093deb02048c" } } - - it_behaves_like 'not found' - end - - context 'public key is inactive' do - let(:client_key) { create(:error_tracking_client_key, :disabled, project: project) } - - it_behaves_like 'not found' - end - - context 'empty body' do - let(:params) { '' } - - it_behaves_like 'bad request' - end - - context 'unknown request type' do - let(:params) { fixture_file('error_tracking/unknown.txt') } - - it_behaves_like 'bad request' - end - - context 'transaction request type' do - let(:params) { fixture_file('error_tracking/transaction.txt') } - - it 'does nothing and returns ok' do - expect { subject }.not_to change { ErrorTracking::ErrorEvent.count } - - expect(response).to have_gitlab_http_status(:ok) - end - end - - context 'gzip body' do - let(:standard_headers) do - { - 'X-Sentry-Auth' => "Sentry sentry_key=#{client_key.public_key}", - 'HTTP_CONTENT_ENCODING' => 'gzip' - } - end - - let(:params) { ActiveSupport::Gzip.compress(raw_event) } - - context 'with application/x-sentry-envelope Content-Type' do - let(:headers) { standard_headers.merge({ 'CONTENT_TYPE' => 'application/x-sentry-envelope' }) } - - it_behaves_like 'successful request' - end - - context 'with unexpected Content-Type' do - let(:headers) { standard_headers.merge({ 'CONTENT_TYPE' => 'application/gzip' }) } - - it 'responds with 415' do - subject - - expect(response).to have_gitlab_http_status(:unsupported_media_type) - end - end - end - end - - describe "POST /error_tracking/collector/api/:id/store" do - let_it_be(:raw_event) { fixture_file('error_tracking/parsed_event.json') } - let_it_be(:url) { "/error_tracking/collector/api/#{project.id}/store" } - - let(:params) { raw_event } - let(:headers) { { 'X-Sentry-Auth' => "Sentry sentry_key=#{client_key.public_key}" } } - - subject { post api(url), params: params, headers: headers } - - it_behaves_like 'successful request' - - context 'empty headers' do - let(:headers) { {} } - - it_behaves_like 'bad request' - end - - context 'empty body' do - let(:params) { '' } - - it_behaves_like 'bad request' - end - - context 'body with string instead of json' do - let(:params) { '"********"' } - - it_behaves_like 'bad request' - end - - context 'collector fails with validation error' do - before do - allow(::ErrorTracking::CollectErrorService) - .to receive(:new).and_raise(Gitlab::ErrorTracking::ErrorRepository::DatabaseError) - end - - it_behaves_like 'bad request' - end - - context 'with platform field too long' do - let(:params) do - event = Gitlab::Json.parse(raw_event) - event['platform'] = 'a' * 256 - Gitlab::Json.dump(event) - end - - it_behaves_like 'bad request' - end - - context 'gzip body' do - let(:headers) do - { - 'X-Sentry-Auth' => "Sentry sentry_key=#{client_key.public_key}", - 'HTTP_CONTENT_ENCODING' => 'gzip', - 'CONTENT_TYPE' => 'application/json' - } - end - - let(:params) { ActiveSupport::Gzip.compress(raw_event) } - - it_behaves_like 'successful request' - end - - context 'body contains nullbytes' do - let_it_be(:raw_event) { fixture_file('error_tracking/parsed_event_nullbytes.json') } - - it_behaves_like 'successful request' - end - - context 'when JSON key transaction is empty string' do - let_it_be(:raw_event) { fixture_file('error_tracking/php_empty_transaction.json') } - - it_behaves_like 'successful request' - end - - context 'sentry_key as param and empty headers' do - let(:url) { "/error_tracking/collector/api/#{project.id}/store?sentry_key=#{sentry_key}" } - let(:headers) { {} } - - context 'key is wrong' do - let(:sentry_key) { 'glet_1fedb514e17f4b958435093deb02048c' } - - it_behaves_like 'not found' - end - - context 'key is empty' do - let(:sentry_key) { '' } - - it_behaves_like 'bad request' - end - - context 'key is correct' do - let(:sentry_key) { client_key.public_key } - - it_behaves_like 'successful request' - end - end - end -end diff --git a/spec/requests/api/graphql/mutations/achievements/delete_user_achievement_spec.rb b/spec/requests/api/graphql/mutations/achievements/delete_user_achievement_spec.rb new file mode 100644 index 00000000000..f759e6dce08 --- /dev/null +++ b/spec/requests/api/graphql/mutations/achievements/delete_user_achievement_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::Achievements::DeleteUserAchievement, feature_category: :user_profile do + include GraphqlHelpers + + let_it_be(:maintainer) { create(:user) } + let_it_be(:owner) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:achievement) { create(:achievement, namespace: group) } + let_it_be(:user_achievement) { create(:user_achievement, achievement: achievement) } + + let(:mutation) { graphql_mutation(:user_achievements_delete, params) } + let(:user_achievement_id) { user_achievement&.to_global_id } + let(:params) { { user_achievement_id: user_achievement_id } } + + subject { post_graphql_mutation(mutation, current_user: current_user) } + + before_all do + group.add_maintainer(maintainer) + group.add_owner(owner) + end + + context 'when the user does not have permission' do + let(:current_user) { maintainer } + + it_behaves_like 'a mutation that returns a top-level access error' + + it 'does not delete any user achievements' do + expect { subject }.not_to change { Achievements::UserAchievement.count } + end + end + + context 'when the user has permission' do + let(:current_user) { owner } + + context 'when the params are invalid' do + let(:user_achievement) { nil } + + it 'returns the validation error' do + subject + + expect(graphql_errors.to_s).to include('invalid value for userAchievementId (Expected value to not be null)') + end + end + + context 'when the user_achievement_id is invalid' do + let(:user_achievement_id) { "gid://gitlab/Achievements::UserAchievement/#{non_existing_record_id}" } + + it 'returns the relevant error' do + subject + + expect(graphql_errors.to_s) + .to include("The resource that you are attempting to access does not exist or you don't have permission") + end + end + + context 'when the feature flag is disabled' do + before do + stub_feature_flags(achievements: false) + end + + it 'returns the relevant error' do + subject + + expect(graphql_errors.to_s) + .to include("The resource that you are attempting to access does not exist or you don't have permission") + end + end + + context 'when everything is ok' do + it 'deletes an user achievement' do + expect { subject }.to change { Achievements::UserAchievement.count }.by(-1) + end + + it 'returns the deleted user achievement' do + subject + + expect(graphql_data_at(:user_achievements_delete, :user_achievement, :achievement, :id)) + .to eq(achievement.to_global_id.to_s) + end + end + end +end |