notes_on_merge_requests_spec.rb 9.03 KB
Newer Older
1 2
require 'spec_helper'

3
describe 'Comments', feature: true do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
4
  include RepoHelpers
5
  include WaitForAjax
6

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
7
  describe 'On a merge request', js: true, feature: true do
8 9 10 11 12
    let!(:project) { create(:project) }
    let!(:merge_request) do
      create(:merge_request, source_project: project, target_project: project)
    end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
13
    let!(:note) do
14 15
      create(:note_on_merge_request, :with_attachment, noteable: merge_request,
                                                       project: project)
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
16
    end
17

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
18 19
    before do
      login_as :admin
Vinnie Okada's avatar
Vinnie Okada committed
20
      visit namespace_project_merge_request_path(project.namespace, project, merge_request)
21 22
    end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
23
    subject { page }
24

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
25
    describe 'the note form' do
26
      it 'is valid' do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
27
        is_expected.to have_css('.js-main-target-form', visible: true, count: 1)
28
        expect(find('.js-main-target-form .js-comment-button').value).
29
          to eq('Comment')
30
        page.within('.js-main-target-form') do
31 32
          expect(page).not_to have_link('Cancel')
        end
33
      end
34

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
35
      describe 'with text' do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
36
        before do
37
          page.within('.js-main-target-form') do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
38
            fill_in 'note[note]', with: 'This is awesome'
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
39 40 41
          end
        end

42
        it 'has enable submit button and preview button' do
43
          page.within('.js-main-target-form') do
Vinnie Okada's avatar
Vinnie Okada committed
44
            expect(page).not_to have_css('.js-comment-button[disabled]')
Vinnie Okada's avatar
Vinnie Okada committed
45
            expect(page).to have_css('.js-md-preview-button', visible: true)
46
          end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
47
        end
48 49 50
      end
    end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
51
    describe 'when posting a note' do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
52
      before do
53
        page.within('.js-main-target-form') do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
54
          fill_in 'note[note]', with: 'This is awsome!'
55
          find('.js-md-preview-button').click
56
          click_button 'Comment'
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
57 58
        end
      end
Jack Weeden's avatar
Jack Weeden committed
59

60
      it 'is added and form reset' do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
61
        is_expected.to have_content('This is awsome!')
62
        page.within('.js-main-target-form') do
Vinnie Okada's avatar
Vinnie Okada committed
63
          expect(page).to have_no_field('note[note]', with: 'This is awesome!')
Vinnie Okada's avatar
Vinnie Okada committed
64
          expect(page).to have_css('.js-md-preview', visible: :hidden)
65
        end
66
        page.within('.js-main-target-form') do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
67 68
          is_expected.to have_css('.js-note-text', visible: true)
        end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
69
      end
Jack Weeden's avatar
Jack Weeden committed
70 71
    end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
72
    describe 'when editing a note', js: true do
Fatih Acet's avatar
Fatih Acet committed
73
      it 'there should be a hidden edit form' do
74 75
        is_expected.to have_css('.note-edit-form:not(.mr-note-edit-form)', visible: false, count: 1)
        is_expected.to have_css('.note-edit-form.mr-note-edit-form', visible: false, count: 1)
76 77
      end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
78
      describe 'editing the note' do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
79 80
        before do
          find('.note').hover
81
          find('.js-note-edit').click
Jack Weeden's avatar
Jack Weeden committed
82 83
        end

84
        it 'shows the note edit form and hide the note body' do
85
          page.within("#note_#{note.id}") do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
86 87
            expect(find('.current-note-edit-form', visible: true)).to be_visible
            expect(find('.note-edit-form', visible: true)).to be_visible
88
            expect(find(:css, '.note-body > .note-text', visible: false)).not_to be_visible
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
89
          end
Jack Weeden's avatar
Jack Weeden committed
90 91
        end

Valery Sizov's avatar
Valery Sizov committed
92
        it 'resets the edit note form textarea with the original content of the note if cancelled' do
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
          within('.current-note-edit-form') do
            fill_in 'note[note]', with: 'Some new content'
            find('.btn-cancel').click
            expect(find('.js-note-text', visible: false).text).to eq ''
          end
        end

        it 'allows using markdown buttons after saving a note and then trying to edit it again' do
          page.within('.current-note-edit-form') do
            fill_in 'note[note]', with: 'This is the new content'
            find('.btn-save').click
          end

          find('.note').hover
          find('.js-note-edit').click

          page.within('.current-note-edit-form') do
            expect(find('#note_note').value).to eq('This is the new content')
            find('.js-md:first-child').click
            expect(find('#note_note').value).to eq('This is the new content****')
          end
        end
Jack Weeden's avatar
Jack Weeden committed
115

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
116
        it 'appends the edited at time to the note' do
117
          page.within('.current-note-edit-form') do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
118 119
            fill_in 'note[note]', with: 'Some new content'
            find('.btn-save').click
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
120 121
          end

122
          page.within("#note_#{note.id}") do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
123 124 125
            is_expected.to have_css('.note_edited_ago')
            expect(find('.note_edited_ago').text).
              to match(/less than a minute ago/)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
126
          end
Jack Weeden's avatar
Jack Weeden committed
127 128 129
        end
      end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
130
      describe 'deleting an attachment' do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
131 132
        before do
          find('.note').hover
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
133
          find('.js-note-edit').click
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
134
        end
Jack Weeden's avatar
Jack Weeden committed
135

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
136
        it 'shows the delete link' do
137
          page.within('.note-attachment') do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
138
            is_expected.to have_css('.js-note-attachment-delete')
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
139
          end
Jack Weeden's avatar
Jack Weeden committed
140 141
        end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
142 143 144
        it 'removes the attachment div and resets the edit form' do
          find('.js-note-attachment-delete').click
          is_expected.not_to have_css('.note-attachment')
145 146
          is_expected.not_to have_css('.current-note-edit-form')
          wait_for_ajax
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
147
        end
Jack Weeden's avatar
Jack Weeden committed
148 149 150
      end
    end
  end
151

152 153 154 155 156 157
  describe 'Handles cross-project system notes', js: true, feature: true do
    let(:user) { create(:user) }
    let(:project) { create(:project, :public) }
    let(:project2) { create(:project, :private) }
    let(:issue) { create(:issue, project: project2) }
    let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'markdown') }
158
    let!(:note) { create(:note_on_merge_request, :system, noteable: merge_request, project: project, note: "mentioned in #{issue.to_reference(project)}") }
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173

    it 'shows the system note' do
      login_as :admin
      visit namespace_project_merge_request_path(project.namespace, project, merge_request)

      expect(page).to have_css('.system-note')
    end

    it 'hides redacted system note' do
      visit namespace_project_merge_request_path(project.namespace, project, merge_request)

      expect(page).not_to have_css('.system-note')
    end
  end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
174
  describe 'On a merge request diff', js: true, feature: true do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
175 176
    let(:merge_request) { create(:merge_request) }
    let(:project) { merge_request.source_project }
177 178

    before do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
179
      login_as :admin
Vinnie Okada's avatar
Vinnie Okada committed
180
      visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)
181 182
    end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
183
    subject { page }
184

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
185
    describe 'when adding a note' do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
186
      before do
187
        click_diff_line
188 189
      end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
190 191
      describe 'the notes holder' do
        it { is_expected.to have_css('.js-temp-notes-holder') }
192

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
193
        it 'has .new_note css class' do
194
          page.within('.js-temp-notes-holder') do
Phil Hughes's avatar
Phil Hughes committed
195
            expect(subject).to have_css('.new-note')
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
196 197
          end
        end
198 199
      end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
200
      describe 'the note form' do
Valery Sizov's avatar
Valery Sizov committed
201
        it "does not add a second form for same row" do
202
          click_diff_line
203

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
204
          is_expected.
205
            to have_css("form[data-line-code='#{line_code}']",
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
206
                        count: 1)
207
        end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
208

Valery Sizov's avatar
Valery Sizov committed
209
        it 'is removed when canceled' do
210 211 212
          is_expected.to have_css('.js-temp-notes-holder')

          page.within("form[data-line-code='#{line_code}']") do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
213
            find('.js-close-discussion-note-form').trigger('click')
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
214 215
          end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
216
          is_expected.to have_no_css('.js-temp-notes-holder')
217 218 219 220
        end
      end
    end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
221
    describe 'with muliple note forms' do
222
      before do
223 224
        click_diff_line
        click_diff_line(line_code_2)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
225 226
      end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
227
      it { is_expected.to have_css('.js-temp-notes-holder', count: 2) }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
228

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
229
      describe 'previewing them separately' do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
230 231
        before do
          # add two separate texts and trigger previews on both
232
          page.within("tr[id='#{line_code}'] + .js-temp-notes-holder") do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
233
            fill_in 'note[note]', with: 'One comment on line 7'
234
            find('.js-md-preview-button').click
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
235
          end
236
          page.within("tr[id='#{line_code_2}'] + .js-temp-notes-holder") do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
237
            fill_in 'note[note]', with: 'Another comment on line 10'
238
            find('.js-md-preview-button').click
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
239
          end
240 241 242
        end
      end

Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
243
      describe 'posting a note' do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
244
        before do
245
          page.within("tr[id='#{line_code_2}'] + .js-temp-notes-holder") do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
246
            fill_in 'note[note]', with: 'Another comment on line 10'
247
            click_button('Comment')
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
248 249 250
          end
        end

251
        it 'adds as discussion' do
Jeroen van Baarsen's avatar
Jeroen van Baarsen committed
252 253 254
          is_expected.to have_content('Another comment on line 10')
          is_expected.to have_css('.notes_holder')
          is_expected.to have_css('.notes_holder .note', count: 1)
Annabel Dunstone's avatar
Annabel Dunstone committed
255
          is_expected.to have_button('Reply...')
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
256
        end
257 258 259 260 261 262 263 264 265 266 267 268

        it 'adds code to discussion' do
          click_button 'Reply...'

          page.within(first('.js-discussion-note-form')) do
            fill_in 'note[note]', with: '```{{ test }}```'

            click_button('Comment')
          end

          expect(page).to have_content('{{ test }}')
        end
269
      end
270 271
    end
  end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
272 273 274 275 276 277 278 279

  def line_code
    sample_compare.changes.first[:line_code]
  end

  def line_code_2
    sample_compare.changes.last[:line_code]
  end
280

281
  def click_diff_line(data = line_code)
282
    find(".line_holder[id='#{data}'] td.line_content").hover
283
    find(".line_holder[id='#{data}'] button").trigger('click')
284
  end
285
end