# frozen_string_literal: true require 'spec_helper' require Rails.root.join('db', 'migrate', '20200526231421_update_index_approval_rule_name_for_code_owners_rule_type.rb') RSpec.describe UpdateIndexApprovalRuleNameForCodeOwnersRuleType do let(:migration) { described_class.new } let(:approval_rules) { table(:approval_merge_request_rules) } let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab') } let(:project) do table(:projects).create!( namespace_id: namespace.id, name: 'gitlab', path: 'gitlab' ) end let(:merge_request) do table(:merge_requests).create!( target_project_id: project.id, source_project_id: project.id, target_branch: 'feature', source_branch: 'master' ) end let(:index_names) do ActiveRecord::Base.connection .indexes(:approval_merge_request_rules) .collect(&:name) end def create_sectional_approval_rules approval_rules.create!( merge_request_id: merge_request.id, name: "*.rb", code_owner: true, rule_type: 2, section: "First Section" ) approval_rules.create!( merge_request_id: merge_request.id, name: "*.rb", code_owner: true, rule_type: 2, section: "Second Section" ) end def create_two_matching_nil_section_approval_rules 2.times do approval_rules.create!( merge_request_id: merge_request.id, name: "nil_section", code_owner: true, rule_type: 2 ) end end before do approval_rules.delete_all end describe "#up" do it "creates the new index and removes the 'legacy' indices" do # Confirm that existing legacy indices prevent duplicate entries # expect { create_sectional_approval_rules } .to raise_exception(ActiveRecord::RecordNotUnique) expect { create_two_matching_nil_section_approval_rules } .to raise_exception(ActiveRecord::RecordNotUnique) approval_rules.delete_all disable_migrations_output { migrate! } # After running the migration, expect `section == nil` rules to still be # blocked by the legacy indices, but sectional rules are allowed. # expect { create_sectional_approval_rules } .to change { approval_rules.count }.by(2) expect { create_two_matching_nil_section_approval_rules } .to raise_exception(ActiveRecord::RecordNotUnique) # Attempt to rerun the creation of sectional rules, and see that sectional # rules are unique by section # expect { create_sectional_approval_rules } .to raise_exception(ActiveRecord::RecordNotUnique) expect(index_names).to include( described_class::SECTIONAL_INDEX_NAME, described_class::LEGACY_INDEX_NAME_RULE_TYPE, described_class::LEGACY_INDEX_NAME_CODE_OWNERS ) end end describe "#down" do context "run as FOSS" do before do expect(Gitlab).to receive(:ee?).twice.and_return(false) end it "recreates legacy indices, but does not invoke EE-specific code" do disable_migrations_output { migrate! } expect(index_names).to include( described_class::SECTIONAL_INDEX_NAME, described_class::LEGACY_INDEX_NAME_RULE_TYPE, described_class::LEGACY_INDEX_NAME_CODE_OWNERS ) # Since ApprovalMergeRequestRules are EE-specific, we expect none to be # deleted during the migration. # expect { disable_migrations_output { migration.down } } .not_to change { approval_rules.count } index_names = ActiveRecord::Base.connection .indexes(:approval_merge_request_rules) .collect(&:name) expect(index_names).not_to include(described_class::SECTIONAL_INDEX_NAME) expect(index_names).to include( described_class::LEGACY_INDEX_NAME_RULE_TYPE, described_class::LEGACY_INDEX_NAME_CODE_OWNERS ) end end context "EE" do it "recreates 'legacy' indices and removes duplicate code owner approval rules" do skip("This test is skipped under FOSS") unless Gitlab.ee? disable_migrations_output { migrate! } expect { create_sectional_approval_rules } .to change { approval_rules.count }.by(2) expect { create_two_matching_nil_section_approval_rules } .to raise_exception(ActiveRecord::RecordNotUnique) expect(MergeRequests::SyncCodeOwnerApprovalRules) .to receive(:new).with(MergeRequest.find(merge_request.id)).once.and_call_original # Run the down migration. This will remove the 3 approval rules we create # above, and call MergeRequests::SyncCodeOwnerApprovalRules to recreate # new ones. However, as there is no CODEOWNERS file in this test # context, no approval rules will be created, so we can expect # approval_rules.count to be changed by -3. # expect { disable_migrations_output { migration.down } } .to change { approval_rules.count }.by(-3) # Test that the index does not allow us to create the same rules as the # previous sectional index. # expect { create_sectional_approval_rules } .to raise_exception(ActiveRecord::RecordNotUnique) expect { create_two_matching_nil_section_approval_rules } .to raise_exception(ActiveRecord::RecordNotUnique) expect(index_names).not_to include(described_class::SECTIONAL_INDEX_NAME) expect(index_names).to include( described_class::LEGACY_INDEX_NAME_RULE_TYPE, described_class::LEGACY_INDEX_NAME_CODE_OWNERS ) end end end end