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>2021-05-19 18:44:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
commit4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch)
tree5423a1c7516cffe36384133ade12572cf709398d /spec/lib/gitlab/background_migration
parente570267f2f6b326480d284e0164a6464ba4081bc (diff)
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'spec/lib/gitlab/background_migration')
-rw-r--r--spec/lib/gitlab/background_migration/backfill_namespace_traversal_ids_children_spec.rb21
-rw-r--r--spec/lib/gitlab/background_migration/backfill_namespace_traversal_ids_roots_spec.rb21
-rw-r--r--spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb73
-rw-r--r--spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb126
-rw-r--r--spec/lib/gitlab/background_migration/migrate_project_taggings_context_from_tags_to_topics_spec.rb29
-rw-r--r--spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb12
-rw-r--r--spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb241
-rw-r--r--spec/lib/gitlab/background_migration/update_timelogs_project_id_spec.rb52
8 files changed, 321 insertions, 254 deletions
diff --git a/spec/lib/gitlab/background_migration/backfill_namespace_traversal_ids_children_spec.rb b/spec/lib/gitlab/background_migration/backfill_namespace_traversal_ids_children_spec.rb
new file mode 100644
index 00000000000..35928deff82
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_namespace_traversal_ids_children_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceTraversalIdsChildren, :migration, schema: 20210506065000 do
+ let(:namespaces_table) { table(:namespaces) }
+
+ let!(:user_namespace) { namespaces_table.create!(id: 1, name: 'user', path: 'user', type: nil) }
+ let!(:root_group) { namespaces_table.create!(id: 2, name: 'group', path: 'group', type: 'Group', parent_id: nil) }
+ let!(:sub_group) { namespaces_table.create!(id: 3, name: 'subgroup', path: 'subgroup', type: 'Group', parent_id: 2) }
+
+ describe '#perform' do
+ it 'backfills traversal_ids for child namespaces' do
+ described_class.new.perform(1, 3, 5)
+
+ expect(user_namespace.reload.traversal_ids).to eq([])
+ expect(root_group.reload.traversal_ids).to eq([])
+ expect(sub_group.reload.traversal_ids).to eq([root_group.id, sub_group.id])
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_namespace_traversal_ids_roots_spec.rb b/spec/lib/gitlab/background_migration/backfill_namespace_traversal_ids_roots_spec.rb
new file mode 100644
index 00000000000..96e43275972
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_namespace_traversal_ids_roots_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceTraversalIdsRoots, :migration, schema: 20210506065000 do
+ let(:namespaces_table) { table(:namespaces) }
+
+ let!(:user_namespace) { namespaces_table.create!(id: 1, name: 'user', path: 'user', type: nil) }
+ let!(:root_group) { namespaces_table.create!(id: 2, name: 'group', path: 'group', type: 'Group', parent_id: nil) }
+ let!(:sub_group) { namespaces_table.create!(id: 3, name: 'subgroup', path: 'subgroup', type: 'Group', parent_id: 2) }
+
+ describe '#perform' do
+ it 'backfills traversal_ids for root namespaces' do
+ described_class.new.perform(1, 3, 5)
+
+ expect(user_namespace.reload.traversal_ids).to eq([user_namespace.id])
+ expect(root_group.reload.traversal_ids).to eq([root_group.id])
+ expect(sub_group.reload.traversal_ids).to eq([])
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb b/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb
index c4c0247ad3e..3e378db04d4 100644
--- a/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb
+++ b/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb
@@ -6,6 +6,11 @@ RSpec.describe Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJo
let(:table_name) { :copy_primary_key_test }
let(:test_table) { table(table_name) }
let(:sub_batch_size) { 1000 }
+ let(:pause_ms) { 0 }
+
+ let(:helpers) do
+ ActiveRecord::Migration.new.extend(Gitlab::Database::MigrationHelpers)
+ end
before do
ActiveRecord::Base.connection.execute(<<~SQL)
@@ -14,8 +19,8 @@ RSpec.describe Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJo
id integer NOT NULL,
name character varying,
fk integer NOT NULL,
- id_convert_to_bigint bigint DEFAULT 0 NOT NULL,
- fk_convert_to_bigint bigint DEFAULT 0 NOT NULL,
+ #{helpers.convert_to_bigint_column(:id)} bigint DEFAULT 0 NOT NULL,
+ #{helpers.convert_to_bigint_column(:fk)} bigint DEFAULT 0 NOT NULL,
name_convert_to_text text DEFAULT 'no name'
);
SQL
@@ -34,43 +39,85 @@ RSpec.describe Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJo
SQL
end
- subject { described_class.new }
+ subject(:copy_columns) { described_class.new }
describe '#perform' do
let(:migration_class) { described_class.name }
it 'copies all primary keys in range' do
- subject.perform(12, 15, table_name, 'id', sub_batch_size, 'id', 'id_convert_to_bigint')
+ temporary_column = helpers.convert_to_bigint_column(:id)
+ copy_columns.perform(12, 15, table_name, 'id', sub_batch_size, pause_ms, 'id', temporary_column)
- expect(test_table.where('id = id_convert_to_bigint').pluck(:id)).to contain_exactly(12, 15)
- expect(test_table.where(id_convert_to_bigint: 0).pluck(:id)).to contain_exactly(11, 19)
+ expect(test_table.where("id = #{temporary_column}").pluck(:id)).to contain_exactly(12, 15)
+ expect(test_table.where(temporary_column => 0).pluck(:id)).to contain_exactly(11, 19)
expect(test_table.all.count).to eq(4)
end
it 'copies all foreign keys in range' do
- subject.perform(10, 14, table_name, 'id', sub_batch_size, 'fk', 'fk_convert_to_bigint')
+ temporary_column = helpers.convert_to_bigint_column(:fk)
+ copy_columns.perform(10, 14, table_name, 'id', sub_batch_size, pause_ms, 'fk', temporary_column)
- expect(test_table.where('fk = fk_convert_to_bigint').pluck(:id)).to contain_exactly(11, 12)
- expect(test_table.where(fk_convert_to_bigint: 0).pluck(:id)).to contain_exactly(15, 19)
+ expect(test_table.where("fk = #{temporary_column}").pluck(:id)).to contain_exactly(11, 12)
+ expect(test_table.where(temporary_column => 0).pluck(:id)).to contain_exactly(15, 19)
expect(test_table.all.count).to eq(4)
end
it 'copies columns with NULLs' do
expect(test_table.where("name_convert_to_text = 'no name'").count).to eq(4)
- subject.perform(10, 20, table_name, 'id', sub_batch_size, 'name', 'name_convert_to_text')
+ copy_columns.perform(10, 20, table_name, 'id', sub_batch_size, pause_ms, 'name', 'name_convert_to_text')
expect(test_table.where('name = name_convert_to_text').pluck(:id)).to contain_exactly(11, 12, 19)
expect(test_table.where('name is NULL and name_convert_to_text is NULL').pluck(:id)).to contain_exactly(15)
expect(test_table.where("name_convert_to_text = 'no name'").count).to eq(0)
end
+ it 'copies multiple columns when given' do
+ columns_to_copy_from = %w[id fk]
+ id_tmp_column = helpers.convert_to_bigint_column('id')
+ fk_tmp_column = helpers.convert_to_bigint_column('fk')
+ columns_to_copy_to = [id_tmp_column, fk_tmp_column]
+
+ subject.perform(10, 15, table_name, 'id', sub_batch_size, pause_ms, columns_to_copy_from, columns_to_copy_to)
+
+ expect(test_table.where("id = #{id_tmp_column} AND fk = #{fk_tmp_column}").pluck(:id)).to contain_exactly(11, 12, 15)
+ expect(test_table.where(id_tmp_column => 0).where(fk_tmp_column => 0).pluck(:id)).to contain_exactly(19)
+ expect(test_table.all.count).to eq(4)
+ end
+
+ it 'raises error when number of source and target columns does not match' do
+ columns_to_copy_from = %w[id fk]
+ columns_to_copy_to = [helpers.convert_to_bigint_column(:id)]
+
+ expect do
+ subject.perform(10, 15, table_name, 'id', sub_batch_size, pause_ms, columns_to_copy_from, columns_to_copy_to)
+ end.to raise_error(ArgumentError, 'number of source and destination columns must match')
+ end
+
it 'tracks timings of queries' do
- expect(subject.batch_metrics.timings).to be_empty
+ expect(copy_columns.batch_metrics.timings).to be_empty
+
+ copy_columns.perform(10, 20, table_name, 'id', sub_batch_size, pause_ms, 'name', 'name_convert_to_text')
+
+ expect(copy_columns.batch_metrics.timings[:update_all]).not_to be_empty
+ end
+
+ context 'pause interval between sub-batches' do
+ it 'sleeps for the specified time between sub-batches' do
+ sub_batch_size = 2
+
+ expect(copy_columns).to receive(:sleep).with(0.005)
+
+ copy_columns.perform(10, 12, table_name, 'id', sub_batch_size, 5, 'name', 'name_convert_to_text')
+ end
+
+ it 'treats negative values as 0' do
+ sub_batch_size = 2
- subject.perform(10, 20, table_name, 'id', sub_batch_size, 'name', 'name_convert_to_text')
+ expect(copy_columns).to receive(:sleep).with(0)
- expect(subject.batch_metrics.timings[:update_all]).not_to be_empty
+ copy_columns.perform(10, 12, table_name, 'id', sub_batch_size, -5, 'name', 'name_convert_to_text')
+ end
end
end
end
diff --git a/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb
new file mode 100644
index 00000000000..c4beb719e1e
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb
@@ -0,0 +1,126 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema: 20201110110454 do
+ let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
+ let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let_it_be(:users) { table(:users) }
+ let_it_be(:user) { create_user! }
+ let_it_be(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+
+ let_it_be(:scanners) { table(:vulnerability_scanners) }
+ let_it_be(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+ let_it_be(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
+
+ let_it_be(:vulnerabilities) { table(:vulnerabilities) }
+ let_it_be(:vulnerability_with_finding) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let_it_be(:vulnerability_without_finding) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let_it_be(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
+ let_it_be(:primary_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_it_be(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+ let_it_be(:finding) do
+ create_finding!(
+ vulnerability_id: vulnerability_with_finding.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: primary_identifier.id
+ )
+ end
+
+ let(:succeeded_status) { 1 }
+ let(:pending_status) { 0 }
+
+ it 'drops Vulnerabilities without any Findings' do
+ expect(vulnerabilities.pluck(:id)).to eq([vulnerability_with_finding.id, vulnerability_without_finding.id])
+
+ expect { subject.perform(vulnerability_with_finding.id, vulnerability_without_finding.id) }.to change(vulnerabilities, :count).by(-1)
+
+ expect(vulnerabilities.pluck(:id)).to eq([vulnerability_with_finding.id])
+ end
+
+ it 'marks jobs as done' do
+ background_migration_jobs.create!(
+ class_name: 'DropInvalidVulnerabilities',
+ arguments: [vulnerability_with_finding.id, vulnerability_with_finding.id]
+ )
+
+ background_migration_jobs.create!(
+ class_name: 'DropInvalidVulnerabilities',
+ arguments: [vulnerability_without_finding.id, vulnerability_without_finding.id]
+ )
+
+ subject.perform(vulnerability_with_finding.id, vulnerability_with_finding.id)
+
+ expect(background_migration_jobs.first.status).to eq(succeeded_status)
+ expect(background_migration_jobs.second.status).to eq(pending_status)
+ 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
+
+ # rubocop:disable Metrics/ParameterLists
+ def create_finding!(
+ vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:,
+ name: "test", severity: 7, confidence: 7, report_type: 0,
+ project_fingerprint: '123qweasdzxc', location_fingerprint: 'test',
+ metadata_version: 'test', raw_metadata: 'test', uuid: 'test')
+ vulnerabilities_findings.create!(
+ vulnerability_id: vulnerability_id,
+ project_id: project_id,
+ name: name,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type,
+ project_fingerprint: project_fingerprint,
+ scanner_id: scanner_id,
+ primary_identifier_id: primary_identifier_id,
+ location_fingerprint: location_fingerprint,
+ metadata_version: metadata_version,
+ raw_metadata: raw_metadata,
+ uuid: uuid
+ )
+ end
+ # rubocop:enable Metrics/ParameterLists
+
+ def create_user!(name: "Example User", email: "user@example.com", user_type: nil)
+ users.create!(
+ name: name,
+ email: email,
+ username: name,
+ projects_limit: 0,
+ user_type: user_type,
+ confirmed_at: Time.current
+ )
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/migrate_project_taggings_context_from_tags_to_topics_spec.rb b/spec/lib/gitlab/background_migration/migrate_project_taggings_context_from_tags_to_topics_spec.rb
new file mode 100644
index 00000000000..5e2f32c54be
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/migrate_project_taggings_context_from_tags_to_topics_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::MigrateProjectTaggingsContextFromTagsToTopics, schema: 20210511095658 do
+ it 'correctly migrates project taggings context from tags to topics' do
+ taggings = table(:taggings)
+
+ project_old_tagging_1 = taggings.create!(taggable_type: 'Project', context: 'tags')
+ project_new_tagging_1 = taggings.create!(taggable_type: 'Project', context: 'topics')
+ project_other_context_tagging_1 = taggings.create!(taggable_type: 'Project', context: 'other')
+ project_old_tagging_2 = taggings.create!(taggable_type: 'Project', context: 'tags')
+ project_old_tagging_3 = taggings.create!(taggable_type: 'Project', context: 'tags')
+
+ subject.perform(project_old_tagging_1.id, project_old_tagging_2.id)
+
+ project_old_tagging_1.reload
+ project_new_tagging_1.reload
+ project_other_context_tagging_1.reload
+ project_old_tagging_2.reload
+ project_old_tagging_3.reload
+
+ expect(project_old_tagging_1.context).to eq('topics')
+ expect(project_new_tagging_1.context).to eq('topics')
+ expect(project_other_context_tagging_1.context).to eq('other')
+ expect(project_old_tagging_2.context).to eq('topics')
+ expect(project_old_tagging_3.context).to eq('tags')
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb b/spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb
index 1c62d703a34..b34a57f51f1 100644
--- a/spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb
+++ b/spec/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature_spec.rb
@@ -31,6 +31,15 @@ RSpec.describe Gitlab::BackgroundMigration::MoveContainerRegistryEnabledToProjec
end
it 'copies values to project_features' do
+ table(:background_migration_jobs).create!(
+ class_name: 'MoveContainerRegistryEnabledToProjectFeature',
+ arguments: [project1.id, project4.id]
+ )
+ table(:background_migration_jobs).create!(
+ class_name: 'MoveContainerRegistryEnabledToProjectFeature',
+ arguments: [-1, -3]
+ )
+
expect(project1.container_registry_enabled).to eq(true)
expect(project2.container_registry_enabled).to eq(false)
expect(project3.container_registry_enabled).to eq(nil)
@@ -57,6 +66,9 @@ RSpec.describe Gitlab::BackgroundMigration::MoveContainerRegistryEnabledToProjec
expect(project_feature1.reload.container_registry_access_level).to eq(enabled)
expect(project_feature2.reload.container_registry_access_level).to eq(disabled)
expect(project_feature3.reload.container_registry_access_level).to eq(disabled)
+
+ expect(table(:background_migration_jobs).first.status).to eq(1) # succeeded
+ expect(table(:background_migration_jobs).second.status).to eq(0) # pending
end
context 'when no projects exist in range' do
diff --git a/spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb b/spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb
deleted file mode 100644
index 1c55b50ea3f..00000000000
--- a/spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb
+++ /dev/null
@@ -1,241 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::RecalculateProjectAuthorizations, schema: 20200204113223 do
- let(:users_table) { table(:users) }
- let(:namespaces_table) { table(:namespaces) }
- let(:projects_table) { table(:projects) }
- let(:project_authorizations_table) { table(:project_authorizations) }
- let(:members_table) { table(:members) }
- let(:group_group_links) { table(:group_group_links) }
- let(:project_group_links) { table(:project_group_links) }
-
- let(:user) { users_table.create!(id: 1, email: 'user@example.com', projects_limit: 10) }
- let(:group) { namespaces_table.create!(type: 'Group', name: 'group', path: 'group') }
-
- subject { described_class.new.perform([user.id]) }
-
- context 'missing authorization' do
- context 'personal project' do
- before do
- user_namespace = namespaces_table.create!(owner_id: user.id, name: 'User', path: 'user')
- projects_table.create!(id: 1,
- name: 'personal-project',
- path: 'personal-project',
- visibility_level: 0,
- namespace_id: user_namespace.id)
- end
-
- it 'creates correct authorization' do
- expect { subject }.to change { project_authorizations_table.count }.from(0).to(1)
- expect(project_authorizations_table.all).to(
- match_array([have_attributes(user_id: 1, project_id: 1, access_level: 40)]))
- end
- end
-
- context 'group membership' do
- before do
- projects_table.create!(id: 1, name: 'group-project', path: 'group-project',
- visibility_level: 0, namespace_id: group.id)
- members_table.create!(user_id: user.id, source_id: group.id, source_type: 'Namespace',
- type: 'GroupMember', access_level: 20, notification_level: 3)
- end
-
- it 'creates correct authorization' do
- expect { subject }.to change { project_authorizations_table.count }.from(0).to(1)
- expect(project_authorizations_table.all).to(
- match_array([have_attributes(user_id: 1, project_id: 1, access_level: 20)]))
- end
- end
-
- context 'inherited group membership' do
- before do
- sub_group = namespaces_table.create!(type: 'Group', name: 'subgroup',
- path: 'subgroup', parent_id: group.id)
- projects_table.create!(id: 1, name: 'group-project', path: 'group-project',
- visibility_level: 0, namespace_id: sub_group.id)
- members_table.create!(user_id: user.id, source_id: group.id, source_type: 'Namespace',
- type: 'GroupMember', access_level: 20, notification_level: 3)
- end
-
- it 'creates correct authorization' do
- expect { subject }.to change { project_authorizations_table.count }.from(0).to(1)
- expect(project_authorizations_table.all).to(
- match_array([have_attributes(user_id: 1, project_id: 1, access_level: 20)]))
- end
- end
-
- context 'project membership' do
- before do
- project = projects_table.create!(id: 1, name: 'group-project', path: 'group-project',
- visibility_level: 0, namespace_id: group.id)
- members_table.create!(user_id: user.id, source_id: project.id, source_type: 'Project',
- type: 'ProjectMember', access_level: 20, notification_level: 3)
- end
-
- it 'creates correct authorization' do
- expect { subject }.to change { project_authorizations_table.count }.from(0).to(1)
- expect(project_authorizations_table.all).to(
- match_array([have_attributes(user_id: 1, project_id: 1, access_level: 20)]))
- end
- end
-
- context 'shared group' do
- before do
- members_table.create!(user_id: user.id, source_id: group.id, source_type: 'Namespace',
- type: 'GroupMember', access_level: 30, notification_level: 3)
-
- shared_group = namespaces_table.create!(type: 'Group', name: 'shared group',
- path: 'shared-group')
- projects_table.create!(id: 1, name: 'project', path: 'project', visibility_level: 0,
- namespace_id: shared_group.id)
-
- group_group_links.create!(shared_group_id: shared_group.id, shared_with_group_id: group.id,
- group_access: 20)
- end
-
- it 'creates correct authorization' do
- expect { subject }.to change { project_authorizations_table.count }.from(0).to(1)
- expect(project_authorizations_table.all).to(
- match_array([have_attributes(user_id: 1, project_id: 1, access_level: 20)]))
- end
- end
-
- context 'shared project' do
- before do
- members_table.create!(user_id: user.id, source_id: group.id, source_type: 'Namespace',
- type: 'GroupMember', access_level: 30, notification_level: 3)
-
- another_group = namespaces_table.create!(type: 'Group', name: 'another group', path: 'another-group')
- shared_project = projects_table.create!(id: 1, name: 'shared project', path: 'shared-project',
- visibility_level: 0, namespace_id: another_group.id)
-
- project_group_links.create!(project_id: shared_project.id, group_id: group.id, group_access: 20)
- end
-
- it 'creates correct authorization' do
- expect { subject }.to change { project_authorizations_table.count }.from(0).to(1)
- expect(project_authorizations_table.all).to(
- match_array([have_attributes(user_id: 1, project_id: 1, access_level: 20)]))
- end
- end
- end
-
- context 'unapproved access requests' do
- context 'group membership' do
- before do
- projects_table.create!(id: 1, name: 'group-project', path: 'group-project',
- visibility_level: 0, namespace_id: group.id)
- members_table.create!(user_id: user.id, source_id: group.id, source_type: 'Namespace',
- type: 'GroupMember', access_level: 20, requested_at: Time.now, notification_level: 3)
- end
-
- it 'does not create authorization' do
- expect { subject }.not_to change { project_authorizations_table.count }.from(0)
- end
- end
-
- context 'inherited group membership' do
- before do
- sub_group = namespaces_table.create!(type: 'Group', name: 'subgroup', path: 'subgroup',
- parent_id: group.id)
- projects_table.create!(id: 1, name: 'group-project', path: 'group-project',
- visibility_level: 0, namespace_id: sub_group.id)
- members_table.create!(user_id: user.id, source_id: group.id, source_type: 'Namespace',
- type: 'GroupMember', access_level: 20, requested_at: Time.now, notification_level: 3)
- end
-
- it 'does not create authorization' do
- expect { subject }.not_to change { project_authorizations_table.count }.from(0)
- end
- end
-
- context 'project membership' do
- before do
- project = projects_table.create!(id: 1, name: 'group-project', path: 'group-project',
- visibility_level: 0, namespace_id: group.id)
- members_table.create!(user_id: user.id, source_id: project.id, source_type: 'Project',
- type: 'ProjectMember', access_level: 20, requested_at: Time.now, notification_level: 3)
- end
-
- it 'does not create authorization' do
- expect { subject }.not_to change { project_authorizations_table.count }.from(0)
- end
- end
-
- context 'shared group' do
- before do
- members_table.create!(user_id: user.id, source_id: group.id, source_type: 'Namespace',
- type: 'GroupMember', access_level: 30, requested_at: Time.now, notification_level: 3)
-
- shared_group = namespaces_table.create!(type: 'Group', name: 'shared group',
- path: 'shared-group')
- projects_table.create!(id: 1, name: 'project', path: 'project', visibility_level: 0,
- namespace_id: shared_group.id)
-
- group_group_links.create!(shared_group_id: shared_group.id, shared_with_group_id: group.id,
- group_access: 20)
- end
-
- it 'does not create authorization' do
- expect { subject }.not_to change { project_authorizations_table.count }.from(0)
- end
- end
-
- context 'shared project' do
- before do
- members_table.create!(user_id: user.id, source_id: group.id, source_type: 'Namespace',
- type: 'GroupMember', access_level: 30, requested_at: Time.now, notification_level: 3)
-
- another_group = namespaces_table.create!(type: 'Group', name: 'another group', path: 'another-group')
- shared_project = projects_table.create!(id: 1, name: 'shared project', path: 'shared-project',
- visibility_level: 0, namespace_id: another_group.id)
-
- project_group_links.create!(project_id: shared_project.id, group_id: group.id, group_access: 20)
- end
-
- it 'does not create authorization' do
- expect { subject }.not_to change { project_authorizations_table.count }.from(0)
- end
- end
- end
-
- context 'incorrect authorization' do
- before do
- project = projects_table.create!(id: 1, name: 'group-project', path: 'group-project',
- visibility_level: 0, namespace_id: group.id)
- members_table.create!(user_id: user.id, source_id: group.id, source_type: 'Namespace',
- type: 'GroupMember', access_level: 30, notification_level: 3)
-
- project_authorizations_table.create!(user_id: user.id, project_id: project.id,
- access_level: 10)
- end
-
- it 'fixes authorization' do
- expect { subject }.not_to change { project_authorizations_table.count }.from(1)
- expect(project_authorizations_table.all).to(
- match_array([have_attributes(user_id: 1, project_id: 1, access_level: 30)]))
- end
- end
-
- context 'unwanted authorization' do
- before do
- project = projects_table.create!(name: 'group-project', path: 'group-project',
- visibility_level: 0, namespace_id: group.id)
-
- project_authorizations_table.create!(user_id: user.id, project_id: project.id,
- access_level: 10)
- end
-
- it 'deletes authorization' do
- expect { subject }.to change { project_authorizations_table.count }.from(1).to(0)
- end
- end
-
- context 'deleted user' do
- it 'does not fail' do
- expect { described_class.new.perform([non_existing_record_id]) }.not_to raise_error
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/update_timelogs_project_id_spec.rb b/spec/lib/gitlab/background_migration/update_timelogs_project_id_spec.rb
new file mode 100644
index 00000000000..fc4d776b8be
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/update_timelogs_project_id_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::UpdateTimelogsProjectId, schema: 20210427212034 do
+ let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') }
+ let!(:project1) { table(:projects).create!(namespace_id: namespace.id) }
+ let!(:project2) { table(:projects).create!(namespace_id: namespace.id) }
+ let!(:issue1) { table(:issues).create!(project_id: project1.id) }
+ let!(:issue2) { table(:issues).create!(project_id: project2.id) }
+ let!(:merge_request1) { table(:merge_requests).create!(target_project_id: project1.id, source_branch: 'master', target_branch: 'feature') }
+ let!(:merge_request2) { table(:merge_requests).create!(target_project_id: project2.id, source_branch: 'master', target_branch: 'feature') }
+ let!(:timelog1) { table(:timelogs).create!(issue_id: issue1.id, time_spent: 60) }
+ let!(:timelog2) { table(:timelogs).create!(issue_id: issue1.id, time_spent: 60) }
+ let!(:timelog3) { table(:timelogs).create!(issue_id: issue2.id, time_spent: 60) }
+ let!(:timelog4) { table(:timelogs).create!(merge_request_id: merge_request1.id, time_spent: 600) }
+ let!(:timelog5) { table(:timelogs).create!(merge_request_id: merge_request1.id, time_spent: 600) }
+ let!(:timelog6) { table(:timelogs).create!(merge_request_id: merge_request2.id, time_spent: 600) }
+ let!(:timelog7) { table(:timelogs).create!(issue_id: issue2.id, time_spent: 60, project_id: project1.id) }
+ let!(:timelog8) { table(:timelogs).create!(merge_request_id: merge_request2.id, time_spent: 600, project_id: project1.id) }
+
+ describe '#perform' do
+ context 'when timelogs belong to issues' do
+ it 'sets correct project_id' do
+ subject.perform(timelog1.id, timelog3.id)
+
+ expect(timelog1.reload.project_id).to eq(issue1.project_id)
+ expect(timelog2.reload.project_id).to eq(issue1.project_id)
+ expect(timelog3.reload.project_id).to eq(issue2.project_id)
+ end
+ end
+
+ context 'when timelogs belong to merge requests' do
+ it 'sets correct project ids' do
+ subject.perform(timelog4.id, timelog6.id)
+
+ expect(timelog4.reload.project_id).to eq(merge_request1.target_project_id)
+ expect(timelog5.reload.project_id).to eq(merge_request1.target_project_id)
+ expect(timelog6.reload.project_id).to eq(merge_request2.target_project_id)
+ end
+ end
+
+ context 'when timelogs already belong to projects' do
+ it 'does not update the project id' do
+ subject.perform(timelog7.id, timelog8.id)
+
+ expect(timelog7.reload.project_id).to eq(project1.id)
+ expect(timelog8.reload.project_id).to eq(project1.id)
+ end
+ end
+ end
+end