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

feature 'Issues > Labels bulk assignment', feature: true do
  include WaitForAjax

Alfredo Sumaran's avatar
Alfredo Sumaran committed
6 7 8 9 10 11
  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') }
12
  let!(:wontfix)  { create(:label, project: project, title: 'wontfix') }
Alfredo Sumaran's avatar
Alfredo Sumaran committed
13

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

Alfredo Sumaran's avatar
Alfredo Sumaran committed
18
      login_as user
Alfredo Sumaran's avatar
Alfredo Sumaran committed
19 20
    end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
21 22 23 24 25 26 27 28 29 30
    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
31
            update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
32 33 34 35 36 37
          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
38 39
        end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
40 41 42 43
        context 'to a issue' do
          before do
            check "selected_issue_#{issue1.id}"
            open_labels_dropdown ['bug']
Alfredo Sumaran's avatar
Alfredo Sumaran committed
44
            update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
45 46 47 48 49 50
          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
51 52 53
        end
      end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
54 55 56 57 58
      context 'multiple labels' do
        context 'to all issues' do
          before do
            check 'check_all_issues'
            open_labels_dropdown ['bug', 'feature']
Alfredo Sumaran's avatar
Alfredo Sumaran committed
59
            update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
60 61 62 63 64 65 66 67 68 69 70 71 72 73
          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}"
            open_labels_dropdown ['bug', 'feature']
Alfredo Sumaran's avatar
Alfredo Sumaran committed
74
            update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
75 76 77 78 79 80 81 82 83 84 85 86
          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

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    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
104 105
    context 'can bulk un-assign' do
      context 'all labels to all issues' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
106
        before do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
107 108 109 110 111 112 113 114 115
          issue1.labels << bug
          issue1.labels << feature
          issue2.labels << bug
          issue2.labels << feature

          visit namespace_project_issues_path(project.namespace, project)

          check 'check_all_issues'
          unmark_labels_in_dropdown ['bug', 'feature']
Alfredo Sumaran's avatar
Alfredo Sumaran committed
116
          update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
117 118 119
        end

        it do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
120 121
          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
122
          expect(find("#issue_#{issue2.id}")).not_to have_content 'bug'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
123
          expect(find("#issue_#{issue2.id}")).not_to have_content 'feature'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
124 125 126
        end
      end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
127
      context 'a label to a issue' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
128
        before do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
129 130 131 132 133 134 135
          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
136
          update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
137 138 139
        end

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

Alfredo Sumaran's avatar
Alfredo Sumaran committed
145
      context 'a label and keep the others label' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
146
        before do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
147 148 149 150 151 152 153 154 155 156
          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
157
          update_issues
Alfredo Sumaran's avatar
Alfredo Sumaran committed
158 159 160
        end

        it do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
161
          expect(find("#issue_#{issue1.id}")).not_to have_content 'bug'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
162 163
          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
164
          expect(find("#issue_#{issue2.id}")).to have_content 'feature'
Alfredo Sumaran's avatar
Alfredo Sumaran committed
165 166 167
        end
      end
    end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
168 169 170 171 172 173 174 175 176 177 178

    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

179
        it 'keeps labels' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
          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

201
        it 'keeps existing label and new label is present' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
          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

226
        it 'keeps existing label and new label is present' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
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 254 255
          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

256
        it 'keeps labels' do
Alfredo Sumaran's avatar
Alfredo Sumaran committed
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 293 294
          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
295 296

    # Special case https://gitlab.com/gitlab-org/gitlab-ce/issues/24877
Alfredo Sumaran's avatar
Alfredo Sumaran committed
297
    context 'unmarking common label' do
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
      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'
          wait_for_ajax

          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'
317
          find('.dropdown-input-field', visible: true).set('wontfix')
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
          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
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
  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
351 352 353 354 355 356 357 358 359 360
  def open_milestone_dropdown(items = [])
    page.within('.issues_bulk_update') do
      click_button 'Milestone'
      wait_for_ajax
      items.map do |item|
        click_link item
      end
    end
  end

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

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

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

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

Alfredo Sumaran's avatar
Alfredo Sumaran committed
395 396 397 398
  def update_issues
    click_button 'Update issues'
    wait_for_ajax
  end
399
end