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

3
describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true 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
53
54
55
56
      expect(doc.to_html).to match(/\(<a.+>#{reference}<\/a>\.\)/)
    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
82
83
84
      issue_id = doc.css('a').first["data-external-issue"]

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

    context 'with RequestStore enabled' do
      let(:reference_filter) { HTML::Pipeline.new([described_class]) }

85
86
87
      before do
        allow(RequestStore).to receive(:active?).and_return(true)
      end
88
89
90

      it 'queries the collection on the first call' do
        expect_any_instance_of(Project).to receive(:default_issues_tracker?).once.and_call_original
91
        expect_any_instance_of(Project).to receive(:external_issue_reference_pattern).once.and_call_original
92
93
94
95

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

        expect_any_instance_of(Project).not_to receive(:default_issues_tracker?)
96
        expect_any_instance_of(Project).not_to receive(:external_issue_reference_pattern)
97
98

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

100
101
102
103
104
105
106
107
108
109
110
        # 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) }
    let(:issue) { ExternalIssue.new("#123", project) }
    let(:reference) { issue.to_reference }

111
112
113
114
115
    before do
      project.issues_enabled = false
      project.save!
    end

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
    it_behaves_like "external issue tracker"
  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

    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
136
137
138
    end
  end
end