summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2016-04-22 18:32:08 +0200
committerRémy Coutable <remy@rymai.me>2016-04-25 16:59:23 +0200
commitab2f25042a977a5bef89c709854b652ceb9c0a12 (patch)
treedc339fa9968a1b563743f88a4d35ee6443ac5ee6
parent81cb636e4fcb7ea76db84a92aac65a73f2376458 (diff)
downloadgitlab-ce-15529-fix=missing-from-clause-for-table-issues.tar.gz
Fix an issue when filtering merge requests with more than one label15529-fix=missing-from-clause-for-table-issues
Signed-off-by: Rémy Coutable <remy@rymai.me>
-rw-r--r--CHANGELOG1
-rw-r--r--app/models/concerns/issuable.rb4
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb185
3 files changed, 188 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index fbc3ee194cb..c16de0f7828 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,7 @@ v 8.7.1 (unreleased)
- Use the `can?` helper instead of `current_user.can?`. !3882
- Prevent users from deleting Webhooks via API they do not own
- Fix Error 500 due to stale cache when projects are renamed or transferred
+ - Fix an issue when filtering merge requests with more than one label
v 8.7.0
- Gitlab::GitAccess and Gitlab::GitAccessWiki are now instrumented
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index d5166e81474..e2f534d2483 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -123,8 +123,8 @@ module Issuable
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}")
+ if title.is_a?(Array) && title.size > 1
+ joins(:labels).where(labels: { title: title }).group(arel_table[:id]).having("COUNT(DISTINCT labels.title) = #{title.size}")
else
joins(:labels).where(labels: { title: title })
end
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
new file mode 100644
index 00000000000..37deac65e6f
--- /dev/null
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -0,0 +1,185 @@
+require 'spec_helper'
+
+describe 'Projects > Merge requests > User lists merge requests', feature: true do
+ include SortingHelper
+
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ before { login_with(user) }
+
+ describe 'Filter merge requests' do
+ before do
+ %w[fix markdown].each do |branch|
+ create(:merge_request,
+ author: user,
+ assignee: user,
+ source_project: project,
+ source_branch: branch,
+ title: branch)
+ end
+ create(:merge_request,
+ author: user,
+ assignee: nil,
+ source_project: project,
+ source_branch: 'lfs',
+ title: 'lfs',
+ milestone: create(:milestone, project: project))
+ end
+
+ it 'allows filtering by merge requests with no specified assignee' do
+ visit namespace_project_merge_requests_path(project.namespace, project, assignee_id: IssuableFinder::NONE)
+
+ expect(current_path).to eq(namespace_project_merge_requests_path(project.namespace, project))
+ expect(page).to have_content 'lfs'
+ expect(page).not_to have_content 'fix'
+ expect(page).not_to have_content 'markdown'
+ end
+
+ it 'allows filtering by a specified assignee' do
+ visit namespace_project_merge_requests_path(project.namespace, project, assignee_id: user.id)
+
+ expect(page).not_to have_content 'lfs'
+ expect(page).to have_content 'fix'
+ expect(page).to have_content 'markdown'
+ end
+ end
+
+ describe 'Filter & Sort merge requests' do
+ %w[fix markdown lfs].each_with_index do |branch, index|
+ let!(branch.to_sym) do
+ create(:merge_request,
+ title: branch,
+ source_project: project,
+ source_branch: branch,
+ created_at: Time.now - (index * 60))
+ end
+ end
+ let(:newer_due_milestone) { create(:milestone, due_date: '2013-12-11') }
+ let(:later_due_milestone) { create(:milestone, due_date: '2013-12-12') }
+
+ describe 'Sort merge requests' do
+ it 'sorts by newest' do
+ visit namespace_project_merge_requests_path(project.namespace, project, sort: sort_value_recently_created)
+
+ expect(first_merge_request).to include('lfs')
+ expect(last_merge_request).to include('fix')
+ end
+
+ it 'sorts by oldest' do
+ visit namespace_project_merge_requests_path(project.namespace, project, sort: sort_value_oldest_created)
+
+ expect(first_merge_request).to include('fix')
+ expect(last_merge_request).to include('lfs')
+ end
+
+ it 'sorts by most recently updated' do
+ lfs.updated_at = Time.now + 100
+ lfs.save
+ visit namespace_project_merge_requests_path(project.namespace, project, sort: sort_value_recently_updated)
+
+ expect(first_merge_request).to include('lfs')
+ end
+
+ it 'sorts by least recently updated' do
+ lfs.updated_at = Time.now - 100
+ lfs.save
+ visit namespace_project_merge_requests_path(project.namespace, project, sort: sort_value_oldest_updated)
+
+ expect(first_merge_request).to include('lfs')
+ end
+
+ describe 'sorting by milestone' do
+ before do
+ fix.milestone = newer_due_milestone
+ fix.save
+ markdown.milestone = later_due_milestone
+ markdown.save
+ end
+
+ it 'sorts by recently due milestone' do
+ visit namespace_project_merge_requests_path(project.namespace, project, sort: sort_value_milestone_soon)
+
+ expect(first_merge_request).to include('fix')
+ end
+
+ it 'sorts by least recently due milestone' do
+ visit namespace_project_merge_requests_path(project.namespace, project, sort: sort_value_milestone_later)
+
+ expect(first_merge_request).to include('markdown')
+ end
+ end
+ end
+
+ describe 'Filter and sort at the same time' do
+ let(:user2) { create(:user) }
+
+ before do
+ fix.assignee = user2
+ fix.milestone = newer_due_milestone
+ fix.save
+ markdown.assignee = user2
+ markdown.milestone = later_due_milestone
+ markdown.save
+ end
+
+ context 'filter on one label' do
+ let(:label) { create(:label, project: project) }
+ before { create(:label_link, label: label, target: fix) }
+
+ it 'sorts by due soon' do
+ visit namespace_project_merge_requests_path(project.namespace, project,
+ label_name: [label.name],
+ sort: sort_value_due_date_soon)
+
+ expect(first_merge_request).to include('fix')
+ end
+ end
+
+ context 'filter on two labels' do
+ let(:label) { create(:label, project: project) }
+ let(:label2) { create(:label, project: project) }
+ before do
+ create(:label_link, label: label, target: fix)
+ create(:label_link, label: label2, target: fix)
+ end
+
+ it 'sorts by due soon' do
+ visit namespace_project_merge_requests_path(project.namespace, project,
+ label_name: [label.name, label2.name],
+ sort: sort_value_due_date_soon)
+
+ expect(first_merge_request).to include('fix')
+ end
+
+ context 'filter on assignee' do
+ it 'sorts by due soon' do
+ visit namespace_project_merge_requests_path(project.namespace, project,
+ label_name: [label.name, label2.name],
+ assignee_id: user2.id,
+ sort: sort_value_due_date_soon)
+
+ expect(first_merge_request).to include('fix')
+ end
+
+ it 'sorts by recently due milestone' do
+ visit namespace_project_merge_requests_path(project.namespace, project,
+ label_name: [label.name, label2.name],
+ assignee_id: user2.id,
+ sort: sort_value_milestone_soon)
+
+ expect(first_merge_request).to include('fix')
+ end
+ end
+ end
+ end
+ end
+
+ def first_merge_request
+ page.all('ul.mr-list > li').first.text
+ end
+
+ def last_merge_request
+ page.all('ul.mr-list > li').last.text
+ end
+end