Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
8eab7b08
Commit
8eab7b08
authored
Nov 08, 2017
by
Jarka Kadlecova
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prepare backend for assigning issues to epics
parent
50298bcc
Changes
32
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
781 additions
and
38 deletions
+781
-38
app/helpers/issuables_helper.rb
app/helpers/issuables_helper.rb
+1
-0
app/models/issue.rb
app/models/issue.rb
+3
-0
config/routes/group.rb
config/routes/group.rb
+2
-0
db/migrate/20171107130813_create_epic_issues_table.rb
db/migrate/20171107130813_create_epic_issues_table.rb
+20
-0
db/schema.rb
db/schema.rb
+12
-0
ee/app/controllers/concerns/issuable_links.rb
ee/app/controllers/concerns/issuable_links.rb
+31
-0
ee/app/controllers/groups/epic_issues_controller.rb
ee/app/controllers/groups/epic_issues_controller.rb
+25
-0
ee/app/controllers/groups/epics_controller.rb
ee/app/controllers/groups/epics_controller.rb
+1
-1
ee/app/controllers/projects/issue_links_controller.rb
ee/app/controllers/projects/issue_links_controller.rb
+10
-18
ee/app/models/ee/epic.rb
ee/app/models/ee/epic.rb
+10
-0
ee/app/models/epic_issue.rb
ee/app/models/epic_issue.rb
+7
-0
ee/app/policies/ee/project_policy.rb
ee/app/policies/ee/project_policy.rb
+1
-0
ee/app/services/epic_issues/create_service.rb
ee/app/services/epic_issues/create_service.rb
+23
-0
ee/app/services/epic_issues/destroy_service.rb
ee/app/services/epic_issues/destroy_service.rb
+21
-0
ee/app/services/epic_issues/list_service.rb
ee/app/services/epic_issues/list_service.rb
+23
-0
ee/app/services/issuable_links/create_service.rb
ee/app/services/issuable_links/create_service.rb
+30
-17
ee/app/services/issuable_links/destroy_service.rb
ee/app/services/issuable_links/destroy_service.rb
+34
-0
ee/app/services/issuable_links/list_service.rb
ee/app/services/issuable_links/list_service.rb
+34
-0
ee/app/services/issue_links/create_service.rb
ee/app/services/issue_links/create_service.rb
+11
-0
ee/app/services/issue_links/destroy_service.rb
ee/app/services/issue_links/destroy_service.rb
+17
-0
ee/app/services/issue_links/list_service.rb
ee/app/services/issue_links/list_service.rb
+29
-0
lib/banzai/reference_parser/issue_parser.rb
lib/banzai/reference_parser/issue_parser.rb
+1
-2
spec/ee/spec/controllers/groups/epic_issues_controller_spec.rb
...ee/spec/controllers/groups/epic_issues_controller_spec.rb
+123
-0
spec/ee/spec/models/epic_spec.rb
spec/ee/spec/models/epic_spec.rb
+37
-0
spec/ee/spec/services/epic_issues/create_service_spec.rb
spec/ee/spec/services/epic_issues/create_service_spec.rb
+143
-0
spec/ee/spec/services/epic_issues/destroy_service_spec.rb
spec/ee/spec/services/epic_issues/destroy_service_spec.rb
+38
-0
spec/ee/spec/services/epic_issues/list_service_spec.rb
spec/ee/spec/services/epic_issues/list_service_spec.rb
+87
-0
spec/ee/spec/services/issue_links/create_service_spec.rb
spec/ee/spec/services/issue_links/create_service_spec.rb
+0
-0
spec/ee/spec/services/issue_links/destroy_service_spec.rb
spec/ee/spec/services/issue_links/destroy_service_spec.rb
+0
-0
spec/ee/spec/services/issue_links/list_service_spec.rb
spec/ee/spec/services/issue_links/list_service_spec.rb
+0
-0
spec/factories/epic_issues.rb
spec/factories/epic_issues.rb
+6
-0
spec/helpers/issuables_helper_spec.rb
spec/helpers/issuables_helper_spec.rb
+1
-0
No files found.
app/helpers/issuables_helper.rb
View file @
8eab7b08
...
...
@@ -228,6 +228,7 @@ module IssuablesHelper
if
parent
.
is_a?
(
Group
)
data
[
:groupPath
]
=
parent
.
path
data
[
:issueLinksEndpoint
]
=
group_epic_issues_path
(
parent
,
issuable
)
else
data
.
merge!
(
projectPath:
ref_project
.
path
,
projectNamespace:
ref_project
.
namespace
.
full_path
)
end
...
...
app/models/issue.rb
View file @
8eab7b08
...
...
@@ -38,6 +38,9 @@ class Issue < ActiveRecord::Base
has_many
:issue_assignees
has_many
:assignees
,
class_name:
"User"
,
through: :issue_assignees
has_one
:epic_issue
has_one
:epic
,
through: :epic_issue
validates
:project
,
presence:
true
scope
:in_projects
,
->
(
project_ids
)
{
where
(
project_id:
project_ids
)
}
...
...
config/routes/group.rb
View file @
8eab7b08
...
...
@@ -78,6 +78,8 @@ constraints(GroupUrlConstrainer.new) do
member
do
get
:realtime_changes
end
resources
:epic_issues
,
only:
[
:index
,
:create
,
:destroy
],
as:
'issues'
,
path:
'issues'
end
legacy_ee_group_boards_redirect
=
redirect
do
|
params
,
request
|
...
...
db/migrate/20171107130813_create_epic_issues_table.rb
0 → 100644
View file @
8eab7b08
class
CreateEpicIssuesTable
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
up
create_table
:epic_issues
do
|
t
|
t
.
references
:epic
,
null:
false
,
index:
true
,
foreign_key:
true
t
.
references
:issue
,
null:
false
,
index:
{
unique:
true
},
foreign_key:
true
t
.
timestamps_with_timezone
end
end
def
down
drop_table
:epic_issues
end
end
db/schema.rb
View file @
8eab7b08
...
...
@@ -732,6 +732,16 @@ ActiveRecord::Schema.define(version: 20171107144726) do
add_index
"environments"
,
[
"project_id"
,
"name"
],
name:
"index_environments_on_project_id_and_name"
,
unique:
true
,
using: :btree
add_index
"environments"
,
[
"project_id"
,
"slug"
],
name:
"index_environments_on_project_id_and_slug"
,
unique:
true
,
using: :btree
create_table
"epic_issues"
,
force: :cascade
do
|
t
|
t
.
integer
"epic_id"
,
null:
false
t
.
integer
"issue_id"
,
null:
false
t
.
datetime_with_timezone
"created_at"
t
.
datetime_with_timezone
"updated_at"
end
add_index
"epic_issues"
,
[
"epic_id"
],
name:
"index_epic_issues_on_epic_id"
,
using: :btree
add_index
"epic_issues"
,
[
"issue_id"
],
name:
"index_epic_issues_on_issue_id"
,
unique:
true
,
using: :btree
create_table
"epic_metrics"
,
force: :cascade
do
|
t
|
t
.
integer
"epic_id"
,
null:
false
t
.
datetime_with_timezone
"created_at"
,
null:
false
...
...
@@ -2393,6 +2403,8 @@ ActiveRecord::Schema.define(version: 20171107144726) do
add_foreign_key
"deploy_keys_projects"
,
"projects"
,
name:
"fk_58a901ca7e"
,
on_delete: :cascade
add_foreign_key
"deployments"
,
"projects"
,
name:
"fk_b9a3851b82"
,
on_delete: :cascade
add_foreign_key
"environments"
,
"projects"
,
name:
"fk_d1c8c1da6a"
,
on_delete: :cascade
add_foreign_key
"epic_issues"
,
"epics"
add_foreign_key
"epic_issues"
,
"issues"
add_foreign_key
"epic_metrics"
,
"epics"
,
on_delete: :cascade
add_foreign_key
"epics"
,
"milestones"
,
on_delete: :nullify
add_foreign_key
"epics"
,
"namespaces"
,
column:
"group_id"
,
name:
"fk_f081aa4489"
,
on_delete: :cascade
...
...
ee/app/controllers/concerns/issuable_links.rb
0 → 100644
View file @
8eab7b08
module
IssuableLinks
def
index
render
json:
issues
end
def
create
result
=
create_service
.
execute
render
json:
{
message:
result
[
:message
],
issues:
issues
},
status:
result
[
:http_status
]
end
def
destroy
result
=
destroy_service
.
execute
render
json:
{
issues:
issues
},
status:
result
[
:http_status
]
end
private
def
create_params
params
.
slice
(
:issue_references
)
end
def
create_service
raise
NotImplementedError
end
def
destroy_service
raise
NotImplementedError
end
end
ee/app/controllers/groups/epic_issues_controller.rb
0 → 100644
View file @
8eab7b08
class
Groups::EpicIssuesController
<
Groups
::
EpicsController
include
IssuableLinks
skip_before_action
:authorize_destroy_issuable!
before_action
:authorize_admin_epic!
,
only:
[
:create
,
:destroy
]
private
def
create_service
EpicIssues
::
CreateService
.
new
(
epic
,
current_user
,
create_params
)
end
def
destroy_service
epic_issue
=
EpicIssue
.
find
(
params
[
:id
])
EpicIssues
::
DestroyService
.
new
(
epic_issue
,
current_user
)
end
def
issues
EpicIssues
::
ListService
.
new
(
epic
,
current_user
).
execute
end
def
authorize_admin_epic!
render_403
unless
can?
(
current_user
,
:admin_epic
,
epic
)
end
end
ee/app/controllers/groups/epics_controller.rb
View file @
8eab7b08
...
...
@@ -9,7 +9,7 @@ class Groups::EpicsController < Groups::ApplicationController
private
def
epic
@issuable
=
@epic
||=
@group
.
epics
.
find_by
(
iid:
params
[
:id
])
@issuable
=
@epic
||=
@group
.
epics
.
find_by
(
iid:
params
[
:
epic_id
]
||
params
[
:
id
])
return
render_404
unless
can?
(
current_user
,
:read_epic
,
@epic
)
...
...
app/controllers/projects/issue_links_controller.rb
→
ee/
app/controllers/projects/issue_links_controller.rb
View file @
8eab7b08
module
Projects
class
IssueLinksController
<
Projects
::
ApplicationController
include
IssuableLinks
before_action
:authorize_admin_issue_link!
,
only:
[
:create
,
:destroy
]
def
index
render
json:
issues
end
def
create
create_params
=
params
.
slice
(
:issue_references
)
result
=
IssueLinks
::
CreateService
.
new
(
issue
,
current_user
,
create_params
).
execute
render
json:
{
message:
result
[
:message
],
issues:
issues
},
status:
result
[
:http_status
]
end
def
destroy
issue_link
=
IssueLink
.
find
(
params
[
:id
])
result
=
IssueLinks
::
DestroyService
.
new
(
issue_link
,
current_user
).
execute
render
json:
{
issues:
issues
},
status:
result
[
:http_status
]
end
private
def
issues
...
...
@@ -36,5 +19,14 @@ module Projects
.
execute
.
find_by!
(
iid:
params
[
:issue_id
])
end
def
create_service
IssueLinks
::
CreateService
.
new
(
issue
,
current_user
,
create_params
)
end
def
destroy_service
issue_link
=
IssueLink
.
find
(
params
[
:id
])
IssueLinks
::
DestroyService
.
new
(
issue_link
,
current_user
)
end
end
end
ee/app/models/ee/epic.rb
View file @
8eab7b08
...
...
@@ -10,6 +10,8 @@ module EE
belongs_to
:assignee
,
class_name:
"User"
belongs_to
:group
has_many
:epic_issues
validates
:group
,
presence:
true
end
...
...
@@ -24,5 +26,13 @@ module EE
def
supports_weight?
false
end
def
issues
(
current_user
)
related_issues
=
::
Issue
.
select
(
'issues.*, epic_issues.id as epic_issue_id'
)
.
joins
(
:epic_issue
)
.
where
(
"epic_issues.epic_id =
#{
id
}
"
)
Ability
.
issues_readable_by_user
(
related_issues
,
current_user
)
end
end
end
ee/app/models/epic_issue.rb
0 → 100644
View file @
8eab7b08
class
EpicIssue
<
ActiveRecord
::
Base
validates
:epic
,
:issue
,
presence:
true
validates
:issue
,
uniqueness:
true
belongs_to
:epic
belongs_to
:issue
end
ee/app/policies/ee/project_policy.rb
View file @
8eab7b08
...
...
@@ -55,6 +55,7 @@ module EE
enable
:admin_board
enable
:read_deploy_board
enable
:admin_issue_link
enable
:admin_epic_issue
end
rule
{
can?
(
:developer_access
)
}.
enable
:admin_board
...
...
ee/app/services/epic_issues/create_service.rb
0 → 100644
View file @
8eab7b08
module
EpicIssues
class
CreateService
<
IssuableLinks
::
CreateService
private
def
relate_issues
(
referenced_issue
)
link
=
EpicIssue
.
find_or_initialize_by
(
issue:
referenced_issue
)
link
.
epic
=
issuable
link
.
save
end
def
create_notes?
false
end
def
extractor_context
{
group:
issuable
.
group
}
end
def
linkable_issues
(
issues
)
issues
.
select
{
|
issue
|
can?
(
current_user
,
:admin_epic_issue
,
issue
)
&&
issue
.
project
.
group
==
issuable
.
group
}
end
end
end
ee/app/services/epic_issues/destroy_service.rb
0 → 100644
View file @
8eab7b08
module
EpicIssues
class
DestroyService
<
IssuableLinks
::
DestroyService
private
def
create_notes?
false
end
def
source
@source
||=
link
.
epic
end
def
target
@target
||=
link
.
issue
end
def
permission_to_remove_relation?
can?
(
current_user
,
:admin_epic_issue
,
target
)
&&
can?
(
current_user
,
:admin_epic
,
source
)
end
end
end
ee/app/services/epic_issues/list_service.rb
0 → 100644
View file @
8eab7b08
module
EpicIssues
class
ListService
<
IssuableLinks
::
ListService
private
def
issues
issuable
.
issues
(
current_user
)
end
def
destroy_relation_path
(
issue
)
if
can_destroy_issue_link?
(
issue
)
group_epic_issue_path
(
issuable
.
group
,
issuable
.
iid
,
issue
.
epic_issue_id
)
end
end
def
can_destroy_issue_link?
(
issue
)
Ability
.
allowed?
(
current_user
,
:admin_issue_link
,
issue
)
&&
Ability
.
allowed?
(
current_user
,
:admin_epic
,
issuable
)
end
def
reference
(
issue
)
issue
.
to_reference
(
full:
true
)
end
end
end
app/services/issu
e_links/create_service.rb
→
ee/app/services/issuabl
e_links/create_service.rb
View file @
8eab7b08
module
IssueLinks
module
Issu
abl
eLinks
class
CreateService
<
BaseService
def
initialize
(
issue
,
user
,
params
)
@issue
,
@current_user
,
@params
=
issue
,
user
,
params
.
dup
attr_reader
:issuable
,
:current_user
,
:params
def
initialize
(
issuable
,
user
,
params
)
@issuable
,
@current_user
,
@params
=
issuable
,
user
,
params
.
dup
end
def
execute
...
...
@@ -17,20 +19,10 @@ module IssueLinks
def
create_issue_links
referenced_issues
.
each
do
|
referenced_issue
|
create_notes
(
referenced_issue
)
if
relate_issues
(
referenced_issue
)
create_notes
(
referenced_issue
)
if
relate_issues
(
referenced_issue
)
&&
create_notes?
end
end
# Returns a Boolean indicating if the Issue was related.
def
relate_issues
(
referenced_issue
)
IssueLink
.
new
(
source:
@issue
,
target:
referenced_issue
).
save
end
def
create_notes
(
referenced_issue
)
SystemNoteService
.
relate_issue
(
@issue
,
referenced_issue
,
current_user
)
SystemNoteService
.
relate_issue
(
referenced_issue
,
@issue
,
current_user
)
end
def
referenced_issues
@referenced_issues
||=
begin
target_issue
=
params
[
:target_issue
]
...
...
@@ -43,7 +35,7 @@ module IssueLinks
[]
end
issues
.
select
{
|
issue
|
can?
(
current_user
,
:admin_issue_link
,
issue
)
}
linkable_issues
(
issues
)
end
end
...
...
@@ -51,10 +43,31 @@ module IssueLinks
issue_references
=
params
[
:issue_references
]
text
=
issue_references
.
join
(
' '
)
extractor
=
Gitlab
::
ReferenceExtractor
.
new
(
@issu
e
.
project
,
@current_user
)
extractor
.
analyze
(
text
)
extractor
=
Gitlab
::
ReferenceExtractor
.
new
(
issuabl
e
.
project
,
@current_user
)
extractor
.
analyze
(
text
,
extractor_context
)
extractor
.
issues
end
def
create_notes
(
referenced_issue
)
SystemNoteService
.
relate_issue
(
issuable
,
referenced_issue
,
current_user
)
SystemNoteService
.
relate_issue
(
referenced_issue
,
issuable
,
current_user
)
end
def
extractor_context
{}
end
def
create_notes?
true
end
def
linkable_issues
(
issues
)
raise
NotImplementedError
end
def
relate_issues
(
referenced_issue
)
raise
NotImplementedError
end
end
end
app/services/issu
e_links/destroy_service.rb
→
ee/app/services/issuabl
e_links/destroy_service.rb
View file @
8eab7b08
module
IssueLinks
module
Issu
abl
eLinks
class
DestroyService
<
BaseService
def
initialize
(
issue_link
,
user
)
@issue_link
=
issue_link
attr_reader
:link
,
:current_user
def
initialize
(
link
,
user
)
@link
=
link
@current_user
=
user
@issue
=
issue_link
.
source
@referenced_issue
=
issue_link
.
target
end
def
execute
return
error
(
'No Issue Link found'
,
404
)
unless
permission_to_remove_relation?
remove_relation
create_notes
create_notes
if
create_notes?
success
(
message:
'Relation was removed'
)
end
private
def
remove_relation
@issue_link
.
destroy!
def
create_notes
SystemNoteService
.
unrelate_issue
(
source
,
target
,
current_user
)
SystemNoteService
.
unrelate_issue
(
target
,
source
,
current_user
)
end
def
create_notes
SystemNoteService
.
unrelate_issue
(
@issue
,
@referenced_issue
,
current_user
)
SystemNoteService
.
unrelate_issue
(
@referenced_issue
,
@issue
,
current_user
)
def
remove_relation
link
.
destroy!
end
def
permission_to_remove_relation?
can?
(
current_user
,
:admin_issue_link
,
@issue
)
&&
can?
(
current_user
,
:admin_issue_link
,
@referenced_issue
)
def
create_notes?
true
end
end
end
app/services/issu
e_links/list_service.rb
→
ee/app/services/issuabl
e_links/list_service.rb
View file @
8eab7b08
module
IssueLinks
module
Issu
abl
eLinks
class
ListService
include
Gitlab
::
Routing
def
initialize
(
issue
,
user
)
@issue
,
@current_user
,
@project
=
issue
,
user
,
issue
.
project
attr_reader
:issuable
,
:current_user
def
initialize
(
issuable
,
user
)
@issuable
,
@current_user
=
issuable
,
user
end
def
execute
...
...
@@ -12,7 +14,7 @@ module IssueLinks
id:
referenced_issue
.
id
,
title:
referenced_issue
.
title
,
state:
referenced_issue
.
state
,
reference:
reference
d_issue
.
to_reference
(
@project
),
reference:
reference
(
referenced_issue
),
path:
project_issue_path
(
referenced_issue
.
project
,
referenced_issue
.
iid
),
destroy_relation_path:
destroy_relation_path
(
referenced_issue
)
}
...
...
@@ -21,26 +23,12 @@ module IssueLinks
private
def
issues
@issue
.
related_issues
(
@current_user
,
preload:
{
project: :namespace
})
end
def
destroy_relation_path
(
issue
)
# Make sure the user can admin both the current issue AND the
# referenced issue projects in order to return the removal link.
if
can_destroy_issue_link_on_current_project?
&&
can_destroy_issue_link?
(
issue
.
project
)
project_issue_link_path
(
@project
,
@issue
.
iid
,
issue
.
issue_link_id
)
end
end
def
can_destroy_issue_link_on_current_project?
return
@can_destroy_on_current_project
if
defined?
(
@can_destroy_on_current_project
)
@can_destroy_on_current_project
=
can_destroy_issue_link?
(
@project
)
raise
NotImplementedError
end
def
can_destroy_issue_link?
(
project
)
Ability
.
allowed?
(
@current_user
,
:admin_issue_link
,
project
)
def
reference
(
issue
)
issue
.
to_reference
(
issuable
.
project
)
end
end
end
ee/app/services/issue_links/create_service.rb
0 → 100644
View file @
8eab7b08
module
IssueLinks
class
CreateService
<
IssuableLinks
::
CreateService
def
relate_issues
(
referenced_issue
)
IssueLink
.
new
(
source:
issuable
,
target:
referenced_issue
).
save
end
def
linkable_issues
(
issues
)
issues
.
select
{
|
issue
|
can?
(
current_user
,
:admin_issue_link
,
issue
)
}
end
end
end
ee/app/services/issue_links/destroy_service.rb
0 → 100644
View file @
8eab7b08
module
IssueLinks
class
DestroyService
<
IssuableLinks
::
DestroyService
private
def
source
@source
||=
link
.
source
end
def
target
@target
||=
link
.
target
end
def
permission_to_remove_relation?
can?
(
current_user
,
:admin_issue_link
,
source
)
&&
can?
(
current_user
,
:admin_issue_link
,
target
)
end
end
end
ee/app/services/issue_links/list_service.rb
0 → 100644
View file @
8eab7b08
module
IssueLinks
class
ListService
<
IssuableLinks
::
ListService
private
def
issues
issuable
.
related_issues
(
current_user
,
preload:
{
project: :namespace
})
end
def
destroy_relation_path
(
issue
)
current_project
=
issuable
.
project
# Make sure the user can admin both the current issue AND the
# referenced issue projects in order to return the removal link.
if
can_destroy_issue_link_on_current_project?
(
current_project
)
&&
can_destroy_issue_link?
(
issue
.
project
)
project_issue_link_path
(
current_project
,
issuable
.
iid
,
issue
.
issue_link_id
)
end
end
def
can_destroy_issue_link_on_current_project?
(
current_project
)
return
@can_destroy_on_current_project
if
defined?
(
@can_destroy_on_current_project
)
@can_destroy_on_current_project
=
can_destroy_issue_link?
(
current_project
)
end
def
can_destroy_issue_link?
(
project
)
Ability
.
allowed?
(
current_user
,
:admin_issue_link
,
project
)
end
end
end
lib/banzai/reference_parser/issue_parser.rb
View file @
8eab7b08
...
...
@@ -6,8 +6,7 @@ module Banzai
def
nodes_visible_to_user
(
user
,
nodes
)
issues
=
issues_for_nodes
(
nodes
)
readable_issues
=
Ability
.
issues_readable_by_user
(
issues
.
values
,
user
).
to_set
readable_issues
=
Ability
.
issues_readable_by_user
(
issues
.
values
,
user
).
to_set
nodes
.
select
do
|
node
|
readable_issues
.
include?
(
issues
[
node
])
...
...
spec/ee/spec/controllers/groups/epic_issues_controller_spec.rb
0 → 100644
View file @
8eab7b08
require
'spec_helper'
describe
Groups
::
EpicIssuesController
do
let
(
:group
)
{
create
(
:group
,
:public
)
}
let
(
:project
)
{
create
(
:project
,
:public
,
group:
group
)
}
let
(
:epic
)
{
create
(
:epic
,
group:
group
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:user
)
{
create
(
:user
)
}
before
do
sign_in
(
user
)
end
describe
'GET #index'
do
let!
(
:epic_issues
)
{
create
(
:epic_issue
,
epic:
epic
,
issue:
issue
)
}
before
do
group
.
add_developer
(
user
)
get
:index
,
group_id:
group
,
epic_id:
epic
.
to_param
end
it
'returns status 200'
do
expect
(
response
.
status
).
to
eq
(
200
)
end
it
'returns the correct json'
do
expected_result
=
[
{
'id'
=>
issue
.
id
,
'title'
=>
issue
.
title
,
'state'
=>
issue
.
state
,
'reference'
=>
"
#{
project
.
full_path
}
#
#{
issue
.
iid
}
"
,
'path'
=>
"/
#{
project
.
full_path
}
/issues/
#{
issue
.
iid
}
"
,
'destroy_relation_path'
=>
"/groups/
#{
group
.
full_path
}
/-/epics/
#{
epic
.
iid
}
/issues/
#{
epic_issues
.
id
}
"
}
]
expect
(
JSON
.
parse
(
response
.
body
)).
to
eq
(
expected_result
)
end
end
describe
'POST #create'
do
subject
do
reference
=
[
issue
.
to_reference
(
full:
true
)]
post
:create
,
group_id:
group
,
epic_id:
epic
.
to_param
,
issue_references:
reference
end
context
'when user has permissions to create requested associtaion'
do
before
do
group
.
add_developer
(
user
)
end
it
'returns correct response for the correct issue reference'
do
subject
list_service_response
=
EpicIssues
::
ListService
.
new
(
epic
,
user
).
execute
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
json_response
).
to
eq
(
'message'
=>
nil
,
'issues'
=>
list_service_response
.
as_json
)
end
it
'creates a new EpicIssue record'
do
expect
{
subject
}.
to
change
{
EpicIssue
.
count
}.
from
(
0
).
to
(
1
)
end
end
context
'when user does not have permissions to create requested associtaion'
do
it
'returns correct response for the correct issue reference'
do
subject
expect
(
response
).
to
have_gitlab_http_status
(
403
)
end
it
'does not create a new EpicIssue record'
do
expect
{
subject
}.
not_to
change
{
EpicIssue
.
count
}.
from
(
0
)
end
end
end
describe
'DELETE #destroy'
do
let!
(
:epic_issue
)
{
create
(
:epic_issue
,
epic:
epic
,
issue:
issue
)
}
subject
do
delete
:destroy
,
group_id:
group
,
epic_id:
epic
.
to_param
,
id:
epic_issue
.
id
end
context
'when user has permissions to detele the link'
do
before
do
group
.
add_developer
(
user
)
end
it
'returns status 200'
do
subject
expect
(
response
.
status
).
to
eq
(
200
)
end
it
'destroys the link'
do
expect
{
subject
}.
to
change
{
EpicIssue
.
count
}.
from
(
1
).
to
(
0
)
end
end
context
'when user does not have permissions to delete the link'
do
it
'returns status 404'
do
subject
expect
(
response
.
status
).
to
eq
(
403
)
end
it
'does not destroy the link'
do
expect
{
subject
}.
not_to
change
{
EpicIssue
.
count
}.
from
(
1
)
end
end
context
'when the epic_issue record does not exixst'
do
it
'returns status 404'
do
delete
:destroy
,
group_id:
group
,
epic_id:
epic
.
to_param
,
id:
9999
expect
(
response
.
status
).
to
eq
(
403
)
end
end
end
end
spec/ee/spec/models/epic_spec.rb
View file @
8eab7b08
...
...
@@ -5,6 +5,7 @@ describe Epic do
subject
{
build
(
:epic
)
}
it
{
is_expected
.
to
belong_to
(
:author
).
class_name
(
'User'
)
}
it
{
is_expected
.
to
belong_to
(
:assignee
).
class_name
(
'User'
)
}
it
{
is_expected
.
to
belong_to
(
:group
)
}
end
...
...
@@ -21,4 +22,40 @@ describe Epic do
it
{
is_expected
.
to
include_module
(
InternalId
)
}
end
describe
'#issues'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:group
)
{
create
(
:group
,
:private
)
}
let
(
:project
)
{
create
(
:project
,
group:
group
)
}
let
(
:project2
)
{
create
(
:project
,
group:
group
)
}
let!
(
:epic
)
{
create
(
:epic
,
group:
group
)
}
let!
(
:issue
)
{
create
(
:issue
,
project:
project
)}
let!
(
:lone_issue
)
{
create
(
:issue
,
project:
project
)}
let!
(
:other_issue
)
{
create
(
:issue
,
project:
project2
)}
let!
(
:epic_issues
)
do
[
create
(
:epic_issue
,
epic:
epic
,
issue:
issue
),
create
(
:epic_issue
,
epic:
epic
,
issue:
other_issue
)
]
end
subject
{
epic
.
issues
(
user
)
}
it
'returns all issues if a user has access to them'
do
group
.
add_developer
(
user
)
expect
(
subject
.
count
).
to
eq
(
2
)
expect
(
subject
.
map
(
&
:id
)).
to
match_array
([
issue
.
id
,
other_issue
.
id
])
expect
(
subject
.
map
(
&
:epic_issue_id
)).
to
match_array
(
epic_issues
.
map
(
&
:id
))
end
it
'does not return issues user can not see'
do
project
.
add_developer
(
user
)
expect
(
subject
.
count
).
to
eq
(
1
)
expect
(
subject
.
map
(
&
:id
)).
to
match_array
([
issue
.
id
])
expect
(
subject
.
map
(
&
:epic_issue_id
)).
to
match_array
([
epic_issues
.
first
.
id
])
end
end
end
spec/ee/spec/services/epic_issues/create_service_spec.rb
0 → 100644
View file @
8eab7b08
require
'spec_helper'
describe
EpicIssues
::
CreateService
do
describe
'#execute'
do
let
(
:group
)
{
create
:group
}
let
(
:epic
)
{
create
:epic
,
group:
group
}
let
(
:project
)
{
create
(
:project
,
group:
group
)
}
let
(
:issue
)
{
create
:issue
,
project:
project
}
let
(
:user
)
{
create
:user
}
let
(
:reference
)
{
issue
.
to_reference
(
full:
true
)
}
let
(
:params
)
do
{}
end
subject
{
described_class
.
new
(
epic
,
user
,
params
).
execute
}
context
'when user has permissions to link the issue'
do
before
do
group
.
add_developer
(
user
)
end
context
'when the reference list is empty'
do
let
(
:params
)
do
{
issue_references:
[]
}
end
it
'returns error'
do
is_expected
.
to
eq
(
message:
'No Issue found for given params'
,
status: :error
,
http_status:
404
)
end
end
context
'when there is an issue to relate'
do
context
'when shortcut for Issue is given'
do
let
(
:params
)
do
{
issue_references:
[
issue
.
to_reference
]
}
end
it
'returns error'
do
is_expected
.
to
eq
(
message:
'No Issue found for given params'
,
status: :error
,
http_status:
404
)
end
it
'no relationship is created'
do
expect
{
subject
}.
not_to
change
{
EpicIssue
.
count
}
end
end
context
'when a full reference is given'
do
let
(
:params
)
do
{
issue_references:
[
reference
]
}
end
it
'creates relationships'
do
expect
{
subject
}.
to
change
(
EpicIssue
,
:count
).
from
(
0
).
to
(
1
)
expect
(
EpicIssue
.
find_by!
(
issue_id:
issue
.
id
)).
to
have_attributes
(
epic:
epic
)
end
it
'returns success status'
do
is_expected
.
to
eq
(
status: :success
)
end
end
context
'when an issue links is given'
do
let
(
:params
)
do
{
issue_references:
[
IssuesHelper
.
url_for_issue
(
issue
.
iid
,
issue
.
project
)]
}
end
it
'creates relationships'
do
expect
{
subject
}.
to
change
(
EpicIssue
,
:count
).
from
(
0
).
to
(
1
)
expect
(
EpicIssue
.
find_by!
(
issue_id:
issue
.
id
)).
to
have_attributes
(
epic:
epic
)
end
it
'returns success status'
do
is_expected
.
to
eq
(
status: :success
)
end
end
end
end
context
'when user does not have permissions to link the issue'
do
let
(
:params
)
do
{
issue_references:
[
reference
]
}
end
it
'returns error'
do
is_expected
.
to
eq
(
message:
'No Issue found for given params'
,
status: :error
,
http_status:
404
)
end
it
'no relationship is created'
do
expect
{
subject
}.
not_to
change
{
EpicIssue
.
count
}
end
end
context
'when an issue is already assigned to another epic'
do
let
(
:params
)
do
{
issue_references:
[
reference
]
}
end
before
do
group
.
add_developer
(
user
)
create
(
:epic_issue
,
epic:
epic
,
issue:
issue
)
end
let
(
:another_epic
)
{
create
(
:epic
,
group:
group
)
}
subject
{
described_class
.
new
(
another_epic
,
user
,
params
).
execute
}
it
'does not create a new association'
do
expect
{
subject
}.
not_to
change
(
EpicIssue
,
:count
).
from
(
1
)
end
it
'updates the existing association'
do
expect
{
subject
}.
to
change
{
EpicIssue
.
find_by!
(
issue_id:
issue
.
id
).
epic
}.
from
(
epic
).
to
(
another_epic
)
end
it
'returns success status'
do
is_expected
.
to
eq
(
status: :success
)
end
end
context
'when issue from non group project is given'
do
let
(
:another_issue
)
{
create
:issue
}
let
(
:params
)
do
{
issue_references:
[
another_issue
.
to_reference
(
full:
true
)]
}
end
before
do
group
.
add_developer
(
user
)
another_issue
.
project
.
add_developer
(
user
)
end
it
'returns error'
do
is_expected
.
to
eq
(
message:
'No Issue found for given params'
,
status: :error
,
http_status:
404
)
end
it
'no relationship is created'
do
expect
{
subject
}.
not_to
change
{
EpicIssue
.
count
}
end
end
end
end
spec/ee/spec/services/epic_issues/destroy_service_spec.rb
0 → 100644
View file @
8eab7b08
require
'spec_helper'
describe
EpicIssues
::
DestroyService
do
describe
'#execute'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:group
)
{
create
(
:group
,
:public
)
}
let
(
:project
)
{
create
(
:project
,
group:
group
)
}
let
(
:epic
)
{
create
(
:epic
,
group:
group
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let!
(
:epic_issue
)
{
create
(
:epic_issue
,
epic:
epic
,
issue:
issue
)
}
subject
{
described_class
.
new
(
epic_issue
,
user
).
execute
}
context
'when user has permissions to remove associations'
do
before
do
group
.
add_reporter
(
user
)
end
it
'removes related issue'
do
expect
{
subject
}.
to
change
{
EpicIssue
.
count
}.
from
(
1
).
to
(
0
)
end
it
'returns success message'
do
is_expected
.
to
eq
(
message:
'Relation was removed'
,
status: :success
)
end
end
context
'user does not have permissions to remove associations'
do
it
'does not remove relation'
do
expect
{
subject
}.
not_to
change
{
EpicIssue
.
count
}.
from
(
1
)
end
it
'returns error message'
do
is_expected
.
to
eq
(
message:
'No Issue Link found'
,
status: :error
,
http_status:
404
)
end
end
end
end
spec/ee/spec/services/epic_issues/list_service_spec.rb
0 → 100644
View file @
8eab7b08
require
'spec_helper'
describe
EpicIssues
::
ListService
do
let
(
:user
)
{
create
:user
}
let
(
:group
)
{
create
(
:group
,
:private
)
}
let
(
:project
)
{
create
(
:project_empty_repo
,
group:
group
)
}
let
(
:other_project
)
{
create
(
:project_empty_repo
,
group:
group
)
}
let
(
:epic
)
{
create
(
:epic
,
group:
group
)
}
let
(
:issue1
)
{
create
:issue
,
project:
project
}
let
(
:issue2
)
{
create
:issue
,
project:
project
}
let
(
:issue3
)
{
create
:issue
,
project:
other_project
}
let!
(
:epic_issue1
)
{
create
(
:epic_issue
,
issue:
issue1
,
epic:
epic
)
}
let!
(
:epic_issue2
)
{
create
(
:epic_issue
,
issue:
issue2
,
epic:
epic
)
}
let!
(
:epic_issue3
)
{
create
(
:epic_issue
,
issue:
issue3
,
epic:
epic
)
}
describe
'#execute'
do
subject
{
described_class
.
new
(
epic
,
user
).
execute
}
context
'user can see all issues and destroy their associations'
do
before
do
group
.
add_developer
(
user
)
end
it
'returns related issues JSON'
do
expected_result
=
[
{
id:
issue1
.
id
,
title:
issue1
.
title
,
state:
issue1
.
state
,
reference:
issue1
.
to_reference
(
full:
true
),
path:
"/
#{
project
.
full_path
}
/issues/
#{
issue1
.
iid
}
"
,
destroy_relation_path:
"/groups/
#{
group
.
full_path
}
/-/epics/
#{
epic
.
iid
}
/issues/
#{
epic_issue1
.
id
}
"
},
{
id:
issue2
.
id
,
title:
issue2
.
title
,
state:
issue2
.
state
,
reference:
issue2
.
to_reference
(
full:
true
),
path:
"/
#{
project
.
full_path
}
/issues/
#{
issue2
.
iid
}
"
,
destroy_relation_path:
"/groups/
#{
group
.
full_path
}
/-/epics/
#{
epic
.
iid
}
/issues/
#{
epic_issue2
.
id
}
"
},
{
id:
issue3
.
id
,
title:
issue3
.
title
,
state:
issue3
.
state
,
reference:
issue3
.
to_reference
(
full:
true
),
path:
"/
#{
other_project
.
full_path
}
/issues/
#{
issue3
.
iid
}
"
,
destroy_relation_path:
"/groups/
#{
group
.
full_path
}
/-/epics/
#{
epic
.
iid
}
/issues/
#{
epic_issue3
.
id
}
"
}
]
expect
(
subject
).
to
match_array
(
expected_result
)
end
end
context
'user can see only some issues'
do
before
do
project
.
add_developer
(
user
)
end
it
'returns related issues JSON'
do
expected_result
=
[
{
id:
issue1
.
id
,
title:
issue1
.
title
,
state:
issue1
.
state
,
reference:
issue1
.
to_reference
(
full:
true
),
path:
"/
#{
project
.
full_path
}
/issues/
#{
issue1
.
iid
}
"
,
destroy_relation_path:
nil
},
{
id:
issue2
.
id
,
title:
issue2
.
title
,
state:
issue2
.
state
,
reference:
issue2
.
to_reference
(
full:
true
),
path:
"/
#{
project
.
full_path
}
/issues/
#{
issue2
.
iid
}
"
,
destroy_relation_path:
nil
}
]
expect
(
subject
).
to
match_array
(
expected_result
)
end
end
end
end
spec/services/issue_links/create_service_spec.rb
→
spec/
ee/spec/
services/issue_links/create_service_spec.rb
View file @
8eab7b08
File moved
spec/services/issue_links/destroy_service_spec.rb
→
spec/
ee/spec/
services/issue_links/destroy_service_spec.rb
View file @
8eab7b08
File moved
spec/services/issue_links/list_service_spec.rb
→
spec/
ee/spec/
services/issue_links/list_service_spec.rb
View file @
8eab7b08
File moved
spec/factories/epic_issues.rb
0 → 100644
View file @
8eab7b08
FactoryGirl
.
define
do
factory
:epic_issue
do
epic
issue
end
end
spec/helpers/issuables_helper_spec.rb
View file @
8eab7b08
...
...
@@ -197,6 +197,7 @@ describe IssuablesHelper do
expected_data
=
{
'endpoint'
=>
"/groups/
#{
@group
.
full_path
}
/-/epics/
#{
epic
.
iid
}
"
,
'issueLinksEndpoint'
=>
"/groups/
#{
@group
.
full_path
}
/-/epics/
#{
epic
.
iid
}
/links"
,
'canUpdate'
=>
true
,
'canDestroy'
=>
true
,
'issuableRef'
=>
nil
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment