merge_requests_spec.rb 27.0 KB
Newer Older
V
Valeriy Sizov 已提交
1 2
require "spec_helper"

J
Jeroen van Baarsen 已提交
3
describe API::API, api: true  do
V
Valeriy Sizov 已提交
4
  include ApiHelpers
Z
Zeger-Jan van de Weg 已提交
5 6 7
  let(:base_time)   { Time.now }
  let(:user)        { create(:user) }
  let(:admin)       { create(:user, :admin) }
8
  let(:non_member)  { create(:user) }
Z
Zeger-Jan van de Weg 已提交
9
  let!(:project)    { create(:project, creator_id: user.id, namespace: user.namespace) }
S
Stan Hu 已提交
10
  let!(:merge_request) { create(:merge_request, :simple, author: user, assignee: user, source_project: project, target_project: project, title: "Test", created_at: base_time) }
G
Gabriel Mazetto 已提交
11
  let!(:merge_request_closed) { create(:merge_request, state: "closed", author: user, assignee: user, source_project: project, target_project: project, title: "Closed test", created_at: base_time + 1.second) }
S
Stan Hu 已提交
12
  let!(:merge_request_merged) { create(:merge_request, state: "merged", author: user, assignee: user, source_project: project, target_project: project, title: "Merged test", created_at: base_time + 2.seconds) }
Z
Zeger-Jan van de Weg 已提交
13 14 15
  let!(:note)       { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") }
  let!(:note2)      { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "another comment on a MR") }
  let(:milestone)   { create(:milestone, title: '1.0.0', project: project) }
16 17

  before do
I
Izaak Alpert 已提交
18
    project.team << [user, :reporters]
19
  end
V
Valeriy Sizov 已提交
20 21 22 23

  describe "GET /projects/:id/merge_requests" do
    context "when unauthenticated" do
      it "should return authentication error" do
H
Hiroyuki Sato 已提交
24
        get api("/projects/#{project.id}/merge_requests")
25
        expect(response.status).to eq(401)
V
Valeriy Sizov 已提交
26 27 28 29
      end
    end

    context "when authenticated" do
30
      it "should return an array of all merge_requests" do
H
Hiroyuki Sato 已提交
31
        get api("/projects/#{project.id}/merge_requests", user)
32 33 34 35
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(3)
        expect(json_response.last['title']).to eq(merge_request.title)
V
Valeriy Sizov 已提交
36
      end
37

38 39
      it "should return an array of all merge_requests" do
        get api("/projects/#{project.id}/merge_requests?state", user)
40 41 42 43
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(3)
        expect(json_response.last['title']).to eq(merge_request.title)
44
      end
45

46 47
      it "should return an array of open merge_requests" do
        get api("/projects/#{project.id}/merge_requests?state=opened", user)
48 49 50 51
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(1)
        expect(json_response.last['title']).to eq(merge_request.title)
52
      end
53

54 55
      it "should return an array of closed merge_requests" do
        get api("/projects/#{project.id}/merge_requests?state=closed", user)
56 57
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
58 59
        expect(json_response.length).to eq(1)
        expect(json_response.first['title']).to eq(merge_request_closed.title)
60
      end
61

62 63
      it "should return an array of merged merge_requests" do
        get api("/projects/#{project.id}/merge_requests?state=merged", user)
64 65 66 67
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(1)
        expect(json_response.first['title']).to eq(merge_request_merged.title)
68
      end
69 70 71 72 73 74 75 76 77

      context "with ordering" do
        before do
          @mr_later = mr_with_later_created_and_updated_at_time
          @mr_earlier = mr_with_earlier_created_and_updated_at_time
        end

        it "should return an array of merge_requests in ascending order" do
          get api("/projects/#{project.id}/merge_requests?sort=asc", user)
78 79 80
          expect(response.status).to eq(200)
          expect(json_response).to be_an Array
          expect(json_response.length).to eq(3)
S
Stan Hu 已提交
81 82
          response_dates = json_response.map{ |merge_request| merge_request['created_at'] }
          expect(response_dates).to eq(response_dates.sort)
83
        end
D
Dmitriy Zaporozhets 已提交
84

85 86
        it "should return an array of merge_requests in descending order" do
          get api("/projects/#{project.id}/merge_requests?sort=desc", user)
87 88 89
          expect(response.status).to eq(200)
          expect(json_response).to be_an Array
          expect(json_response.length).to eq(3)
S
Stan Hu 已提交
90 91
          response_dates = json_response.map{ |merge_request| merge_request['created_at'] }
          expect(response_dates).to eq(response_dates.sort.reverse)
92
        end
D
Dmitriy Zaporozhets 已提交
93

94 95
        it "should return an array of merge_requests ordered by updated_at" do
          get api("/projects/#{project.id}/merge_requests?order_by=updated_at", user)
96 97 98
          expect(response.status).to eq(200)
          expect(json_response).to be_an Array
          expect(json_response.length).to eq(3)
S
Stan Hu 已提交
99 100
          response_dates = json_response.map{ |merge_request| merge_request['updated_at'] }
          expect(response_dates).to eq(response_dates.sort.reverse)
101
        end
D
Dmitriy Zaporozhets 已提交
102

103
        it "should return an array of merge_requests ordered by created_at" do
S
Stan Hu 已提交
104
          get api("/projects/#{project.id}/merge_requests?order_by=created_at&sort=asc", user)
105 106 107
          expect(response.status).to eq(200)
          expect(json_response).to be_an Array
          expect(json_response.length).to eq(3)
S
Stan Hu 已提交
108 109
          response_dates = json_response.map{ |merge_request| merge_request['created_at'] }
          expect(response_dates).to eq(response_dates.sort)
110
        end
111
      end
V
Valeriy Sizov 已提交
112 113 114
    end
  end

115
  describe "GET /projects/:id/merge_requests/:merge_request_id" do
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
    it 'exposes known attributes' do
      get api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user)

      expect(response.status).to eq(200)
      expect(json_response['id']).to eq(merge_request.id)
      expect(json_response['iid']).to eq(merge_request.iid)
      expect(json_response['project_id']).to eq(merge_request.project.id)
      expect(json_response['title']).to eq(merge_request.title)
      expect(json_response['description']).to eq(merge_request.description)
      expect(json_response['state']).to eq(merge_request.state)
      expect(json_response['created_at']).to be_present
      expect(json_response['updated_at']).to be_present
      expect(json_response['labels']).to eq(merge_request.label_names)
      expect(json_response['milestone']).to be_nil
      expect(json_response['assignee']).to be_a Hash
      expect(json_response['author']).to be_a Hash
      expect(json_response['target_branch']).to eq(merge_request.target_branch)
      expect(json_response['source_branch']).to eq(merge_request.source_branch)
      expect(json_response['upvotes']).to eq(0)
      expect(json_response['downvotes']).to eq(0)
      expect(json_response['source_project_id']).to eq(merge_request.source_project.id)
      expect(json_response['target_project_id']).to eq(merge_request.target_project.id)
      expect(json_response['work_in_progress']).to be_falsy
      expect(json_response['merge_when_build_succeeds']).to be_falsy
      expect(json_response['merge_status']).to eq('can_be_merged')
    end

V
Valeriy Sizov 已提交
143
    it "should return merge_request" do
144
      get api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user)
145 146 147
      expect(response.status).to eq(200)
      expect(json_response['title']).to eq(merge_request.title)
      expect(json_response['iid']).to eq(merge_request.iid)
148
      expect(json_response['work_in_progress']).to eq(false)
149
      expect(json_response['merge_status']).to eq('can_be_merged')
V
Valeriy Sizov 已提交
150
    end
151

152 153 154
    it 'should return merge_request by iid' do
      url = "/projects/#{project.id}/merge_requests?iid=#{merge_request.iid}"
      get api(url, user)
155 156 157
      expect(response.status).to eq 200
      expect(json_response.first['title']).to eq merge_request.title
      expect(json_response.first['id']).to eq merge_request.id
158 159
    end

160
    it "should return a 404 error if merge_request_id not found" do
161
      get api("/projects/#{project.id}/merge_requests/999", user)
162
      expect(response.status).to eq(404)
163
    end
164 165 166 167 168 169 170 171 172 173

    context 'Work in Progress' do
      let!(:merge_request_wip) { create(:merge_request, author: user, assignee: user, source_project: project, target_project: project, title: "WIP: Test", created_at: base_time + 1.second) }

      it "should return merge_request" do
        get api("/projects/#{project.id}/merge_requests/#{merge_request_wip.id}", user)
        expect(response.status).to eq(200)
        expect(json_response['work_in_progress']).to eq(true)
      end
    end
V
Valeriy Sizov 已提交
174 175
  end

176
  describe 'GET /projects/:id/merge_requests/:merge_request_id/commits' do
177
    context 'valid merge request' do
178
      before { get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/commits", user) }
179 180 181 182 183 184 185 186 187
      let(:commit) { merge_request.commits.first }

      it { expect(response.status).to eq 200 }
      it { expect(json_response.size).to eq(merge_request.commits.size) }
      it { expect(json_response.first['id']).to eq(commit.id) }
      it { expect(json_response.first['title']).to eq(commit.title) }
    end

    it 'returns a 404 when merge_request_id not found' do
188
      get api("/projects/#{project.id}/merge_requests/999/commits", user)
189 190 191 192
      expect(response.status).to eq(404)
    end
  end

193
  describe 'GET /projects/:id/merge_requests/:merge_request_id/changes' do
194
    it 'should return the change information of the merge_request' do
195
      get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/changes", user)
196 197 198 199 200
      expect(response.status).to eq 200
      expect(json_response['changes'].size).to eq(merge_request.diffs.size)
    end

    it 'returns a 404 when merge_request_id not found' do
201
      get api("/projects/#{project.id}/merge_requests/999/changes", user)
202 203 204 205
      expect(response.status).to eq(404)
    end
  end

V
Valeriy Sizov 已提交
206
  describe "POST /projects/:id/merge_requests" do
I
Izaak Alpert 已提交
207 208
    context 'between branches projects' do
      it "should return merge_request" do
H
Hiroyuki Sato 已提交
209
        post api("/projects/#{project.id}/merge_requests", user),
210
             title: 'Test merge_request',
211
             source_branch: 'feature_conflict',
212 213
             target_branch: 'master',
             author: user,
214 215
             labels: 'label, label2',
             milestone_id: milestone.id
216 217 218
        expect(response.status).to eq(201)
        expect(json_response['title']).to eq('Test merge_request')
        expect(json_response['labels']).to eq(['label', 'label2'])
219
        expect(json_response['milestone']['id']).to eq(milestone.id)
I
Izaak Alpert 已提交
220
      end
221

I
Izaak Alpert 已提交
222
      it "should return 422 when source_branch equals target_branch" do
H
Hiroyuki Sato 已提交
223
        post api("/projects/#{project.id}/merge_requests", user),
224
        title: "Test merge_request", source_branch: "master", target_branch: "master", author: user
225
        expect(response.status).to eq(422)
I
Izaak Alpert 已提交
226
      end
227

I
Izaak Alpert 已提交
228
      it "should return 400 when source_branch is missing" do
H
Hiroyuki Sato 已提交
229
        post api("/projects/#{project.id}/merge_requests", user),
230
        title: "Test merge_request", target_branch: "master", author: user
231
        expect(response.status).to eq(400)
I
Izaak Alpert 已提交
232
      end
233

I
Izaak Alpert 已提交
234
      it "should return 400 when target_branch is missing" do
H
Hiroyuki Sato 已提交
235
        post api("/projects/#{project.id}/merge_requests", user),
236
        title: "Test merge_request", source_branch: "markdown", author: user
237
        expect(response.status).to eq(400)
I
Izaak Alpert 已提交
238 239 240
      end

      it "should return 400 when title is missing" do
H
Hiroyuki Sato 已提交
241
        post api("/projects/#{project.id}/merge_requests", user),
242
        target_branch: 'master', source_branch: 'markdown'
243
        expect(response.status).to eq(400)
I
Izaak Alpert 已提交
244
      end
245

R
Robert Schilling 已提交
246
      it 'should return 400 on invalid label names' do
247 248
        post api("/projects/#{project.id}/merge_requests", user),
             title: 'Test merge_request',
249
             source_branch: 'markdown',
250 251 252
             target_branch: 'master',
             author: user,
             labels: 'label, ?'
253 254
        expect(response.status).to eq(400)
        expect(json_response['message']['labels']['?']['title']).to eq(
R
Robert Schilling 已提交
255
          ['is invalid']
256
        )
257
      end
J
jubianchi 已提交
258 259 260 261 262

      context 'with existing MR' do
        before do
          post api("/projects/#{project.id}/merge_requests", user),
               title: 'Test merge_request',
263
               source_branch: 'feature_conflict',
J
jubianchi 已提交
264 265 266 267 268 269 270 271 272
               target_branch: 'master',
               author: user
          @mr = MergeRequest.all.last
        end

        it 'should return 409 when MR already exists for source/target' do
          expect do
            post api("/projects/#{project.id}/merge_requests", user),
                 title: 'New test merge_request',
273
                 source_branch: 'feature_conflict',
J
jubianchi 已提交
274 275 276
                 target_branch: 'master',
                 author: user
          end.to change { MergeRequest.count }.by(0)
277
          expect(response.status).to eq(409)
J
jubianchi 已提交
278 279
        end
      end
280
    end
281

I
Izaak Alpert 已提交
282
    context 'forked projects' do
D
Dmitriy Zaporozhets 已提交
283 284 285
      let!(:user2) { create(:user) }
      let!(:fork_project) { create(:project, forked_from_project: project,  namespace: user2.namespace, creator_id: user2.id) }
      let!(:unrelated_project) { create(:project,  namespace: create(:user).namespace, creator_id: user2.id) }
I
Izaak Alpert 已提交
286 287 288 289 290 291

      before :each do |each|
        fork_project.team << [user2, :reporters]
      end

      it "should return merge_request" do
H
Hiroyuki Sato 已提交
292
        post api("/projects/#{fork_project.id}/merge_requests", user2),
293 294
          title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master",
          author: user2, target_project_id: project.id, description: 'Test description for Test merge_request'
295 296 297
        expect(response.status).to eq(201)
        expect(json_response['title']).to eq('Test merge_request')
        expect(json_response['description']).to eq('Test description for Test merge_request')
I
Izaak Alpert 已提交
298 299 300
      end

      it "should not return 422 when source_branch equals target_branch" do
301 302 303
        expect(project.id).not_to eq(fork_project.id)
        expect(fork_project.forked?).to be_truthy
        expect(fork_project.forked_from_project).to eq(project)
H
Hiroyuki Sato 已提交
304
        post api("/projects/#{fork_project.id}/merge_requests", user2),
305
        title: 'Test merge_request', source_branch: "master", target_branch: "master", author: user2, target_project_id: project.id
306 307
        expect(response.status).to eq(201)
        expect(json_response['title']).to eq('Test merge_request')
I
Izaak Alpert 已提交
308 309 310
      end

      it "should return 400 when source_branch is missing" do
H
Hiroyuki Sato 已提交
311
        post api("/projects/#{fork_project.id}/merge_requests", user2),
312
        title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
313
        expect(response.status).to eq(400)
I
Izaak Alpert 已提交
314 315 316
      end

      it "should return 400 when target_branch is missing" do
H
Hiroyuki Sato 已提交
317
        post api("/projects/#{fork_project.id}/merge_requests", user2),
318
        title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
319
        expect(response.status).to eq(400)
I
Izaak Alpert 已提交
320 321 322
      end

      it "should return 400 when title is missing" do
H
Hiroyuki Sato 已提交
323
        post api("/projects/#{fork_project.id}/merge_requests", user2),
324
        target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: project.id
325
        expect(response.status).to eq(400)
I
Izaak Alpert 已提交
326 327
      end

J
jubianchi 已提交
328 329 330 331 332
      context 'when target_branch is specified' do
        it 'should return 422 if not a forked project' do
          post api("/projects/#{project.id}/merge_requests", user),
               title: 'Test merge_request',
               target_branch: 'master',
333
               source_branch: 'markdown',
J
jubianchi 已提交
334 335
               author: user,
               target_project_id: fork_project.id
336
          expect(response.status).to eq(422)
J
jubianchi 已提交
337
        end
I
Izaak Alpert 已提交
338

J
jubianchi 已提交
339 340 341 342
        it 'should return 422 if targeting a different fork' do
          post api("/projects/#{fork_project.id}/merge_requests", user2),
               title: 'Test merge_request',
               target_branch: 'master',
343
               source_branch: 'markdown',
J
jubianchi 已提交
344 345
               author: user2,
               target_project_id: unrelated_project.id
346
          expect(response.status).to eq(422)
J
jubianchi 已提交
347
        end
I
Izaak Alpert 已提交
348 349 350
      end

      it "should return 201 when target_branch is specified and for the same project" do
H
Hiroyuki Sato 已提交
351
        post api("/projects/#{fork_project.id}/merge_requests", user2),
352
        title: 'Test merge_request', target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: fork_project.id
353
        expect(response.status).to eq(201)
I
Izaak Alpert 已提交
354
      end
355
    end
V
Valeriy Sizov 已提交
356 357
  end

358 359 360
  describe "DELETE /projects/:id/merge_requests/:merge_request_id" do
    context "when the user is developer" do
      let(:developer) { create(:user) }
Z
Zeger-Jan van de Weg 已提交
361

362 363 364
      before do
        project.team << [developer, :developer]
      end
Z
Zeger-Jan van de Weg 已提交
365

366 367 368 369
      it "denies the deletion of the merge request" do
        delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}", developer)
        expect(response.status).to be(403)
      end
Z
Zeger-Jan van de Weg 已提交
370
    end
371

372 373 374 375 376 377
    context "when the user is project owner" do
      it "destroys the merge request owners can destroy" do
        delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user)

        expect(response.status).to eq(200)
      end
378
    end
Z
Zeger-Jan van de Weg 已提交
379 380
  end

381
  describe "PUT /projects/:id/merge_requests/:merge_request_id to close MR" do
A
Andrew8xx8 已提交
382
    it "should return merge_request" do
383
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), state_event: "close"
384 385
      expect(response.status).to eq(200)
      expect(json_response['state']).to eq('closed')
A
Andrew8xx8 已提交
386 387 388
    end
  end

389
  describe "PUT /projects/:id/merge_requests/:merge_request_id/merge" do
390
    let(:pipeline) { create(:ci_pipeline_without_jobs) }
391

392
    it "should return merge_request in case of success" do
393
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
394

395
      expect(response.status).to eq(200)
396 397
    end

398
    it "should return 406 if branch can't be merged" do
399 400 401
      allow_any_instance_of(MergeRequest).
        to receive(:can_be_merged?).and_return(false)

402
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
403

404
      expect(response.status).to eq(406)
405
      expect(json_response['message']).to eq('Branch cannot be merged')
A
Andrew8xx8 已提交
406
    end
D
Dmitriy Zaporozhets 已提交
407 408 409

    it "should return 405 if merge_request is not open" do
      merge_request.close
410
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
411 412
      expect(response.status).to eq(405)
      expect(json_response['message']).to eq('405 Method Not Allowed')
D
Dmitriy Zaporozhets 已提交
413 414
    end

415 416
    it "should return 405 if merge_request is a work in progress" do
      merge_request.update_attribute(:title, "WIP: #{merge_request.title}")
417
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
418 419 420 421
      expect(response.status).to eq(405)
      expect(json_response['message']).to eq('405 Method Not Allowed')
    end

422
    it 'returns 405 if the build failed for a merge request that requires success' do
423
      allow_any_instance_of(MergeRequest).to receive(:mergeable_ci_state?).and_return(false)
424 425

      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
426

427 428 429 430
      expect(response.status).to eq(405)
      expect(json_response['message']).to eq('405 Method Not Allowed')
    end

D
Dmitriy Zaporozhets 已提交
431 432 433
    it "should return 401 if user has no permissions to merge" do
      user2 = create(:user)
      project.team << [user2, :reporter]
434
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user2)
435 436
      expect(response.status).to eq(401)
      expect(json_response['message']).to eq('401 Unauthorized')
D
Dmitriy Zaporozhets 已提交
437
    end
438

439 440 441 442 443 444 445 446 447 448 449 450 451
    it "returns 409 if the SHA parameter doesn't match" do
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), sha: merge_request.source_sha.succ

      expect(response.status).to eq(409)
      expect(json_response['message']).to start_with('SHA does not match HEAD of source branch')
    end

    it "succeeds if the SHA parameter matches" do
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), sha: merge_request.source_sha

      expect(response.status).to eq(200)
    end

452
    it "enables merge when build succeeds if the ci is active" do
453
      allow_any_instance_of(MergeRequest).to receive(:pipeline).and_return(pipeline)
454
      allow(pipeline).to receive(:active?).and_return(true)
455

456
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), merge_when_build_succeeds: true
457 458 459 460 461

      expect(response.status).to eq(200)
      expect(json_response['title']).to eq('Test')
      expect(json_response['merge_when_build_succeeds']).to eq(true)
    end
A
Andrew8xx8 已提交
462 463
  end

464
  describe "PUT /projects/:id/merge_requests/:merge_request_id" do
465
    it "updates title and returns merge_request" do
466
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), title: "New title"
467 468
      expect(response.status).to eq(200)
      expect(json_response['title']).to eq('New title')
V
Valeriy Sizov 已提交
469
    end
470

471
    it "updates description and returns merge_request" do
472
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), description: "New description"
473 474
      expect(response.status).to eq(200)
      expect(json_response['description']).to eq('New description')
475 476
    end

477 478 479 480 481 482
    it "updates milestone_id and returns merge_request" do
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), milestone_id: milestone.id
      expect(response.status).to eq(200)
      expect(json_response['milestone']['id']).to eq(milestone.id)
    end

483
    it "should return 400 when source_branch is specified" do
484
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user),
485
      source_branch: "master", target_branch: "master"
486
      expect(response.status).to eq(400)
487 488 489
    end

    it "should return merge_request with renamed target_branch" do
490
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), target_branch: "wiki"
491 492
      expect(response.status).to eq(200)
      expect(json_response['target_branch']).to eq('wiki')
493
    end
494

R
Robert Schilling 已提交
495
    it 'should return 400 on invalid label names' do
496
      put api("/projects/#{project.id}/merge_requests/#{merge_request.id}",
497 498 499
              user),
          title: 'new issue',
          labels: 'label, ?'
500 501
      expect(response.status).to eq(400)
      expect(json_response['message']['labels']['?']['title']).to eq(['is invalid'])
502
    end
V
Valeriy Sizov 已提交
503 504
  end

505
  describe "POST /projects/:id/merge_requests/:merge_request_id/comments" do
V
Valeriy Sizov 已提交
506
    it "should return comment" do
507 508
      original_count = merge_request.notes.size

509
      post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user), note: "My comment"
510 511
      expect(response.status).to eq(201)
      expect(json_response['note']).to eq('My comment')
512 513 514
      expect(json_response['author']['name']).to eq(user.name)
      expect(json_response['author']['username']).to eq(user.username)
      expect(merge_request.notes.size).to eq(original_count + 1)
V
Valeriy Sizov 已提交
515
    end
516 517

    it "should return 400 if note is missing" do
518
      post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user)
519
      expect(response.status).to eq(400)
520
    end
521 522

    it "should return 404 if note is attached to non existent merge request" do
523
      post api("/projects/#{project.id}/merge_requests/404/comments", user),
J
jubianchi 已提交
524
           note: 'My comment'
525
      expect(response.status).to eq(404)
526
    end
V
Valeriy Sizov 已提交
527
  end
528

529
  describe "GET :id/merge_requests/:merge_request_id/comments" do
530
    it "should return merge_request comments ordered by created_at" do
531
      get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user)
532 533
      expect(response.status).to eq(200)
      expect(json_response).to be_an Array
534
      expect(json_response.length).to eq(2)
535 536
      expect(json_response.first['note']).to eq("a comment on a MR")
      expect(json_response.first['author']['id']).to eq(user.id)
537
      expect(json_response.last['note']).to eq("another comment on a MR")
538 539 540
    end

    it "should return a 404 error if merge_request_id not found" do
541
      get api("/projects/#{project.id}/merge_requests/999/comments", user)
542
      expect(response.status).to eq(404)
543 544
    end
  end
545

546 547 548 549 550 551
  describe 'GET :id/merge_requests/:merge_request_id/closes_issues' do
    it 'returns the issue that will be closed on merge' do
      issue = create(:issue, project: project)
      mr = merge_request.tap do |mr|
        mr.update_attribute(:description, "Closes #{issue.to_reference(mr.project)}")
      end
552

553
      get api("/projects/#{project.id}/merge_requests/#{mr.id}/closes_issues", user)
554 555 556 557 558 559
      expect(response.status).to eq(200)
      expect(json_response).to be_an Array
      expect(json_response.length).to eq(1)
      expect(json_response.first['id']).to eq(issue.id)
    end

560
    it 'returns an empty array when there are no issues to be closed' do
561 562 563 564 565
      get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/closes_issues", user)
      expect(response.status).to eq(200)
      expect(json_response).to be_an Array
      expect(json_response.length).to eq(0)
    end
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580

    it 'handles external issues' do
      jira_project = create(:jira_project, :public, name: 'JIR_EXT1')
      issue = ExternalIssue.new("#{jira_project.name}-123", jira_project)
      merge_request = create(:merge_request, :simple, author: user, assignee: user, source_project: jira_project)
      merge_request.update_attribute(:description, "Closes #{issue.to_reference(jira_project)}")

      get api("/projects/#{jira_project.id}/merge_requests/#{merge_request.id}/closes_issues", user)

      expect(response.status).to eq(200)
      expect(json_response).to be_an Array
      expect(json_response.length).to eq(1)
      expect(json_response.first['title']).to eq(issue.title)
      expect(json_response.first['id']).to eq(issue.id)
    end
581 582
  end

583
  describe 'POST :id/merge_requests/:merge_request_id/subscription' do
584
    it 'subscribes to a merge request' do
585
      post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", admin)
586 587 588 589 590 591

      expect(response.status).to eq(201)
      expect(json_response['subscribed']).to eq(true)
    end

    it 'returns 304 if already subscribed' do
592
      post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", user)
593 594 595

      expect(response.status).to eq(304)
    end
596 597 598 599 600 601

    it 'returns 404 if the merge request is not found' do
      post api("/projects/#{project.id}/merge_requests/123/subscription", user)

      expect(response.status).to eq(404)
    end
602 603
  end

604
  describe 'DELETE :id/merge_requests/:merge_request_id/subscription' do
605
    it 'unsubscribes from a merge request' do
606
      delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", user)
607

608
      expect(response.status).to eq(200)
609 610 611 612
      expect(json_response['subscribed']).to eq(false)
    end

    it 'returns 304 if not subscribed' do
613
      delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", admin)
614 615 616

      expect(response.status).to eq(304)
    end
617 618 619 620 621 622

    it 'returns 404 if the merge request is not found' do
      post api("/projects/#{project.id}/merge_requests/123/subscription", user)

      expect(response.status).to eq(404)
    end
623 624
  end

625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
  def mr_with_later_created_and_updated_at_time
    merge_request
    merge_request.created_at += 1.hour
    merge_request.updated_at += 30.minutes
    merge_request.save
    merge_request
  end

  def mr_with_earlier_created_and_updated_at_time
    merge_request_closed
    merge_request_closed.created_at -= 1.hour
    merge_request_closed.updated_at -= 30.minutes
    merge_request_closed.save
    merge_request_closed
  end
V
Valeriy Sizov 已提交
640
end