bulk_assignment_labels_spec.rb 12.3 KB
Newer Older
Alfredo Sumaran's avatar
Alfredo Sumaran committed
1 2 3
require 'rails_helper'

feature 'Issues > Labels bulk assignment', feature: true do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
4 5 6 7 8 9
  let(:user)      { create(:user) }
  let!(:project)  { create(:project) }
  let!(:issue1)   { create(:issue, project: project, title: "Issue 1") }
  let!(:issue2)   { create(:issue, project: project, title: "Issue 2") }
  let!(:bug)      { create(:label, project: project, title: 'bug') }
  let!(:feature)  { create(:label, project: project, title: 'feature') }
10
  let!(:wontfix)  { create(:label, project: project, title: 'wontfix') }
Alfredo Sumaran's avatar
Alfredo Sumaran committed
11

Alfredo Sumaran's avatar
Alfredo Sumaran committed
12
  context 'as an allowed user', js: true do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
13 14 15
    before do
      project.team << [user, :master]

Alfredo Sumaran's avatar
Alfredo Sumaran committed
16
      login_as user
Alfredo Sumaran's avatar
Alfredo Sumaran committed
17 18
    end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
19 20 21 22 23 24 25 26 27 28
    context 'can bulk assign' do
      before do
        visit namespace_project_issues_path(project.namespace, project)
      end

      context 'a label' do
        context 'to all issues' do
          before do
            check 'check_all_issues'
            open_labels_dropdown ['bug']
Alfredo Sumaran's avatar
Alfredo Sumaran committed
29
            update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
30 31 32 33 34 35
          end

          it do
            expect(find("#issue_#{issue1.id}")).to have_content 'bug'
            expect(find("#issue_#{issue2.id}")).to have_content 'bug'
          end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
36 37
        end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
38 39 40 41
        context 'to a issue' do
          before do
            check "selected_issue_#{issue1.id}"
            open_labels_dropdown ['bug']
Alfredo Sumaran's avatar
Alfredo Sumaran committed
42
            update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
43 44 45 46 47 48
          end

          it do
            expect(find("#issue_#{issue1.id}")).to have_content 'bug'
            expect(find("#issue_#{issue2.id}")).not_to have_content 'bug'
          end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
49 50 51
        end
      end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
52 53 54 55
      context 'multiple labels' do
        context 'to all issues' do
          before do
            check 'check_all_issues'
Douwe Maan's avatar
Douwe Maan committed
56
            open_labels_dropdown %w(bug feature)
Alfredo Sumaran's avatar
Alfredo Sumaran committed
57
            update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
58 59 60 61 62 63 64 65 66 67 68 69 70
          end

          it do
            expect(find("#issue_#{issue1.id}")).to have_content 'bug'
            expect(find("#issue_#{issue1.id}")).to have_content 'feature'
            expect(find("#issue_#{issue2.id}")).to have_content 'bug'
            expect(find("#issue_#{issue2.id}")).to have_content 'feature'
          end
        end

        context 'to a issue' do
          before do
            check "selected_issue_#{issue1.id}"
Douwe Maan's avatar
Douwe Maan committed
71
            open_labels_dropdown %w(bug feature)
Alfredo Sumaran's avatar
Alfredo Sumaran committed
72
            update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
73 74 75 76 77 78 79 80 81 82 83 84
          end

          it do
            expect(find("#issue_#{issue1.id}")).to have_content 'bug'
            expect(find("#issue_#{issue1.id}")).to have_content 'feature'
            expect(find("#issue_#{issue2.id}")).not_to have_content 'bug'
            expect(find("#issue_#{issue2.id}")).not_to have_content 'feature'
          end
        end
      end
    end

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    context 'can assign a label to all issues when label is present' do
      before do
        issue2.labels << bug
        issue2.labels << feature
        visit namespace_project_issues_path(project.namespace, project)

        check 'check_all_issues'
        open_labels_dropdown ['bug']
        update_issues
      end

      it do
        expect(find("#issue_#{issue1.id}")).to have_content 'bug'
        expect(find("#issue_#{issue2.id}")).to have_content 'bug'
      end
    end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
102 103
    context 'can bulk un-assign' do
      context 'all labels to all issues' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
104
        before do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
105 106 107 108 109 110 111 112
          issue1.labels << bug
          issue1.labels << feature
          issue2.labels << bug
          issue2.labels << feature

          visit namespace_project_issues_path(project.namespace, project)

          check 'check_all_issues'
Douwe Maan's avatar
Douwe Maan committed
113
          unmark_labels_in_dropdown %w(bug feature)
Alfredo Sumaran's avatar
Alfredo Sumaran committed
114
          update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
115 116 117
        end

        it do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
118 119
          expect(find("#issue_#{issue1.id}")).not_to have_content 'bug'
          expect(find("#issue_#{issue1.id}")).not_to have_content 'feature'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
120
          expect(find("#issue_#{issue2.id}")).not_to have_content 'bug'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
121
          expect(find("#issue_#{issue2.id}")).not_to have_content 'feature'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
122 123 124
        end
      end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
125
      context 'a label to a issue' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
126
        before do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
127 128 129 130 131 132 133
          issue1.labels << bug
          issue2.labels << feature

          visit namespace_project_issues_path(project.namespace, project)

          check_issue issue1
          unmark_labels_in_dropdown ['bug']
Alfredo Sumaran's avatar
Alfredo Sumaran committed
134
          update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
135 136 137
        end

        it do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
138
          expect(find("#issue_#{issue1.id}")).not_to have_content 'bug'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
139 140 141 142
          expect(find("#issue_#{issue2.id}")).to have_content 'feature'
        end
      end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
143
      context 'a label and keep the others label' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
144
        before do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
145 146 147 148 149 150 151 152 153 154
          issue1.labels << bug
          issue1.labels << feature
          issue2.labels << bug
          issue2.labels << feature

          visit namespace_project_issues_path(project.namespace, project)

          check_issue issue1
          check_issue issue2
          unmark_labels_in_dropdown ['bug']
Alfredo Sumaran's avatar
Alfredo Sumaran committed
155
          update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
156 157 158
        end

        it do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
159
          expect(find("#issue_#{issue1.id}")).not_to have_content 'bug'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
160 161
          expect(find("#issue_#{issue1.id}")).to have_content 'feature'
          expect(find("#issue_#{issue2.id}")).not_to have_content 'bug'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
162
          expect(find("#issue_#{issue2.id}")).to have_content 'feature'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
163 164 165
        end
      end
    end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
166 167 168 169 170 171 172 173 174 175 176

    context 'toggling a milestone' do
      let!(:milestone) { create(:milestone, project: project, title: 'First Release') }

      context 'setting a milestone' do
        before do
          issue1.labels << bug
          issue2.labels << feature
          visit namespace_project_issues_path(project.namespace, project)
        end

177
        it 'keeps labels' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
          expect(find("#issue_#{issue1.id}")).to have_content 'bug'
          expect(find("#issue_#{issue2.id}")).to have_content 'feature'

          check 'check_all_issues'
          open_milestone_dropdown(['First Release'])
          update_issues

          expect(find("#issue_#{issue1.id}")).to have_content 'bug'
          expect(find("#issue_#{issue1.id}")).to have_content 'First Release'
          expect(find("#issue_#{issue2.id}")).to have_content 'feature'
          expect(find("#issue_#{issue2.id}")).to have_content 'First Release'
        end
      end

      context 'setting a milestone and adding another label' do
        before do
          issue1.labels << bug

          visit namespace_project_issues_path(project.namespace, project)
        end

199
        it 'keeps existing label and new label is present' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
          expect(find("#issue_#{issue1.id}")).to have_content 'bug'

          check 'check_all_issues'
          open_milestone_dropdown ['First Release']
          open_labels_dropdown ['feature']
          update_issues

          expect(find("#issue_#{issue1.id}")).to have_content 'bug'
          expect(find("#issue_#{issue1.id}")).to have_content 'feature'
          expect(find("#issue_#{issue1.id}")).to have_content 'First Release'
          expect(find("#issue_#{issue2.id}")).to have_content 'feature'
          expect(find("#issue_#{issue2.id}")).to have_content 'First Release'
        end
      end

      context 'setting a milestone and removing existing label' do
        before do
          issue1.labels << bug
          issue1.labels << feature
          issue2.labels << feature

          visit namespace_project_issues_path(project.namespace, project)
        end

224
        it 'keeps existing label and new label is present' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
          expect(find("#issue_#{issue1.id}")).to have_content 'bug'
          expect(find("#issue_#{issue1.id}")).to have_content 'bug'
          expect(find("#issue_#{issue2.id}")).to have_content 'feature'

          check 'check_all_issues'
          open_milestone_dropdown ['First Release']
          unmark_labels_in_dropdown ['feature']
          update_issues

          expect(find("#issue_#{issue1.id}")).to have_content 'bug'
          expect(find("#issue_#{issue1.id}")).not_to have_content 'feature'
          expect(find("#issue_#{issue1.id}")).to have_content 'First Release'
          expect(find("#issue_#{issue2.id}")).not_to have_content 'feature'
          expect(find("#issue_#{issue2.id}")).to have_content 'First Release'
        end
      end

      context 'unsetting a milestone' do
        before do
          issue1.milestone = milestone
          issue2.milestone = milestone
          issue1.save
          issue2.save
          issue1.labels << bug
          issue2.labels << feature

          visit namespace_project_issues_path(project.namespace, project)
        end

254
        it 'keeps labels' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
255 256 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
          expect(find("#issue_#{issue1.id}")).to have_content 'bug'
          expect(find("#issue_#{issue1.id}")).to have_content 'First Release'
          expect(find("#issue_#{issue2.id}")).to have_content 'feature'
          expect(find("#issue_#{issue2.id}")).to have_content 'First Release'

          check 'check_all_issues'
          open_milestone_dropdown(['No Milestone'])
          update_issues

          expect(find("#issue_#{issue1.id}")).to have_content 'bug'
          expect(find("#issue_#{issue1.id}")).not_to have_content 'First Release'
          expect(find("#issue_#{issue2.id}")).to have_content 'feature'
          expect(find("#issue_#{issue2.id}")).not_to have_content 'First Release'
        end
      end
    end

    context 'toggling checked issues' do
      before do
        issue1.labels << bug

        visit namespace_project_issues_path(project.namespace, project)
      end

      it do
        expect(find("#issue_#{issue1.id}")).to have_content 'bug'

        check_issue issue1
        open_labels_dropdown ['feature']
        uncheck_issue issue1
        check_issue issue1
        update_issues
        sleep 1 # needed

        expect(find("#issue_#{issue1.id}")).to have_content 'bug'
        expect(find("#issue_#{issue1.id}")).not_to have_content 'feature'
      end
    end
293 294

    # Special case https://gitlab.com/gitlab-org/gitlab-ce/issues/24877
Alfredo Sumaran's avatar
Alfredo Sumaran committed
295
    context 'unmarking common label' do
296 297 298 299 300 301 302 303 304 305 306 307 308
      before do
        issue1.labels << bug
        issue1.labels << feature
        issue2.labels << bug

        visit namespace_project_issues_path(project.namespace, project)
      end

      it 'applies label from filtered results' do
        check 'check_all_issues'

        page.within('.issues_bulk_update') do
          click_button 'Labels'
309
          wait_for_requests
310 311 312 313 314

          expect(find('.dropdown-menu-labels li', text: 'bug')).to have_css('.is-active')
          expect(find('.dropdown-menu-labels li', text: 'feature')).to have_css('.is-indeterminate')

          click_link 'bug'
315
          find('.dropdown-input-field', visible: true).set('wontfix')
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
          click_link 'wontfix'
        end

        update_issues

        page.within '.issues-holder' do
          expect(find("#issue_#{issue1.id}")).not_to have_content 'bug'
          expect(find("#issue_#{issue1.id}")).to have_content 'feature'
          expect(find("#issue_#{issue1.id}")).to have_content 'wontfix'

          expect(find("#issue_#{issue2.id}")).not_to have_content 'bug'
          expect(find("#issue_#{issue2.id}")).not_to have_content 'feature'
          expect(find("#issue_#{issue2.id}")).to have_content 'wontfix'
        end
      end
    end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
  end

  context 'as a guest' do
    before do
      login_as user

      visit namespace_project_issues_path(project.namespace, project)
    end

    context 'cannot bulk assign labels' do
      it do
        expect(page).not_to have_css '.check_all_issues'
        expect(page).not_to have_css '.issue-check'
      end
    end
  end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
349 350 351
  def open_milestone_dropdown(items = [])
    page.within('.issues_bulk_update') do
      click_button 'Milestone'
352
      wait_for_requests
Alfredo Sumaran's avatar
Alfredo Sumaran committed
353 354 355 356 357 358
      items.map do |item|
        click_link item
      end
    end
  end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
359
  def open_labels_dropdown(items = [], unmark = false)
Alfredo Sumaran's avatar
Alfredo Sumaran committed
360
    page.within('.issues_bulk_update') do
361
      click_button 'Labels'
362
      wait_for_requests
Alfredo Sumaran's avatar
Alfredo Sumaran committed
363 364 365
      items.map do |item|
        click_link item
      end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
366 367
      if unmark
        items.map do |item|
368
          # Make sure we are unmarking the item no matter the state it has currently
369
          click_link item until find('a', text: item)[:class] == 'label-item'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
370 371 372 373 374 375 376 377 378
        end
      end
    end
  end

  def unmark_labels_in_dropdown(items = [])
    open_labels_dropdown(items, true)
  end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
379
  def check_issue(issue, uncheck = false)
Alfredo Sumaran's avatar
Alfredo Sumaran committed
380
    page.within('.issues-list') do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
381 382 383 384 385
      if uncheck
        uncheck "selected_issue_#{issue.id}"
      else
        check "selected_issue_#{issue.id}"
      end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
386 387
    end
  end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
388

Alfredo Sumaran's avatar
Alfredo Sumaran committed
389 390 391 392
  def uncheck_issue(issue)
    check_issue(issue, true)
  end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
393 394
  def update_issues
    click_button 'Update issues'
395
    wait_for_requests
Alfredo Sumaran's avatar
Alfredo Sumaran committed
396
  end
397
end