closing_issue_extractor_spec.rb 11.8 KB
Newer Older
1 2
require 'spec_helper'

3
describe Gitlab::ClosingIssueExtractor do
4 5
  let(:project) { create(:project) }
  let(:project2) { create(:project) }
6
  let(:forked_project) { Projects::ForkService.new(project, project.creator).execute }
7 8
  let(:issue) { create(:issue, project: project) }
  let(:issue2) { create(:issue, project: project2) }
9
  let(:reference) { issue.to_reference }
10
  let(:cross_reference) { issue2.to_reference(project) }
11
  let(:fork_cross_reference) { issue.to_reference(forked_project) }
12

Douwe Maan's avatar
Douwe Maan committed
13 14
  subject { described_class.new(project, project.creator) }

15
  before do
16
    project.team  << [project.creator, :developer]
17 18 19
    project2.team << [project.creator, :master]
  end

Douwe Maan's avatar
Douwe Maan committed
20
  describe "#closed_by_message" do
21 22
    context 'with a single reference' do
      it do
23
        message = "Awesome commit (Closes #{reference})"
Douwe Maan's avatar
Douwe Maan committed
24
        expect(subject.closed_by_message(message)).to eq([issue])
25 26
      end

27 28 29 30 31
      it do
        message = "Awesome commit (Closes: #{reference})"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

32
      it do
33
        message = "Awesome commit (closes #{reference})"
Douwe Maan's avatar
Douwe Maan committed
34
        expect(subject.closed_by_message(message)).to eq([issue])
35 36
      end

37 38 39 40 41
      it do
        message = "Awesome commit (closes: #{reference})"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

42
      it do
43
        message = "Closed #{reference}"
Douwe Maan's avatar
Douwe Maan committed
44
        expect(subject.closed_by_message(message)).to eq([issue])
45 46 47
      end

      it do
48
        message = "closed #{reference}"
Douwe Maan's avatar
Douwe Maan committed
49
        expect(subject.closed_by_message(message)).to eq([issue])
50 51
      end

52 53 54 55 56
      it do
        message = "closed: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
57
      it do
58
        message = "Closing #{reference}"
Douwe Maan's avatar
Douwe Maan committed
59
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
60 61
      end

62 63 64 65 66
      it do
        message = "Closing: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
67
      it do
68
        message = "closing #{reference}"
Douwe Maan's avatar
Douwe Maan committed
69
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
70 71
      end

72 73 74 75 76
      it do
        message = "closing: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
77
      it do
78
        message = "Close #{reference}"
Douwe Maan's avatar
Douwe Maan committed
79
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
80 81
      end

82 83 84 85 86
      it do
        message = "Close: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
87
      it do
88
        message = "close #{reference}"
Douwe Maan's avatar
Douwe Maan committed
89
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
90 91
      end

92 93 94 95 96
      it do
        message = "close: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
97
      it do
98
        message = "Awesome commit (Fixes #{reference})"
Douwe Maan's avatar
Douwe Maan committed
99
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
100 101
      end

102 103 104 105 106
      it do
        message = "Awesome commit (Fixes: #{reference})"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

107
      it do
108
        message = "Awesome commit (fixes #{reference})"
Douwe Maan's avatar
Douwe Maan committed
109
        expect(subject.closed_by_message(message)).to eq([issue])
110 111
      end

112 113 114 115 116
      it do
        message = "Awesome commit (Fixes: #{reference})"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

117
      it do
118
        message = "Fixed #{reference}"
Douwe Maan's avatar
Douwe Maan committed
119
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
120 121
      end

122 123 124 125 126
      it do
        message = "Fixed: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
127
      it do
128
        message = "fixed #{reference}"
Douwe Maan's avatar
Douwe Maan committed
129
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
130 131
      end

132 133 134 135 136
      it do
        message = "fixed: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
137
      it do
138
        message = "Fixing #{reference}"
Douwe Maan's avatar
Douwe Maan committed
139
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
140 141
      end

142 143 144 145 146
      it do
        message = "Fixing: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
147
      it do
148
        message = "fixing #{reference}"
Douwe Maan's avatar
Douwe Maan committed
149
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
150 151
      end

152 153 154 155 156
      it do
        message = "fixing: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
157
      it do
158
        message = "Fix #{reference}"
Douwe Maan's avatar
Douwe Maan committed
159
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
160 161
      end

162 163 164 165 166
      it do
        message = "Fix: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
167
      it do
168
        message = "fix #{reference}"
Douwe Maan's avatar
Douwe Maan committed
169
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
170 171
      end

172 173 174 175 176
      it do
        message = "fix: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
177
      it do
178
        message = "Awesome commit (Resolves #{reference})"
Douwe Maan's avatar
Douwe Maan committed
179
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
180 181
      end

182 183 184 185 186
      it do
        message = "Awesome commit (Resolves: #{reference})"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
187
      it do
188
        message = "Awesome commit (resolves #{reference})"
Douwe Maan's avatar
Douwe Maan committed
189
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
190 191
      end

192 193 194 195 196
      it do
        message = "Awesome commit (resolves: #{reference})"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
197
      it do
198
        message = "Resolved #{reference}"
Douwe Maan's avatar
Douwe Maan committed
199
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
200 201
      end

202 203 204 205 206
      it do
        message = "Resolved: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
207
      it do
208
        message = "resolved #{reference}"
Douwe Maan's avatar
Douwe Maan committed
209
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
210 211
      end

212 213 214 215 216
      it do
        message = "resolved: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
217
      it do
218
        message = "Resolving #{reference}"
Douwe Maan's avatar
Douwe Maan committed
219
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
220 221
      end

222 223 224 225 226
      it do
        message = "Resolving: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
227
      it do
228
        message = "resolving #{reference}"
Douwe Maan's avatar
Douwe Maan committed
229
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
230 231
      end

232 233 234 235 236
      it do
        message = "resolving: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
237
      it do
238
        message = "Resolve #{reference}"
Douwe Maan's avatar
Douwe Maan committed
239
        expect(subject.closed_by_message(message)).to eq([issue])
Douwe Maan's avatar
Douwe Maan committed
240 241
      end

242 243 244 245 246
      it do
        message = "Resolve: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

Douwe Maan's avatar
Douwe Maan committed
247
      it do
248
        message = "resolve #{reference}"
Douwe Maan's avatar
Douwe Maan committed
249
        expect(subject.closed_by_message(message)).to eq([issue])
250
      end
251

252 253 254 255 256
      it do
        message = "resolve: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
      it do
        message = "Implement: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

      it do
        message = "Implements: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

      it do
        message = "Implemented: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

      it do
        message = "Implementing: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

      it do
        message = "implement: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

      it do
        message = "implements: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

      it do
        message = "implemented: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

      it do
        message = "implementing: #{reference}"
        expect(subject.closed_by_message(message)).to eq([issue])
      end

297 298 299
      context 'with an external issue tracker reference' do
        it 'extracts the referenced issue' do
          jira_project = create(:jira_project, name: 'JIRA_EXT1')
300
          jira_project.team << [jira_project.creator, :master]
301
          jira_issue = ExternalIssue.new("#{jira_project.name}-1", project: jira_project)
302
          closing_issue_extractor = described_class.new(jira_project, jira_project.creator)
303 304 305 306 307
          message = "Resolve #{jira_issue.to_reference}"

          expect(closing_issue_extractor.closed_by_message(message)).to eq([jira_issue])
        end
      end
308 309
    end

310 311 312 313 314 315 316 317 318
    context "with a cross-project reference" do
      it do
        message = "Closes #{cross_reference}"
        expect(subject.closed_by_message(message)).to eq([issue2])
      end
    end

    context "with a cross-project URL" do
      it do
319
        message = "Closes #{urls.project_issue_url(issue2.project, issue2)}"
320 321 322 323
        expect(subject.closed_by_message(message)).to eq([issue2])
      end
    end

324 325 326 327 328 329 330 331 332
    context "with a cross-project fork reference" do
      subject { described_class.new(forked_project, forked_project.creator) }

      it do
        message = "Closes #{fork_cross_reference}"
        expect(subject.closed_by_message(message)).to be_empty
      end
    end

333 334
    context "with an invalid URL" do
      it do
335
        message = "Closes https://google.com#{urls.project_issue_path(issue2.project, issue2)}"
336 337 338 339
        expect(subject.closed_by_message(message)).to eq([])
      end
    end

340 341 342
    context 'with multiple references' do
      let(:other_issue) { create(:issue, project: project) }
      let(:third_issue) { create(:issue, project: project) }
343 344
      let(:reference2) { other_issue.to_reference }
      let(:reference3) { third_issue.to_reference }
345 346

      it 'fetches issues in single line message' do
347
        message = "Closes #{reference} and fix #{reference2}"
348

349 350
        expect(subject.closed_by_message(message))
            .to match_array([issue, other_issue])
351 352 353
      end

      it 'fetches comma-separated issues references in single line message' do
354
        message = "Closes #{reference}, closes #{reference2}"
355

356 357
        expect(subject.closed_by_message(message))
            .to match_array([issue, other_issue])
358 359 360
      end

      it 'fetches comma-separated issues numbers in single line message' do
361
        message = "Closes #{reference}, #{reference2} and #{reference3}"
362

363 364
        expect(subject.closed_by_message(message))
            .to match_array([issue, other_issue, third_issue])
365 366 367
      end

      it 'fetches issues in multi-line message' do
368
        message = "Awesome commit (closes #{reference})\nAlso fixes #{reference2}"
369

370 371
        expect(subject.closed_by_message(message))
            .to match_array([issue, other_issue])
372 373 374
      end

      it 'fetches issues in hybrid message' do
375
        message = "Awesome commit (closes #{reference})\n"\
376
                  "Also fixing issues #{reference2}, #{reference3} and #4"
377

378 379
        expect(subject.closed_by_message(message))
            .to match_array([issue, other_issue, third_issue])
380
      end
381 382 383 384

      it "fetches cross-project references" do
        message = "Closes #{reference} and #{cross_reference}"

385 386
        expect(subject.closed_by_message(message))
            .to match_array([issue, issue2])
387 388 389
      end

      it "fetches cross-project URL references" do
390
        message = "Closes #{urls.project_issue_url(issue2.project, issue2)}, #{reference} and #{urls.project_issue_url(other_issue.project, other_issue)}"
391

392
        expect(subject.closed_by_message(message))
393
            .to match_array([issue, issue2, other_issue])
394 395 396
      end

      it "ignores invalid cross-project URL references" do
397
        message = "Closes https://google.com#{urls.project_issue_path(issue2.project, issue2)} and #{reference}"
398

399 400
        expect(subject.closed_by_message(message))
            .to match_array([issue])
401
      end
402 403
    end
  end
Douwe Maan's avatar
Douwe Maan committed
404 405

  def urls
406
    Gitlab::Routing.url_helpers
Douwe Maan's avatar
Douwe Maan committed
407
  end
408
end