Commit b9712c81 authored by Jacob Schatz's avatar Jacob Schatz

Merge branch '21961-issues-filtering-issue-with-labels-that-contain-spaces' into 'master'

Fixes labels multi-encode and selecting labels with single quotes

## What does this MR do?

Replaced single quotes with escaped single quotes when setting item `.is-active` and when removing its field.

Adds a test to test selecting 2 different labels _(one with a single quote)_ with a full page load inbetween, it checks the labels are selected as well as shown as `.is-active` in the list.

## Are there points in the code the reviewer needs to double check?



## Why was this MR needed?

The javascript handles the url encoding when it is sent to the server so we shouldn't let the javascript begin processing an already encoded string but we needed to stop single quotes from breaking a jquery selector.

## Screenshots (if relevant)

https://youtu.be/-H0_L2hV9tM

## Does this MR meet the acceptance criteria?

- [ ] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG) entry added
- [ ] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
- [ ] API support added
- Tests
  - [ ] Added for this feature/bug
  - [ ] All builds are passing
- [ ] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)
- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [ ] Branch has no merge conflicts with `master` (if you do - rebase it please)
- [ ] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)

## What are the relevant issue numbers?

Closes #21961

Closes #21880

Closes #21248

Closes #20759

Closes #21935

See merge request !6313
parents b94de5fd 2e11cdd0
...@@ -607,13 +607,15 @@ ...@@ -607,13 +607,15 @@
selectedObject = this.renderedData[selectedIndex]; selectedObject = this.renderedData[selectedIndex];
} }
} }
field = [];
fieldName = typeof this.options.fieldName === 'function' ? this.options.fieldName(selectedObject) : this.options.fieldName;
value = this.options.id ? this.options.id(selectedObject, el) : selectedObject.id; value = this.options.id ? this.options.id(selectedObject, el) : selectedObject.id;
if (isInput) { if (isInput) {
field = $(this.el); field = $(this.el);
} else { } else if(value) {
field = this.dropdown.parent().find("input[name='" + fieldName + "'][value='" + escape(value) + "']"); field = this.dropdown.parent().find("input[name='" + fieldName + "'][value='" + value.toString().replace(/'/g, '\\\'') + "']");
} }
if (el.hasClass(ACTIVE_CLASS)) { if (field.length && el.hasClass(ACTIVE_CLASS)) {
el.removeClass(ACTIVE_CLASS); el.removeClass(ACTIVE_CLASS);
if (isInput) { if (isInput) {
field.val(''); field.val('');
...@@ -623,7 +625,7 @@ ...@@ -623,7 +625,7 @@
} else if (el.hasClass(INDETERMINATE_CLASS)) { } else if (el.hasClass(INDETERMINATE_CLASS)) {
el.addClass(ACTIVE_CLASS); el.addClass(ACTIVE_CLASS);
el.removeClass(INDETERMINATE_CLASS); el.removeClass(INDETERMINATE_CLASS);
if (value == null) { if (field.length && value == null) {
field.remove(); field.remove();
} }
if (!field.length && fieldName) { if (!field.length && fieldName) {
...@@ -636,7 +638,7 @@ ...@@ -636,7 +638,7 @@
this.dropdown.parent().find("input[name='" + fieldName + "']").remove(); this.dropdown.parent().find("input[name='" + fieldName + "']").remove();
} }
} }
if (value == null) { if (field.length && value == null) {
field.remove(); field.remove();
} }
// Toggle active class for the tick mark // Toggle active class for the tick mark
...@@ -644,7 +646,7 @@ ...@@ -644,7 +646,7 @@
if (value != null) { if (value != null) {
if (!field.length && fieldName) { if (!field.length && fieldName) {
this.addInput(fieldName, value, selectedObject); this.addInput(fieldName, value, selectedObject);
} else { } else if (field.length) {
field.val(value).trigger('change'); field.val(value).trigger('change');
} }
} }
......
...@@ -166,7 +166,7 @@ ...@@ -166,7 +166,7 @@
instance.addInput(this.fieldName, label.id); instance.addInput(this.fieldName, label.id);
} }
} }
if ($form.find("input[type='hidden'][name='" + ($dropdown.data('fieldName')) + "'][value='" + escape(this.id(label)) + "']").length) { if (this.id(label) && $form.find("input[type='hidden'][name='" + ($dropdown.data('fieldName')) + "'][value='" + this.id(label).toString().replace(/'/g, '\\\'') + "']").length) {
selectedClass.push('is-active'); selectedClass.push('is-active');
} }
if ($dropdown.hasClass('js-multiselect') && removesAll) { if ($dropdown.hasClass('js-multiselect') && removesAll) {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
- if params[:label_name].present? - if params[:label_name].present?
- if params[:label_name].respond_to?('any?') - if params[:label_name].respond_to?('any?')
- params[:label_name].each do |label| - params[:label_name].each do |label|
= hidden_field_tag "label_name[]", u(label), id: nil = hidden_field_tag "label_name[]", label, id: nil
.dropdown .dropdown
%button.dropdown-menu-toggle.js-label-select.js-multiselect{class: classes.join(' '), type: "button", data: dropdown_data} %button.dropdown-menu-toggle.js-label-select.js-multiselect{class: classes.join(' '), type: "button", data: dropdown_data}
%span.dropdown-toggle-text %span.dropdown-toggle-text
......
...@@ -101,7 +101,7 @@ describe 'Filter issues', feature: true do ...@@ -101,7 +101,7 @@ describe 'Filter issues', feature: true do
expect(find('.js-label-select .dropdown-toggle-text')).to have_content('No Label') expect(find('.js-label-select .dropdown-toggle-text')).to have_content('No Label')
end end
it 'filters by no label' do it 'filters by a label' do
find('.dropdown-menu-labels a', text: label.title).click find('.dropdown-menu-labels a', text: label.title).click
page.within '.labels-filter' do page.within '.labels-filter' do
expect(page).to have_content label.title expect(page).to have_content label.title
...@@ -109,7 +109,7 @@ describe 'Filter issues', feature: true do ...@@ -109,7 +109,7 @@ describe 'Filter issues', feature: true do
expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title) expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title)
end end
it 'filters by wont fix labels' do it "filters by `won't fix` and another label" do
find('.dropdown-menu-labels a', text: label.title).click find('.dropdown-menu-labels a', text: label.title).click
page.within '.labels-filter' do page.within '.labels-filter' do
expect(page).to have_content wontfix.title expect(page).to have_content wontfix.title
...@@ -117,6 +117,33 @@ describe 'Filter issues', feature: true do ...@@ -117,6 +117,33 @@ describe 'Filter issues', feature: true do
end end
expect(find('.js-label-select .dropdown-toggle-text')).to have_content(wontfix.title) expect(find('.js-label-select .dropdown-toggle-text')).to have_content(wontfix.title)
end end
it "filters by `won't fix` label followed by another label after page load" do
find('.dropdown-menu-labels a', text: wontfix.title).click
# Close label dropdown to load
find('body').click
expect(find('.filtered-labels')).to have_content(wontfix.title)
find('.js-label-select').click
wait_for_ajax
find('.dropdown-menu-labels a', text: label.title).click
# Close label dropdown to load
find('body').click
expect(find('.filtered-labels')).to have_content(label.title)
find('.js-label-select').click
wait_for_ajax
expect(find('.dropdown-menu-labels li', text: wontfix.title)).to have_css('.is-active')
expect(find('.dropdown-menu-labels li', text: label.title)).to have_css('.is-active')
end
it "selects and unselects `won't fix`" do
find('.dropdown-menu-labels a', text: wontfix.title).click
find('.dropdown-menu-labels a', text: wontfix.title).click
# Close label dropdown to load
find('body').click
expect(page).not_to have_css('.filtered-labels')
end
end end
describe 'Filter issues for assignee and label from issues#index' do describe 'Filter issues for assignee and label from issues#index' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment