Commit bbf18a95 authored by Nick Thomas's avatar Nick Thomas

Merge branch '10795-add-epic-tree-BE-initial-support' into 'master'

Epic Tree initial backend support

Closes #10795

See merge request gitlab-org/gitlab-ee!13246
parents 3469e336 a2b64174
......@@ -33,6 +33,7 @@ class EpicsFinder < IssuableFinder
items = by_state(items)
items = by_label(items)
items = by_parent(items)
items = by_iids(items)
sort(items)
end
......@@ -49,7 +50,14 @@ class EpicsFinder < IssuableFinder
# rubocop: disable CodeReuse/ActiveRecord
def init_collection
groups = groups_user_can_read_epics(group.self_and_descendants)
groups = if params[:iids].present?
# If we are querying for specific iids, then we should only be looking at
# those in the group, not any sub-groups (which can have identical iids).
# The `group` method takes care of checking permissions
[group]
else
groups_user_can_read_epics(group.self_and_descendants)
end
Epic.where(group: groups)
end
......
......@@ -22,6 +22,7 @@ module EE
data[:issueLinksEndpoint] = group_epic_issues_path(parent, issuable)
data[:epicLinksEndpoint] = group_epic_links_path(parent, issuable)
data[:subepicsSupported] = ::Epic.supports_nested_objects?
data[:fullPath] = parent.full_path
end
data
......
......@@ -280,7 +280,11 @@ module EE
end
def has_children?
issues.any? || descendants.any?
descendants.any?
end
def has_issues?
issues.any?
end
def child?(id)
......
......@@ -3,7 +3,7 @@
class LinkedEpicEntity < Grape::Entity
include RequestAwareEntity
expose :id, :title, :state
expose :id, :iid, :title, :state, :created_at, :closed_at
expose :reference do |epic|
epic.to_reference(request.issuable.group)
......@@ -16,4 +16,20 @@ class LinkedEpicEntity < Grape::Entity
expose :relation_path do |epic|
group_epic_link_path(request.issuable.group, request.issuable.iid, epic.id)
end
expose :has_children do |epic|
epic.has_children?
end
expose :has_issues do |epic|
epic.has_issues?
end
expose :full_path do |epic|
epic.group.full_path
end
expose :can_admin do |epic|
can?(request.current_user, :admin_epic, epic)
end
end
......@@ -208,6 +208,7 @@ module EE
expose :group_id
expose :parent_id
expose :has_children?, as: :has_children
expose :has_issues?, as: :has_issues
expose :reference do |epic|
epic.to_reference(epic.parent.group)
end
......
......@@ -27,7 +27,7 @@ describe EpicsFinder do
end
end
# Enabeling the `request_store` for this to avoid counting queries that check
# Enabling the `request_store` for this to avoid counting queries that check
# the license.
context 'when epics feature is enabled', :request_store do
before do
......@@ -178,6 +178,23 @@ describe EpicsFinder do
expect(epics(params)).to contain_exactly(epic2)
end
end
context 'by iids' do
let(:subgroup) { create(:group, :private, parent: group) }
let!(:subepic1) { create(:epic, group: subgroup, iid: epic1.iid) }
it 'returns the specified epics' do
params = { iids: [epic1.iid, epic2.iid] }
expect(epics(params)).to contain_exactly(epic1, epic2)
end
it 'does not return epics from the sub-group with the same iid' do
params = { iids: [epic1.iid] }
expect(epics(params)).to contain_exactly(epic1)
end
end
end
end
end
......
......@@ -7,12 +7,13 @@
"group_id": { "type": "integer" },
"parent_id": { "type": ["integer", "null"] },
"has_children": { "type": "boolean" },
"has_issues": { "type": "boolean" },
"reference": { "type": "string" },
"url": { "type": "string" },
"relation_url": { "type": "string" }
},
"required": [
"id", "iid", "group_id", "title", "parent_id", "has_children", "reference", "url", "relation_url"
"id", "iid", "group_id", "title", "parent_id", "has_children", "has_issues", "reference", "url", "relation_url"
],
"additionalProperties": false
}
......@@ -29,6 +29,7 @@ describe IssuablesHelper do
markdownDocsPath: '/help/user/markdown',
issuableTemplates: nil,
lockVersion: epic.lock_version,
fullPath: @group.full_path,
groupPath: @group.path,
initialTitleHtml: epic.title,
initialTitleText: epic.title,
......
......@@ -722,6 +722,34 @@ describe Epic do
end
end
describe '#has_children?' do
let(:epic) { create(:epic, group: group) }
it 'has no children' do
expect(epic.has_children?).to be_falsey
end
it 'has child epics' do
create(:epic, group: group, parent: epic)
expect(epic.has_children?).to be_truthy
end
end
describe '#has_issues?' do
let(:epic) { create(:epic, group: group) }
it 'has no issues' do
expect(epic.has_issues?).to be_falsey
end
it 'has child issues' do
create(:epic_issue, epic: epic, issue: create(:issue))
expect(epic.has_issues?).to be_truthy
end
end
context 'mentioning other objects' do
let(:epic) { create(:epic, group: group) }
......
......@@ -14,15 +14,33 @@ describe EpicLinks::ListService, :postgresql do
epics.map do |epic|
{
id: epic.id,
iid: epic.iid,
title: epic.title,
state: epic.state,
created_at: epic.created_at,
closed_at: epic.closed_at,
reference: epic.to_reference(group),
path: "/groups/#{epic.group.full_path}/-/epics/#{epic.iid}",
relation_path: "/groups/#{parent_epic.group.full_path}/-/epics/#{parent_epic.iid}/links/#{epic.id}"
relation_path: "/groups/#{parent_epic.group.full_path}/-/epics/#{parent_epic.iid}/links/#{epic.id}",
has_children: epic.has_children?,
has_issues: epic.has_issues?,
full_path: epic.group.full_path,
can_admin: Ability.allowed?(user, :admin_epic, epic)
}
end
end
def expect_results_are_equal(results, expected)
results.each_index do |index|
expect(results[index][:created_at]).to be_like_time(expected[index][:created_at])
end
results.each { |h| h.delete(:created_at) }
expected.each { |h| h.delete(:created_at) }
expect(results).to eq(expected)
end
describe '#execute' do
subject { described_class.new(parent_epic, user).execute }
......@@ -47,7 +65,7 @@ describe EpicLinks::ListService, :postgresql do
it 'returns related issues JSON' do
expected_result = epics_to_results([epic1, epic2])
expect(subject).to eq(expected_result)
expect_results_are_equal(subject, expected_result)
end
end
......@@ -62,7 +80,7 @@ describe EpicLinks::ListService, :postgresql do
expected_result = epics_to_results([epic1, epic2, epic_subgroup2, epic_subgroup1])
expect(subject).to eq(expected_result)
expect_results_are_equal(subject, expected_result)
end
it 'returns only some child epics for a subgroup member' do
......@@ -70,7 +88,7 @@ describe EpicLinks::ListService, :postgresql do
expected_result = epics_to_results([epic1, epic2, epic_subgroup2])
expect(subject).to eq(expected_result)
expect_results_are_equal(subject, expected_result)
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