Read about our upcoming Code of Conduct on this issue

This instance will be upgraded to Heptapod 0.28.1 on 2022-01-26 at 16:00 UTC+1 (a few minutes of down time)

external_issue_reference_filter_spec.rb 5.1 KB
Newer Older
1
2
require 'spec_helper'

3
describe Banzai::Filter::ExternalIssueReferenceFilter do
4
5
6
7
8
9
  include FilterSpecHelper

  def helper
    IssuesHelper
  end

10
  shared_examples_for "external issue tracker" do
11
12
    it_behaves_like 'a reference containing an element node'

13
14
15
16
17
18
19
    it 'requires project context' do
      expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
    end

    %w(pre code a style).each do |elem|
      it "ignores valid references contained inside '#{elem}' element" do
        exp = act = "<#{elem}>Issue #{reference}</#{elem}>"
20

21
22
23
24
25
26
27
28
29
30
31
32
33
        expect(filter(act).to_html).to eq exp
      end
    end

    it 'ignores valid references when using default tracker' do
      expect(project).to receive(:default_issues_tracker?).and_return(true)

      exp = act = "Issue #{reference}"
      expect(filter(act).to_html).to eq exp
    end

    it 'links to a valid reference' do
      doc = filter("Issue #{reference}")
34
35
      issue_id = doc.css('a').first.attr("data-external-issue")

36
      expect(doc.css('a').first.attr('href'))
37
        .to eq helper.url_for_issue(issue_id, project)
38
39
40
41
    end

    it 'links to the external tracker' do
      doc = filter("Issue #{reference}")
42

43
      link = doc.css('a').first.attr('href')
44
      issue_id = doc.css('a').first.attr("data-external-issue")
45

46
      expect(link).to eq(helper.url_for_issue(issue_id, project))
47
48
49
50
    end

    it 'links with adjacent text' do
      doc = filter("Issue (#{reference}.)")
51

52
      expect(doc.to_html).to match(%r{\(<a.+>#{reference}</a>\.\)})
53
54
55
56
    end

    it 'includes a title attribute' do
      doc = filter("Issue #{reference}")
57
      expect(doc.css('a').first.attr('title')).to include("Issue in #{project.issues_tracker.title}")
58
59
60
    end

    it 'escapes the title attribute' do
61
62
      allow(project.external_issue_tracker).to receive(:title)
        .and_return(%{"></a>whatever<a title="})
63
64
65
66
67
68
69

      doc = filter("Issue #{reference}")
      expect(doc.text).to eq "Issue #{reference}"
    end

    it 'includes default classes' do
      doc = filter("Issue #{reference}")
70
      expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-issue has-tooltip'
71
72
73
74
    end

    it 'supports an :only_path context' do
      doc = filter("Issue #{reference}", only_path: true)
75

76
      link = doc.css('a').first.attr('href')
77
78
79
80
81
      issue_id = doc.css('a').first["data-external-issue"]

      expect(link).to eq helper.url_for_issue(issue_id, project, only_path: true)
    end

82
    context 'with RequestStore enabled', :request_store do
83
84
85
86
      let(:reference_filter) { HTML::Pipeline.new([described_class]) }

      it 'queries the collection on the first call' do
        expect_any_instance_of(Project).to receive(:default_issues_tracker?).once.and_call_original
87
        expect_any_instance_of(Project).to receive(:external_issue_reference_pattern).once.and_call_original
88
89
90
91

        not_cached = reference_filter.call("look for #{reference}", { project: project })

        expect_any_instance_of(Project).not_to receive(:default_issues_tracker?)
92
        expect_any_instance_of(Project).not_to receive(:external_issue_reference_pattern)
93
94

        cached = reference_filter.call("look for #{reference}", { project: project })
95

96
97
98
99
100
101
102
103
104
        # Links must be the same
        expect(cached[:output].css('a').first[:href]).to eq(not_cached[:output].css('a').first[:href])
      end
    end
  end

  context "redmine project" do
    let(:project) { create(:redmine_project) }

105
    before do
106
107
108
109
110
111
      project.update!(issues_enabled: false)
    end

    context "with a hash prefix" do
      let(:issue) { ExternalIssue.new("#123", project) }
      let(:reference) { issue.to_reference }
Yauhen Kotau's avatar
Yauhen Kotau committed
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

      it_behaves_like "external issue tracker"
    end

    context "with a single-letter prefix" do
      let(:issue) { ExternalIssue.new("T-123", project) }
      let(:reference) { issue.to_reference }

      it_behaves_like "external issue tracker"
    end
  end

  context "youtrack project" do
    let(:project) { create(:youtrack_project) }

    before do
      project.update!(issues_enabled: false)
    end

    context "with right markdown" do
      let(:issue) { ExternalIssue.new("YT-123", project) }
      let(:reference) { issue.to_reference }
134
135

      it_behaves_like "external issue tracker"
136
137
    end

138
139
140
141
142
143
    context "with a single-letter prefix" do
      let(:issue) { ExternalIssue.new("T-123", project) }
      let(:reference) { issue.to_reference }

      it_behaves_like "external issue tracker"
    end
144
145
146
147
148
149
150
151
152
153
154
155
  end

  context "jira project" do
    let(:project) { create(:jira_project) }
    let(:reference) { issue.to_reference }

    context "with right markdown" do
      let(:issue) { ExternalIssue.new("JIRA-123", project) }

      it_behaves_like "external issue tracker"
    end

156
157
158
159
160
161
162
163
164
    context "with a single-letter prefix" do
      let(:issue) { ExternalIssue.new("J-123", project) }

      it "ignores reference" do
        exp = act = "Issue #{reference}"
        expect(filter(act).to_html).to eq exp
      end
    end

165
166
167
168
169
170
171
    context "with wrong markdown" do
      let(:issue) { ExternalIssue.new("#123", project) }

      it "ignores reference" do
        exp = act = "Issue #{reference}"
        expect(filter(act).to_html).to eq exp
      end
172
173
174
    end
  end
end