notes_controller_spec.rb 9.46 KB
Newer Older
1
require 'spec_helper'
2 3 4

describe Projects::NotesController do
  let(:user)    { create(:user) }
5
  let(:project) { create(:empty_project) }
6 7 8
  let(:issue)   { create(:issue, project: project) }
  let(:note)    { create(:note, noteable: issue, project: project) }

Douwe Maan's avatar
Douwe Maan committed
9 10 11 12 13 14 15 16
  let(:request_params) do
    {
      namespace_id: project.namespace,
      project_id: project,
      id: note
    }
  end

17
  describe 'GET index' do
Douwe Maan's avatar
Douwe Maan committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
    let(:request_params) do
      {
        namespace_id: project.namespace,
        project_id: project,
        target_type: 'issue',
        target_id: issue.id,
        format: 'json'
      }
    end

    let(:parsed_response) { JSON.parse(response.body).with_indifferent_access }
    let(:note_json) { parsed_response[:notes].first }

    before do
      sign_in(user)
      project.team << [user, :developer]
    end

    it 'passes last_fetched_at from headers to NotesFinder' do
Douwe Maan's avatar
Douwe Maan committed
37 38
      last_fetched_at = 3.hours.ago.to_i

Douwe Maan's avatar
Douwe Maan committed
39 40 41 42 43 44 45 46 47 48 49 50
      request.headers['X-Last-Fetched-At'] = last_fetched_at

      expect(NotesFinder).to receive(:new)
        .with(anything, anything, hash_including(last_fetched_at: last_fetched_at))
        .and_call_original

      get :index, request_params
    end

    context 'for a discussion note' do
      let!(:note) { create(:discussion_note_on_issue, noteable: issue, project: project) }

Douwe Maan's avatar
Douwe Maan committed
51
      it 'responds with the expected attributes' do
Douwe Maan's avatar
Douwe Maan committed
52 53 54 55 56 57 58 59 60 61 62 63 64 65
        get :index, request_params

        expect(note_json[:id]).to eq(note.id)
        expect(note_json[:discussion_html]).not_to be_nil
        expect(note_json[:diff_discussion_html]).to be_nil
      end
    end

    context 'for a diff discussion note' do
      let(:project) { create(:project, :repository) }
      let!(:note) { create(:diff_note_on_merge_request, project: project) }

      let(:params) { request_params.merge(target_type: 'merge_request', target_id: note.noteable_id) }

Douwe Maan's avatar
Douwe Maan committed
66
      it 'responds with the expected attributes' do
Douwe Maan's avatar
Douwe Maan committed
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
        get :index, params

        expect(note_json[:id]).to eq(note.id)
        expect(note_json[:discussion_html]).not_to be_nil
        expect(note_json[:diff_discussion_html]).not_to be_nil
      end
    end

    context 'for a commit note' do
      let(:project) { create(:project, :repository) }
      let!(:note) { create(:note_on_commit, project: project) }

      context 'when displayed on a merge request' do
        let(:merge_request) { create(:merge_request, source_project: project) }

        let(:params) { request_params.merge(target_type: 'merge_request', target_id: merge_request.id) }

Douwe Maan's avatar
Douwe Maan committed
84
        it 'responds with the expected attributes' do
Douwe Maan's avatar
Douwe Maan committed
85 86 87 88 89 90 91 92 93 94 95
          get :index, params

          expect(note_json[:id]).to eq(note.id)
          expect(note_json[:discussion_html]).not_to be_nil
          expect(note_json[:diff_discussion_html]).to be_nil
        end
      end

      context 'when displayed on the commit' do
        let(:params) { request_params.merge(target_type: 'commit', target_id: note.commit_id) }

Douwe Maan's avatar
Douwe Maan committed
96
        it 'responds with the expected attributes' do
Douwe Maan's avatar
Douwe Maan committed
97 98 99 100 101 102 103 104 105 106 107 108
          get :index, params

          expect(note_json[:id]).to eq(note.id)
          expect(note_json[:discussion_html]).to be_nil
          expect(note_json[:diff_discussion_html]).to be_nil
        end
      end
    end

    context 'for a regular note' do
      let!(:note) { create(:note, noteable: issue, project: project) }

Douwe Maan's avatar
Douwe Maan committed
109
      it 'responds with the expected attributes' do
Douwe Maan's avatar
Douwe Maan committed
110 111 112 113 114 115 116 117
        get :index, request_params

        expect(note_json[:id]).to eq(note.id)
        expect(note_json[:html]).not_to be_nil
        expect(note_json[:discussion_html]).to be_nil
        expect(note_json[:diff_discussion_html]).to be_nil
      end
    end
118 119
  end

120 121
  describe 'POST create' do
    let(:merge_request) { create(:merge_request) }
122
    let(:project) { merge_request.source_project }
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    let(:request_params) do
      {
        note: { note: 'some note', noteable_id: merge_request.id, noteable_type: 'MergeRequest' },
        namespace_id: project.namespace,
        project_id: project,
        merge_request_diff_head_sha: 'sha'
      }
    end

    before do
      sign_in(user)
      project.team << [user, :developer]
    end

    it "returns status 302 for html" do
      post :create, request_params

      expect(response).to have_http_status(302)
    end

    it "returns status 200 for json" do
      post :create, request_params.merge(format: :json)

      expect(response).to have_http_status(200)
    end

    context 'when merge_request_diff_head_sha present' do
      before do
        service_params = {
          note: 'some note',
          noteable_id: merge_request.id.to_s,
          noteable_type: 'MergeRequest',
155
          merge_request_diff_head_sha: 'sha',
Douwe Maan's avatar
Douwe Maan committed
156
          in_reply_to_discussion_id: nil
157 158 159 160 161 162 163 164 165 166 167 168 169
        }

        expect(Notes::CreateService).to receive(:new).with(project, user, service_params).and_return(double(execute: true))
      end

      it "returns status 302 for html" do
        post :create, request_params

        expect(response).to have_http_status(302)
      end
    end
  end

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
  describe 'DELETE destroy' do
    let(:request_params) do
      {
        namespace_id: project.namespace,
        project_id: project,
        id: note,
        format: :js
      }
    end

    context 'user is the author of a note' do
      before do
        sign_in(note.author)
        project.team << [note.author, :developer]
      end

      it "returns status 200 for html" do
        delete :destroy, request_params

        expect(response).to have_http_status(200)
      end

      it "deletes the note" do
        expect { delete :destroy, request_params }.to change { Note.count }.from(1).to(0)
      end
    end

    context 'user is not the author of a note' do
      before do
        sign_in(user)
        project.team << [user, :developer]
      end

      it "returns status 404" do
        delete :destroy, request_params

        expect(response).to have_http_status(404)
      end
    end
  end

211
  describe 'POST toggle_award_emoji' do
212 213 214 215 216 217 218
    before do
      sign_in(user)
      project.team << [user, :developer]
    end

    it "toggles the award emoji" do
      expect do
Douwe Maan's avatar
Douwe Maan committed
219
        post(:toggle_award_emoji, request_params.merge(name: "thumbsup"))
Z.J. van de Weg's avatar
Z.J. van de Weg committed
220
      end.to change { note.award_emoji.count }.by(1)
221

222
      expect(response).to have_http_status(200)
223 224
    end

Z.J. van de Weg's avatar
Z.J. van de Weg committed
225
    it "removes the already awarded emoji" do
Douwe Maan's avatar
Douwe Maan committed
226
      post(:toggle_award_emoji, request_params.merge(name: "thumbsup"))
227 228

      expect do
Douwe Maan's avatar
Douwe Maan committed
229
        post(:toggle_award_emoji, request_params.merge(name: "thumbsup"))
230 231
      end.to change { AwardEmoji.count }.by(-1)

232
      expect(response).to have_http_status(200)
233 234
    end
  end
235

Douwe Maan's avatar
Douwe Maan committed
236
  describe "resolving and unresolving" do
237
    let(:project) { create(:project, :repository) }
Douwe Maan's avatar
Douwe Maan committed
238 239
    let(:merge_request) { create(:merge_request, source_project: project) }
    let(:note) { create(:diff_note_on_merge_request, noteable: merge_request, project: project) }
240

Douwe Maan's avatar
Douwe Maan committed
241
    describe 'POST resolve' do
242
      before do
Douwe Maan's avatar
Douwe Maan committed
243
        sign_in user
244 245
      end

Douwe Maan's avatar
Douwe Maan committed
246
      context "when the user is not authorized to resolve the note" do
247
        it "returns status 404" do
Douwe Maan's avatar
Douwe Maan committed
248
          post :resolve, request_params
249 250 251 252 253

          expect(response).to have_http_status(404)
        end
      end

Douwe Maan's avatar
Douwe Maan committed
254 255 256
      context "when the user is authorized to resolve the note" do
        before do
          project.team << [user, :developer]
257 258
        end

Douwe Maan's avatar
Douwe Maan committed
259 260 261 262
        context "when the note is not resolvable" do
          before do
            note.update(system: true)
          end
263

Douwe Maan's avatar
Douwe Maan committed
264 265 266 267 268
          it "returns status 404" do
            post :resolve, request_params

            expect(response).to have_http_status(404)
          end
269 270
        end

Douwe Maan's avatar
Douwe Maan committed
271 272 273
        context "when the note is resolvable" do
          it "resolves the note" do
            post :resolve, request_params
274

Douwe Maan's avatar
Douwe Maan committed
275 276 277
            expect(note.reload.resolved?).to be true
            expect(note.reload.resolved_by).to eq(user)
          end
278

Douwe Maan's avatar
Douwe Maan committed
279 280
          it "sends notifications if all discussions are resolved" do
            expect_any_instance_of(MergeRequests::ResolvedDiscussionNotificationService).to receive(:execute).with(merge_request)
281

Douwe Maan's avatar
Douwe Maan committed
282 283
            post :resolve, request_params
          end
284

Douwe Maan's avatar
Douwe Maan committed
285 286 287 288 289
          it "returns the name of the resolving user" do
            post :resolve, request_params

            expect(JSON.parse(response.body)["resolved_by"]).to eq(user.name)
          end
290

Douwe Maan's avatar
Douwe Maan committed
291 292
          it "returns status 200" do
            post :resolve, request_params
293

Douwe Maan's avatar
Douwe Maan committed
294 295 296
            expect(response).to have_http_status(200)
          end
        end
297 298 299
      end
    end

Douwe Maan's avatar
Douwe Maan committed
300
    describe 'DELETE unresolve' do
301
      before do
Douwe Maan's avatar
Douwe Maan committed
302 303 304
        sign_in user

        note.resolve!(user)
305 306
      end

Douwe Maan's avatar
Douwe Maan committed
307
      context "when the user is not authorized to resolve the note" do
308
        it "returns status 404" do
Douwe Maan's avatar
Douwe Maan committed
309
          delete :unresolve, request_params
310 311 312 313 314

          expect(response).to have_http_status(404)
        end
      end

Douwe Maan's avatar
Douwe Maan committed
315 316 317 318 319 320 321 322 323
      context "when the user is authorized to resolve the note" do
        before do
          project.team << [user, :developer]
        end

        context "when the note is not resolvable" do
          before do
            note.update(system: true)
          end
324

Douwe Maan's avatar
Douwe Maan committed
325 326
          it "returns status 404" do
            delete :unresolve, request_params
327

Douwe Maan's avatar
Douwe Maan committed
328 329
            expect(response).to have_http_status(404)
          end
330 331
        end

Douwe Maan's avatar
Douwe Maan committed
332 333 334 335 336 337 338 339 340
        context "when the note is resolvable" do
          it "unresolves the note" do
            delete :unresolve, request_params

            expect(note.reload.resolved?).to be false
          end

          it "returns status 200" do
            delete :unresolve, request_params
341

Douwe Maan's avatar
Douwe Maan committed
342 343
            expect(response).to have_http_status(200)
          end
344 345 346 347
        end
      end
    end
  end
348
end