Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/features/issues/gfm_autocomplete_spec.rb')
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb198
1 files changed, 178 insertions, 20 deletions
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index 0b2e8013304..3757985f99c 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -487,7 +487,7 @@ RSpec.describe 'GFM autocomplete', :js do
wait_for_requests
- find('.tribute-container .highlight').click
+ find('.tribute-container .highlight', visible: true).click
click_button 'Save changes'
@@ -501,30 +501,36 @@ RSpec.describe 'GFM autocomplete', :js do
find('#note-body').native.send_keys('@')
end
- expect(page).to have_selector('.tribute-container')
+ expect(page).to have_selector('.tribute-container', visible: true)
end
- it 'opens autocomplete menu for Username when field starts with text with item escaping HTML characters' do
+ it 'opens autocomplete menu for Issues when field starts with text with item escaping HTML characters' do
+ issue_xss_title = 'This will execute alert<img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;'
+ create(:issue, project: project, title: issue_xss_title)
+
page.within '.timeline-content-form' do
- find('#note-body').native.send_keys('@ev')
+ find('#note-body').native.send_keys('#')
end
wait_for_requests
- expect(page).to have_selector('.tribute-container')
+ expect(page).to have_selector('.tribute-container', visible: true)
page.within '.tribute-container ul' do
- expect(find('li').text).to have_content(user_xss.username)
+ expect(page.all('li').first.text).to include(issue_xss_title)
end
end
- it 'doesnt open autocomplete menu character is prefixed with text' do
+ it 'opens autocomplete menu for Username when field starts with text with item escaping HTML characters' do
page.within '.timeline-content-form' do
- find('#note-body').native.send_keys('testing')
- find('#note-body').native.send_keys('@')
+ find('#note-body').native.send_keys('@ev')
end
- expect(page).not_to have_selector('.tribute-container')
+ wait_for_requests
+
+ expect(page).to have_selector('.tribute-container', visible: true)
+
+ expect(find('.tribute-container ul', visible: true).text).to have_content(user_xss.username)
end
it 'selects the first item for assignee dropdowns' do
@@ -532,11 +538,11 @@ RSpec.describe 'GFM autocomplete', :js do
find('#note-body').native.send_keys('@')
end
- expect(page).to have_selector('.tribute-container')
+ expect(page).to have_selector('.tribute-container', visible: true)
wait_for_requests
- expect(find('.tribute-container ul')).to have_selector('.highlight:first-of-type')
+ expect(find('.tribute-container ul', visible: true)).to have_selector('.highlight:first-of-type')
end
it 'includes items for assignee dropdowns with non-ASCII characters in name' do
@@ -545,14 +551,26 @@ RSpec.describe 'GFM autocomplete', :js do
simulate_input('#note-body', "@#{user.name[0...8]}")
end
- expect(page).to have_selector('.tribute-container')
+ expect(page).to have_selector('.tribute-container', visible: true)
wait_for_requests
- expect(find('.tribute-container')).to have_content(user.name)
+ expect(find('.tribute-container ul', visible: true)).to have_content(user.name)
end
context 'if a selected value has special characters' do
+ it 'wraps the result in double quotes' do
+ note = find('#note-body')
+ page.within '.timeline-content-form' do
+ find('#note-body').native.send_keys('')
+ simulate_input('#note-body', "~#{label.title[0]}")
+ end
+
+ label_item = find('.tribute-container ul', text: label.title, visible: true)
+
+ expect_to_wrap(true, label_item, note, label.title)
+ end
+
it "shows dropdown after a new line" do
note = find('#note-body')
page.within '.timeline-content-form' do
@@ -562,7 +580,7 @@ RSpec.describe 'GFM autocomplete', :js do
note.native.send_keys('@')
end
- expect(page).to have_selector('.tribute-container')
+ expect(page).to have_selector('.tribute-container', visible: true)
end
it "does not show dropdown when preceded with a special character" do
@@ -571,12 +589,21 @@ RSpec.describe 'GFM autocomplete', :js do
note.native.send_keys("@")
end
- expect(page).to have_selector('.tribute-container')
+ expect(page).to have_selector('.tribute-container', visible: true)
page.within '.timeline-content-form' do
note.native.send_keys("@")
end
+ expect(page).not_to have_selector('.tribute-container')
+ end
+
+ it "does not throw an error if no labels exist" do
+ note = find('#note-body')
+ page.within '.timeline-content-form' do
+ note.native.send_keys('~')
+ end
+
expect(page).to have_selector('.tribute-container', visible: false)
end
@@ -586,7 +613,7 @@ RSpec.describe 'GFM autocomplete', :js do
note.native.send_keys("@#{user.username[0]}")
end
- user_item = find('.tribute-container li', text: user.username)
+ user_item = find('.tribute-container ul', text: user.username, visible: true)
expect_to_wrap(false, user_item, note, user.username)
end
@@ -611,7 +638,7 @@ RSpec.describe 'GFM autocomplete', :js do
wait_for_requests
- user_item = find('.tribute-container li', text: user.username)
+ user_item = find('.tribute-container ul', text: user.username, visible: true)
expect(user_item).to have_content(user.username)
end
end
@@ -640,8 +667,139 @@ RSpec.describe 'GFM autocomplete', :js do
wait_for_requests
- expect(find('.tribute-container ul')).not_to have_content(user.username)
- expect(find('.tribute-container ul')).to have_content(unassigned_user.username)
+ expect(find('.tribute-container ul', visible: true)).not_to have_content(user.username)
+ expect(find('.tribute-container ul', visible: true)).to have_content(unassigned_user.username)
+ end
+
+ it 'lists users who are currently not assigned to the issue when using /assign on the second line' do
+ visit project_issue_path(project, issue_assignee)
+
+ note = find('#note-body')
+ page.within '.timeline-content-form' do
+ note.native.send_keys('/assign @user2')
+ note.native.send_keys(:enter)
+ note.native.send_keys('/assign @')
+ note.native.send_keys(:right)
+ end
+
+ wait_for_requests
+
+ expect(find('.tribute-container ul', visible: true)).not_to have_content(user.username)
+ expect(find('.tribute-container ul', visible: true)).to have_content(unassigned_user.username)
+ end
+ end
+
+ context 'labels' do
+ it 'opens autocomplete menu for Labels when field starts with text with item escaping HTML characters' do
+ label_xss_title = 'alert label &lt;img src=x onerror="alert(\'Hello xss\');" a'
+ create(:label, project: project, title: label_xss_title)
+
+ note = find('#note-body')
+
+ # It should show all the labels on "~".
+ type(note, '~')
+
+ wait_for_requests
+
+ expect(find('.tribute-container ul', visible: true).text).to have_content('alert label')
+ end
+
+ it 'allows colons when autocompleting scoped labels' do
+ create(:label, project: project, title: 'scoped:label')
+
+ note = find('#note-body')
+ type(note, '~scoped:')
+
+ wait_for_requests
+
+ expect(find('.tribute-container ul', visible: true).text).to have_content('scoped:label')
+ end
+
+ it 'allows colons when autocompleting scoped labels with double colons' do
+ create(:label, project: project, title: 'scoped::label')
+
+ note = find('#note-body')
+ type(note, '~scoped::')
+
+ wait_for_requests
+
+ expect(find('.tribute-container ul', visible: true).text).to have_content('scoped::label')
+ end
+
+ it 'autocompletes multi-word labels' do
+ create(:label, project: project, title: 'Accepting merge requests')
+
+ note = find('#note-body')
+ type(note, '~Acceptingmerge')
+
+ wait_for_requests
+
+ expect(find('.tribute-container ul', visible: true).text).to have_content('Accepting merge requests')
+ end
+
+ it 'only autocompletes the latest label' do
+ create(:label, project: project, title: 'documentation')
+ create(:label, project: project, title: 'feature')
+
+ note = find('#note-body')
+ type(note, '~documentation foo bar ~feat')
+ note.native.send_keys(:right)
+
+ wait_for_requests
+
+ expect(find('.tribute-container ul', visible: true).text).to have_content('feature')
+ expect(find('.tribute-container ul', visible: true).text).not_to have_content('documentation')
+ end
+
+ it 'does not autocomplete labels if no tilde is typed' do
+ create(:label, project: project, title: 'documentation')
+
+ note = find('#note-body')
+ type(note, 'document')
+
+ wait_for_requests
+
+ expect(page).not_to have_selector('.tribute-container')
+ end
+ end
+
+ context 'when other notes are destroyed' do
+ let!(:discussion) { create(:discussion_note_on_issue, noteable: issue, project: issue.project) }
+
+ # This is meant to protect against this issue https://gitlab.com/gitlab-org/gitlab/-/issues/228729
+ it 'keeps autocomplete key listeners' do
+ visit project_issue_path(project, issue)
+ note = find('#note-body')
+
+ start_comment_with_emoji(note)
+
+ start_and_cancel_discussion
+
+ note.fill_in(with: '')
+ start_comment_with_emoji(note)
+ note.native.send_keys(:enter)
+
+ expect(note.value).to eql('Hello :100: ')
+ end
+
+ def start_comment_with_emoji(note)
+ note.native.send_keys('Hello :10')
+
+ wait_for_requests
+
+ find('.atwho-view li', text: '100')
+ end
+
+ def start_and_cancel_discussion
+ click_button('Reply...')
+
+ fill_in('note_note', with: 'Whoops!')
+
+ page.accept_alert 'Are you sure you want to cancel creating this comment?' do
+ click_button('Cancel')
+ end
+
+ wait_for_requests
end
end
end