commit_range_reference_filter_spec.rb 8.7 KB
Newer Older
1 2
require 'spec_helper'

3
describe Banzai::Filter::CommitRangeReferenceFilter do
4 5
  include FilterSpecHelper

6
  let(:project) { create(:project, :public, :repository) }
7 8
  let(:commit1) { project.commit("HEAD~2") }
  let(:commit2) { project.commit }
9

10 11
  let(:range)  { CommitRange.new("#{commit1.id}...#{commit2.id}", project) }
  let(:range2) { CommitRange.new("#{commit1.id}..#{commit2.id}", project) }
12 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}>Commit Range #{range.to_reference}</#{elem}>"
20
      expect(reference_filter(act).to_html).to eq exp
21 22 23 24 25 26 27 28
    end
  end

  context 'internal reference' do
    let(:reference)  { range.to_reference }
    let(:reference2) { range2.to_reference }

    it 'links to a valid two-dot reference' do
29
      doc = reference_filter("See #{reference2}")
30

31
      expect(doc.css('a').first.attr('href'))
32
        .to eq urls.project_compare_url(project, range2.to_param)
33 34 35
    end

    it 'links to a valid three-dot reference' do
36
      doc = reference_filter("See #{reference}")
37

38
      expect(doc.css('a').first.attr('href'))
39
        .to eq urls.project_compare_url(project, range.to_param)
40 41 42 43 44 45 46 47
    end

    it 'links to a valid short ID' do
      reference = "#{commit1.short_id}...#{commit2.id}"
      reference2 = "#{commit1.id}...#{commit2.short_id}"

      exp = commit1.short_id + '...' + commit2.short_id

48 49
      expect(reference_filter("See #{reference}").css('a').first.text).to eq exp
      expect(reference_filter("See #{reference2}").css('a').first.text).to eq exp
50 51 52
    end

    it 'links with adjacent text' do
53
      doc = reference_filter("See (#{reference}.)")
54

55
      exp = Regexp.escape(range.reference_link_text)
56
      expect(doc.to_html).to match(%r{\(<a.+>#{exp}</a>\.\)})
57 58 59 60 61
    end

    it 'ignores invalid commit IDs' do
      exp = act = "See #{commit1.id.reverse}...#{commit2.id}"

62
      allow(project.repository).to receive(:commit).with(commit1.id.reverse)
63
      expect(reference_filter(act).to_html).to eq exp
64 65
    end

66
    it 'includes no title attribute' do
67
      doc = reference_filter("See #{reference}")
68
      expect(doc.css('a').first.attr('title')).to eq ""
69 70 71
    end

    it 'includes default classes' do
72
      doc = reference_filter("See #{reference}")
73
      expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-commit_range has-tooltip'
74 75 76
    end

    it 'includes a data-project attribute' do
77
      doc = reference_filter("See #{reference}")
78 79 80 81 82 83 84
      link = doc.css('a').first

      expect(link).to have_attribute('data-project')
      expect(link.attr('data-project')).to eq project.id.to_s
    end

    it 'includes a data-commit-range attribute' do
85
      doc = reference_filter("See #{reference}")
86 87 88
      link = doc.css('a').first

      expect(link).to have_attribute('data-commit-range')
89
      expect(link.attr('data-commit-range')).to eq range.to_s
90 91 92
    end

    it 'supports an :only_path option' do
93
      doc = reference_filter("See #{reference}", only_path: true)
94 95 96
      link = doc.css('a').first.attr('href')

      expect(link).not_to match %r(https?://)
97
      expect(link).to eq urls.project_compare_url(project, from: commit1.id, to: commit2.id, only_path: true)
98 99 100
    end
  end

101
  context 'cross-project / cross-namespace complete reference' do
102
    let(:project2)  { create(:project, :public, :repository) }
103
    let(:reference) { "#{project2.full_path}@#{commit1.id}...#{commit2.id}" }
104 105 106 107

    it 'links to a valid reference' do
      doc = reference_filter("See #{reference}")

108
      expect(doc.css('a').first.attr('href'))
109
        .to eq urls.project_compare_url(project2, range.to_param)
110 111 112 113 114
    end

    it 'link has valid text' do
      doc = reference_filter("Fixed (#{reference}.)")

115
      expect(doc.css('a').first.text)
116
        .to eql("#{project2.full_path}@#{commit1.short_id}...#{commit2.short_id}")
117 118 119 120
    end

    it 'has valid text' do
      doc = reference_filter("Fixed (#{reference}.)")
121

122
      expect(doc.text).to eql("Fixed (#{project2.full_path}@#{commit1.short_id}...#{commit2.short_id}.)")
123 124
    end

125
    it 'ignores invalid commit IDs on the referenced project' do
126
      exp = act = "Fixed #{project2.full_path}@#{commit1.id.reverse}...#{commit2.id}"
127 128
      expect(reference_filter(act).to_html).to eq exp

129
      exp = act = "Fixed #{project2.full_path}@#{commit1.id}...#{commit2.id.reverse}"
130 131 132 133 134 135
      expect(reference_filter(act).to_html).to eq exp
    end
  end

  context 'cross-project / same-namespace complete reference' do
    let(:namespace)         { create(:namespace) }
136 137
    let(:project)           { create(:project, :public, :repository, namespace: namespace) }
    let(:project2)          { create(:project, :public, :repository, path: "same-namespace", namespace: namespace) }
138 139
    let(:reference)         { "#{project2.path}@#{commit1.id}...#{commit2.id}" }

140
    it 'links to a valid reference' do
141
      doc = reference_filter("See #{reference}")
142

143
      expect(doc.css('a').first.attr('href'))
144
        .to eq urls.project_compare_url(project2, range.to_param)
145 146
    end

147
    it 'link has valid text' do
148
      doc = reference_filter("Fixed (#{reference}.)")
149

150 151
      expect(doc.css('a').first.text)
        .to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}")
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
    end

    it 'has valid text' do
      doc = reference_filter("Fixed (#{reference}.)")

      expect(doc.text).to eql("Fixed (#{project2.path}@#{commit1.short_id}...#{commit2.short_id}.)")
    end

    it 'ignores invalid commit IDs on the referenced project' do
      exp = act = "Fixed #{project2.path}@#{commit1.id.reverse}...#{commit2.id}"
      expect(reference_filter(act).to_html).to eq exp

      exp = act = "Fixed #{project2.path}@#{commit1.id}...#{commit2.id.reverse}"
      expect(reference_filter(act).to_html).to eq exp
    end
  end

  context 'cross-project shorthand reference' do
    let(:namespace)         { create(:namespace) }
171 172
    let(:project)           { create(:project, :public, :repository, namespace: namespace) }
    let(:project2)          { create(:project, :public, :repository, path: "same-namespace", namespace: namespace) }
173 174 175 176 177
    let(:reference)         { "#{project2.path}@#{commit1.id}...#{commit2.id}" }

    it 'links to a valid reference' do
      doc = reference_filter("See #{reference}")

178
      expect(doc.css('a').first.attr('href'))
179
        .to eq urls.project_compare_url(project2, range.to_param)
180 181 182 183 184
    end

    it 'link has valid text' do
      doc = reference_filter("Fixed (#{reference}.)")

185 186
      expect(doc.css('a').first.text)
        .to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}")
187 188 189 190 191 192
    end

    it 'has valid text' do
      doc = reference_filter("Fixed (#{reference}.)")

      expect(doc.text).to eql("Fixed (#{project2.path}@#{commit1.short_id}...#{commit2.short_id}.)")
193 194 195
    end

    it 'ignores invalid commit IDs on the referenced project' do
196
      exp = act = "Fixed #{project2.path}@#{commit1.id.reverse}...#{commit2.id}"
197
      expect(reference_filter(act).to_html).to eq exp
198

199
      exp = act = "Fixed #{project2.path}@#{commit1.id}...#{commit2.id.reverse}"
200 201 202 203 204
      expect(reference_filter(act).to_html).to eq exp
    end
  end

  context 'cross-project URL reference' do
205
    let(:namespace) { create(:namespace) }
206
    let(:project2)  { create(:project, :public, :repository, namespace: namespace) }
207
    let(:range)  { CommitRange.new("#{commit1.id}...master", project) }
208
    let(:reference) { urls.project_compare_url(project2, from: commit1.id, to: 'master') }
209 210 211 212 213 214 215 216

    before do
      range.project = project2
    end

    it 'links to a valid reference' do
      doc = reference_filter("See #{reference}")

217 218
      expect(doc.css('a').first.attr('href'))
        .to eq reference
219 220 221 222 223 224
    end

    it 'links with adjacent text' do
      doc = reference_filter("Fixed (#{reference}.)")

      exp = Regexp.escape(range.reference_link_text(project))
225
      expect(doc.to_html).to match(%r{\(<a.+>#{exp}</a>\.\)})
226 227 228 229 230 231 232 233
    end

    it 'ignores invalid commit IDs on the referenced project' do
      exp = act = "Fixed #{project2.to_reference}@#{commit1.id.reverse}...#{commit2.id}"
      expect(reference_filter(act).to_html).to eq exp

      exp = act = "Fixed #{project2.to_reference}@#{commit1.id}...#{commit2.id.reverse}"
      expect(reference_filter(act).to_html).to eq exp
234 235
    end
  end
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251

  context 'group context' do
    let(:context) { { project: nil, group: create(:group) } }

    it 'ignores internal references' do
      exp = act = "See #{range.to_reference}"

      expect(reference_filter(act, context).to_html).to eq exp
    end

    it 'links to a full-path reference' do
      reference = "#{project.full_path}@#{commit1.short_id}...#{commit2.short_id}"

      expect(reference_filter("See #{reference}", context).css('a').first.text).to eql(reference)
    end
  end
252
end