Commit 7ded28ff authored by Douwe Maan's avatar Douwe Maan

Merge branch 'fix/label-filters' into 'master'

Filter labels by including ALL filter titles

Fixed query to use `AND` and not `OR`. Refactored relevant specs

See merge request !3815
parents 53534682 b09b175d
...@@ -272,7 +272,6 @@ class IssuableFinder ...@@ -272,7 +272,6 @@ class IssuableFinder
items = items.without_label items = items.without_label
else else
items = items.with_label(label_names) items = items.with_label(label_names)
if projects if projects
items = items.where(labels: { project_id: projects }) items = items.where(labels: { project_id: projects })
end end
...@@ -321,7 +320,7 @@ class IssuableFinder ...@@ -321,7 +320,7 @@ class IssuableFinder
end end
def label_names def label_names
params[:label_name].split(',') params[:label_name].is_a?(String) ? params[:label_name].split(',') : params[:label_name]
end end
def current_user_related? def current_user_related?
......
...@@ -37,7 +37,6 @@ module Issuable ...@@ -37,7 +37,6 @@ module Issuable
scope :closed, -> { with_state(:closed) } scope :closed, -> { with_state(:closed) }
scope :order_milestone_due_desc, -> { joins(:milestone).reorder('milestones.due_date DESC, milestones.id DESC') } scope :order_milestone_due_desc, -> { joins(:milestone).reorder('milestones.due_date DESC, milestones.id DESC') }
scope :order_milestone_due_asc, -> { joins(:milestone).reorder('milestones.due_date ASC, milestones.id ASC') } scope :order_milestone_due_asc, -> { joins(:milestone).reorder('milestones.due_date ASC, milestones.id ASC') }
scope :with_label, ->(title) { joins(:labels).where(labels: { title: title }) }
scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) } scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) }
scope :join_project, -> { joins(:project) } scope :join_project, -> { joins(:project) }
...@@ -122,6 +121,14 @@ module Issuable ...@@ -122,6 +121,14 @@ module Issuable
joins(join_clause).group(issuable_table[:id]).reorder("COUNT(notes.id) DESC") joins(join_clause).group(issuable_table[:id]).reorder("COUNT(notes.id) DESC")
end end
def with_label(title)
if title.is_a?(Array) && title.count > 1
joins(:labels).where(labels: { title: title }).group('issues.id').having("count(distinct labels.title) = #{title.count}")
else
joins(:labels).where(labels: { title: title })
end
end
end end
def today? def today?
......
require 'rails_helper' require 'rails_helper'
feature 'Issue filtering by Labels', feature: true do feature 'Issue filtering by Labels', feature: true do
include WaitForAjax
let(:project) { create(:project, :public) } let(:project) { create(:project, :public) }
let!(:user) { create(:user)} let!(:user) { create(:user)}
let!(:label) { create(:label, project: project) } let!(:label) { create(:label, project: project) }
before do before do
['bug', 'feature', 'enhancement'].each do |title| bug = create(:label, project: project, title: 'bug')
create(:label, feature = create(:label, project: project, title: 'feature')
project: project, enhancement = create(:label, project: project, title: 'enhancement')
title: title)
end
issue1 = create(:issue, title: "Bugfix1", project: project) issue1 = create(:issue, title: "Bugfix1", project: project)
issue1.labels << project.labels.find_by(title: 'bug') issue1.labels << bug
issue2 = create(:issue, title: "Bugfix2", project: project) issue2 = create(:issue, title: "Bugfix2", project: project)
issue2.labels << project.labels.find_by(title: 'bug') issue2.labels << bug
issue2.labels << project.labels.find_by(title: 'enhancement') issue2.labels << enhancement
issue3 = create(:issue, title: "Feature1", project: project) issue3 = create(:issue, title: "Feature1", project: project)
issue3.labels << project.labels.find_by(title: 'feature') issue3.labels << feature
project.team << [user, :master] project.team << [user, :master]
login_as(user) login_as(user)
...@@ -31,10 +31,10 @@ feature 'Issue filtering by Labels', feature: true do ...@@ -31,10 +31,10 @@ feature 'Issue filtering by Labels', feature: true do
context 'filter by label bug', js: true do context 'filter by label bug', js: true do
before do before do
page.find('.js-label-select').click page.find('.js-label-select').click
sleep 0.5 wait_for_ajax
execute_script("$('.dropdown-menu-labels li:contains(\"bug\") a').click()") execute_script("$('.dropdown-menu-labels li:contains(\"bug\") a').click()")
page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
sleep 2 wait_for_ajax
end end
it 'should show issue "Bugfix1" and "Bugfix2" in issues list' do it 'should show issue "Bugfix1" and "Bugfix2" in issues list' do
...@@ -59,10 +59,10 @@ feature 'Issue filtering by Labels', feature: true do ...@@ -59,10 +59,10 @@ feature 'Issue filtering by Labels', feature: true do
context 'filter by label feature', js: true do context 'filter by label feature', js: true do
before do before do
page.find('.js-label-select').click page.find('.js-label-select').click
sleep 0.5 wait_for_ajax
execute_script("$('.dropdown-menu-labels li:contains(\"feature\") a').click()") execute_script("$('.dropdown-menu-labels li:contains(\"feature\") a').click()")
page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
sleep 2 wait_for_ajax
end end
it 'should show issue "Feature1" in issues list' do it 'should show issue "Feature1" in issues list' do
...@@ -87,10 +87,10 @@ feature 'Issue filtering by Labels', feature: true do ...@@ -87,10 +87,10 @@ feature 'Issue filtering by Labels', feature: true do
context 'filter by label enhancement', js: true do context 'filter by label enhancement', js: true do
before do before do
page.find('.js-label-select').click page.find('.js-label-select').click
sleep 0.5 wait_for_ajax
execute_script("$('.dropdown-menu-labels li:contains(\"enhancement\") a').click()") execute_script("$('.dropdown-menu-labels li:contains(\"enhancement\") a').click()")
page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
sleep 2 wait_for_ajax
end end
it 'should show issue "Bugfix2" in issues list' do it 'should show issue "Bugfix2" in issues list' do
...@@ -115,20 +115,16 @@ feature 'Issue filtering by Labels', feature: true do ...@@ -115,20 +115,16 @@ feature 'Issue filtering by Labels', feature: true do
context 'filter by label enhancement or feature', js: true do context 'filter by label enhancement or feature', js: true do
before do before do
page.find('.js-label-select').click page.find('.js-label-select').click
sleep 0.5 wait_for_ajax
execute_script("$('.dropdown-menu-labels li:contains(\"enhancement\") a').click()") execute_script("$('.dropdown-menu-labels li:contains(\"enhancement\") a').click()")
execute_script("$('.dropdown-menu-labels li:contains(\"feature\") a').click()") execute_script("$('.dropdown-menu-labels li:contains(\"feature\") a').click()")
page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
sleep 2 wait_for_ajax
end end
it 'should show issue "Bugfix2" or "Feature1" in issues list' do it 'should not show "Bugfix1" or "Feature1" in issues list' do
expect(page).to have_content "Bugfix2"
expect(page).to have_content "Feature1"
end
it 'should not show "Bugfix1" in issues list' do
expect(page).not_to have_content "Bugfix1" expect(page).not_to have_content "Bugfix1"
expect(page).not_to have_content "Feature1"
end end
it 'should show label "enhancement" and "feature" in filtered-labels' do it 'should show label "enhancement" and "feature" in filtered-labels' do
...@@ -141,19 +137,18 @@ feature 'Issue filtering by Labels', feature: true do ...@@ -141,19 +137,18 @@ feature 'Issue filtering by Labels', feature: true do
end end
end end
context 'filter by label enhancement or bug in issues list', js: true do context 'filter by label enhancement and bug in issues list', js: true do
before do before do
page.find('.js-label-select').click page.find('.js-label-select').click
sleep 0.5 wait_for_ajax
execute_script("$('.dropdown-menu-labels li:contains(\"enhancement\") a').click()") execute_script("$('.dropdown-menu-labels li:contains(\"enhancement\") a').click()")
execute_script("$('.dropdown-menu-labels li:contains(\"bug\") a').click()") execute_script("$('.dropdown-menu-labels li:contains(\"bug\") a').click()")
page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click
sleep 2 wait_for_ajax
end end
it 'should show issue "Bugfix2" or "Bugfix1" in issues list' do it 'should show issue "Bugfix2" in issues list' do
expect(page).to have_content "Bugfix2" expect(page).to have_content "Bugfix2"
expect(page).to have_content "Bugfix1"
end end
it 'should not show "Feature1"' do it 'should not show "Feature1"' do
......
...@@ -212,4 +212,34 @@ describe Issue, "Issuable" do ...@@ -212,4 +212,34 @@ describe Issue, "Issuable" do
expect(issue.downvotes).to eq(1) expect(issue.downvotes).to eq(1)
end end
end end
describe ".with_label" do
let(:project) { create(:project, :public) }
let(:bug) { create(:label, project: project, title: 'bug') }
let(:feature) { create(:label, project: project, title: 'feature') }
let(:enhancement) { create(:label, project: project, title: 'enhancement') }
let(:issue1) { create(:issue, title: "Bugfix1", project: project) }
let(:issue2) { create(:issue, title: "Bugfix2", project: project) }
let(:issue3) { create(:issue, title: "Feature1", project: project) }
before(:each) do
issue1.labels << bug
issue1.labels << feature
issue2.labels << bug
issue2.labels << enhancement
issue3.labels << feature
end
it 'finds the correct issue containing just enhancement label' do
expect(Issue.with_label(enhancement.title)).to match_array([issue2])
end
it 'finds the correct issues containing the same label' do
expect(Issue.with_label(bug.title)).to match_array([issue1, issue2])
end
it 'finds the correct issues containing only both labels' do
expect(Issue.with_label([bug.title, enhancement.title])).to match_array([issue2])
end
end
end end
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