197 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
require 'spec_helper'
 | 
						|
 | 
						|
RSpec.describe Gitlab::Gfm::ReferenceRewriter do
 | 
						|
  let_it_be(:group) { create(:group) }
 | 
						|
  let_it_be(:user) { create(:user) }
 | 
						|
 | 
						|
  let(:new_project) { create(:project, name: 'new-project', group: group) }
 | 
						|
  let(:old_project) { create(:project, name: 'old-project', group: group) }
 | 
						|
  let(:old_project_ref) { old_project.to_reference_base(new_project) }
 | 
						|
  let(:text) { 'some text' }
 | 
						|
  let(:note) { create(:note, note: text, project: old_project) }
 | 
						|
 | 
						|
  before do
 | 
						|
    old_project.add_reporter(user)
 | 
						|
  end
 | 
						|
 | 
						|
  describe '#rewrite' do
 | 
						|
    subject do
 | 
						|
      described_class.new(note.note, note.note_html, old_project, user).rewrite(new_project)
 | 
						|
    end
 | 
						|
 | 
						|
    context 'multiple issues and merge requests referenced' do
 | 
						|
      let!(:issue_first) { create(:issue, project: old_project) }
 | 
						|
      let!(:issue_second) { create(:issue, project: old_project) }
 | 
						|
      let!(:merge_request) { create(:merge_request, source_project: old_project) }
 | 
						|
 | 
						|
      context 'plain text description' do
 | 
						|
        let(:text) { 'Description that references #1, #2 and !1' }
 | 
						|
 | 
						|
        it { is_expected.to include issue_first.to_reference(new_project) }
 | 
						|
        it { is_expected.to include issue_second.to_reference(new_project) }
 | 
						|
        it { is_expected.to include merge_request.to_reference(new_project) }
 | 
						|
      end
 | 
						|
 | 
						|
      context 'description with ignored elements' do
 | 
						|
        let(:text) do
 | 
						|
          "Hi. This references #1, but not `#2`\n" \
 | 
						|
            '<pre>and not !1</pre>'
 | 
						|
        end
 | 
						|
 | 
						|
        it { is_expected.to include issue_first.to_reference(new_project) }
 | 
						|
        it { is_expected.not_to include issue_second.to_reference(new_project) }
 | 
						|
        it { is_expected.not_to include merge_request.to_reference(new_project) }
 | 
						|
      end
 | 
						|
 | 
						|
      context 'rewrite ambigous references' do
 | 
						|
        context 'url' do
 | 
						|
          let(:url) { 'http://gitlab.com/#1' }
 | 
						|
          let(:text) { "This references #1, but not #{url}" }
 | 
						|
 | 
						|
          it { is_expected.to include url }
 | 
						|
        end
 | 
						|
 | 
						|
        context 'code' do
 | 
						|
          let(:text) { "#1, but not `[#1]`" }
 | 
						|
 | 
						|
          it { is_expected.to eq "#{issue_first.to_reference(new_project)}, but not `[#1]`" }
 | 
						|
        end
 | 
						|
 | 
						|
        context 'code reverse' do
 | 
						|
          let(:text) { "not `#1`, but #1" }
 | 
						|
 | 
						|
          it { is_expected.to eq "not `#1`, but #{issue_first.to_reference(new_project)}" }
 | 
						|
        end
 | 
						|
 | 
						|
        context 'code in random order' do
 | 
						|
          let(:text) { "#1, `#1`, #1, `#1`" }
 | 
						|
          let(:ref) { issue_first.to_reference(new_project) }
 | 
						|
 | 
						|
          it { is_expected.to eq "#{ref}, `#1`, #{ref}, `#1`" }
 | 
						|
        end
 | 
						|
 | 
						|
        context 'description with project labels' do
 | 
						|
          let!(:label) { create(:label, id: 123, name: 'test', project: old_project) }
 | 
						|
 | 
						|
          context 'label referenced by id' do
 | 
						|
            let(:text) { '#1 and ~123' }
 | 
						|
 | 
						|
            it { is_expected.to eq %Q{#{old_project_ref}#1 and #{old_project_ref}~123} }
 | 
						|
          end
 | 
						|
 | 
						|
          context 'label referenced by text' do
 | 
						|
            let(:text) { '#1 and ~"test"' }
 | 
						|
 | 
						|
            it { is_expected.to eq %Q{#{old_project_ref}#1 and #{old_project_ref}~123} }
 | 
						|
          end
 | 
						|
        end
 | 
						|
 | 
						|
        context 'description with group labels' do
 | 
						|
          let(:old_group) { create(:group) }
 | 
						|
          let!(:group_label) { create(:group_label, id: 321, name: 'group label', group: old_group) }
 | 
						|
 | 
						|
          before do
 | 
						|
            old_project.update!(namespace: old_group)
 | 
						|
          end
 | 
						|
 | 
						|
          context 'label referenced by id' do
 | 
						|
            let(:text) { '#1 and ~321' }
 | 
						|
 | 
						|
            it { is_expected.to eq %Q{#{old_project_ref}#1 and #{old_project_ref}~321} }
 | 
						|
          end
 | 
						|
 | 
						|
          context 'label referenced by text' do
 | 
						|
            let(:text) { '#1 and ~"group label"' }
 | 
						|
 | 
						|
            it { is_expected.to eq %Q{#{old_project_ref}#1 and #{old_project_ref}~321} }
 | 
						|
          end
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when description contains a local reference' do
 | 
						|
      let(:local_issue) { create(:issue, project: old_project) }
 | 
						|
      let(:text) { "See ##{local_issue.iid}" }
 | 
						|
 | 
						|
      it { is_expected.to eq("See #{old_project.path}##{local_issue.iid}") }
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when description contains a cross reference' do
 | 
						|
      let(:merge_request) { create(:merge_request) }
 | 
						|
      let(:text) { "See #{merge_request.project.full_path}!#{merge_request.iid}" }
 | 
						|
 | 
						|
      it { is_expected.to eq(text) }
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with a commit' do
 | 
						|
      let(:old_project) { create(:project, :repository, name: 'old-project', group: group) }
 | 
						|
      let(:commit) { old_project.commit }
 | 
						|
 | 
						|
      context 'reference to an absolute URL to a commit' do
 | 
						|
        let(:text) { Gitlab::UrlBuilder.build(commit) }
 | 
						|
 | 
						|
        it { is_expected.to eq(text) }
 | 
						|
      end
 | 
						|
 | 
						|
      context 'reference to a commit' do
 | 
						|
        let(:text) { commit.id }
 | 
						|
 | 
						|
        it { is_expected.to eq("#{old_project_ref}@#{text}") }
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'reference contains project milestone' do
 | 
						|
      let!(:milestone) do
 | 
						|
        create(:milestone, title: '9.0', project: old_project)
 | 
						|
      end
 | 
						|
 | 
						|
      let(:text) { 'milestone: %"9.0"' }
 | 
						|
 | 
						|
      it { is_expected.to eq %Q[milestone: #{old_project_ref}%"9.0"] }
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when referring to group milestone' do
 | 
						|
      let!(:milestone) do
 | 
						|
        create(:milestone, title: '10.0', group: group)
 | 
						|
      end
 | 
						|
 | 
						|
      let(:text) { 'milestone %"10.0"' }
 | 
						|
 | 
						|
      it { is_expected.to eq text }
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when referring to a group' do
 | 
						|
      let(:text) { "group @#{group.full_path}" }
 | 
						|
 | 
						|
      it { is_expected.to eq text }
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when referring to a user' do
 | 
						|
      let(:text) { "user @#{user.full_path}" }
 | 
						|
 | 
						|
      it { is_expected.to eq text }
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when referable has a nil reference' do
 | 
						|
      before do
 | 
						|
        create(:milestone, title: '9.0', project: old_project)
 | 
						|
 | 
						|
        allow_any_instance_of(Milestone)
 | 
						|
          .to receive(:to_reference)
 | 
						|
          .and_return(nil)
 | 
						|
      end
 | 
						|
 | 
						|
      let(:text) { 'milestone: %"9.0"' }
 | 
						|
 | 
						|
      it 'raises an error that should be fixed' do
 | 
						|
        expect { subject }.to raise_error(
 | 
						|
          described_class::RewriteError,
 | 
						|
          'Unspecified reference detected for Milestone'
 | 
						|
        )
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |