summaryrefslogtreecommitdiff
path: root/spec/features/issues
diff options
context:
space:
mode:
Diffstat (limited to 'spec/features/issues')
-rw-r--r--spec/features/issues/award_emoji_spec.rb8
-rw-r--r--spec/features/issues/award_spec.rb6
-rw-r--r--spec/features/issues/bulk_assignment_labels_spec.rb2
-rw-r--r--spec/features/issues/create_branch_merge_request_spec.rb91
-rw-r--r--spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb12
-rw-r--r--spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb (renamed from spec/features/issues/create_issue_for_single_discussion_in_merge_request.rb)6
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb3
-rw-r--r--spec/features/issues/filtered_search/dropdown_author_spec.rb3
-rw-r--r--spec/features/issues/filtered_search/dropdown_hint_spec.rb15
-rw-r--r--spec/features/issues/filtered_search/dropdown_label_spec.rb33
-rw-r--r--spec/features/issues/filtered_search/dropdown_milestone_spec.rb16
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb55
-rw-r--r--spec/features/issues/filtered_search/recent_searches_spec.rb109
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb27
-rw-r--r--spec/features/issues/form_spec.rb89
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb28
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb41
-rw-r--r--spec/features/issues/move_spec.rb4
-rw-r--r--spec/features/issues/new_branch_button_spec.rb62
-rw-r--r--spec/features/issues/note_polling_spec.rb132
-rw-r--r--spec/features/issues/notes_on_issues_spec.rb77
-rw-r--r--spec/features/issues/spam_issues_spec.rb2
-rw-r--r--spec/features/issues/update_issues_spec.rb4
-rw-r--r--spec/features/issues/user_uses_slash_commands_spec.rb1
24 files changed, 640 insertions, 186 deletions
diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb
index 16e453bc328..853632614c4 100644
--- a/spec/features/issues/award_emoji_spec.rb
+++ b/spec/features/issues/award_emoji_spec.rb
@@ -1,13 +1,13 @@
require 'rails_helper'
describe 'Awards Emoji', feature: true do
- include WaitForAjax
+ include WaitForVueResource
let!(:project) { create(:project, :public) }
let!(:user) { create(:user) }
let(:issue) do
create(:issue,
- assignee: @user,
+ assignees: [user],
project: project)
end
@@ -22,10 +22,11 @@ describe 'Awards Emoji', feature: true do
# The `heart_tip` emoji is not valid anymore so we need to skip validation
issue.award_emoji.build(user: user, name: 'heart_tip').save!(validate: false)
visit namespace_project_issue_path(project.namespace, project, issue)
+ wait_for_vue_resource
end
# Regression test: https://gitlab.com/gitlab-org/gitlab-ce/issues/29529
- it 'does not shows a 500 page' do
+ it 'does not shows a 500 page', js: true do
expect(page).to have_text(issue.title)
end
end
@@ -35,6 +36,7 @@ describe 'Awards Emoji', feature: true do
before do
visit namespace_project_issue_path(project.namespace, project, issue)
+ wait_for_vue_resource
end
it 'increments the thumbsdown emoji', js: true do
diff --git a/spec/features/issues/award_spec.rb b/spec/features/issues/award_spec.rb
index 401e1ea2b89..08e3f99e29f 100644
--- a/spec/features/issues/award_spec.rb
+++ b/spec/features/issues/award_spec.rb
@@ -6,9 +6,12 @@ feature 'Issue awards', js: true, feature: true do
let(:issue) { create(:issue, project: project) }
describe 'logged in' do
+ include WaitForVueResource
+
before do
login_as(user)
visit namespace_project_issue_path(project.namespace, project, issue)
+ wait_for_vue_resource
end
it 'adds award to issue' do
@@ -38,8 +41,11 @@ feature 'Issue awards', js: true, feature: true do
end
describe 'logged out' do
+ include WaitForVueResource
+
before do
visit namespace_project_issue_path(project.namespace, project, issue)
+ wait_for_vue_resource
end
it 'does not see award menu button' do
diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb
index 2f59630b4fb..1de50d6d77e 100644
--- a/spec/features/issues/bulk_assignment_labels_spec.rb
+++ b/spec/features/issues/bulk_assignment_labels_spec.rb
@@ -1,8 +1,6 @@
require 'rails_helper'
feature 'Issues > Labels bulk assignment', feature: true do
- include WaitForAjax
-
let(:user) { create(:user) }
let!(:project) { create(:project) }
let!(:issue1) { create(:issue, project: project, title: "Issue 1") }
diff --git a/spec/features/issues/create_branch_merge_request_spec.rb b/spec/features/issues/create_branch_merge_request_spec.rb
new file mode 100644
index 00000000000..44c19275ae5
--- /dev/null
+++ b/spec/features/issues/create_branch_merge_request_spec.rb
@@ -0,0 +1,91 @@
+require 'rails_helper'
+
+feature 'Create Branch/Merge Request Dropdown on issue page', feature: true, js: true do
+ let(:user) { create(:user) }
+ let!(:project) { create(:project) }
+ let(:issue) { create(:issue, project: project, title: 'Cherry-Coloured Funk') }
+
+ context 'for team members' do
+ before do
+ project.team << [user, :developer]
+ login_as(user)
+ end
+
+ it 'allows creating a merge request from the issue page' do
+ visit namespace_project_issue_path(project.namespace, project, issue)
+
+ select_dropdown_option('create-mr')
+
+ wait_for_ajax
+
+ expect(page).to have_content("created branch 1-cherry-coloured-funk")
+ expect(page).to have_content("mentioned in merge request !1")
+
+ visit namespace_project_merge_request_path(project.namespace, project, MergeRequest.first)
+
+ expect(page).to have_content('WIP: Resolve "Cherry-Coloured Funk"')
+ expect(current_path).to eq(namespace_project_merge_request_path(project.namespace, project, MergeRequest.first))
+ end
+
+ it 'allows creating a branch from the issue page' do
+ visit namespace_project_issue_path(project.namespace, project, issue)
+
+ select_dropdown_option('create-branch')
+
+ wait_for_ajax
+
+ expect(page).to have_selector('.dropdown-toggle-text ', text: '1-cherry-coloured-funk')
+ expect(current_path).to eq namespace_project_tree_path(project.namespace, project, '1-cherry-coloured-funk')
+ end
+
+ context "when there is a referenced merge request" do
+ let!(:note) do
+ create(:note, :on_issue, :system, project: project, noteable: issue,
+ note: "mentioned in #{referenced_mr.to_reference}")
+ end
+
+ let(:referenced_mr) do
+ create(:merge_request, :simple, source_project: project, target_project: project,
+ description: "Fixes #{issue.to_reference}", author: user)
+ end
+
+ before do
+ referenced_mr.cache_merge_request_closes_issues!(user)
+
+ visit namespace_project_issue_path(project.namespace, project, issue)
+ end
+
+ it 'disables the create branch button' do
+ expect(page).to have_css('.create-mr-dropdown-wrap .unavailable:not(.hide)')
+ expect(page).to have_css('.create-mr-dropdown-wrap .available.hide', visible: false)
+ expect(page).to have_content /1 Related Merge Request/
+ end
+ end
+
+ context 'when issue is confidential' do
+ it 'disables the create branch button' do
+ issue = create(:issue, :confidential, project: project)
+
+ visit namespace_project_issue_path(project.namespace, project, issue)
+
+ expect(page).not_to have_css('.create-mr-dropdown-wrap')
+ end
+ end
+ end
+
+ context 'for visitors' do
+ before do
+ visit namespace_project_issue_path(project.namespace, project, issue)
+ end
+
+ it 'shows no buttons' do
+ expect(page).not_to have_selector('.create-mr-dropdown-wrap')
+ end
+ end
+
+ def select_dropdown_option(option)
+ find('.create-mr-dropdown-wrap .dropdown-toggle').click
+ find("li[data-value='#{option}']").click
+ find('.js-create-merge-request').click
+ end
+end
diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
index 572bca3de21..24e2419b5ce 100644
--- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
@@ -4,7 +4,7 @@ feature 'Resolving all open discussions in a merge request from an issue', featu
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:merge_request) { create(:merge_request, source_project: project) }
- let!(:discussion) { Discussion.for_diff_notes([create(:diff_note_on_merge_request, noteable: merge_request, project: project)]).first }
+ let!(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
describe 'as a user with access to the project' do
before do
@@ -14,7 +14,7 @@ feature 'Resolving all open discussions in a merge request from an issue', featu
end
it 'shows a button to resolve all discussions by creating a new issue' do
- within('li#resolve-count-app') do
+ within('#resolve-count-app') do
expect(page).to have_link "Resolve all discussions in new issue", href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid)
end
end
@@ -49,7 +49,7 @@ feature 'Resolving all open discussions in a merge request from an issue', featu
end
it 'does not show a link to create a new issue' do
- expect(page).not_to have_link 'open an issue to resolve them later'
+ expect(page).not_to have_link 'Create an issue to resolve them later'
end
end
@@ -59,18 +59,18 @@ feature 'Resolving all open discussions in a merge request from an issue', featu
end
it 'shows a warning that the merge request contains unresolved discussions' do
- expect(page).to have_content 'This merge request has unresolved discussions'
+ expect(page).to have_content 'There are unresolved discussions.'
end
it 'has a link to resolve all discussions by creating an issue' do
page.within '.mr-widget-body' do
- expect(page).to have_link 'open an issue to resolve them later', href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid)
+ expect(page).to have_link 'Create an issue to resolve them later', href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid)
end
end
context 'creating an issue for discussions' do
before do
- page.click_link 'open an issue to resolve them later', href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid)
+ page.click_link 'Create an issue to resolve them later', href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid)
end
it_behaves_like 'creating an issue for a discussion'
diff --git a/spec/features/issues/create_issue_for_single_discussion_in_merge_request.rb b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
index 88e2cc60d79..3a5a79e03f4 100644
--- a/spec/features/issues/create_issue_for_single_discussion_in_merge_request.rb
+++ b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
@@ -4,7 +4,7 @@ feature 'Resolve an open discussion in a merge request by creating an issue', fe
let(:user) { create(:user) }
let(:project) { create(:project, only_allow_merge_if_all_discussions_are_resolved: true) }
let(:merge_request) { create(:merge_request, source_project: project) }
- let!(:discussion) { Discussion.for_diff_notes([create(:diff_note_on_merge_request, noteable: merge_request, project: project)]).first }
+ let!(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
describe 'As a user with access to the project' do
before do
@@ -74,8 +74,8 @@ feature 'Resolve an open discussion in a merge request by creating an issue', fe
it 'Shows a notice to ask someone else to resolve the discussions' do
expect(page).to have_content("The discussion at #{merge_request.to_reference}"\
- "(discussion #{discussion.first_note.id}) will stay unresolved."\
- "Ask someone with permission to resolve it.")
+ " (discussion #{discussion.first_note.id}) will stay unresolved."\
+ " Ask someone with permission to resolve it.")
end
end
end
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index 4dcc56a97d1..0b573d7cef4 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -2,7 +2,6 @@ require 'rails_helper'
describe 'Dropdown assignee', :feature, :js do
include FilteredSearchHelpers
- include WaitForAjax
let!(:project) { create(:empty_project) }
let!(:user) { create(:user, name: 'administrator', username: 'root') }
@@ -194,7 +193,7 @@ describe 'Dropdown assignee', :feature, :js do
new_user = create(:user)
project.team << [new_user, :master]
- find('.filtered-search-input-container .clear-search').click
+ find('.filtered-search-box .clear-search').click
filtered_search.set('assignee')
filtered_search.send_keys(':')
diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb
index 1772a120045..0579d6c80ab 100644
--- a/spec/features/issues/filtered_search/dropdown_author_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb
@@ -2,7 +2,6 @@ require 'rails_helper'
describe 'Dropdown author', js: true, feature: true do
include FilteredSearchHelpers
- include WaitForAjax
let!(:project) { create(:empty_project) }
let!(:user) { create(:user, name: 'administrator', username: 'root') }
@@ -172,7 +171,7 @@ describe 'Dropdown author', js: true, feature: true do
new_user = create(:user)
project.team << [new_user, :master]
- find('.filtered-search-input-container .clear-search').click
+ find('.filtered-search-box .clear-search').click
filtered_search.set('author')
send_keys_to_filtered_search(':')
diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
index bc8cbe30e66..b9a37cfcc22 100644
--- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
@@ -1,18 +1,13 @@
require 'rails_helper'
-describe 'Dropdown hint', js: true, feature: true do
+describe 'Dropdown hint', :js, :feature do
include FilteredSearchHelpers
- include WaitForAjax
let!(:project) { create(:empty_project) }
let!(:user) { create(:user) }
let(:filtered_search) { find('.filtered-search') }
let(:js_dropdown_hint) { '#js-dropdown-hint' }
- def dropdown_hint_size
- page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size
- end
-
def click_hint(text)
find('#js-dropdown-hint .filter-dropdown .filter-dropdown-item', text: text).click
end
@@ -46,14 +41,16 @@ describe 'Dropdown hint', js: true, feature: true do
it 'does not filter `Press Enter or click to search`' do
filtered_search.set('randomtext')
- expect(page).to have_css(js_dropdown_hint, text: 'Press Enter or click to search', visible: false)
- expect(dropdown_hint_size).to eq(0)
+ hint_dropdown = find(js_dropdown_hint)
+
+ expect(hint_dropdown).to have_content('Press Enter or click to search')
+ expect(hint_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 0)
end
it 'filters with text' do
filtered_search.set('a')
- expect(dropdown_hint_size).to eq(3)
+ expect(find(js_dropdown_hint)).to have_selector('.filter-dropdown .filter-dropdown-item', count: 3)
end
end
diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb
index b192064b693..abe5d61e38c 100644
--- a/spec/features/issues/filtered_search/dropdown_label_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb
@@ -28,12 +28,8 @@ describe 'Dropdown label', js: true, feature: true do
filter_dropdown.find('.filter-dropdown-item', text: text).click
end
- def dropdown_label_size
- filter_dropdown.all('.filter-dropdown-item').size
- end
-
def clear_search_field
- find('.filtered-search-input-container .clear-search').click
+ find('.filtered-search-box .clear-search').click
end
before do
@@ -81,7 +77,7 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search.set('label:')
expect(filter_dropdown).to have_content(bug_label.title)
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
end
end
@@ -97,7 +93,8 @@ describe 'Dropdown label', js: true, feature: true do
expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible
expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible
- expect(dropdown_label_size).to eq(2)
+
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 2)
clear_search_field
init_label_search
@@ -106,14 +103,14 @@ describe 'Dropdown label', js: true, feature: true do
expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible
expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible
- expect(dropdown_label_size).to eq(2)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 2)
end
it 'filters by multiple words with or without symbol' do
filtered_search.send_keys('Hig')
expect(filter_dropdown.find('.filter-dropdown-item', text: two_words_label.title)).to be_visible
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
clear_search_field
init_label_search
@@ -121,14 +118,14 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search.send_keys('~Hig')
expect(filter_dropdown.find('.filter-dropdown-item', text: two_words_label.title)).to be_visible
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
end
it 'filters by multiple words containing single quotes with or without symbol' do
filtered_search.send_keys('won\'t')
expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_single_label.title)).to be_visible
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
clear_search_field
init_label_search
@@ -136,14 +133,14 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search.send_keys('~won\'t')
expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_single_label.title)).to be_visible
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
end
it 'filters by multiple words containing double quotes with or without symbol' do
filtered_search.send_keys('won"t')
expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_label.title)).to be_visible
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
clear_search_field
init_label_search
@@ -151,14 +148,14 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search.send_keys('~won"t')
expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_label.title)).to be_visible
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
end
it 'filters by special characters with or without symbol' do
filtered_search.send_keys('^+')
expect(filter_dropdown.find('.filter-dropdown-item', text: special_label.title)).to be_visible
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
clear_search_field
init_label_search
@@ -166,7 +163,7 @@ describe 'Dropdown label', js: true, feature: true do
filtered_search.send_keys('~^+')
expect(filter_dropdown.find('.filter-dropdown-item', text: special_label.title)).to be_visible
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
end
end
@@ -280,13 +277,13 @@ describe 'Dropdown label', js: true, feature: true do
create(:label, project: project, title: 'bug-label')
init_label_search
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
create(:label, project: project)
clear_search_field
init_label_search
- expect(dropdown_label_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1)
end
end
end
diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
index ce96a420699..448259057b0 100644
--- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
@@ -65,7 +65,7 @@ describe 'Dropdown milestone', :feature, :js do
it 'should load all the milestones when opened' do
filtered_search.set('milestone:')
- expect(dropdown_milestone_size).to be > 0
+ expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 6)
end
end
@@ -84,37 +84,37 @@ describe 'Dropdown milestone', :feature, :js do
it 'filters by name' do
filtered_search.send_keys('v1')
- expect(dropdown_milestone_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1)
end
it 'filters by case insensitive name' do
filtered_search.send_keys('V1')
- expect(dropdown_milestone_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1)
end
it 'filters by name with symbol' do
filtered_search.send_keys('%v1')
- expect(dropdown_milestone_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1)
end
it 'filters by case insensitive name with symbol' do
filtered_search.send_keys('%V1')
- expect(dropdown_milestone_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1)
end
it 'filters by special characters' do
filtered_search.send_keys('(+')
- expect(dropdown_milestone_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1)
end
it 'filters by special characters with symbol' do
filtered_search.send_keys('%(+')
- expect(dropdown_milestone_size).to eq(1)
+ expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1)
end
end
@@ -252,7 +252,7 @@ describe 'Dropdown milestone', :feature, :js do
expect(initial_size).to be > 0
create(:milestone, project: project)
- find('.filtered-search-input-container .clear-search').click
+ find('.filtered-search-box .clear-search').click
filtered_search.set('milestone:')
expect(dropdown_milestone_size).to eq(initial_size)
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index f463312bf57..a8f4e2d7e10 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -1,18 +1,18 @@
require 'spec_helper'
describe 'Filter issues', js: true, feature: true do
+ include Devise::Test::IntegrationHelpers
include FilteredSearchHelpers
- include WaitForAjax
let!(:group) { create(:group) }
let!(:project) { create(:project, group: group) }
- let!(:user) { create(:user) }
- let!(:user2) { create(:user) }
+ let!(:user) { create(:user, username: 'joe') }
+ let!(:user2) { create(:user, username: 'jane') }
let!(:label) { create(:label, project: project) }
let!(:wontfix) { create(:label, project: project, title: "Won't fix") }
let!(:bug_label) { create(:label, project: project, title: 'bug') }
- let!(:caps_sensitive_label) { create(:label, project: project, title: 'CAPS_sensitive') }
+ let!(:caps_sensitive_label) { create(:label, project: project, title: 'CaPs') }
let!(:milestone) { create(:milestone, title: "8", project: project, start_date: 2.days.ago) }
let!(:multiple_words_label) { create(:label, project: project, title: "Two words") }
@@ -42,23 +42,24 @@ describe 'Filter issues', js: true, feature: true do
project.team << [user2, :master]
group.add_developer(user)
group.add_developer(user2)
- login_as(user)
- create(:issue, project: project)
- create(:issue, title: "Bug report 1", project: project)
- create(:issue, title: "Bug report 2", project: project)
- create(:issue, title: "issue with 'single quotes'", project: project)
- create(:issue, title: "issue with \"double quotes\"", project: project)
- create(:issue, title: "issue with !@\#{$%^&*()-+", project: project)
- create(:issue, title: "issue by assignee", project: project, milestone: milestone, author: user, assignee: user)
- create(:issue, title: "issue by assignee with searchTerm", project: project, milestone: milestone, author: user, assignee: user)
+ sign_in(user)
+
+ create(:issue, project: project)
+ create(:issue, project: project, title: "Bug report 1")
+ create(:issue, project: project, title: "Bug report 2")
+ create(:issue, project: project, title: "issue with 'single quotes'")
+ create(:issue, project: project, title: "issue with \"double quotes\"")
+ create(:issue, project: project, title: "issue with !@\#{$%^&*()-+")
+ create(:issue, project: project, title: "issue by assignee", milestone: milestone, author: user, assignees: [user])
+ create(:issue, project: project, title: "issue by assignee with searchTerm", milestone: milestone, author: user, assignees: [user])
issue = create(:issue,
title: "Bug 2",
project: project,
milestone: milestone,
author: user,
- assignee: user)
+ assignees: [user])
issue.labels << bug_label
issue_with_caps_label = create(:issue,
@@ -66,15 +67,15 @@ describe 'Filter issues', js: true, feature: true do
project: project,
milestone: milestone,
author: user,
- assignee: user)
+ assignees: [user])
issue_with_caps_label.labels << caps_sensitive_label
issue_with_everything = create(:issue,
- title: "Bug report with everything you thought was possible",
+ title: "Bug report foo was possible",
project: project,
milestone: milestone,
author: user,
- assignee: user)
+ assignees: [user])
issue_with_everything.labels << bug_label
issue_with_everything.labels << caps_sensitive_label
@@ -687,10 +688,10 @@ describe 'Filter issues', js: true, feature: true do
end
it 'filters issues by searched text, author, more text, assignee and even more text' do
- input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username} with")
+ input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username} foo")
expect_issues_list_count(1)
- expect_filtered_search_input('bug report with')
+ expect_filtered_search_input('bug report foo')
end
it 'filters issues by searched text, author, assignee and label' do
@@ -701,10 +702,10 @@ describe 'Filter issues', js: true, feature: true do
end
it 'filters issues by searched text, author, text, assignee, text, label and text' do
- input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username} with label:~#{bug_label.title} everything")
+ input_filtered_search("bug author:@#{user.username} assignee:@#{user.username} report label:~#{bug_label.title} foo")
expect_issues_list_count(1)
- expect_filtered_search_input('bug report with everything')
+ expect_filtered_search_input('bug report foo')
end
it 'filters issues by searched text, author, assignee, label and milestone' do
@@ -715,10 +716,10 @@ describe 'Filter issues', js: true, feature: true do
end
it 'filters issues by searched text, author, text, assignee, text, label, text, milestone and text' do
- input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username} with label:~#{bug_label.title} everything milestone:%#{milestone.title} you")
+ input_filtered_search("bug author:@#{user.username} assignee:@#{user.username} report label:~#{bug_label.title} milestone:%#{milestone.title} foo")
expect_issues_list_count(1)
- expect_filtered_search_input('bug report with everything you')
+ expect_filtered_search_input('bug report foo')
end
it 'filters issues by searched text, author, assignee, multiple labels and milestone' do
@@ -729,10 +730,10 @@ describe 'Filter issues', js: true, feature: true do
end
it 'filters issues by searched text, author, text, assignee, text, label1, text, label2, text, milestone and text' do
- input_filtered_search("bug author:@#{user.username} report assignee:@#{user.username} with label:~#{bug_label.title} everything label:~#{caps_sensitive_label.title} you milestone:%#{milestone.title} thought")
+ input_filtered_search("bug author:@#{user.username} assignee:@#{user.username} report label:~#{bug_label.title} label:~#{caps_sensitive_label.title} milestone:%#{milestone.title} foo")
expect_issues_list_count(1)
- expect_filtered_search_input('bug report with everything you thought')
+ expect_filtered_search_input('bug report foo')
end
end
@@ -756,10 +757,10 @@ describe 'Filter issues', js: true, feature: true do
expect_issues_list_count(2)
- sort_toggle = find('.filtered-search-container .dropdown-toggle')
+ sort_toggle = find('.filtered-search-wrapper .dropdown-toggle')
sort_toggle.click
- find('.filtered-search-container .dropdown-menu li a', text: 'Oldest updated').click
+ find('.filtered-search-wrapper .dropdown-menu li a', text: 'Oldest updated').click
wait_for_ajax
expect(find('.issues-list .issue:first-of-type .issue-title-text a')).to have_content(old_issue.title)
diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb
new file mode 100644
index 00000000000..09f228bcf49
--- /dev/null
+++ b/spec/features/issues/filtered_search/recent_searches_spec.rb
@@ -0,0 +1,109 @@
+require 'spec_helper'
+
+describe 'Recent searches', js: true, feature: true do
+ include FilteredSearchHelpers
+
+ let(:project_1) { create(:empty_project, :public) }
+ let(:project_2) { create(:empty_project, :public) }
+ let(:project_1_local_storage_key) { "#{project_1.full_path}-issue-recent-searches" }
+
+ before do
+ Capybara.ignore_hidden_elements = false
+ create(:issue, project: project_1)
+ create(:issue, project: project_2)
+
+ # Visit any fast-loading page so we can clear local storage without a DOM exception
+ visit '/404'
+ remove_recent_searches
+ end
+
+ after do
+ Capybara.ignore_hidden_elements = true
+ end
+
+ it 'searching adds to recent searches' do
+ visit namespace_project_issues_path(project_1.namespace, project_1)
+
+ input_filtered_search('foo', submit: true)
+ input_filtered_search('bar', submit: true)
+
+ items = all('.filtered-search-history-dropdown-item', visible: false)
+
+ expect(items.count).to eq(2)
+ expect(items[0].text).to eq('bar')
+ expect(items[1].text).to eq('foo')
+ end
+
+ it 'visiting URL with search params adds to recent searches' do
+ visit namespace_project_issues_path(project_1.namespace, project_1, label_name: 'foo', search: 'bar')
+ visit namespace_project_issues_path(project_1.namespace, project_1, label_name: 'qux', search: 'garply')
+
+ items = all('.filtered-search-history-dropdown-item', visible: false)
+
+ expect(items.count).to eq(2)
+ expect(items[0].text).to eq('label:~qux garply')
+ expect(items[1].text).to eq('label:~foo bar')
+ end
+
+ it 'saved recent searches are restored last on the list' do
+ set_recent_searches(project_1_local_storage_key, '["saved1", "saved2"]')
+
+ visit namespace_project_issues_path(project_1.namespace, project_1, search: 'foo')
+
+ items = all('.filtered-search-history-dropdown-item', visible: false)
+
+ expect(items.count).to eq(3)
+ expect(items[0].text).to eq('foo')
+ expect(items[1].text).to eq('saved1')
+ expect(items[2].text).to eq('saved2')
+ end
+
+ it 'searches are scoped to projects' do
+ visit namespace_project_issues_path(project_1.namespace, project_1)
+
+ input_filtered_search('foo', submit: true)
+ input_filtered_search('bar', submit: true)
+
+ visit namespace_project_issues_path(project_2.namespace, project_2)
+
+ input_filtered_search('more', submit: true)
+ input_filtered_search('things', submit: true)
+
+ items = all('.filtered-search-history-dropdown-item', visible: false)
+
+ expect(items.count).to eq(2)
+ expect(items[0].text).to eq('things')
+ expect(items[1].text).to eq('more')
+ end
+
+ it 'clicking item fills search input' do
+ set_recent_searches(project_1_local_storage_key, '["foo", "bar"]')
+ visit namespace_project_issues_path(project_1.namespace, project_1)
+
+ all('.filtered-search-history-dropdown-item', visible: false)[0].trigger('click')
+ wait_for_filtered_search('foo')
+
+ expect(find('.filtered-search').value.strip).to eq('foo')
+ end
+
+ it 'clear recent searches button, clears recent searches' do
+ set_recent_searches(project_1_local_storage_key, '["foo"]')
+ visit namespace_project_issues_path(project_1.namespace, project_1)
+
+ items_before = all('.filtered-search-history-dropdown-item', visible: false)
+
+ expect(items_before.count).to eq(1)
+
+ find('.filtered-search-history-clear-button', visible: false).trigger('click')
+ items_after = all('.filtered-search-history-dropdown-item', visible: false)
+
+ expect(items_after.count).to eq(0)
+ end
+
+ it 'shows flash error when failed to parse saved history' do
+ set_recent_searches(project_1_local_storage_key, 'fail')
+ visit namespace_project_issues_path(project_1.namespace, project_1)
+
+ expect(find('.flash-alert')).to have_text('An error occured while parsing recent searches')
+ end
+end
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index 59244d65eec..3ea95aed0a6 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -2,7 +2,6 @@ require 'rails_helper'
describe 'Search bar', js: true, feature: true do
include FilteredSearchHelpers
- include WaitForAjax
let!(:project) { create(:empty_project) }
let!(:user) { create(:user) }
@@ -26,7 +25,7 @@ describe 'Search bar', js: true, feature: true do
filtered_search.native.send_keys(:down)
page.within '#js-dropdown-hint' do
- expect(page).to have_selector('.dropdown-active')
+ expect(page).to have_selector('.droplab-item-active')
end
end
@@ -44,7 +43,7 @@ describe 'Search bar', js: true, feature: true do
filtered_search.set(search_text)
expect(filtered_search.value).to eq(search_text)
- find('.filtered-search-input-container .clear-search').click
+ find('.filtered-search-box .clear-search').click
expect(filtered_search.value).to eq('')
end
@@ -55,7 +54,7 @@ describe 'Search bar', js: true, feature: true do
it 'hides after clicked' do
filtered_search.set('a')
- find('.filtered-search-input-container .clear-search').click
+ find('.filtered-search-box .clear-search').click
expect(page).to have_css('.clear-search', visible: false)
end
@@ -79,28 +78,30 @@ describe 'Search bar', js: true, feature: true do
filtered_search.set('author')
- expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to eq(1)
+ expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1)
- find('.filtered-search-input-container .clear-search').click
+ find('.filtered-search-box .clear-search').click
filtered_search.click
- expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to eq(original_size)
+ expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: original_size)
end
it 'resets the dropdown filters' do
+ filtered_search.click
+
+ hint_offset = get_left_style(find('#js-dropdown-hint')['style'])
+
filtered_search.set('a')
- hint_style = page.find('#js-dropdown-hint')['style']
- hint_offset = get_left_style(hint_style)
filtered_search.set('author:')
- expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to eq(0)
+ find('#js-dropdown-hint', visible: false)
- find('.filtered-search-input-container .clear-search').click
+ find('.filtered-search-box .clear-search').click
filtered_search.click
- expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to be > 0
- expect(get_left_style(page.find('#js-dropdown-hint')['style'])).to eq(hint_offset)
+ expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 4)
+ expect(get_left_style(find('#js-dropdown-hint')['style'])).to eq(hint_offset)
end
end
end
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index 755992069ff..5c0907e26df 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -1,7 +1,9 @@
require 'rails_helper'
-describe 'New/edit issue', feature: true, js: true do
+describe 'New/edit issue', :feature, :js do
include GitlabRoutingHelper
+ include ActionView::Helpers::JavaScriptHelper
+ include WaitForAjax
let!(:project) { create(:project) }
let!(:user) { create(:user)}
@@ -9,7 +11,7 @@ describe 'New/edit issue', feature: true, js: true do
let!(:milestone) { create(:milestone, project: project) }
let!(:label) { create(:label, project: project) }
let!(:label2) { create(:label, project: project) }
- let!(:issue) { create(:issue, project: project, assignee: user, milestone: milestone) }
+ let!(:issue) { create(:issue, project: project, assignees: [user], milestone: milestone) }
before do
project.team << [user, :master]
@@ -22,23 +24,67 @@ describe 'New/edit issue', feature: true, js: true do
visit new_namespace_project_issue_path(project.namespace, project)
end
+ describe 'single assignee' do
+ before do
+ click_button 'Unassigned'
+
+ wait_for_ajax
+ end
+
+ it 'unselects other assignees when unassigned is selected' do
+ page.within '.dropdown-menu-user' do
+ click_link user2.name
+ end
+
+ click_button user2.name
+
+ page.within '.dropdown-menu-user' do
+ click_link 'Unassigned'
+ end
+
+ expect(find('input[name="issue[assignee_ids][]"]', visible: false).value).to match('0')
+ end
+
+ it 'toggles assign to me when current user is selected and unselected' do
+ page.within '.dropdown-menu-user' do
+ click_link user.name
+ end
+
+ expect(find('a', text: 'Assign to me', visible: false)).not_to be_visible
+
+ click_button user.name
+
+ page.within('.dropdown-menu-user') do
+ click_link user.name
+ end
+
+ expect(page.find('.dropdown-menu-user', visible: false)).not_to be_visible
+ end
+ end
+
it 'allows user to create new issue' do
fill_in 'issue_title', with: 'title'
fill_in 'issue_description', with: 'title'
expect(find('a', text: 'Assign to me')).to be_visible
- click_button 'Assignee'
+ click_button 'Unassigned'
+
+ wait_for_ajax
+
page.within '.dropdown-menu-user' do
click_link user2.name
end
- expect(find('input[name="issue[assignee_id]"]', visible: false).value).to match(user2.id.to_s)
+ expect(find('input[name="issue[assignee_ids][]"]', visible: false).value).to match(user2.id.to_s)
page.within '.js-assignee-search' do
expect(page).to have_content user2.name
end
expect(find('a', text: 'Assign to me')).to be_visible
click_link 'Assign to me'
- expect(find('input[name="issue[assignee_id]"]', visible: false).value).to match(user.id.to_s)
+ assignee_ids = page.all('input[name="issue[assignee_ids][]"]', visible: false)
+
+ expect(assignee_ids[0].value).to match(user.id.to_s)
+
page.within '.js-assignee-search' do
expect(page).to have_content user.name
end
@@ -68,7 +114,7 @@ describe 'New/edit issue', feature: true, js: true do
page.within '.issuable-sidebar' do
page.within '.assignee' do
- expect(page).to have_content user.name
+ expect(page).to have_content "Assignee"
end
page.within '.milestone' do
@@ -105,6 +151,25 @@ describe 'New/edit issue', feature: true, js: true do
expect(find('.js-label-select')).to have_content('Labels')
end
+
+ it 'correctly updates the selected user when changing assignee' do
+ click_button 'Unassigned'
+
+ wait_for_ajax
+
+ page.within '.dropdown-menu-user' do
+ click_link user.name
+ end
+
+ expect(find('.js-assignee-search')).to have_content(user.name)
+ click_button user.name
+
+ page.within '.dropdown-menu-user' do
+ click_link user2.name
+ end
+
+ expect(find('.js-assignee-search')).to have_content(user2.name)
+ end
end
context 'edit issue' do
@@ -113,7 +178,7 @@ describe 'New/edit issue', feature: true, js: true do
end
it 'allows user to update issue' do
- expect(find('input[name="issue[assignee_id]"]', visible: false).value).to match(user.id.to_s)
+ expect(find('input[name="issue[assignee_ids][]"]', visible: false).value).to match(user.id.to_s)
expect(find('input[name="issue[milestone_id]"]', visible: false).value).to match(milestone.id.to_s)
expect(find('a', text: 'Assign to me', visible: false)).not_to be_visible
@@ -154,4 +219,14 @@ describe 'New/edit issue', feature: true, js: true do
end
end
end
+
+ def before_for_selector(selector)
+ js = <<-JS.strip_heredoc
+ (function(selector) {
+ var el = document.querySelector(selector);
+ return window.getComputedStyle(el, '::before').getPropertyValue('content');
+ })("#{escape_javascript(selector)}")
+ JS
+ page.evaluate_script(js)
+ end
end
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index 7135565294b..ad29911248f 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -1,7 +1,6 @@
require 'rails_helper'
feature 'GFM autocomplete', feature: true, js: true do
- include WaitForAjax
let(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') }
let(:project) { create(:project) }
let(:label) { create(:label, project: project, title: 'special+') }
@@ -46,6 +45,33 @@ feature 'GFM autocomplete', feature: true, js: true do
expect(find('#at-view-58')).not_to have_selector('.cur:first-of-type')
end
+ it 'does not open autocomplete menu when ":" is prefixed by a number and letters' do
+ note = find('#note_note')
+
+ # Number.
+ page.within '.timeline-content-form' do
+ note.native.send_keys('7:')
+ end
+
+ expect(page).not_to have_selector('.atwho-view')
+
+ # ASCII letter.
+ page.within '.timeline-content-form' do
+ note.set('')
+ note.native.send_keys('w:')
+ end
+
+ expect(page).not_to have_selector('.atwho-view')
+
+ # Non-ASCII letter.
+ page.within '.timeline-content-form' do
+ note.set('')
+ note.native.send_keys('Ё:')
+ end
+
+ expect(page).not_to have_selector('.atwho-view')
+ end
+
it 'selects the first item for assignee dropdowns' do
page.within '.timeline-content-form' do
find('#note_note').native.send_keys('')
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 7b9d4534ada..0de0f93089a 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -1,10 +1,10 @@
require 'rails_helper'
feature 'Issue Sidebar', feature: true do
- include WaitForAjax
include MobileHelpers
- let(:project) { create(:project, :public) }
+ let(:group) { create(:group, :nested) }
+ let(:project) { create(:project, :public, namespace: group) }
let(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
let!(:label) { create(:label, project: project, title: 'bug') }
@@ -42,6 +42,21 @@ feature 'Issue Sidebar', feature: true do
expect(page).to have_content(user2.name)
end
end
+
+ it 'assigns yourself' do
+ find('.block.assignee .dropdown-menu-toggle').click
+
+ click_button 'assign yourself'
+
+ wait_for_ajax
+
+ find('.block.assignee .edit-link').click
+
+ page.within '.dropdown-menu-user' do
+ expect(page.find('.dropdown-header')).to be_visible
+ expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name)
+ end
+ end
end
context 'as a allowed user' do
@@ -56,10 +71,12 @@ feature 'Issue Sidebar', feature: true do
# Resize the window
resize_screen_sm
# Make sure the sidebar is collapsed
+ find(sidebar_selector)
expect(page).to have_css(sidebar_selector)
# Once is collapsed let's open the sidebard and reload
open_issue_sidebar
refresh
+ find(sidebar_selector)
expect(page).to have_css(sidebar_selector)
# Restore the window size as it was including the sidebar
restore_window_size
@@ -120,6 +137,20 @@ feature 'Issue Sidebar', feature: true do
end
end
+ context 'as a allowed mobile user', js: true do
+ before do
+ project.team << [user, :developer]
+ resize_screen_xs
+ visit_issue(project, issue)
+ end
+
+ context 'mobile sidebar' do
+ it 'collapses the sidebar for small screens' do
+ expect(page).not_to have_css('aside.right-sidebar.right-sidebar-collapsed')
+ end
+ end
+ end
+
context 'as a guest' do
before do
project.team << [user, :guest]
@@ -136,9 +167,7 @@ feature 'Issue Sidebar', feature: true do
end
def open_issue_sidebar
- page.within('aside.right-sidebar.right-sidebar-collapsed') do
- find('.js-sidebar-toggle').click
- sleep 1
- end
+ find('aside.right-sidebar.right-sidebar-collapsed .js-sidebar-toggle').trigger('click')
+ find('aside.right-sidebar.right-sidebar-expanded')
end
end
diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb
index f89b4db9e62..6c09903a2f6 100644
--- a/spec/features/issues/move_spec.rb
+++ b/spec/features/issues/move_spec.rb
@@ -37,8 +37,8 @@ feature 'issue move to another project' do
edit_issue(issue)
end
- scenario 'moving issue to another project' do
- first('#move_to_project_id', visible: false).set(new_project.id)
+ scenario 'moving issue to another project', js: true do
+ find('#move_to_project_id', visible: false).set(new_project.id)
click_button('Save changes')
expect(current_url).to include project_path(new_project)
diff --git a/spec/features/issues/new_branch_button_spec.rb b/spec/features/issues/new_branch_button_spec.rb
deleted file mode 100644
index c0ab42c6822..00000000000
--- a/spec/features/issues/new_branch_button_spec.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require 'rails_helper'
-
-feature 'Start new branch from an issue', feature: true, js: true do
- let!(:project) { create(:project) }
- let!(:issue) { create(:issue, project: project) }
- let!(:user) { create(:user)}
-
- context "for team members" do
- before do
- project.team << [user, :master]
- login_as(user)
- end
-
- it 'shows the new branch button' do
- visit namespace_project_issue_path(project.namespace, project, issue)
-
- expect(page).to have_css('#new-branch .available')
- end
-
- context "when there is a referenced merge request" do
- let!(:note) do
- create(:note, :on_issue, :system, project: project, noteable: issue,
- note: "mentioned in #{referenced_mr.to_reference}")
- end
-
- let(:referenced_mr) do
- create(:merge_request, :simple, source_project: project, target_project: project,
- description: "Fixes #{issue.to_reference}", author: user)
- end
-
- before do
- referenced_mr.cache_merge_request_closes_issues!(user)
-
- visit namespace_project_issue_path(project.namespace, project, issue)
- end
-
- it "hides the new branch button" do
- expect(page).to have_css('#new-branch .unavailable')
- expect(page).not_to have_css('#new-branch .available')
- expect(page).to have_content /1 Related Merge Request/
- end
- end
-
- context 'when issue is confidential' do
- it 'hides the new branch button' do
- issue = create(:issue, :confidential, project: project)
-
- visit namespace_project_issue_path(project.namespace, project, issue)
-
- expect(page).not_to have_css('#new-branch')
- end
- end
- end
-
- context 'for visitors' do
- it 'shows no buttons' do
- visit namespace_project_issue_path(project.namespace, project, issue)
-
- expect(page).not_to have_css('#new-branch')
- end
- end
-end
diff --git a/spec/features/issues/note_polling_spec.rb b/spec/features/issues/note_polling_spec.rb
index f5cfe2d666e..80f57906506 100644
--- a/spec/features/issues/note_polling_spec.rb
+++ b/spec/features/issues/note_polling_spec.rb
@@ -1,19 +1,131 @@
require 'spec_helper'
-feature 'Issue notes polling' do
- let!(:project) { create(:project, :public) }
- let!(:issue) { create(:issue, project: project) }
+feature 'Issue notes polling', :feature, :js do
+ let(:project) { create(:empty_project, :public) }
+ let(:issue) { create(:issue, project: project) }
- background do
- visit namespace_project_issue_path(project.namespace, project, issue)
+ describe 'creates' do
+ before do
+ visit namespace_project_issue_path(project.namespace, project, issue)
+ end
+
+ it 'displays the new comment' do
+ note = create(:note, noteable: issue, project: project, note: 'Looks good!')
+ page.execute_script('notes.refresh();')
+
+ expect(page).to have_selector("#note_#{note.id}", text: 'Looks good!')
+ end
end
- scenario 'Another user adds a comment to an issue', js: true do
- note = create(:note, noteable: issue, project: project,
- note: 'Looks good!')
+ describe 'updates' do
+ context 'when from own user' do
+ let(:user) { create(:user) }
+ let(:note_text) { "Hello World" }
+ let(:updated_text) { "Bye World" }
+ let!(:existing_note) { create(:note, noteable: issue, project: project, author: user, note: note_text) }
- page.execute_script('notes.refresh();')
+ before do
+ login_as(user)
+ visit namespace_project_issue_path(project.namespace, project, issue)
+ end
+
+ it 'has .original-note-content to compare against' do
+ expect(page).to have_selector("#note_#{existing_note.id}", text: note_text)
+ expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", count: 1, visible: false)
+
+ update_note(existing_note, updated_text)
+
+ expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text)
+ expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", count: 1, visible: false)
+ end
+
+ it 'displays the updated content' do
+ expect(page).to have_selector("#note_#{existing_note.id}", text: note_text)
+
+ update_note(existing_note, updated_text)
+
+ expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text)
+ end
+
+ it 'when editing but have not changed anything, and an update comes in, show the updated content in the textarea' do
+ find("#note_#{existing_note.id} .js-note-edit").click
+
+ expect(page).to have_field("note[note]", with: note_text)
+
+ update_note(existing_note, updated_text)
+
+ expect(page).to have_field("note[note]", with: updated_text)
+ end
+
+ it 'when editing but you changed some things, and an update comes in, show a warning' do
+ find("#note_#{existing_note.id} .js-note-edit").click
+
+ expect(page).to have_field("note[note]", with: note_text)
+
+ find("#note_#{existing_note.id} .js-note-text").set('something random')
+
+ update_note(existing_note, updated_text)
- expect(page).to have_selector("#note_#{note.id}", text: 'Looks good!')
+ expect(page).to have_selector(".alert")
+ end
+
+ it 'when editing but you changed some things, an update comes in, and you press cancel, show the updated content' do
+ find("#note_#{existing_note.id} .js-note-edit").click
+
+ expect(page).to have_field("note[note]", with: note_text)
+
+ find("#note_#{existing_note.id} .js-note-text").set('something random')
+
+ update_note(existing_note, updated_text)
+
+ find("#note_#{existing_note.id} .note-edit-cancel").click
+
+ expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text)
+ end
+ end
+
+ context 'when from another user' do
+ let(:user1) { create(:user) }
+ let(:user2) { create(:user) }
+ let(:note_text) { "Hello World" }
+ let(:updated_text) { "Bye World" }
+ let!(:existing_note) { create(:note, noteable: issue, project: project, author: user1, note: note_text) }
+
+ before do
+ login_as(user2)
+ visit namespace_project_issue_path(project.namespace, project, issue)
+ end
+
+ it 'has .original-note-content to compare against' do
+ expect(page).to have_selector("#note_#{existing_note.id}", text: note_text)
+ expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", count: 1, visible: false)
+
+ update_note(existing_note, updated_text)
+
+ expect(page).to have_selector("#note_#{existing_note.id}", text: updated_text)
+ expect(page).to have_selector("#note_#{existing_note.id} .original-note-content", count: 1, visible: false)
+ end
+ end
+
+ context 'system notes' do
+ let(:user) { create(:user) }
+ let(:note_text) { "Some system note" }
+ let!(:system_note) { create(:system_note, noteable: issue, project: project, author: user, note: note_text) }
+
+ before do
+ login_as(user)
+ visit namespace_project_issue_path(project.namespace, project, issue)
+ end
+
+ it 'has .original-note-content to compare against' do
+ expect(page).to have_selector("#note_#{system_note.id}", text: note_text)
+ expect(page).to have_selector("#note_#{system_note.id} .original-note-content", count: 1, visible: false)
+ end
+ end
+ end
+
+ def update_note(note, new_text)
+ note.update(note: new_text)
+ page.execute_script('notes.refresh();')
end
end
diff --git a/spec/features/issues/notes_on_issues_spec.rb b/spec/features/issues/notes_on_issues_spec.rb
new file mode 100644
index 00000000000..a4035324d2b
--- /dev/null
+++ b/spec/features/issues/notes_on_issues_spec.rb
@@ -0,0 +1,77 @@
+require 'spec_helper'
+
+describe 'Create notes on issues', :js, :feature do
+ let(:user) { create(:user) }
+
+ shared_examples 'notes with reference' do
+ let(:issue) { create(:issue, project: project) }
+ let(:note_text) { "Check #{mention.to_reference}" }
+
+ before do
+ project.team << [user, :developer]
+ login_as(user)
+ visit namespace_project_issue_path(project.namespace, project, issue)
+
+ fill_in 'note[note]', with: note_text
+ click_button 'Comment'
+
+ wait_for_ajax
+ end
+
+ it 'creates a note with reference and cross references the issue' do
+ page.within('div#notes li.note div.note-text') do
+ expect(page).to have_content(note_text)
+ expect(page.find('a')).to have_content(mention.to_reference)
+ end
+
+ find('div#notes li.note div.note-text a').click
+
+ page.within('div#notes li.note .system-note-message') do
+ expect(page).to have_content('mentioned in issue')
+ expect(page.find('a')).to have_content(issue.to_reference)
+ end
+ end
+ end
+
+ context 'mentioning issue on a private project' do
+ it_behaves_like 'notes with reference' do
+ let(:project) { create(:project, :private) }
+ let(:mention) { create(:issue, project: project) }
+ end
+ end
+
+ context 'mentioning issue on an internal project' do
+ it_behaves_like 'notes with reference' do
+ let(:project) { create(:project, :internal) }
+ let(:mention) { create(:issue, project: project) }
+ end
+ end
+
+ context 'mentioning issue on a public project' do
+ it_behaves_like 'notes with reference' do
+ let(:project) { create(:project, :public) }
+ let(:mention) { create(:issue, project: project) }
+ end
+ end
+
+ context 'mentioning merge request on a private project' do
+ it_behaves_like 'notes with reference' do
+ let(:project) { create(:project, :private) }
+ let(:mention) { create(:merge_request, source_project: project) }
+ end
+ end
+
+ context 'mentioning merge request on an internal project' do
+ it_behaves_like 'notes with reference' do
+ let(:project) { create(:project, :internal) }
+ let(:mention) { create(:merge_request, source_project: project) }
+ end
+ end
+
+ context 'mentioning merge request on a public project' do
+ it_behaves_like 'notes with reference' do
+ let(:project) { create(:project, :public) }
+ let(:mention) { create(:merge_request, source_project: project) }
+ end
+ end
+end
diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb
index 4bc9b49f889..6001476d0ca 100644
--- a/spec/features/issues/spam_issues_spec.rb
+++ b/spec/features/issues/spam_issues_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-describe 'New issue', feature: true do
+describe 'New issue', feature: true, js: true do
include StubENV
let(:project) { create(:project, :public) }
diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb
index ae5da3877a8..b250fa2ed3c 100644
--- a/spec/features/issues/update_issues_spec.rb
+++ b/spec/features/issues/update_issues_spec.rb
@@ -1,8 +1,6 @@
require 'rails_helper'
feature 'Multiple issue updating from issues#index', feature: true do
- include WaitForAjax
-
let!(:project) { create(:project) }
let!(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
@@ -101,7 +99,7 @@ feature 'Multiple issue updating from issues#index', feature: true do
end
def create_assigned
- create(:issue, project: project, assignee: user)
+ create(:issue, project: project, assignees: [user])
end
def create_with_milestone
diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb
index 0a9cd11ad6e..4cd6c1171ac 100644
--- a/spec/features/issues/user_uses_slash_commands_spec.rb
+++ b/spec/features/issues/user_uses_slash_commands_spec.rb
@@ -2,7 +2,6 @@ require 'rails_helper'
feature 'Issues > User uses slash commands', feature: true, js: true do
include SlashCommandsHelpers
- include WaitForAjax
it_behaves_like 'issuable record that supports slash commands in its description and notes', :issue do
let(:issuable) { create(:issue, project: project) }