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:
Diffstat (limited to 'spec/migrations/20231207145335_cleanup_group_level_work_items_spec.rb')
-rw-r--r--spec/migrations/20231207145335_cleanup_group_level_work_items_spec.rb216
1 files changed, 216 insertions, 0 deletions
diff --git a/spec/migrations/20231207145335_cleanup_group_level_work_items_spec.rb b/spec/migrations/20231207145335_cleanup_group_level_work_items_spec.rb
new file mode 100644
index 00000000000..a6b547b091a
--- /dev/null
+++ b/spec/migrations/20231207145335_cleanup_group_level_work_items_spec.rb
@@ -0,0 +1,216 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe CleanupGroupLevelWorkItems, feature_category: :team_planning do
+ include MigrationHelpers::WorkItemTypesHelper
+
+ let(:users) { table(:users) }
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+ let(:issues) { table(:issues) }
+ let(:notes) { table(:notes) }
+ let(:labels) { table(:labels) }
+ let(:label_links) { table(:label_links) }
+ let(:todos) { table(:todos) }
+ let(:work_item_types) { table(:work_item_types) }
+
+ let!(:user) { users.create!(name: 'Test User', email: 'test@example.com', projects_limit: 5) }
+
+ let!(:group1) { namespaces.create!(name: 'group1', path: 'group1', type: 'Group') }
+ let!(:group2) { namespaces.create!(name: 'group2', path: 'group2', type: 'Group') }
+ let!(:project_namespace) { namespaces.create!(name: 'project1', path: 'project1', type: 'Project') }
+ let!(:project) do
+ projects.create!(
+ name: 'project1', path: 'project1', namespace_id: group1.id, project_namespace_id: project_namespace.id
+ )
+ end
+
+ let!(:issue_type) do
+ ensure_work_item_type_exists
+ work_item_types.first
+ end
+
+ let!(:group1_issue1) { issues.create!(title: 'Issue1-1', namespace_id: group1.id, work_item_type_id: issue_type.id) }
+ let!(:group1_issue2) { issues.create!(title: 'Issue1-2', namespace_id: group1.id, work_item_type_id: issue_type.id) }
+ let!(:group2_issue1) { issues.create!(title: 'Issue2-1', namespace_id: group2.id, work_item_type_id: issue_type.id) }
+ let!(:group2_issue2) { issues.create!(title: 'Issue2-2', namespace_id: group2.id, work_item_type_id: issue_type.id) }
+ let!(:project_issue) do
+ issues.create!(
+ title: 'Issue2', project_id: project.id, namespace_id: project_namespace.id, work_item_type_id: issue_type.id
+ )
+ end
+
+ # associated labels
+ let!(:label1) { labels.create!(title: 'label1', group_id: group1.id) }
+ let!(:label2) { labels.create!(title: 'label2', group_id: group2.id) }
+
+ after(:all) do
+ # Make sure base types are recreated after running the migration
+ # because migration specs are not run in a transaction
+ reset_work_item_types
+ end
+
+ describe '#up' do
+ before do
+ # stub batch to make sure we are also testing the batching deletion
+ stub_const("#{described_class}::BATCH_SIZE", 2)
+
+ # Project label_link that must not be deleted
+ label_links.create!(label_id: label1.id, target_id: project_issue.id, target_type: 'Issue')
+
+ label_links.create!(label_id: label1.id, target_id: group1_issue1.id, target_type: 'Issue')
+ label_links.create!(label_id: label2.id, target_id: group1_issue1.id, target_type: 'Issue')
+ label_links.create!(label_id: label1.id, target_id: group1_issue2.id, target_type: 'Issue')
+ label_links.create!(label_id: label2.id, target_id: group1_issue2.id, target_type: 'Issue')
+ label_links.create!(label_id: label1.id, target_id: group2_issue1.id, target_type: 'Issue')
+ label_links.create!(label_id: label2.id, target_id: group2_issue1.id, target_type: 'Issue')
+ label_links.create!(label_id: label1.id, target_id: group2_issue2.id, target_type: 'Issue')
+ label_links.create!(label_id: label2.id, target_id: group2_issue2.id, target_type: 'Issue')
+
+ # associated notes
+
+ # Project issue note that must not be deleted
+ notes.create!(
+ noteable_id: project_issue.id,
+ noteable_type: 'Issue',
+ project_id: project.id,
+ namespace_id: project_namespace.id,
+ note: "project issue 1 note 1"
+ )
+
+ notes.create!(
+ noteable_id: group1_issue1.id, noteable_type: 'Issue', namespace_id: group1.id, note: "group1 issue 1 note 1"
+ )
+ notes.create!(
+ noteable_id: group1_issue1.id, noteable_type: 'Issue', namespace_id: group1.id, note: "group1 issue 1 note 2"
+ )
+ notes.create!(
+ noteable_id: group1_issue2.id, noteable_type: 'Issue', namespace_id: group1.id, note: "group1 issue 2 note 1"
+ )
+ notes.create!(
+ noteable_id: group1_issue2.id, noteable_type: 'Issue', namespace_id: group1.id, note: "group1 issue 2 note 2"
+ )
+ notes.create!(
+ noteable_id: group2_issue1.id, noteable_type: 'Issue', namespace_id: group2.id, note: "group2 issue 1 note 1"
+ )
+ notes.create!(
+ noteable_id: group2_issue1.id, noteable_type: 'Issue', namespace_id: group2.id, note: "group2 issue 1 note 2"
+ )
+ notes.create!(
+ noteable_id: group2_issue2.id, noteable_type: 'Issue', namespace_id: group2.id, note: "group2 issue 2 note 1"
+ )
+ notes.create!(
+ noteable_id: group2_issue2.id, noteable_type: 'Issue', namespace_id: group2.id, note: "group2 issue 2 note 2"
+ )
+
+ # associated todos
+
+ # Project issue todo that must not be deleted
+ todos.create!(
+ target_id: project_issue.id,
+ target_type: 'Issue',
+ project_id: project.id,
+ user_id: user.id,
+ author_id: user.id,
+ action: 1,
+ state: 'pending'
+ )
+
+ todos.create!(
+ target_id: group1_issue1.id,
+ target_type: 'Issue',
+ group_id: group1.id,
+ user_id: user.id,
+ author_id: user.id,
+ action: 1,
+ state: 'pending'
+ )
+ todos.create!(
+ target_id: group1_issue1.id,
+ target_type: 'Issue',
+ group_id: group1.id,
+ user_id: user.id,
+ author_id: user.id,
+ action: 1,
+ state: 'pending'
+ )
+ todos.create!(
+ target_id: group1_issue2.id,
+ target_type: 'Issue',
+ group_id: group1.id,
+ user_id: user.id,
+ author_id: user.id,
+ action: 1,
+ state: 'pending'
+ )
+ todos.create!(
+ target_id: group1_issue2.id,
+ target_type: 'Issue',
+ group_id: group1.id,
+ user_id: user.id,
+ author_id: user.id,
+ action: 1,
+ state: 'pending'
+ )
+ todos.create!(
+ target_id: group2_issue1.id,
+ target_type: 'Issue',
+ group_id: group2.id,
+ user_id: user.id,
+ author_id: user.id,
+ action: 1,
+ state: 'pending'
+ )
+ todos.create!(
+ target_id: group2_issue1.id,
+ target_type: 'Issue',
+ group_id: group2.id,
+ user_id: user.id,
+ author_id: user.id,
+ action: 1,
+ state: 'pending'
+ )
+ todos.create!(
+ target_id: group2_issue2.id,
+ target_type: 'Issue',
+ group_id: group2.id,
+ user_id: user.id,
+ author_id: user.id,
+ action: 1,
+ state: 'pending'
+ )
+ todos.create!(
+ target_id: group2_issue2.id,
+ target_type: 'Issue',
+ group_id: group2.id,
+ user_id: user.id,
+ author_id: user.id,
+ action: 1,
+ state: 'pending'
+ )
+ end
+
+ it 'removes group level issues' do
+ # We have 1 record of each table that should not be deleted
+ expect do
+ migrate!
+ end.to change { issues.count }.from(5).to(1).and(
+ change { label_links.count }.from(9).to(1)
+ ).and(
+ change { notes.count }.from(9).to(1)
+ ).and(
+ change { todos.count }.from(9).to(1)
+ )
+ end
+ end
+
+ def ensure_work_item_type_exists
+ # We need to make sure at least one work item type exists for this spec and they might have been deleted
+ # by other migrations
+ work_item_types.find_or_create_by!(
+ name: 'Issue', namespace_id: nil, base_type: 0, icon_name: 'issue-type-issue'
+ )
+ end
+end