notes_spec.rb 15.7 KB
Newer Older
1 2
require 'spec_helper'

3
describe API::V3::Notes do
4
  let(:user) { create(:user) }
5
  let!(:project) { create(:project, :public, namespace: user.namespace) }
6 7 8 9 10 11 12 13 14 15
  let!(:issue) { create(:issue, project: project, author: user) }
  let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: user) }
  let!(:snippet) { create(:project_snippet, project: project, author: user) }
  let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) }
  let!(:merge_request_note) { create(:note, noteable: merge_request, project: project, author: user) }
  let!(:snippet_note) { create(:note, noteable: snippet, project: project, author: user) }

  # For testing the cross-reference of a private issue in a public issue
  let(:private_user)    { create(:user) }
  let(:private_project) do
16
    create(:project, namespace: private_user.namespace)
17
    .tap { |p| p.add_master(private_user) }
18 19 20
  end
  let(:private_issue)    { create(:issue, project: private_project) }

21
  let(:ext_proj)  { create(:project, :public) }
22 23 24 25 26 27 28 29 30
  let(:ext_issue) { create(:issue, project: ext_proj) }

  let!(:cross_reference_note) do
    create :note,
    noteable: ext_issue, project: ext_proj,
    note: "mentioned in issue #{private_issue.to_reference(ext_proj)}",
    system: true
  end

31
  before { project.add_reporter(user) }
32 33 34 35 36 37

  describe "GET /projects/:id/noteable/:noteable_id/notes" do
    context "when noteable is an Issue" do
      it "returns an array of issue notes" do
        get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user)

38
        expect(response).to have_gitlab_http_status(200)
39 40 41 42 43 44 45 46 47 48
        expect(response).to include_pagination_headers
        expect(json_response).to be_an Array
        expect(json_response.first['body']).to eq(issue_note.note)
        expect(json_response.first['upvote']).to be_falsey
        expect(json_response.first['downvote']).to be_falsey
      end

      it "returns a 404 error when issue id not found" do
        get v3_api("/projects/#{project.id}/issues/12345/notes", user)

49
        expect(response).to have_gitlab_http_status(404)
50 51 52 53 54 55
      end

      context "and current user cannot view the notes" do
        it "returns an empty array" do
          get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user)

56
          expect(response).to have_gitlab_http_status(200)
57 58 59 60 61 62 63 64 65 66 67
          expect(response).to include_pagination_headers
          expect(json_response).to be_an Array
          expect(json_response).to be_empty
        end

        context "and issue is confidential" do
          before { ext_issue.update_attributes(confidential: true) }

          it "returns 404" do
            get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user)

68
            expect(response).to have_gitlab_http_status(404)
69 70 71 72 73 74 75
          end
        end

        context "and current user can view the note" do
          it "returns an empty array" do
            get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", private_user)

76
            expect(response).to have_gitlab_http_status(200)
77 78 79 80 81 82 83 84 85 86 87 88
            expect(response).to include_pagination_headers
            expect(json_response).to be_an Array
            expect(json_response.first['body']).to eq(cross_reference_note.note)
          end
        end
      end
    end

    context "when noteable is a Snippet" do
      it "returns an array of snippet notes" do
        get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user)

89
        expect(response).to have_gitlab_http_status(200)
90 91 92 93 94 95 96 97
        expect(response).to include_pagination_headers
        expect(json_response).to be_an Array
        expect(json_response.first['body']).to eq(snippet_note.note)
      end

      it "returns a 404 error when snippet id not found" do
        get v3_api("/projects/#{project.id}/snippets/42/notes", user)

98
        expect(response).to have_gitlab_http_status(404)
99 100 101 102 103
      end

      it "returns 404 when not authorized" do
        get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", private_user)

104
        expect(response).to have_gitlab_http_status(404)
105 106 107 108 109 110 111
      end
    end

    context "when noteable is a Merge Request" do
      it "returns an array of merge_requests notes" do
        get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/notes", user)

112
        expect(response).to have_gitlab_http_status(200)
113 114 115 116 117 118 119 120
        expect(response).to include_pagination_headers
        expect(json_response).to be_an Array
        expect(json_response.first['body']).to eq(merge_request_note.note)
      end

      it "returns a 404 error if merge request id not found" do
        get v3_api("/projects/#{project.id}/merge_requests/4444/notes", user)

121
        expect(response).to have_gitlab_http_status(404)
122 123 124 125 126
      end

      it "returns 404 when not authorized" do
        get v3_api("/projects/#{project.id}/merge_requests/4444/notes", private_user)

127
        expect(response).to have_gitlab_http_status(404)
128 129 130 131 132 133 134 135 136
      end
    end
  end

  describe "GET /projects/:id/noteable/:noteable_id/notes/:note_id" do
    context "when noteable is an Issue" do
      it "returns an issue note by id" do
        get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", user)

137
        expect(response).to have_gitlab_http_status(200)
138 139 140 141 142 143
        expect(json_response['body']).to eq(issue_note.note)
      end

      it "returns a 404 error if issue note not found" do
        get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user)

144
        expect(response).to have_gitlab_http_status(404)
145 146 147 148 149 150
      end

      context "and current user cannot view the note" do
        it "returns a 404 error" do
          get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", user)

151
          expect(response).to have_gitlab_http_status(404)
152 153 154 155 156 157 158 159
        end

        context "when issue is confidential" do
          before { issue.update_attributes(confidential: true) }

          it "returns 404" do
            get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", private_user)

160
            expect(response).to have_gitlab_http_status(404)
161 162 163 164 165 166 167
          end
        end

        context "and current user can view the note" do
          it "returns an issue note by id" do
            get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", private_user)

168
            expect(response).to have_gitlab_http_status(200)
169 170 171 172 173 174 175 176 177 178
            expect(json_response['body']).to eq(cross_reference_note.note)
          end
        end
      end
    end

    context "when noteable is a Snippet" do
      it "returns a snippet note by id" do
        get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes/#{snippet_note.id}", user)

179
        expect(response).to have_gitlab_http_status(200)
180 181 182 183 184 185
        expect(json_response['body']).to eq(snippet_note.note)
      end

      it "returns a 404 error if snippet note not found" do
        get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes/12345", user)

186
        expect(response).to have_gitlab_http_status(404)
187 188 189 190 191 192 193 194 195
      end
    end
  end

  describe "POST /projects/:id/noteable/:noteable_id/notes" do
    context "when noteable is an Issue" do
      it "creates a new issue note" do
        post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!'

196
        expect(response).to have_gitlab_http_status(201)
197 198 199 200 201 202 203
        expect(json_response['body']).to eq('hi!')
        expect(json_response['author']['username']).to eq(user.username)
      end

      it "returns a 400 bad request error if body not given" do
        post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user)

204
        expect(response).to have_gitlab_http_status(400)
205 206 207 208 209
      end

      it "returns a 401 unauthorized error if user not authenticated" do
        post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes"), body: 'hi!'

210
        expect(response).to have_gitlab_http_status(401)
211 212 213 214 215 216 217 218
      end

      context 'when an admin or owner makes the request' do
        it 'accepts the creation date to be set' do
          creation_time = 2.weeks.ago
          post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user),
            body: 'hi!', created_at: creation_time

219
          expect(response).to have_gitlab_http_status(201)
220 221 222 223 224 225 226 227 228
          expect(json_response['body']).to eq('hi!')
          expect(json_response['author']['username']).to eq(user.username)
          expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
        end
      end

      context 'when the user is posting an award emoji on an issue created by someone else' do
        let(:issue2) { create(:issue, project: project) }

mhasbini's avatar
mhasbini committed
229
        it 'creates a new issue note' do
230 231
          post v3_api("/projects/#{project.id}/issues/#{issue2.id}/notes", user), body: ':+1:'

232
          expect(response).to have_gitlab_http_status(201)
mhasbini's avatar
mhasbini committed
233
          expect(json_response['body']).to eq(':+1:')
234 235 236 237 238 239 240
        end
      end

      context 'when the user is posting an award emoji on his/her own issue' do
        it 'creates a new issue note' do
          post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: ':+1:'

241
          expect(response).to have_gitlab_http_status(201)
242 243 244 245 246 247 248 249 250
          expect(json_response['body']).to eq(':+1:')
        end
      end
    end

    context "when noteable is a Snippet" do
      it "creates a new snippet note" do
        post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user), body: 'hi!'

251
        expect(response).to have_gitlab_http_status(201)
252 253 254 255 256 257 258
        expect(json_response['body']).to eq('hi!')
        expect(json_response['author']['username']).to eq(user.username)
      end

      it "returns a 400 bad request error if body not given" do
        post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user)

259
        expect(response).to have_gitlab_http_status(400)
260 261 262 263 264
      end

      it "returns a 401 unauthorized error if user not authenticated" do
        post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes"), body: 'hi!'

265
        expect(response).to have_gitlab_http_status(401)
266 267 268 269 270
      end
    end

    context 'when user does not have access to read the noteable' do
      it 'responds with 404' do
271
        project = create(:project, :private) { |p| p.add_guest(user) }
272 273 274 275 276
        issue = create(:issue, :confidential, project: project)

        post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user),
          body: 'Foo'

277
        expect(response).to have_gitlab_http_status(404)
278 279 280 281
      end
    end

    context 'when user does not have access to create noteable' do
282
      let(:private_issue) { create(:issue, project: create(:project, :private)) }
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316

      ##
      # We are posting to project user has access to, but we use issue id
      # from a different project, see #15577
      #
      before do
        post v3_api("/projects/#{project.id}/issues/#{private_issue.id}/notes", user),
             body: 'Hi!'
      end

      it 'responds with resource not found error' do
        expect(response.status).to eq 404
      end

      it 'does not create new note' do
        expect(private_issue.notes.reload).to be_empty
      end
    end
  end

  describe "POST /projects/:id/noteable/:noteable_id/notes to test observer on create" do
    it "creates an activity event when an issue note is created" do
      expect(Event).to receive(:create)

      post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!'
    end
  end

  describe 'PUT /projects/:id/noteable/:noteable_id/notes/:note_id' do
    context 'when noteable is an Issue' do
      it 'returns modified note' do
        put v3_api("/projects/#{project.id}/issues/#{issue.id}/"\
                  "notes/#{issue_note.id}", user), body: 'Hello!'

317
        expect(response).to have_gitlab_http_status(200)
318 319 320 321 322 323 324
        expect(json_response['body']).to eq('Hello!')
      end

      it 'returns a 404 error when note id not found' do
        put v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user),
                body: 'Hello!'

325
        expect(response).to have_gitlab_http_status(404)
326 327 328 329 330 331
      end

      it 'returns a 400 bad request error if body not given' do
        put v3_api("/projects/#{project.id}/issues/#{issue.id}/"\
                  "notes/#{issue_note.id}", user)

332
        expect(response).to have_gitlab_http_status(400)
333 334 335 336 337 338 339 340
      end
    end

    context 'when noteable is a Snippet' do
      it 'returns modified note' do
        put v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
                  "notes/#{snippet_note.id}", user), body: 'Hello!'

341
        expect(response).to have_gitlab_http_status(200)
342 343 344 345 346 347 348
        expect(json_response['body']).to eq('Hello!')
      end

      it 'returns a 404 error when note id not found' do
        put v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
                  "notes/12345", user), body: "Hello!"

349
        expect(response).to have_gitlab_http_status(404)
350 351 352 353 354 355 356 357
      end
    end

    context 'when noteable is a Merge Request' do
      it 'returns modified note' do
        put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\
                  "notes/#{merge_request_note.id}", user), body: 'Hello!'

358
        expect(response).to have_gitlab_http_status(200)
359 360 361 362 363 364 365
        expect(json_response['body']).to eq('Hello!')
      end

      it 'returns a 404 error when note id not found' do
        put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\
                  "notes/12345", user), body: "Hello!"

366
        expect(response).to have_gitlab_http_status(404)
367 368 369 370 371 372 373 374
      end
    end
  end

  describe 'DELETE /projects/:id/noteable/:noteable_id/notes/:note_id' do
    context 'when noteable is an Issue' do
      it 'deletes a note' do
        delete v3_api("/projects/#{project.id}/issues/#{issue.id}/"\
Robert Schilling's avatar
Robert Schilling committed
375
                      "notes/#{issue_note.id}", user)
376

377
        expect(response).to have_gitlab_http_status(200)
378 379
        # Check if note is really deleted
        delete v3_api("/projects/#{project.id}/issues/#{issue.id}/"\
Robert Schilling's avatar
Robert Schilling committed
380
                      "notes/#{issue_note.id}", user)
381
        expect(response).to have_gitlab_http_status(404)
382 383 384 385 386
      end

      it 'returns a 404 error when note id not found' do
        delete v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user)

387
        expect(response).to have_gitlab_http_status(404)
388 389 390 391 392 393
      end
    end

    context 'when noteable is a Snippet' do
      it 'deletes a note' do
        delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
Robert Schilling's avatar
Robert Schilling committed
394
                      "notes/#{snippet_note.id}", user)
395

396
        expect(response).to have_gitlab_http_status(200)
397 398
        # Check if note is really deleted
        delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
Robert Schilling's avatar
Robert Schilling committed
399
                      "notes/#{snippet_note.id}", user)
400
        expect(response).to have_gitlab_http_status(404)
401 402 403 404
      end

      it 'returns a 404 error when note id not found' do
        delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
Robert Schilling's avatar
Robert Schilling committed
405
                      "notes/12345", user)
406

407
        expect(response).to have_gitlab_http_status(404)
408 409 410 411 412 413
      end
    end

    context 'when noteable is a Merge Request' do
      it 'deletes a note' do
        delete v3_api("/projects/#{project.id}/merge_requests/"\
Robert Schilling's avatar
Robert Schilling committed
414
                      "#{merge_request.id}/notes/#{merge_request_note.id}", user)
415

416
        expect(response).to have_gitlab_http_status(200)
417 418
        # Check if note is really deleted
        delete v3_api("/projects/#{project.id}/merge_requests/"\
Robert Schilling's avatar
Robert Schilling committed
419
                      "#{merge_request.id}/notes/#{merge_request_note.id}", user)
420
        expect(response).to have_gitlab_http_status(404)
421 422 423 424
      end

      it 'returns a 404 error when note id not found' do
        delete v3_api("/projects/#{project.id}/merge_requests/"\
Robert Schilling's avatar
Robert Schilling committed
425
                      "#{merge_request.id}/notes/12345", user)
426

427
        expect(response).to have_gitlab_http_status(404)
428 429 430 431
      end
    end
  end
end