From edaa33dee2ff2f7ea3fac488d41558eb5f86d68c Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 20 Jan 2022 09:16:11 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-7-stable-ee --- ...210112143418_remove_duplicate_services2_spec.rb | 52 ------- ...a_issue_first_mentioned_in_commit_value_spec.rb | 30 ---- ...4_remove_bad_dependency_proxy_manifests_spec.rb | 28 ---- ...pdated_at_after_repository_storage_move_spec.rb | 47 ------ ...dd_environment_scope_to_group_variables_spec.rb | 46 ------ .../20210226141517_dedup_issue_metrics_spec.rb | 66 --------- ...culate_vulnerabilities_occurrences_uuid_spec.rb | 30 ---- ...culate_vulnerabilities_occurrences_uuid_spec.rb | 44 ++++++ ...te_uuid_on_vulnerabilities_occurrences4_spec.rb | 148 +++++++++++++++++++ ...11210140629_encrypt_static_object_token_spec.rb | 50 +++++++ ...fill_incident_issue_escalation_statuses_spec.rb | 36 +++++ ...lculate_finding_signatures_as_completed_spec.rb | 64 ++++++++ .../add_has_external_issue_tracker_trigger_spec.rb | 164 --------------------- .../add_has_external_wiki_trigger_spec.rb | 128 ---------------- spec/migrations/add_new_post_eoa_plans_spec.rb | 32 ---- ...imary_email_to_emails_if_user_confirmed_spec.rb | 48 ++++++ ...ith_bad_has_external_issue_tracker_data_spec.rb | 94 ------------ ...rojects_with_bad_has_external_wiki_data_spec.rb | 89 ----------- spec/migrations/drop_alerts_service_data_spec.rb | 21 --- ...l_from_namespaces_to_namespace_settings_spec.rb | 30 ---- .../remove_alerts_service_records_again_spec.rb | 23 --- .../remove_alerts_service_records_spec.rb | 30 ---- .../reschedule_artifact_expiry_backfill_spec.rb | 38 ----- .../schedule_migrate_pages_to_zip_storage_spec.rb | 2 +- ...finding_uuid_for_vulnerability_feedback_spec.rb | 37 ----- ...te_uuid_on_vulnerabilities_occurrences2_spec.rb | 127 ---------------- ...te_uuid_on_vulnerabilities_occurrences3_spec.rb | 127 ---------------- ...te_application_settings_protected_paths_spec.rb | 46 ++++++ .../update_invalid_member_states_spec.rb | 30 ++++ 29 files changed, 467 insertions(+), 1240 deletions(-) delete mode 100644 spec/migrations/20210112143418_remove_duplicate_services2_spec.rb delete mode 100644 spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb delete mode 100644 spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb delete mode 100644 spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb delete mode 100644 spec/migrations/20210218040814_add_environment_scope_to_group_variables_spec.rb delete mode 100644 spec/migrations/20210226141517_dedup_issue_metrics_spec.rb delete mode 100644 spec/migrations/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb create mode 100644 spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb create mode 100644 spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb create mode 100644 spec/migrations/20211210140629_encrypt_static_object_token_spec.rb create mode 100644 spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb create mode 100644 spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb delete mode 100644 spec/migrations/add_has_external_issue_tracker_trigger_spec.rb delete mode 100644 spec/migrations/add_has_external_wiki_trigger_spec.rb delete mode 100644 spec/migrations/add_new_post_eoa_plans_spec.rb create mode 100644 spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb delete mode 100644 spec/migrations/cleanup_projects_with_bad_has_external_issue_tracker_data_spec.rb delete mode 100644 spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb delete mode 100644 spec/migrations/drop_alerts_service_data_spec.rb delete mode 100644 spec/migrations/migrate_delayed_project_removal_from_namespaces_to_namespace_settings_spec.rb delete mode 100644 spec/migrations/remove_alerts_service_records_again_spec.rb delete mode 100644 spec/migrations/remove_alerts_service_records_spec.rb delete mode 100644 spec/migrations/reschedule_artifact_expiry_backfill_spec.rb delete mode 100644 spec/migrations/schedule_populate_finding_uuid_for_vulnerability_feedback_spec.rb delete mode 100644 spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences2_spec.rb delete mode 100644 spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb create mode 100644 spec/migrations/update_application_settings_protected_paths_spec.rb create mode 100644 spec/migrations/update_invalid_member_states_spec.rb (limited to 'spec/migrations') diff --git a/spec/migrations/20210112143418_remove_duplicate_services2_spec.rb b/spec/migrations/20210112143418_remove_duplicate_services2_spec.rb deleted file mode 100644 index b8dc4d7c8ae..00000000000 --- a/spec/migrations/20210112143418_remove_duplicate_services2_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe RemoveDuplicateServices2 do - let_it_be(:namespaces) { table(:namespaces) } - let_it_be(:projects) { table(:projects) } - let_it_be(:services) { table(:services) } - - describe '#up' do - before do - stub_const("#{described_class}::BATCH_SIZE", 2) - - namespaces.create!(id: 1, name: 'group', path: 'group') - - projects.create!(id: 1, namespace_id: 1) # duplicate services - projects.create!(id: 2, namespace_id: 1) # normal services - projects.create!(id: 3, namespace_id: 1) # no services - projects.create!(id: 4, namespace_id: 1) # duplicate services - projects.create!(id: 5, namespace_id: 1) # duplicate services - - services.create!(id: 1, project_id: 1, type: 'JiraService') - services.create!(id: 2, project_id: 1, type: 'JiraService') - services.create!(id: 3, project_id: 2, type: 'JiraService') - services.create!(id: 4, project_id: 4, type: 'AsanaService') - services.create!(id: 5, project_id: 4, type: 'AsanaService') - services.create!(id: 6, project_id: 4, type: 'JiraService') - services.create!(id: 7, project_id: 4, type: 'JiraService') - services.create!(id: 8, project_id: 4, type: 'SlackService') - services.create!(id: 9, project_id: 4, type: 'SlackService') - services.create!(id: 10, project_id: 5, type: 'JiraService') - services.create!(id: 11, project_id: 5, type: 'JiraService') - - # Services without a project_id should be ignored - services.create!(id: 12, type: 'JiraService') - services.create!(id: 13, type: 'JiraService') - end - - it 'schedules background jobs for all projects with duplicate services' do - Sidekiq::Testing.fake! do - freeze_time do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 1, 4) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 5) - end - end - end - end -end diff --git a/spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb b/spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb deleted file mode 100644 index e07b5a48909..00000000000 --- a/spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe AlterVsaIssueFirstMentionedInCommitValue, schema: 20210114033715 do - let(:group_stages) { table(:analytics_cycle_analytics_group_stages) } - let(:value_streams) { table(:analytics_cycle_analytics_group_value_streams) } - let(:namespaces) { table(:namespaces) } - - let(:namespace) { namespaces.create!(id: 1, name: 'group', path: 'group') } - let(:value_stream) { value_streams.create!(name: 'test', group_id: namespace.id) } - - let!(:stage_1) { group_stages.create!(group_value_stream_id: value_stream.id, group_id: namespace.id, name: 'stage 1', start_event_identifier: described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_EE, end_event_identifier: 1) } - let!(:stage_2) { group_stages.create!(group_value_stream_id: value_stream.id, group_id: namespace.id, name: 'stage 2', start_event_identifier: 2, end_event_identifier: described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_EE) } - let!(:stage_3) { group_stages.create!(group_value_stream_id: value_stream.id, group_id: namespace.id, name: 'stage 3', start_event_identifier: described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS, end_event_identifier: 3) } - - describe '#up' do - it 'changes the EE specific identifier values to the FOSS version' do - migrate! - - expect(stage_1.reload.start_event_identifier).to eq(described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS) - expect(stage_2.reload.end_event_identifier).to eq(described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS) - end - - it 'does not change irrelevant records' do - expect { migrate! }.not_to change { stage_3.reload } - end - end -end diff --git a/spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb b/spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb deleted file mode 100644 index 97438062458..00000000000 --- a/spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe RemoveBadDependencyProxyManifests, schema: 20210128140157 do - let_it_be(:namespaces) { table(:namespaces) } - let_it_be(:dependency_proxy_manifests) { table(:dependency_proxy_manifests) } - let_it_be(:group) { namespaces.create!(type: 'Group', name: 'test', path: 'test') } - - let_it_be(:dependency_proxy_manifest_with_content_type) do - dependency_proxy_manifests.create!(group_id: group.id, file: 'foo', file_name: 'foo', digest: 'asdf1234', content_type: 'content-type' ) - end - - let_it_be(:dependency_proxy_manifest_without_content_type) do - dependency_proxy_manifests.create!(group_id: group.id, file: 'bar', file_name: 'bar', digest: 'fdsa6789') - end - - it 'removes the dependency_proxy_manifests with a content_type', :aggregate_failures do - expect(dependency_proxy_manifest_with_content_type).to be_present - expect(dependency_proxy_manifest_without_content_type).to be_present - - expect { migrate! }.to change { dependency_proxy_manifests.count }.from(2).to(1) - - expect(dependency_proxy_manifests.where.not(content_type: nil)).to be_empty - expect(dependency_proxy_manifest_without_content_type.reload).to be_present - end -end diff --git a/spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb b/spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb deleted file mode 100644 index 4a31d36e2bc..00000000000 --- a/spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe BackfillUpdatedAtAfterRepositoryStorageMove, :sidekiq do - let_it_be(:projects) { table(:projects) } - let_it_be(:project_repository_storage_moves) { table(:project_repository_storage_moves) } - let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } - - describe '#up' do - it 'schedules background jobs for all distinct projects in batches' do - stub_const("#{described_class}::BATCH_SIZE", 3) - - project_1 = projects.create!(id: 1, namespace_id: namespace.id) - project_2 = projects.create!(id: 2, namespace_id: namespace.id) - project_3 = projects.create!(id: 3, namespace_id: namespace.id) - project_4 = projects.create!(id: 4, namespace_id: namespace.id) - project_5 = projects.create!(id: 5, namespace_id: namespace.id) - project_6 = projects.create!(id: 6, namespace_id: namespace.id) - project_7 = projects.create!(id: 7, namespace_id: namespace.id) - projects.create!(id: 8, namespace_id: namespace.id) - - project_repository_storage_moves.create!(id: 1, project_id: project_1.id, source_storage_name: 'default', destination_storage_name: 'default') - project_repository_storage_moves.create!(id: 2, project_id: project_1.id, source_storage_name: 'default', destination_storage_name: 'default') - project_repository_storage_moves.create!(id: 3, project_id: project_2.id, source_storage_name: 'default', destination_storage_name: 'default') - project_repository_storage_moves.create!(id: 4, project_id: project_3.id, source_storage_name: 'default', destination_storage_name: 'default') - project_repository_storage_moves.create!(id: 5, project_id: project_3.id, source_storage_name: 'default', destination_storage_name: 'default') - project_repository_storage_moves.create!(id: 6, project_id: project_4.id, source_storage_name: 'default', destination_storage_name: 'default') - project_repository_storage_moves.create!(id: 7, project_id: project_4.id, source_storage_name: 'default', destination_storage_name: 'default') - project_repository_storage_moves.create!(id: 8, project_id: project_5.id, source_storage_name: 'default', destination_storage_name: 'default') - project_repository_storage_moves.create!(id: 9, project_id: project_6.id, source_storage_name: 'default', destination_storage_name: 'default') - project_repository_storage_moves.create!(id: 10, project_id: project_7.id, source_storage_name: 'default', destination_storage_name: 'default') - - Sidekiq::Testing.fake! do - freeze_time do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(3) - expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(2.minutes, 1, 2, 3) - expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(4.minutes, 4, 5, 6) - expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(6.minutes, 7) - end - end - end - end -end diff --git a/spec/migrations/20210218040814_add_environment_scope_to_group_variables_spec.rb b/spec/migrations/20210218040814_add_environment_scope_to_group_variables_spec.rb deleted file mode 100644 index 039ce53cac4..00000000000 --- a/spec/migrations/20210218040814_add_environment_scope_to_group_variables_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe AddEnvironmentScopeToGroupVariables do - let(:migration) { described_class.new } - let(:ci_group_variables) { table(:ci_group_variables) } - let(:group) { table(:namespaces).create!(name: 'group', path: 'group') } - - def create_variable!(group, key:, environment_scope: '*') - table(:ci_group_variables).create!( - group_id: group.id, - key: key, - environment_scope: environment_scope - ) - end - - describe '#down' do - context 'group has variables with duplicate keys' do - it 'deletes all but the first record' do - migration.up - - remaining_variable = create_variable!(group, key: 'key') - create_variable!(group, key: 'key', environment_scope: 'staging') - create_variable!(group, key: 'key', environment_scope: 'production') - - migration.down - - expect(ci_group_variables.pluck(:id)).to eq [remaining_variable.id] - end - end - - context 'group does not have variables with duplicate keys' do - it 'does not delete any records' do - migration.up - - create_variable!(group, key: 'key') - create_variable!(group, key: 'staging') - create_variable!(group, key: 'production') - - expect { migration.down }.not_to change { ci_group_variables.count } - end - end - end -end diff --git a/spec/migrations/20210226141517_dedup_issue_metrics_spec.rb b/spec/migrations/20210226141517_dedup_issue_metrics_spec.rb deleted file mode 100644 index 1b57bf0431f..00000000000 --- a/spec/migrations/20210226141517_dedup_issue_metrics_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe DedupIssueMetrics, :migration, schema: 20210205104425 do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:issues) { table(:issues) } - let(:metrics) { table(:issue_metrics) } - let(:issue_params) { { title: 'title', project_id: project.id } } - - let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') } - let!(:project) { projects.create!(namespace_id: namespace.id) } - let!(:issue_1) { issues.create!(issue_params) } - let!(:issue_2) { issues.create!(issue_params) } - let!(:issue_3) { issues.create!(issue_params) } - - let!(:duplicated_metrics_1) { metrics.create!(issue_id: issue_1.id, first_mentioned_in_commit_at: 1.day.ago, first_added_to_board_at: 5.days.ago, updated_at: 2.months.ago) } - let!(:duplicated_metrics_2) { metrics.create!(issue_id: issue_1.id, first_mentioned_in_commit_at: Time.now, first_associated_with_milestone_at: Time.now, updated_at: 1.month.ago) } - - let!(:duplicated_metrics_3) { metrics.create!(issue_id: issue_3.id, first_mentioned_in_commit_at: 1.day.ago, updated_at: 2.months.ago) } - let!(:duplicated_metrics_4) { metrics.create!(issue_id: issue_3.id, first_added_to_board_at: 1.day.ago, updated_at: 1.month.ago) } - - let!(:non_duplicated_metrics) { metrics.create!(issue_id: issue_2.id, first_added_to_board_at: 2.days.ago) } - - it 'deduplicates issue_metrics table' do - expect { migrate! }.to change { metrics.count }.from(5).to(3) - end - - it 'merges `duplicated_metrics_1` with `duplicated_metrics_2`' do - migrate! - - expect(metrics.where(id: duplicated_metrics_1.id)).not_to exist - - merged_metrics = metrics.find_by(id: duplicated_metrics_2.id) - - expect(merged_metrics).to be_present - expect(merged_metrics.first_mentioned_in_commit_at).to be_like_time(duplicated_metrics_2.first_mentioned_in_commit_at) - expect(merged_metrics.first_added_to_board_at).to be_like_time(duplicated_metrics_1.first_added_to_board_at) - end - - it 'merges `duplicated_metrics_3` with `duplicated_metrics_4`' do - migrate! - - expect(metrics.where(id: duplicated_metrics_3.id)).not_to exist - - merged_metrics = metrics.find_by(id: duplicated_metrics_4.id) - - expect(merged_metrics).to be_present - expect(merged_metrics.first_mentioned_in_commit_at).to be_like_time(duplicated_metrics_3.first_mentioned_in_commit_at) - expect(merged_metrics.first_added_to_board_at).to be_like_time(duplicated_metrics_4.first_added_to_board_at) - end - - it 'does not change non duplicated records' do - expect { migrate! }.not_to change { non_duplicated_metrics.reload.attributes } - end - - it 'does nothing when there are no metrics' do - metrics.delete_all - - migrate! - - expect(metrics.count).to eq(0) - end -end diff --git a/spec/migrations/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/migrations/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb deleted file mode 100644 index 5a2531bb63f..00000000000 --- a/spec/migrations/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb') - -RSpec.describe ReschedulePendingJobsForRecalculateVulnerabilitiesOccurrencesUuid, :migration do - let_it_be(:background_migration_jobs) { table(:background_migration_jobs) } - - context 'when RecalculateVulnerabilitiesOccurrencesUuid jobs are pending' do - before do - background_migration_jobs.create!( - class_name: 'RecalculateVulnerabilitiesOccurrencesUuid', - arguments: [1, 2, 3], - status: Gitlab::Database::BackgroundMigrationJob.statuses['pending'] - ) - background_migration_jobs.create!( - class_name: 'RecalculateVulnerabilitiesOccurrencesUuid', - arguments: [4, 5, 6], - status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded'] - ) - end - - it 'queues pending jobs' do - migrate! - - expect(BackgroundMigrationWorker.jobs.length).to eq(1) - expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['RecalculateVulnerabilitiesOccurrencesUuid', [1, 2, 3]]) - expect(BackgroundMigrationWorker.jobs[0]['at']).to be_nil - end - end -end diff --git a/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb new file mode 100644 index 00000000000..491aad1b30b --- /dev/null +++ b/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true +require 'spec_helper' +require_migration! + +def create_background_migration_jobs(ids, status, created_at) + proper_status = case status + when :pending + Gitlab::Database::BackgroundMigrationJob.statuses['pending'] + when :succeeded + Gitlab::Database::BackgroundMigrationJob.statuses['succeeded'] + else + raise ArgumentError + end + + background_migration_jobs.create!( + class_name: 'RecalculateVulnerabilitiesOccurrencesUuid', + arguments: Array(ids), + status: proper_status, + created_at: created_at + ) +end + +RSpec.describe RemoveJobsForRecalculateVulnerabilitiesOccurrencesUuid, :migration do + let_it_be(:background_migration_jobs) { table(:background_migration_jobs) } + + context 'when RecalculateVulnerabilitiesOccurrencesUuid jobs are present' do + before do + create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 5, 5, 0, 2)) + create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 5, 5, 0, 4)) + + create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 8, 18, 0, 0)) + create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 8, 18, 0, 2)) + create_background_migration_jobs([7, 8, 9], :pending, DateTime.new(2021, 8, 18, 0, 4)) + end + + it 'removes all jobs' do + expect(background_migration_jobs.count).to eq(5) + + migrate! + + expect(background_migration_jobs.count).to eq(0) + end + end +end diff --git a/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb b/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb new file mode 100644 index 00000000000..71ffcafaae1 --- /dev/null +++ b/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences4 do + let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } + let(:users) { table(:users) } + let(:user) { create_user! } + let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) } + let(:scanners) { table(:vulnerability_scanners) } + let(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') } + let(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') } + let(:vulnerabilities) { table(:vulnerabilities) } + let(:vulnerabilities_findings) { table(:vulnerability_occurrences) } + let(:vulnerability_finding_signatures) { table(:vulnerability_finding_signatures) } + let(:vulnerability_identifiers) { table(:vulnerability_identifiers) } + let(:vulnerability_identifier) do + vulnerability_identifiers.create!( + project_id: project.id, + external_type: 'uuid-v5', + external_id: 'uuid-v5', + fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a', + name: 'Identifier for UUIDv5') + end + + let(:different_vulnerability_identifier) do + vulnerability_identifiers.create!( + project_id: project.id, + external_type: 'uuid-v4', + external_id: 'uuid-v4', + fingerprint: '772da93d34a1ba010bcb5efa9fb6f8e01bafcc89', + name: 'Identifier for UUIDv4') + end + + let!(:uuidv4_finding) do + create_finding!( + vulnerability_id: vulnerability_for_uuidv4.id, + project_id: project.id, + scanner_id: different_scanner.id, + primary_identifier_id: different_vulnerability_identifier.id, + location_fingerprint: Gitlab::Database::ShaAttribute.serialize('fa18f432f1d56675f4098d318739c3cd5b14eb3e'), + uuid: 'b3cc2518-5446-4dea-871c-89d5e999c1ac' + ) + end + + let(:vulnerability_for_uuidv4) do + create_vulnerability!( + project_id: project.id, + author_id: user.id + ) + end + + let!(:uuidv5_finding) do + create_finding!( + vulnerability_id: vulnerability_for_uuidv5.id, + project_id: project.id, + scanner_id: scanner.id, + primary_identifier_id: vulnerability_identifier.id, + location_fingerprint: Gitlab::Database::ShaAttribute.serialize('838574be0210968bf6b9f569df9c2576242cbf0a'), + uuid: '77211ed6-7dff-5f6b-8c9a-da89ad0a9b60' + ) + end + + let(:vulnerability_for_uuidv5) do + create_vulnerability!( + project_id: project.id, + author_id: user.id + ) + end + + let(:vulnerability_for_finding_with_signature) do + create_vulnerability!( + project_id: project.id, + author_id: user.id + ) + end + + let!(:finding_with_signature) do + create_finding!( + vulnerability_id: vulnerability_for_finding_with_signature.id, + project_id: project.id, + scanner_id: scanner.id, + primary_identifier_id: vulnerability_identifier.id, + report_type: 0, # "sast" + location_fingerprint: Gitlab::Database::ShaAttribute.serialize('123609eafffffa2207a9ca2425ba4337h34fga1b'), + uuid: '252aa474-d689-5d2b-ab42-7bbb5a100c02' + ) + end + + before do + stub_const("#{described_class}::BATCH_SIZE", 1) + end + + around do |example| + freeze_time { Sidekiq::Testing.fake! { example.run } } + end + + it 'schedules background migrations', :aggregate_failures do + migrate! + + expect(BackgroundMigrationWorker.jobs.size).to eq(3) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, uuidv4_finding.id, uuidv4_finding.id) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, uuidv5_finding.id, uuidv5_finding.id) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration(6.minutes, finding_with_signature.id, finding_with_signature.id) + end + + private + + def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0) + vulnerabilities.create!( + project_id: project_id, + author_id: author_id, + title: title, + severity: severity, + confidence: confidence, + report_type: report_type + ) + end + + def create_finding!( + vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, location_fingerprint:, uuid:, report_type: 0) + vulnerabilities_findings.create!( + vulnerability_id: vulnerability_id, + project_id: project_id, + name: 'test', + severity: 7, + confidence: 7, + report_type: report_type, + project_fingerprint: '123qweasdzxc', + scanner_id: scanner_id, + primary_identifier_id: primary_identifier_id, + location_fingerprint: location_fingerprint, + metadata_version: 'test', + raw_metadata: 'test', + uuid: uuid + ) + end + + def create_user!(name: "Example User", email: "user@example.com", user_type: nil) + users.create!( + name: name, + email: email, + username: name, + projects_limit: 0 + ) + end +end diff --git a/spec/migrations/20211210140629_encrypt_static_object_token_spec.rb b/spec/migrations/20211210140629_encrypt_static_object_token_spec.rb new file mode 100644 index 00000000000..289cf9a93ed --- /dev/null +++ b/spec/migrations/20211210140629_encrypt_static_object_token_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true +require 'spec_helper' + +require_migration! + +RSpec.describe EncryptStaticObjectToken, :migration do + let_it_be(:background_migration_jobs) { table(:background_migration_jobs) } + let_it_be(:users) { table(:users) } + + let!(:user_without_tokens) { create_user!(name: 'notoken') } + let!(:user_with_plaintext_token_1) { create_user!(name: 'plaintext_1', token: 'token') } + let!(:user_with_plaintext_token_2) { create_user!(name: 'plaintext_2', token: 'TOKEN') } + let!(:user_with_encrypted_token) { create_user!(name: 'encrypted', encrypted_token: 'encrypted') } + let!(:user_with_both_tokens) { create_user!(name: 'both', token: 'token2', encrypted_token: 'encrypted2') } + + before do + stub_const("#{described_class}::BATCH_SIZE", 1) + end + + around do |example| + freeze_time { Sidekiq::Testing.fake! { example.run } } + end + + it 'schedules background migrations' do + migrate! + + expect(background_migration_jobs.count).to eq(2) + expect(background_migration_jobs.first.arguments).to match_array([user_with_plaintext_token_1.id, user_with_plaintext_token_1.id]) + expect(background_migration_jobs.second.arguments).to match_array([user_with_plaintext_token_2.id, user_with_plaintext_token_2.id]) + + expect(BackgroundMigrationWorker.jobs.size).to eq(2) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, user_with_plaintext_token_1.id, user_with_plaintext_token_1.id) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, user_with_plaintext_token_2.id, user_with_plaintext_token_2.id) + end + + private + + def create_user!(name:, token: nil, encrypted_token: nil) + email = "#{name}@example.com" + + table(:users).create!( + name: name, + email: email, + username: name, + projects_limit: 0, + static_object_token: token, + static_object_token_encrypted: encrypted_token + ) + end +end diff --git a/spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb b/spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb new file mode 100644 index 00000000000..a17fee6bab2 --- /dev/null +++ b/spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe BackfillIncidentIssueEscalationStatuses do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:issues) { table(:issues) } + let(:namespace) { namespaces.create!(name: 'foo', path: 'foo') } + let(:project) { projects.create!(namespace_id: namespace.id) } + + before do + stub_const("#{described_class.name}::BATCH_SIZE", 1) + end + + it 'schedules jobs for incident issues' do + issue_1 = issues.create!(project_id: project.id) # non-incident issue + incident_1 = issues.create!(project_id: project.id, issue_type: 1) + incident_2 = issues.create!(project_id: project.id, issue_type: 1) + + Sidekiq::Testing.fake! do + freeze_time do + migrate! + + expect(described_class::MIGRATION).to be_scheduled_delayed_migration( + 2.minutes, issue_1.id, issue_1.id) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration( + 4.minutes, incident_1.id, incident_1.id) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration( + 6.minutes, incident_2.id, incident_2.id) + expect(BackgroundMigrationWorker.jobs.size).to eq(3) + end + end + end +end diff --git a/spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb b/spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb new file mode 100644 index 00000000000..c5058f30d82 --- /dev/null +++ b/spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true +require 'spec_helper' +require_migration! + +def create_background_migration_jobs(ids, status, created_at) + proper_status = case status + when :pending + Gitlab::Database::BackgroundMigrationJob.statuses['pending'] + when :succeeded + Gitlab::Database::BackgroundMigrationJob.statuses['succeeded'] + else + raise ArgumentError + end + + background_migration_jobs.create!( + class_name: 'RecalculateVulnerabilitiesOccurrencesUuid', + arguments: Array(ids), + status: proper_status, + created_at: created_at + ) +end + +RSpec.describe MarkRecalculateFindingSignaturesAsCompleted, :migration do + let_it_be(:background_migration_jobs) { table(:background_migration_jobs) } + + context 'when RecalculateVulnerabilitiesOccurrencesUuid jobs are present' do + before do + create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 5, 5, 0, 2)) + create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 5, 5, 0, 4)) + + create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 8, 18, 0, 0)) + create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 8, 18, 0, 2)) + create_background_migration_jobs([7, 8, 9], :pending, DateTime.new(2021, 8, 18, 0, 4)) + end + + describe 'gitlab.com' do + before do + allow(::Gitlab).to receive(:com?).and_return(true) + end + + it 'marks all jobs as succeeded' do + expect(background_migration_jobs.where(status: 1).count).to eq(2) + + migrate! + + expect(background_migration_jobs.where(status: 1).count).to eq(5) + end + end + + describe 'self managed' do + before do + allow(::Gitlab).to receive(:com?).and_return(false) + end + + it 'does not change job status' do + expect(background_migration_jobs.where(status: 1).count).to eq(2) + + migrate! + + expect(background_migration_jobs.where(status: 1).count).to eq(2) + end + end + end +end diff --git a/spec/migrations/add_has_external_issue_tracker_trigger_spec.rb b/spec/migrations/add_has_external_issue_tracker_trigger_spec.rb deleted file mode 100644 index 72983c7cfbf..00000000000 --- a/spec/migrations/add_has_external_issue_tracker_trigger_spec.rb +++ /dev/null @@ -1,164 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe AddHasExternalIssueTrackerTrigger do - let(:migration) { described_class.new } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:services) { table(:services) } - - before do - @namespace = namespaces.create!(name: 'foo', path: 'foo') - @project = projects.create!(namespace_id: @namespace.id) - end - - describe '#up' do - before do - migrate! - end - - describe 'INSERT trigger' do - it 'sets `has_external_issue_tracker` to true when active `issue_tracker` is inserted' do - expect do - services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - end.to change { @project.reload.has_external_issue_tracker }.to(true) - end - - it 'does not set `has_external_issue_tracker` to true when service is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - - expect do - services.create!(category: 'issue_tracker', active: true, project_id: different_project.id) - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'does not set `has_external_issue_tracker` to true when inactive `issue_tracker` is inserted' do - expect do - services.create!(category: 'issue_tracker', active: false, project_id: @project.id) - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'does not set `has_external_issue_tracker` to true when a non-`issue tracker` active service is inserted' do - expect do - services.create!(category: 'my_type', active: true, project_id: @project.id) - end.not_to change { @project.reload.has_external_issue_tracker } - end - end - - describe 'UPDATE trigger' do - it 'sets `has_external_issue_tracker` to true when `issue_tracker` is made active' do - service = services.create!(category: 'issue_tracker', active: false, project_id: @project.id) - - expect do - service.update!(active: true) - end.to change { @project.reload.has_external_issue_tracker }.to(true) - end - - it 'sets `has_external_issue_tracker` to false when `issue_tracker` is made inactive' do - service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - service.update!(active: false) - end.to change { @project.reload.has_external_issue_tracker }.to(false) - end - - it 'sets `has_external_issue_tracker` to false when `issue_tracker` is made inactive, and an inactive `issue_tracker` exists' do - services.create!(category: 'issue_tracker', active: false, project_id: @project.id) - service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - service.update!(active: false) - end.to change { @project.reload.has_external_issue_tracker }.to(false) - end - - it 'does not change `has_external_issue_tracker` when `issue_tracker` is made inactive, if an active `issue_tracker` exists' do - services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - service.update!(active: false) - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'does not change `has_external_issue_tracker` when service is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - service = services.create!(category: 'issue_tracker', active: false, project_id: different_project.id) - - expect do - service.update!(active: true) - end.not_to change { @project.reload.has_external_issue_tracker } - end - end - - describe 'DELETE trigger' do - it 'sets `has_external_issue_tracker` to false when `issue_tracker` is deleted' do - service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - service.delete - end.to change { @project.reload.has_external_issue_tracker }.to(false) - end - - it 'sets `has_external_issue_tracker` to false when `issue_tracker` is deleted, if an inactive `issue_tracker` still exists' do - services.create!(category: 'issue_tracker', active: false, project_id: @project.id) - service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - service.delete - end.to change { @project.reload.has_external_issue_tracker }.to(false) - end - - it 'does not change `has_external_issue_tracker` when `issue_tracker` is deleted, if an active `issue_tracker` still exists' do - services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - service.delete - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'does not change `has_external_issue_tracker` when service is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - service = services.create!(category: 'issue_tracker', active: true, project_id: different_project.id) - - expect do - service.delete - end.not_to change { @project.reload.has_external_issue_tracker } - end - end - end - - describe '#down' do - before do - migration.up - migration.down - end - - it 'drops the INSERT trigger' do - expect do - services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'drops the UPDATE trigger' do - service = services.create!(category: 'issue_tracker', active: false, project_id: @project.id) - @project.update!(has_external_issue_tracker: false) - - expect do - service.update!(active: true) - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'drops the DELETE trigger' do - service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id) - @project.update!(has_external_issue_tracker: true) - - expect do - service.delete - end.not_to change { @project.reload.has_external_issue_tracker } - end - end -end diff --git a/spec/migrations/add_has_external_wiki_trigger_spec.rb b/spec/migrations/add_has_external_wiki_trigger_spec.rb deleted file mode 100644 index 10c6888c87e..00000000000 --- a/spec/migrations/add_has_external_wiki_trigger_spec.rb +++ /dev/null @@ -1,128 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe AddHasExternalWikiTrigger do - let(:migration) { described_class.new } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:services) { table(:services) } - - before do - @namespace = namespaces.create!(name: 'foo', path: 'foo') - @project = projects.create!(namespace_id: @namespace.id) - end - - describe '#up' do - before do - migrate! - end - - describe 'INSERT trigger' do - it 'sets `has_external_wiki` to true when active `ExternalWikiService` is inserted' do - expect do - services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id) - end.to change { @project.reload.has_external_wiki }.to(true) - end - - it 'does not set `has_external_wiki` to true when service is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - - expect do - services.create!(type: 'ExternalWikiService', active: true, project_id: different_project.id) - end.not_to change { @project.reload.has_external_wiki } - end - - it 'does not set `has_external_wiki` to true when inactive `ExternalWikiService` is inserted' do - expect do - services.create!(type: 'ExternalWikiService', active: false, project_id: @project.id) - end.not_to change { @project.reload.has_external_wiki } - end - - it 'does not set `has_external_wiki` to true when active other service is inserted' do - expect do - services.create!(type: 'MyService', active: true, project_id: @project.id) - end.not_to change { @project.reload.has_external_wiki } - end - end - - describe 'UPDATE trigger' do - it 'sets `has_external_wiki` to true when `ExternalWikiService` is made active' do - service = services.create!(type: 'ExternalWikiService', active: false, project_id: @project.id) - - expect do - service.update!(active: true) - end.to change { @project.reload.has_external_wiki }.to(true) - end - - it 'sets `has_external_wiki` to false when `ExternalWikiService` is made inactive' do - service = services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id) - - expect do - service.update!(active: false) - end.to change { @project.reload.has_external_wiki }.to(false) - end - - it 'does not change `has_external_wiki` when service is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - service = services.create!(type: 'ExternalWikiService', active: false, project_id: different_project.id) - - expect do - service.update!(active: true) - end.not_to change { @project.reload.has_external_wiki } - end - end - - describe 'DELETE trigger' do - it 'sets `has_external_wiki` to false when `ExternalWikiService` is deleted' do - service = services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id) - - expect do - service.delete - end.to change { @project.reload.has_external_wiki }.to(false) - end - - it 'does not change `has_external_wiki` when service is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - service = services.create!(type: 'ExternalWikiService', active: true, project_id: different_project.id) - - expect do - service.delete - end.not_to change { @project.reload.has_external_wiki } - end - end - end - - describe '#down' do - before do - migration.up - migration.down - end - - it 'drops the INSERT trigger' do - expect do - services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id) - end.not_to change { @project.reload.has_external_wiki } - end - - it 'drops the UPDATE trigger' do - service = services.create!(type: 'ExternalWikiService', active: false, project_id: @project.id) - @project.update!(has_external_wiki: false) - - expect do - service.update!(active: true) - end.not_to change { @project.reload.has_external_wiki } - end - - it 'drops the DELETE trigger' do - service = services.create!(type: 'ExternalWikiService', active: true, project_id: @project.id) - @project.update!(has_external_wiki: true) - - expect do - service.delete - end.not_to change { @project.reload.has_external_wiki } - end - end -end diff --git a/spec/migrations/add_new_post_eoa_plans_spec.rb b/spec/migrations/add_new_post_eoa_plans_spec.rb deleted file mode 100644 index 02360d5a12d..00000000000 --- a/spec/migrations/add_new_post_eoa_plans_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe AddNewPostEoaPlans do - let(:plans) { table(:plans) } - - subject(:migration) { described_class.new } - - describe '#up' do - it 'creates the two new records' do - expect { migration.up }.to change { plans.count }.by(2) - - new_plans = plans.last(2) - expect(new_plans.map(&:name)).to contain_exactly('premium', 'ultimate') - end - end - - describe '#down' do - it 'removes these two new records' do - plans.create!(name: 'premium', title: 'Premium (Formerly Silver)') - plans.create!(name: 'ultimate', title: 'Ultimate (Formerly Gold)') - - expect { migration.down }.to change { plans.count }.by(-2) - - expect(plans.find_by(name: 'premium')).to be_nil - expect(plans.find_by(name: 'ultimate')).to be_nil - end - end -end diff --git a/spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb b/spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb new file mode 100644 index 00000000000..abff7c6aba1 --- /dev/null +++ b/spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe CleanupAfterAddPrimaryEmailToEmailsIfUserConfirmed, :sidekiq do + let(:migration) { described_class.new } + let(:users) { table(:users) } + let(:emails) { table(:emails) } + + let!(:user_1) { users.create!(name: 'confirmed-user-1', email: 'confirmed-1@example.com', confirmed_at: 3.days.ago, projects_limit: 100) } + let!(:user_2) { users.create!(name: 'confirmed-user-2', email: 'confirmed-2@example.com', confirmed_at: 1.day.ago, projects_limit: 100) } + let!(:user_3) { users.create!(name: 'confirmed-user-3', email: 'confirmed-3@example.com', confirmed_at: 1.day.ago, projects_limit: 100) } + let!(:user_4) { users.create!(name: 'unconfirmed-user', email: 'unconfirmed@example.com', confirmed_at: nil, projects_limit: 100) } + + let!(:email_1) { emails.create!(email: 'confirmed-1@example.com', user_id: user_1.id, confirmed_at: 1.day.ago) } + let!(:email_2) { emails.create!(email: 'other_2@example.com', user_id: user_2.id, confirmed_at: 1.day.ago) } + + before do + stub_const("#{described_class.name}::BATCH_SIZE", 2) + end + + it 'consume any pending background migration job' do + expect_next_instance_of(Gitlab::BackgroundMigration::JobCoordinator) do |coordinator| + expect(coordinator).to receive(:steal).with('AddPrimaryEmailToEmailsIfUserConfirmed').twice + end + + migration.up + end + + it 'adds the primary email to emails for leftover confirmed users that do not have their primary email in the emails table', :aggregate_failures do + original_email_1_confirmed_at = email_1.reload.confirmed_at + + expect { migration.up }.to change { emails.count }.by(2) + + expect(emails.find_by(user_id: user_2.id, email: 'confirmed-2@example.com').confirmed_at).to eq(user_2.reload.confirmed_at) + expect(emails.find_by(user_id: user_3.id, email: 'confirmed-3@example.com').confirmed_at).to eq(user_3.reload.confirmed_at) + expect(email_1.reload.confirmed_at).to eq(original_email_1_confirmed_at) + + expect(emails.exists?(user_id: user_4.id)).to be(false) + end + + it 'continues in case of errors with one email' do + allow(Email).to receive(:create) { raise 'boom!' } + + expect { migration.up }.not_to raise_error + end +end diff --git a/spec/migrations/cleanup_projects_with_bad_has_external_issue_tracker_data_spec.rb b/spec/migrations/cleanup_projects_with_bad_has_external_issue_tracker_data_spec.rb deleted file mode 100644 index 8aedd1f9607..00000000000 --- a/spec/migrations/cleanup_projects_with_bad_has_external_issue_tracker_data_spec.rb +++ /dev/null @@ -1,94 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe CleanupProjectsWithBadHasExternalIssueTrackerData, :migration do - let(:namespace) { table(:namespaces).create!(name: 'foo', path: 'bar') } - let(:projects) { table(:projects) } - let(:services) { table(:services) } - - def create_projects!(num) - Array.new(num) do - projects.create!(namespace_id: namespace.id) - end - end - - def create_active_external_issue_tracker_integrations!(*projects) - projects.each do |project| - services.create!(category: 'issue_tracker', project_id: project.id, active: true) - end - end - - def create_disabled_external_issue_tracker_integrations!(*projects) - projects.each do |project| - services.create!(category: 'issue_tracker', project_id: project.id, active: false) - end - end - - def create_active_other_integrations!(*projects) - projects.each do |project| - services.create!(category: 'not_an_issue_tracker', project_id: project.id, active: true) - end - end - - it 'sets `projects.has_external_issue_tracker` correctly' do - allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false) - - project_with_an_external_issue_tracker_1, - project_with_an_external_issue_tracker_2, - project_with_only_a_disabled_external_issue_tracker_1, - project_with_only_a_disabled_external_issue_tracker_2, - project_without_any_external_issue_trackers_1, - project_without_any_external_issue_trackers_2 = create_projects!(6) - - create_active_external_issue_tracker_integrations!( - project_with_an_external_issue_tracker_1, - project_with_an_external_issue_tracker_2 - ) - - create_disabled_external_issue_tracker_integrations!( - project_with_an_external_issue_tracker_1, - project_with_an_external_issue_tracker_2, - project_with_only_a_disabled_external_issue_tracker_1, - project_with_only_a_disabled_external_issue_tracker_2 - ) - - create_active_other_integrations!( - project_with_an_external_issue_tracker_1, - project_with_an_external_issue_tracker_2, - project_without_any_external_issue_trackers_1, - project_without_any_external_issue_trackers_2 - ) - - # PG triggers on the services table added in - # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51852 will have set - # the `has_external_issue_tracker` columns to correct data when the services - # records were created above. - # - # We set the `has_external_issue_tracker` columns for projects to incorrect - # data manually below to emulate projects in a state before the PG - # triggers were added. - project_with_an_external_issue_tracker_2.update!(has_external_issue_tracker: false) - project_with_only_a_disabled_external_issue_tracker_2.update!(has_external_issue_tracker: true) - project_without_any_external_issue_trackers_2.update!(has_external_issue_tracker: true) - - migrate! - - expected_true = [ - project_with_an_external_issue_tracker_1, - project_with_an_external_issue_tracker_2 - ].each(&:reload).map(&:has_external_issue_tracker) - - expected_not_true = [ - project_without_any_external_issue_trackers_1, - project_without_any_external_issue_trackers_2, - project_with_only_a_disabled_external_issue_tracker_1, - project_with_only_a_disabled_external_issue_tracker_2 - ].each(&:reload).map(&:has_external_issue_tracker) - - expect(expected_true).to all(eq(true)) - expect(expected_not_true).to all(be_falsey) - end -end diff --git a/spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb b/spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb deleted file mode 100644 index ee1f718849f..00000000000 --- a/spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe CleanupProjectsWithBadHasExternalWikiData, :migration do - let(:namespace) { table(:namespaces).create!(name: 'foo', path: 'bar') } - let(:projects) { table(:projects) } - let(:services) { table(:services) } - - def create_projects!(num) - Array.new(num) do - projects.create!(namespace_id: namespace.id) - end - end - - def create_active_external_wiki_integrations!(*projects) - projects.each do |project| - services.create!(type: 'ExternalWikiService', project_id: project.id, active: true) - end - end - - def create_disabled_external_wiki_integrations!(*projects) - projects.each do |project| - services.create!(type: 'ExternalWikiService', project_id: project.id, active: false) - end - end - - def create_active_other_integrations!(*projects) - projects.each do |project| - services.create!(type: 'NotAnExternalWikiService', project_id: project.id, active: true) - end - end - - it 'sets `projects.has_external_wiki` correctly' do - allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false) - - project_with_external_wiki_1, - project_with_external_wiki_2, - project_with_disabled_external_wiki_1, - project_with_disabled_external_wiki_2, - project_without_external_wiki_1, - project_without_external_wiki_2 = create_projects!(6) - - create_active_external_wiki_integrations!( - project_with_external_wiki_1, - project_with_external_wiki_2 - ) - - create_disabled_external_wiki_integrations!( - project_with_disabled_external_wiki_1, - project_with_disabled_external_wiki_2 - ) - - create_active_other_integrations!( - project_without_external_wiki_1, - project_without_external_wiki_2 - ) - - # PG triggers on the services table added in a previous migration - # will have set the `has_external_wiki` columns to correct data when - # the services records were created above. - # - # We set the `has_external_wiki` columns for projects to incorrect - # data manually below to emulate projects in a state before the PG - # triggers were added. - project_with_external_wiki_2.update!(has_external_wiki: false) - project_with_disabled_external_wiki_2.update!(has_external_wiki: true) - project_without_external_wiki_2.update!(has_external_wiki: true) - - migrate! - - expected_true = [ - project_with_external_wiki_1, - project_with_external_wiki_2 - ].each(&:reload).map(&:has_external_wiki) - - expected_not_true = [ - project_without_external_wiki_1, - project_without_external_wiki_2, - project_with_disabled_external_wiki_1, - project_with_disabled_external_wiki_2 - ].each(&:reload).map(&:has_external_wiki) - - expect(expected_true).to all(eq(true)) - expect(expected_not_true).to all(be_falsey) - end -end diff --git a/spec/migrations/drop_alerts_service_data_spec.rb b/spec/migrations/drop_alerts_service_data_spec.rb deleted file mode 100644 index 06382132952..00000000000 --- a/spec/migrations/drop_alerts_service_data_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe DropAlertsServiceData do - let_it_be(:alerts_service_data) { table(:alerts_service_data) } - - it 'correctly migrates up and down' do - reversible_migration do |migration| - migration.before -> { - expect(alerts_service_data.create!(service_id: 1)).to be_a alerts_service_data - } - - migration.after -> { - expect { alerts_service_data.create!(service_id: 1) } - .to raise_error(ActiveRecord::StatementInvalid, /UndefinedTable/) - } - end - end -end diff --git a/spec/migrations/migrate_delayed_project_removal_from_namespaces_to_namespace_settings_spec.rb b/spec/migrations/migrate_delayed_project_removal_from_namespaces_to_namespace_settings_spec.rb deleted file mode 100644 index 0f45cc842ef..00000000000 --- a/spec/migrations/migrate_delayed_project_removal_from_namespaces_to_namespace_settings_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe MigrateDelayedProjectRemovalFromNamespacesToNamespaceSettings, :migration do - let(:namespaces) { table(:namespaces) } - let(:namespace_settings) { table(:namespace_settings) } - - let!(:namespace_wo_settings) { namespaces.create!(name: generate(:name), path: generate(:name), delayed_project_removal: true) } - let!(:namespace_wo_settings_delay_false) { namespaces.create!(name: generate(:name), path: generate(:name), delayed_project_removal: false) } - let!(:namespace_w_settings_delay_true) { namespaces.create!(name: generate(:name), path: generate(:name), delayed_project_removal: true) } - let!(:namespace_w_settings_delay_false) { namespaces.create!(name: generate(:name), path: generate(:name), delayed_project_removal: false) } - - let!(:namespace_settings_delay_true) { namespace_settings.create!(namespace_id: namespace_w_settings_delay_true.id, delayed_project_removal: false, created_at: DateTime.now, updated_at: DateTime.now) } - let!(:namespace_settings_delay_false) { namespace_settings.create!(namespace_id: namespace_w_settings_delay_false.id, delayed_project_removal: false, created_at: DateTime.now, updated_at: DateTime.now) } - - it 'migrates delayed_project_removal to namespace_settings' do - disable_migrations_output { migrate! } - - expect(namespace_settings.count).to eq(3) - - expect(namespace_settings.find_by(namespace_id: namespace_wo_settings.id).delayed_project_removal).to eq(true) - expect(namespace_settings.find_by(namespace_id: namespace_wo_settings_delay_false.id)).to be_nil - - expect(namespace_settings_delay_true.reload.delayed_project_removal).to eq(true) - expect(namespace_settings_delay_false.reload.delayed_project_removal).to eq(false) - end -end diff --git a/spec/migrations/remove_alerts_service_records_again_spec.rb b/spec/migrations/remove_alerts_service_records_again_spec.rb deleted file mode 100644 index 94d3e957b6a..00000000000 --- a/spec/migrations/remove_alerts_service_records_again_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe RemoveAlertsServiceRecordsAgain do - let(:services) { table(:services) } - - before do - 5.times { services.create!(type: 'AlertsService') } - services.create!(type: 'SomeOtherType') - end - - it 'removes services records of type AlertsService and corresponding data', :aggregate_failures do - expect(services.count).to eq(6) - - migrate! - - expect(services.count).to eq(1) - expect(services.first.type).to eq('SomeOtherType') - expect(services.where(type: 'AlertsService')).to be_empty - end -end diff --git a/spec/migrations/remove_alerts_service_records_spec.rb b/spec/migrations/remove_alerts_service_records_spec.rb deleted file mode 100644 index 83f440f8e17..00000000000 --- a/spec/migrations/remove_alerts_service_records_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe RemoveAlertsServiceRecords do - let(:services) { table(:services) } - let(:alerts_service_data) { table(:alerts_service_data) } - - before do - 5.times do - service = services.create!(type: 'AlertsService') - alerts_service_data.create!(service_id: service.id) - end - - services.create!(type: 'SomeOtherType') - end - - it 'removes services records of type AlertsService and corresponding data', :aggregate_failures do - expect(services.count).to eq(6) - expect(alerts_service_data.count).to eq(5) - - migrate! - - expect(services.count).to eq(1) - expect(services.first.type).to eq('SomeOtherType') - expect(services.where(type: 'AlertsService')).to be_empty - expect(alerts_service_data.all).to be_empty - end -end diff --git a/spec/migrations/reschedule_artifact_expiry_backfill_spec.rb b/spec/migrations/reschedule_artifact_expiry_backfill_spec.rb deleted file mode 100644 index c06ce3d5bea..00000000000 --- a/spec/migrations/reschedule_artifact_expiry_backfill_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe RescheduleArtifactExpiryBackfill, :migration do - let(:migration_class) { Gitlab::BackgroundMigration::BackfillArtifactExpiryDate } - let(:migration_name) { migration_class.to_s.demodulize } - - before do - table(:namespaces).create!(id: 123, name: 'test_namespace', path: 'test_namespace') - table(:projects).create!(id: 123, name: 'sample_project', path: 'sample_project', namespace_id: 123) - end - - it 'correctly schedules background migrations' do - first_artifact = create_artifact(job_id: 0, expire_at: nil, created_at: Date.new(2020, 06, 21)) - second_artifact = create_artifact(job_id: 1, expire_at: nil, created_at: Date.new(2020, 06, 21)) - create_artifact(job_id: 2, expire_at: Date.yesterday, created_at: Date.new(2020, 06, 21)) - create_artifact(job_id: 3, expire_at: nil, created_at: Date.new(2020, 06, 23)) - - Sidekiq::Testing.fake! do - freeze_time do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(1) - expect(migration_name).to be_scheduled_migration_with_multiple_args(first_artifact.id, second_artifact.id) - end - end - end - - private - - def create_artifact(params) - table(:ci_builds).create!(id: params[:job_id], project_id: 123) - table(:ci_job_artifacts).create!(project_id: 123, file_type: 1, **params) - end -end diff --git a/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb b/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb index 29e4cf05c2b..52bbd5b4f6e 100644 --- a/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb +++ b/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe ScheduleMigratePagesToZipStorage, :sidekiq_might_not_need_inline, schema: 20201231133921 do +RSpec.describe ScheduleMigratePagesToZipStorage, :sidekiq_might_not_need_inline, schema: 20210301200959 do let(:migration_class) { described_class::MIGRATION } let(:migration_name) { migration_class.to_s.demodulize } diff --git a/spec/migrations/schedule_populate_finding_uuid_for_vulnerability_feedback_spec.rb b/spec/migrations/schedule_populate_finding_uuid_for_vulnerability_feedback_spec.rb deleted file mode 100644 index d8bdefd5546..00000000000 --- a/spec/migrations/schedule_populate_finding_uuid_for_vulnerability_feedback_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe SchedulePopulateFindingUuidForVulnerabilityFeedback do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:users) { table(:users) } - let(:vulnerability_feedback) { table(:vulnerability_feedback) } - - let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') } - let(:project) { projects.create!(namespace_id: namespace.id, name: 'foo') } - let(:user) { users.create!(username: 'john.doe', projects_limit: 1) } - - let(:common_feedback_params) { { feedback_type: 0, category: 0, project_id: project.id, author_id: user.id } } - let!(:feedback_1) { vulnerability_feedback.create!(**common_feedback_params, project_fingerprint: 'foo') } - let!(:feedback_2) { vulnerability_feedback.create!(**common_feedback_params, project_fingerprint: 'bar') } - let!(:feedback_3) { vulnerability_feedback.create!(**common_feedback_params, project_fingerprint: 'zoo', finding_uuid: SecureRandom.uuid) } - - around do |example| - freeze_time { Sidekiq::Testing.fake! { example.run } } - end - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 1) - end - - it 'schedules the background jobs', :aggregate_failures do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to be(3) - expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(2.minutes, feedback_1.id, feedback_1.id) - expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(4.minutes, feedback_2.id, feedback_2.id) - expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(6.minutes, feedback_3.id, feedback_3.id) - end -end diff --git a/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences2_spec.rb b/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences2_spec.rb deleted file mode 100644 index e7d1813e428..00000000000 --- a/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences2_spec.rb +++ /dev/null @@ -1,127 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences2 do - let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } - let(:users) { table(:users) } - let(:user) { create_user! } - let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) } - let(:scanners) { table(:vulnerability_scanners) } - let(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') } - let(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') } - let(:vulnerabilities) { table(:vulnerabilities) } - let(:vulnerabilities_findings) { table(:vulnerability_occurrences) } - let(:vulnerability_identifiers) { table(:vulnerability_identifiers) } - let(:vulnerability_identifier) do - vulnerability_identifiers.create!( - project_id: project.id, - external_type: 'uuid-v5', - external_id: 'uuid-v5', - fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a', - name: 'Identifier for UUIDv5') - end - - let(:different_vulnerability_identifier) do - vulnerability_identifiers.create!( - project_id: project.id, - external_type: 'uuid-v4', - external_id: 'uuid-v4', - fingerprint: '772da93d34a1ba010bcb5efa9fb6f8e01bafcc89', - name: 'Identifier for UUIDv4') - end - - let(:vulnerability_for_uuidv4) do - create_vulnerability!( - project_id: project.id, - author_id: user.id - ) - end - - let(:vulnerability_for_uuidv5) do - create_vulnerability!( - project_id: project.id, - author_id: user.id - ) - end - - let!(:finding1) do - create_finding!( - vulnerability_id: vulnerability_for_uuidv4.id, - project_id: project.id, - scanner_id: different_scanner.id, - primary_identifier_id: different_vulnerability_identifier.id, - location_fingerprint: 'fa18f432f1d56675f4098d318739c3cd5b14eb3e', - uuid: 'b3cc2518-5446-4dea-871c-89d5e999c1ac' - ) - end - - let!(:finding2) do - create_finding!( - vulnerability_id: vulnerability_for_uuidv5.id, - project_id: project.id, - scanner_id: scanner.id, - primary_identifier_id: vulnerability_identifier.id, - location_fingerprint: '838574be0210968bf6b9f569df9c2576242cbf0a', - uuid: '77211ed6-7dff-5f6b-8c9a-da89ad0a9b60' - ) - end - - before do - stub_const("#{described_class}::BATCH_SIZE", 1) - end - - around do |example| - freeze_time { Sidekiq::Testing.fake! { example.run } } - end - - it 'schedules background migrations', :aggregate_failures do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, finding1.id, finding1.id) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, finding2.id, finding2.id) - end - - private - - def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0) - vulnerabilities.create!( - project_id: project_id, - author_id: author_id, - title: title, - severity: severity, - confidence: confidence, - report_type: report_type - ) - end - - def create_finding!( - vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, location_fingerprint:, uuid:) - vulnerabilities_findings.create!( - vulnerability_id: vulnerability_id, - project_id: project_id, - name: 'test', - severity: 7, - confidence: 7, - report_type: 0, - project_fingerprint: '123qweasdzxc', - scanner_id: scanner_id, - primary_identifier_id: primary_identifier_id, - location_fingerprint: location_fingerprint, - metadata_version: 'test', - raw_metadata: 'test', - uuid: uuid - ) - end - - def create_user!(name: "Example User", email: "user@example.com", user_type: nil) - users.create!( - name: name, - email: email, - username: name, - projects_limit: 0 - ) - end -end diff --git a/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb b/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb deleted file mode 100644 index 77f298b5ecb..00000000000 --- a/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb +++ /dev/null @@ -1,127 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 do - let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } - let(:users) { table(:users) } - let(:user) { create_user! } - let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) } - let(:scanners) { table(:vulnerability_scanners) } - let(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') } - let(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') } - let(:vulnerabilities) { table(:vulnerabilities) } - let(:vulnerabilities_findings) { table(:vulnerability_occurrences) } - let(:vulnerability_identifiers) { table(:vulnerability_identifiers) } - let(:vulnerability_identifier) do - vulnerability_identifiers.create!( - project_id: project.id, - external_type: 'uuid-v5', - external_id: 'uuid-v5', - fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a', - name: 'Identifier for UUIDv5') - end - - let(:different_vulnerability_identifier) do - vulnerability_identifiers.create!( - project_id: project.id, - external_type: 'uuid-v4', - external_id: 'uuid-v4', - fingerprint: '772da93d34a1ba010bcb5efa9fb6f8e01bafcc89', - name: 'Identifier for UUIDv4') - end - - let(:vulnerability_for_uuidv4) do - create_vulnerability!( - project_id: project.id, - author_id: user.id - ) - end - - let(:vulnerability_for_uuidv5) do - create_vulnerability!( - project_id: project.id, - author_id: user.id - ) - end - - let!(:finding1) do - create_finding!( - vulnerability_id: vulnerability_for_uuidv4.id, - project_id: project.id, - scanner_id: different_scanner.id, - primary_identifier_id: different_vulnerability_identifier.id, - location_fingerprint: 'fa18f432f1d56675f4098d318739c3cd5b14eb3e', - uuid: 'b3cc2518-5446-4dea-871c-89d5e999c1ac' - ) - end - - let!(:finding2) do - create_finding!( - vulnerability_id: vulnerability_for_uuidv5.id, - project_id: project.id, - scanner_id: scanner.id, - primary_identifier_id: vulnerability_identifier.id, - location_fingerprint: '838574be0210968bf6b9f569df9c2576242cbf0a', - uuid: '77211ed6-7dff-5f6b-8c9a-da89ad0a9b60' - ) - end - - before do - stub_const("#{described_class}::BATCH_SIZE", 1) - end - - around do |example| - freeze_time { Sidekiq::Testing.fake! { example.run } } - end - - it 'schedules background migrations', :aggregate_failures do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, finding1.id, finding1.id) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, finding2.id, finding2.id) - end - - private - - def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0) - vulnerabilities.create!( - project_id: project_id, - author_id: author_id, - title: title, - severity: severity, - confidence: confidence, - report_type: report_type - ) - end - - def create_finding!( - vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, location_fingerprint:, uuid:) - vulnerabilities_findings.create!( - vulnerability_id: vulnerability_id, - project_id: project_id, - name: 'test', - severity: 7, - confidence: 7, - report_type: 0, - project_fingerprint: '123qweasdzxc', - scanner_id: scanner_id, - primary_identifier_id: primary_identifier_id, - location_fingerprint: location_fingerprint, - metadata_version: 'test', - raw_metadata: 'test', - uuid: uuid - ) - end - - def create_user!(name: "Example User", email: "user@example.com", user_type: nil) - users.create!( - name: name, - email: email, - username: name, - projects_limit: 0 - ) - end -end diff --git a/spec/migrations/update_application_settings_protected_paths_spec.rb b/spec/migrations/update_application_settings_protected_paths_spec.rb new file mode 100644 index 00000000000..21879995f1b --- /dev/null +++ b/spec/migrations/update_application_settings_protected_paths_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe UpdateApplicationSettingsProtectedPaths, :aggregate_failures do + subject(:migration) { described_class.new } + + let_it_be(:application_settings) { table(:application_settings) } + let_it_be(:oauth_paths) { %w[/oauth/authorize /oauth/token] } + let_it_be(:custom_paths) { %w[/foo /bar] } + + let(:default_paths) { application_settings.column_defaults.fetch('protected_paths') } + + before do + application_settings.create!(protected_paths: custom_paths) + application_settings.create!(protected_paths: custom_paths + oauth_paths) + application_settings.create!(protected_paths: custom_paths + oauth_paths.take(1)) + end + + describe '#up' do + before do + migrate! + application_settings.reset_column_information + end + + it 'removes the OAuth paths from the default value and persisted records' do + expect(default_paths).not_to include(*oauth_paths) + expect(default_paths).to eq(described_class::NEW_DEFAULT_PROTECTED_PATHS) + expect(application_settings.all).to all(have_attributes(protected_paths: custom_paths)) + end + end + + describe '#down' do + before do + migrate! + schema_migrate_down! + end + + it 'adds the OAuth paths to the default value and persisted records' do + expect(default_paths).to include(*oauth_paths) + expect(default_paths).to eq(described_class::OLD_DEFAULT_PROTECTED_PATHS) + expect(application_settings.all).to all(have_attributes(protected_paths: custom_paths + oauth_paths)) + end + end +end diff --git a/spec/migrations/update_invalid_member_states_spec.rb b/spec/migrations/update_invalid_member_states_spec.rb new file mode 100644 index 00000000000..802634230a9 --- /dev/null +++ b/spec/migrations/update_invalid_member_states_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe UpdateInvalidMemberStates do + let(:members) { table(:members) } + let(:groups) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:users) { table(:users) } + + before do + user = users.create!(first_name: 'Test', last_name: 'User', email: 'test@user.com', projects_limit: 1) + group = groups.create!(name: 'gitlab', path: 'gitlab-org') + project = projects.create!(namespace_id: group.id) + + members.create!(state: 2, source_id: group.id, source_type: 'Group', type: 'GroupMember', user_id: user.id, access_level: 50, notification_level: 0) + members.create!(state: 2, source_id: project.id, source_type: 'Project', type: 'ProjectMember', user_id: user.id, access_level: 50, notification_level: 0) + members.create!(state: 1, source_id: group.id, source_type: 'Group', type: 'GroupMember', user_id: user.id, access_level: 50, notification_level: 0) + members.create!(state: 0, source_id: group.id, source_type: 'Group', type: 'GroupMember', user_id: user.id, access_level: 50, notification_level: 0) + end + + it 'updates matching member record states' do + expect { migrate! } + .to change { members.where(state: 0).count }.from(1).to(3) + .and change { members.where(state: 2).count }.from(2).to(0) + .and change { members.where(state: 1).count }.by(0) + end +end -- cgit v1.2.3