Commit 7919587e authored by Jan Provaznik's avatar Jan Provaznik Committed by charlie ablett

Fix all_list board param

When filtering board issues, EE version of the list_service can
add additional filters which were not covered in CE version of the
method.
parent fd4a3d64
...@@ -8,6 +8,8 @@ module EE ...@@ -8,6 +8,8 @@ module EE
override :filter override :filter
def filter(issues) def filter(issues)
return issues if params[:all_lists]
unless list&.movable? || list&.closed? unless list&.movable? || list&.closed?
issues = without_assignees_from_lists(issues) issues = without_assignees_from_lists(issues)
issues = without_milestones_from_lists(issues) issues = without_milestones_from_lists(issues)
......
...@@ -4,46 +4,40 @@ require 'spec_helper' ...@@ -4,46 +4,40 @@ require 'spec_helper'
RSpec.describe Boards::Issues::ListService, services: true do RSpec.describe Boards::Issues::ListService, services: true do
describe '#execute' do describe '#execute' do
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:group) { create(:group) } let_it_be(:group) { create(:group) }
let(:project) { create(:project, :empty_repo, namespace: group) } let_it_be(:project) { create(:project, :empty_repo, namespace: group) }
let(:project1) { create(:project, :empty_repo, namespace: group) } let_it_be(:project1) { create(:project, :empty_repo, namespace: group) }
let(:board) { create(:board, group: group) } let_it_be(:board, reload: true) { create(:board, group: group) }
let(:m1) { create(:milestone, group: group) } let_it_be(:m1) { create(:milestone, group: group) }
let(:m2) { create(:milestone, group: group) } let_it_be(:m2) { create(:milestone, group: group) }
let(:bug) { create(:group_label, group: group, name: 'Bug') } let_it_be(:bug) { create(:group_label, group: group, name: 'Bug') }
let(:development) { create(:group_label, group: group, name: 'Development') } let_it_be(:development) { create(:group_label, group: group, name: 'Development') }
let(:testing) { create(:group_label, group: group, name: 'Testing') } let_it_be(:testing) { create(:group_label, group: group, name: 'Testing') }
let(:p1) { create(:group_label, title: 'P1', group: group) } let_it_be(:p1) { create(:group_label, title: 'P1', group: group) }
let(:p2) { create(:group_label, title: 'P2', group: group) } let_it_be(:p2) { create(:group_label, title: 'P2', group: group) }
let(:p3) { create(:group_label, title: 'P3', group: group) } let_it_be(:p3) { create(:group_label, title: 'P3', group: group) }
let(:user_list) { create(:user_list, board: board, position: 2) } let_it_be(:milestone) { create(:milestone, group: group) }
let(:milestone) { create(:milestone, group: group) }
let(:milestone_list) { create(:milestone_list, board: board, position: 3, milestone: milestone) } let_it_be(:opened_issue1) { create(:labeled_issue, project: project, milestone: m1, weight: 9, title: 'Issue 1', labels: [bug]) }
let(:backlog) { create(:backlog_list, board: board) } let_it_be(:opened_issue2) { create(:labeled_issue, project: project, milestone: m2, weight: 1, title: 'Issue 2', labels: [p2]) }
let(:list1) { create(:list, board: board, label: development, position: 0) } let_it_be(:opened_issue3) { create(:labeled_issue, project: project, milestone: m2, title: 'Assigned Issue', labels: [p3]) }
let(:list2) { create(:list, board: board, label: testing, position: 1) } let_it_be(:reopened_issue1) { create(:issue, state: 'opened', project: project, title: 'Issue 3', closed_at: Time.current ) }
let(:closed) { create(:closed_list, board: board) }
let_it_be(:list1_issue1) { create(:labeled_issue, project: project, milestone: m1, labels: [p2, development]) }
let!(:opened_issue1) { create(:labeled_issue, project: project, milestone: m1, weight: 9, title: 'Issue 1', labels: [bug]) } let_it_be(:list1_issue2) { create(:labeled_issue, project: project, milestone: m2, labels: [development]) }
let!(:opened_issue2) { create(:labeled_issue, project: project, milestone: m2, weight: 1, title: 'Issue 2', labels: [p2]) } let_it_be(:list1_issue3) { create(:labeled_issue, project: project1, milestone: m1, labels: [development, p1]) }
let!(:opened_issue3) { create(:labeled_issue, project: project, milestone: m2, title: 'Assigned Issue', labels: [p3]) } let_it_be(:list2_issue1) { create(:labeled_issue, project: project1, milestone: m1, labels: [testing]) }
let!(:reopened_issue1) { create(:issue, state: 'opened', project: project, title: 'Issue 3', closed_at: Time.current ) }
let_it_be(:closed_issue1) { create(:labeled_issue, :closed, project: project, labels: [bug]) }
let(:list1_issue1) { create(:labeled_issue, project: project, milestone: m1, labels: [p2, development]) } let_it_be(:closed_issue2) { create(:labeled_issue, :closed, project: project, labels: [p3]) }
let(:list1_issue2) { create(:labeled_issue, project: project, milestone: m2, labels: [development]) } let_it_be(:closed_issue3) { create(:issue, :closed, project: project1, milestone: m1) }
let(:list1_issue3) { create(:labeled_issue, project: project1, milestone: m1, labels: [development, p1]) } let_it_be(:closed_issue4) { create(:labeled_issue, :closed, project: project1, labels: [p1]) }
let(:list2_issue1) { create(:labeled_issue, project: project1, milestone: m1, labels: [testing]) } let_it_be(:closed_issue5) { create(:labeled_issue, :closed, project: project1, labels: [development]) }
let(:closed_issue1) { create(:labeled_issue, :closed, project: project, labels: [bug]) }
let(:closed_issue2) { create(:labeled_issue, :closed, project: project, labels: [p3]) }
let(:closed_issue3) { create(:issue, :closed, project: project1) }
let(:closed_issue4) { create(:labeled_issue, :closed, project: project1, labels: [p1]) }
let(:closed_issue5) { create(:labeled_issue, :closed, project: project1, labels: [development]) }
let(:parent) { group } let(:parent) { group }
...@@ -54,117 +48,137 @@ RSpec.describe Boards::Issues::ListService, services: true do ...@@ -54,117 +48,137 @@ RSpec.describe Boards::Issues::ListService, services: true do
opened_issue3.assignees.push(user_list.user) opened_issue3.assignees.push(user_list.user)
end end
context 'milestone lists' do context 'with assignee, milestone and label lists present' do
let!(:milestone_issue) { create(:labeled_issue, project: project, milestone: milestone_list.milestone, labels: [p3]) } let!(:user_list) { create(:user_list, board: board, position: 2) }
let!(:milestone_list) { create(:milestone_list, board: board, position: 3, milestone: milestone) }
let!(:backlog) { create(:backlog_list, board: board) }
let!(:list1) { create(:list, board: board, label: development, position: 0) }
let!(:list2) { create(:list, board: board, label: testing, position: 1) }
let!(:closed) { create(:closed_list, board: board) }
it 'returns issues from milestone persisted in the list' do context 'milestone lists' do
params = { board_id: board.id, id: milestone_list.id } let!(:milestone_issue) { create(:labeled_issue, project: project, milestone: milestone_list.milestone, labels: [p3]) }
issues = described_class.new(parent, user, params).execute it 'returns issues from milestone persisted in the list' do
params = { board_id: board.id, id: milestone_list.id }
expect(issues).to contain_exactly(milestone_issue)
end
context 'backlog list context' do
it 'returns issues without milestones and without milestones from other lists' do
params = { board_id: board.id, id: backlog.id }
issues = described_class.new(parent, user, params).execute issues = described_class.new(parent, user, params).execute
expect(issues).to contain_exactly(opened_issue1, # milestone from this issue is not in a list expect(issues).to contain_exactly(milestone_issue)
opened_issue2, # milestone from this issue is not in a list
reopened_issue1) # has no milestone
end end
end
end
describe '#metadata' do context 'backlog list context' do
it 'returns issues count and weight for list' do it 'returns issues without milestones and without milestones from other lists' do
params = { board_id: board.id, id: backlog.id } params = { board_id: board.id, id: backlog.id }
metadata = described_class.new(parent, user, params).metadata issues = described_class.new(parent, user, params).execute
expect(metadata[:size]).to eq(3) expect(issues).to contain_exactly(opened_issue1, # milestone from this issue is not in a list
expect(metadata[:total_weight]).to eq(10) opened_issue2, # milestone from this issue is not in a list
reopened_issue1) # has no milestone
end
end
end end
# When collection is filtered by labels the ActiveRecord::Relation returns '{}' on #count or #sum describe '#metadata' do
# if no issues are found it 'returns issues count and weight for list' do
it 'returns 0 when filtering by labels and issues are not present' do params = { board_id: board.id, id: backlog.id }
params = { board_id: board.id, id: list1.id, label_name: [bug.title, p2.title] }
metadata = described_class.new(parent, user, params).metadata metadata = described_class.new(parent, user, params).metadata
expect(metadata[:size]).to eq(0) expect(metadata[:size]).to eq(3)
expect(metadata[:total_weight]).to eq(0) expect(metadata[:total_weight]).to eq(10)
end end
end
context 'when list_id is missing' do # When collection is filtered by labels the ActiveRecord::Relation returns '{}' on #count or #sum
context 'when board is not scoped by milestone' do # if no issues are found
it 'returns opened issues without board labels and assignees applied' do it 'returns 0 when filtering by labels and issues are not present' do
params = { board_id: board.id } params = { board_id: board.id, id: list1.id, label_name: [bug.title, p2.title] }
issues = described_class.new(parent, user, params).execute metadata = described_class.new(parent, user, params).metadata
expect(issues).to match_array([opened_issue2, reopened_issue1, opened_issue1]) expect(metadata[:size]).to eq(0)
expect(metadata[:total_weight]).to eq(0)
end end
end end
context 'when board is scoped by milestone' do context 'when list_id is missing' do
it 'returns opened issues without board labels, assignees, or milestone applied' do context 'when board is not scoped by milestone' do
params = { board_id: board.id } it 'returns opened issues without board labels and assignees applied' do
board.update_attribute(:milestone, m1) params = { board_id: board.id }
issues = described_class.new(parent, user, params).execute issues = described_class.new(parent, user, params).execute
expect(issues) expect(issues).to match_array([opened_issue2, reopened_issue1, opened_issue1])
.to match_array([opened_issue2, list1_issue2, reopened_issue1, opened_issue1]) end
end end
context 'when milestone is predefined' do context 'when board is scoped by milestone' do
let(:params) { { board_id: board.id, id: backlog.id } } it 'returns opened issues without board labels, assignees, or milestone applied' do
params = { board_id: board.id }
board.update_attribute(:milestone, m1)
issues = described_class.new(parent, user, params).execute
expect(issues)
.to match_array([opened_issue2, list1_issue2, reopened_issue1, opened_issue1])
end
context 'when milestone is predefined' do
let(:params) { { board_id: board.id, id: backlog.id } }
context 'as upcoming' do
before do
board.update(milestone_id: Milestone::Upcoming.id)
end
it 'returns open issue for backlog without board label or assignees' do
issues = described_class.new(parent, user, params).execute
context 'as upcoming' do expect(issues).to match_array([opened_issue2, reopened_issue1, opened_issue1])
before do end
board.update(milestone_id: Milestone::Upcoming.id)
end end
it 'returns open issue for backlog without board label or assignees' do context 'as started' do
issues = described_class.new(parent, user, params).execute before do
board.update(milestone_id: Milestone::Started.id)
end
it 'returns open issue for backlog without board label or assignees' do
issues = described_class.new(parent, user, params).execute
expect(issues).to match_array([opened_issue2, reopened_issue1, opened_issue1]) expect(issues).to match_array([opened_issue2, reopened_issue1, opened_issue1])
end
end end
end end
context 'as started' do context 'when :all_lists param is set' do
before do let(:params) { { board_id: board.id, all_lists: true, milestone_title: m1.title } }
board.update(milestone_id: Milestone::Started.id)
end
it 'returns open issue for backlog without board label or assignees' do it 'returns matching issues in all board lists' do
issues = described_class.new(parent, user, params).execute issues = described_class.new(parent, user, params).execute
expect(issues).to match_array([opened_issue2, reopened_issue1, opened_issue1]) expect(issues).to match_array([opened_issue1, list1_issue1,
list1_issue3, list2_issue1, closed_issue3])
end end
end end
end end
end end
end
context 'when search param is present' do context 'when search param is present' do
it 'returns correct issues' do it 'returns correct issues' do
params = { board_id: board.id, search: 'Iss' } params = { board_id: board.id, search: 'Iss' }
issues = described_class.new(parent, user, params).execute issues = described_class.new(parent, user, params).execute
expect(issues).to contain_exactly(opened_issue1, opened_issue2, reopened_issue1) expect(issues).to contain_exactly(opened_issue1, opened_issue2, reopened_issue1)
end end
it 'returns correct issues using 2 characters' do it 'returns correct issues using 2 characters' do
params = { board_id: board.id, search: 'Is' } params = { board_id: board.id, search: 'Is' }
issues = described_class.new(parent, user, params).execute issues = described_class.new(parent, user, params).execute
expect(issues).to contain_exactly(opened_issue1, opened_issue2, reopened_issue1) expect(issues).to contain_exactly(opened_issue1, opened_issue2, reopened_issue1)
end
end end
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