2016-04-27 00:55:58 -04:00
|
|
|
require 'rails_helper'
|
|
|
|
|
|
|
|
feature 'Issues > Labels bulk assignment', feature: true do
|
|
|
|
include WaitForAjax
|
|
|
|
|
2016-05-06 16:58:21 -04:00
|
|
|
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') }
|
2016-11-29 02:47:02 -05:00
|
|
|
let!(:wontfix) { create(:label, project: project, title: 'wontfix') }
|
2016-04-27 00:55:58 -04:00
|
|
|
|
2016-06-23 07:57:30 -04:00
|
|
|
context 'as an allowed user', js: true do
|
2016-04-27 00:55:58 -04:00
|
|
|
before do
|
|
|
|
project.team << [user, :master]
|
|
|
|
|
2016-05-06 16:58:21 -04:00
|
|
|
login_as user
|
2016-04-27 00:55:58 -04:00
|
|
|
end
|
|
|
|
|
2016-05-06 16:58:21 -04:00
|
|
|
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']
|
2016-05-13 01:56:37 -04:00
|
|
|
update_issues
|
2016-05-06 16:58:21 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(find("#issue_#{issue1.id}")).to have_content 'bug'
|
|
|
|
expect(find("#issue_#{issue2.id}")).to have_content 'bug'
|
|
|
|
end
|
2016-04-27 00:55:58 -04:00
|
|
|
end
|
|
|
|
|
2016-05-06 16:58:21 -04:00
|
|
|
context 'to a issue' do
|
|
|
|
before do
|
|
|
|
check "selected_issue_#{issue1.id}"
|
|
|
|
open_labels_dropdown ['bug']
|
2016-05-13 01:56:37 -04:00
|
|
|
update_issues
|
2016-05-06 16:58:21 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(find("#issue_#{issue1.id}")).to have_content 'bug'
|
|
|
|
expect(find("#issue_#{issue2.id}")).not_to have_content 'bug'
|
|
|
|
end
|
2016-04-27 00:55:58 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-05-06 16:58:21 -04:00
|
|
|
context 'multiple labels' do
|
|
|
|
context 'to all issues' do
|
|
|
|
before do
|
|
|
|
check 'check_all_issues'
|
2017-02-22 12:46:57 -05:00
|
|
|
open_labels_dropdown %w(bug feature)
|
2016-05-13 01:56:37 -04:00
|
|
|
update_issues
|
2016-05-06 16:58:21 -04:00
|
|
|
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}"
|
2017-02-22 12:46:57 -05:00
|
|
|
open_labels_dropdown %w(bug feature)
|
2016-05-13 01:56:37 -04:00
|
|
|
update_issues
|
2016-05-06 16:58:21 -04:00
|
|
|
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
|
|
|
|
|
2016-06-10 13:40:54 -04:00
|
|
|
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
|
|
|
|
|
2016-05-06 16:58:21 -04:00
|
|
|
context 'can bulk un-assign' do
|
|
|
|
context 'all labels to all issues' do
|
2016-04-27 00:55:58 -04:00
|
|
|
before do
|
2016-05-06 16:58:21 -04:00
|
|
|
issue1.labels << bug
|
|
|
|
issue1.labels << feature
|
|
|
|
issue2.labels << bug
|
|
|
|
issue2.labels << feature
|
|
|
|
|
|
|
|
visit namespace_project_issues_path(project.namespace, project)
|
|
|
|
|
|
|
|
check 'check_all_issues'
|
2017-02-22 12:46:57 -05:00
|
|
|
unmark_labels_in_dropdown %w(bug feature)
|
2016-05-13 01:56:37 -04:00
|
|
|
update_issues
|
2016-04-27 00:55:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
2016-05-06 16:58:21 -04:00
|
|
|
expect(find("#issue_#{issue1.id}")).not_to have_content 'bug'
|
|
|
|
expect(find("#issue_#{issue1.id}")).not_to have_content 'feature'
|
2016-04-27 00:55:58 -04:00
|
|
|
expect(find("#issue_#{issue2.id}")).not_to have_content 'bug'
|
2016-05-06 16:58:21 -04:00
|
|
|
expect(find("#issue_#{issue2.id}")).not_to have_content 'feature'
|
2016-04-27 00:55:58 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-05-06 16:58:21 -04:00
|
|
|
context 'a label to a issue' do
|
2016-04-27 00:55:58 -04:00
|
|
|
before do
|
2016-05-06 16:58:21 -04:00
|
|
|
issue1.labels << bug
|
|
|
|
issue2.labels << feature
|
|
|
|
|
|
|
|
visit namespace_project_issues_path(project.namespace, project)
|
|
|
|
|
|
|
|
check_issue issue1
|
|
|
|
unmark_labels_in_dropdown ['bug']
|
2016-05-13 01:56:37 -04:00
|
|
|
update_issues
|
2016-04-27 00:55:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
2016-05-06 16:58:21 -04:00
|
|
|
expect(find("#issue_#{issue1.id}")).not_to have_content 'bug'
|
2016-04-27 00:55:58 -04:00
|
|
|
expect(find("#issue_#{issue2.id}")).to have_content 'feature'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-05-06 16:58:21 -04:00
|
|
|
context 'a label and keep the others label' do
|
2016-04-27 00:55:58 -04:00
|
|
|
before do
|
2016-05-06 16:58:21 -04:00
|
|
|
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']
|
2016-05-13 01:56:37 -04:00
|
|
|
update_issues
|
2016-04-27 00:55:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
2016-05-06 16:58:21 -04:00
|
|
|
expect(find("#issue_#{issue1.id}")).not_to have_content 'bug'
|
2016-04-27 00:55:58 -04:00
|
|
|
expect(find("#issue_#{issue1.id}")).to have_content 'feature'
|
|
|
|
expect(find("#issue_#{issue2.id}")).not_to have_content 'bug'
|
2016-05-06 16:58:21 -04:00
|
|
|
expect(find("#issue_#{issue2.id}")).to have_content 'feature'
|
2016-04-27 00:55:58 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2016-06-23 07:57:30 -04:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2016-07-25 14:16:19 -04:00
|
|
|
it 'keeps labels' do
|
2016-06-23 07:57:30 -04:00
|
|
|
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
|
|
|
|
|
2016-07-25 14:16:19 -04:00
|
|
|
it 'keeps existing label and new label is present' do
|
2016-06-23 07:57:30 -04:00
|
|
|
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
|
|
|
|
|
2016-07-25 14:16:19 -04:00
|
|
|
it 'keeps existing label and new label is present' do
|
2016-06-23 07:57:30 -04:00
|
|
|
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
|
|
|
|
|
2016-07-25 14:16:19 -04:00
|
|
|
it 'keeps labels' do
|
2016-06-23 07:57:30 -04:00
|
|
|
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
|
2016-11-29 02:47:02 -05:00
|
|
|
|
|
|
|
# Special case https://gitlab.com/gitlab-org/gitlab-ce/issues/24877
|
2016-12-06 18:32:42 -05:00
|
|
|
context 'unmarking common label' do
|
2016-11-29 02:47:02 -05:00
|
|
|
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'
|
2016-12-06 23:32:21 -05:00
|
|
|
find('.dropdown-input-field', visible: true).set('wontfix')
|
2016-11-29 02:47:02 -05:00
|
|
|
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
|
2016-04-27 00:55:58 -04:00
|
|
|
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
|
|
|
|
|
2016-06-23 07:57:30 -04:00
|
|
|
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
|
|
|
|
|
2016-05-06 16:58:21 -04:00
|
|
|
def open_labels_dropdown(items = [], unmark = false)
|
2016-04-27 00:55:58 -04:00
|
|
|
page.within('.issues_bulk_update') do
|
2016-11-29 02:47:02 -05:00
|
|
|
click_button 'Labels'
|
2016-04-27 00:55:58 -04:00
|
|
|
wait_for_ajax
|
|
|
|
items.map do |item|
|
|
|
|
click_link item
|
|
|
|
end
|
2016-05-06 16:58:21 -04:00
|
|
|
if unmark
|
|
|
|
items.map do |item|
|
2016-06-16 17:27:46 -04:00
|
|
|
# Make sure we are unmarking the item no matter the state it has currently
|
2016-06-16 18:59:20 -04:00
|
|
|
click_link item until find('a', text: item)[:class] == 'label-item'
|
2016-05-06 16:58:21 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def unmark_labels_in_dropdown(items = [])
|
|
|
|
open_labels_dropdown(items, true)
|
|
|
|
end
|
|
|
|
|
2016-06-23 07:57:30 -04:00
|
|
|
def check_issue(issue, uncheck = false)
|
2016-05-06 16:58:21 -04:00
|
|
|
page.within('.issues-list') do
|
2016-06-23 07:57:30 -04:00
|
|
|
if uncheck
|
|
|
|
uncheck "selected_issue_#{issue.id}"
|
|
|
|
else
|
|
|
|
check "selected_issue_#{issue.id}"
|
|
|
|
end
|
2016-04-27 00:55:58 -04:00
|
|
|
end
|
|
|
|
end
|
2016-05-13 01:56:37 -04:00
|
|
|
|
2016-06-23 07:57:30 -04:00
|
|
|
def uncheck_issue(issue)
|
|
|
|
check_issue(issue, true)
|
|
|
|
end
|
|
|
|
|
2016-05-13 01:56:37 -04:00
|
|
|
def update_issues
|
|
|
|
click_button 'Update issues'
|
|
|
|
wait_for_ajax
|
|
|
|
end
|
2016-04-27 12:07:09 -04:00
|
|
|
end
|