Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-01-20 12:16:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-01-20 12:16:11 +0300
commitedaa33dee2ff2f7ea3fac488d41558eb5f86d68c (patch)
tree11f143effbfeba52329fb7afbd05e6e2a3790241 /spec/migrations
parentd8a5691316400a0f7ec4f83832698f1988eb27c1 (diff)
Add latest changes from gitlab-org/gitlab@14-7-stable-eev14.7.0-rc42
Diffstat (limited to 'spec/migrations')
-rw-r--r--spec/migrations/20210112143418_remove_duplicate_services2_spec.rb52
-rw-r--r--spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb30
-rw-r--r--spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb28
-rw-r--r--spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb47
-rw-r--r--spec/migrations/20210218040814_add_environment_scope_to_group_variables_spec.rb46
-rw-r--r--spec/migrations/20210226141517_dedup_issue_metrics_spec.rb66
-rw-r--r--spec/migrations/20210918202855_reschedule_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb30
-rw-r--r--spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb44
-rw-r--r--spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb (renamed from spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb)55
-rw-r--r--spec/migrations/20211210140629_encrypt_static_object_token_spec.rb50
-rw-r--r--spec/migrations/20211214012507_backfill_incident_issue_escalation_statuses_spec.rb36
-rw-r--r--spec/migrations/20211217174331_mark_recalculate_finding_signatures_as_completed_spec.rb64
-rw-r--r--spec/migrations/add_has_external_issue_tracker_trigger_spec.rb164
-rw-r--r--spec/migrations/add_has_external_wiki_trigger_spec.rb128
-rw-r--r--spec/migrations/add_new_post_eoa_plans_spec.rb32
-rw-r--r--spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb48
-rw-r--r--spec/migrations/cleanup_projects_with_bad_has_external_issue_tracker_data_spec.rb94
-rw-r--r--spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb89
-rw-r--r--spec/migrations/drop_alerts_service_data_spec.rb21
-rw-r--r--spec/migrations/migrate_delayed_project_removal_from_namespaces_to_namespace_settings_spec.rb30
-rw-r--r--spec/migrations/remove_alerts_service_records_again_spec.rb23
-rw-r--r--spec/migrations/remove_alerts_service_records_spec.rb30
-rw-r--r--spec/migrations/reschedule_artifact_expiry_backfill_spec.rb38
-rw-r--r--spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb2
-rw-r--r--spec/migrations/schedule_populate_finding_uuid_for_vulnerability_feedback_spec.rb37
-rw-r--r--spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences2_spec.rb127
-rw-r--r--spec/migrations/update_application_settings_protected_paths_spec.rb46
-rw-r--r--spec/migrations/update_invalid_member_states_spec.rb30
28 files changed, 357 insertions, 1130 deletions
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/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb b/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb
index 77f298b5ecb..71ffcafaae1 100644
--- a/spec/migrations/schedule_recalculate_uuid_on_vulnerabilities_occurrences3_spec.rb
+++ b/spec/migrations/20211207135331_schedule_recalculate_uuid_on_vulnerabilities_occurrences4_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 do
+RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences4 do
let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
let(:users) { table(:users) }
let(:user) { create_user! }
@@ -13,6 +13,7 @@ RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 do
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!(
@@ -32,6 +33,17 @@ RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 do
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,
@@ -39,6 +51,17 @@ RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 do
)
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,
@@ -46,25 +69,22 @@ RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 do
)
end
- let!(:finding1) do
- create_finding!(
- vulnerability_id: vulnerability_for_uuidv4.id,
+ let(:vulnerability_for_finding_with_signature) do
+ create_vulnerability!(
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'
+ author_id: user.id
)
end
- let!(:finding2) do
+ let!(:finding_with_signature) do
create_finding!(
- vulnerability_id: vulnerability_for_uuidv5.id,
+ vulnerability_id: vulnerability_for_finding_with_signature.id,
project_id: project.id,
scanner_id: scanner.id,
primary_identifier_id: vulnerability_identifier.id,
- location_fingerprint: '838574be0210968bf6b9f569df9c2576242cbf0a',
- uuid: '77211ed6-7dff-5f6b-8c9a-da89ad0a9b60'
+ report_type: 0, # "sast"
+ location_fingerprint: Gitlab::Database::ShaAttribute.serialize('123609eafffffa2207a9ca2425ba4337h34fga1b'),
+ uuid: '252aa474-d689-5d2b-ab42-7bbb5a100c02'
)
end
@@ -79,9 +99,10 @@ RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 do
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)
+ 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
@@ -98,14 +119,14 @@ RSpec.describe ScheduleRecalculateUuidOnVulnerabilitiesOccurrences3 do
end
def create_finding!(
- vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, location_fingerprint:, uuid:)
+ 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: 0,
+ report_type: report_type,
project_fingerprint: '123qweasdzxc',
scanner_id: scanner_id,
primary_identifier_id: primary_identifier_id,
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/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