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
0
Merge Requests
0
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
Jérome Perrin
gitlab-ce
Commits
7bee7b84
Commit
7bee7b84
authored
Jul 10, 2017
by
Jarka Kadlecova
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support both internal and external issue trackers
parent
2fa22a07
Changes
31
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
563 additions
and
99 deletions
+563
-99
app/controllers/projects/issues_controller.rb
app/controllers/projects/issues_controller.rb
+0
-4
app/helpers/issues_helper.rb
app/helpers/issues_helper.rb
+23
-3
app/models/merge_request.rb
app/models/merge_request.rb
+1
-1
app/models/project.rb
app/models/project.rb
+6
-4
app/models/project_services/issue_tracker_service.rb
app/models/project_services/issue_tracker_service.rb
+6
-2
app/models/project_services/jira_service.rb
app/models/project_services/jira_service.rb
+1
-1
app/services/issues/close_service.rb
app/services/issues/close_service.rb
+2
-2
app/views/layouts/nav/_new_project_sidebar.html.haml
app/views/layouts/nav/_new_project_sidebar.html.haml
+3
-3
app/views/layouts/nav/_project.html.haml
app/views/layouts/nav/_project.html.haml
+3
-3
app/views/projects/merge_requests/index.html.haml
app/views/projects/merge_requests/index.html.haml
+1
-1
app/views/shared/_mr_head.html.haml
app/views/shared/_mr_head.html.haml
+1
-1
lib/api/entities.rb
lib/api/entities.rb
+1
-1
lib/api/merge_requests.rb
lib/api/merge_requests.rb
+8
-9
lib/banzai/filter/issue_reference_filter.rb
lib/banzai/filter/issue_reference_filter.rb
+1
-1
lib/banzai/reference_parser/external_issue_parser.rb
lib/banzai/reference_parser/external_issue_parser.rb
+7
-3
lib/gitlab/reference_extractor.rb
lib/gitlab/reference_extractor.rb
+6
-1
lib/gitlab/slash_commands/issue_command.rb
lib/gitlab/slash_commands/issue_command.rb
+1
-1
spec/features/issuables/markdown_references_spec.rb
spec/features/issuables/markdown_references_spec.rb
+193
-0
spec/features/projects/features_visibility_spec.rb
spec/features/projects/features_visibility_spec.rb
+1
-1
spec/helpers/issues_helper_spec.rb
spec/helpers/issues_helper_spec.rb
+7
-1
spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
...lib/banzai/filter/external_issue_reference_filter_spec.rb
+5
-0
spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
+75
-14
spec/lib/gitlab/reference_extractor_spec.rb
spec/lib/gitlab/reference_extractor_spec.rb
+27
-4
spec/models/concerns/mentionable_spec.rb
spec/models/concerns/mentionable_spec.rb
+12
-6
spec/models/merge_request_spec.rb
spec/models/merge_request_spec.rb
+46
-6
spec/models/project_spec.rb
spec/models/project_spec.rb
+39
-6
spec/requests/api/merge_requests_spec.rb
spec/requests/api/merge_requests_spec.rb
+10
-4
spec/requests/api/projects_spec.rb
spec/requests/api/projects_spec.rb
+25
-0
spec/services/git_push_service_spec.rb
spec/services/git_push_service_spec.rb
+47
-11
spec/services/issues/close_service_spec.rb
spec/services/issues/close_service_spec.rb
+4
-4
spec/services/merge_requests/build_service_spec.rb
spec/services/merge_requests/build_service_spec.rb
+1
-1
No files found.
app/controllers/projects/issues_controller.rb
View file @
7bee7b84
...
@@ -269,10 +269,6 @@ class Projects::IssuesController < Projects::ApplicationController
...
@@ -269,10 +269,6 @@ class Projects::IssuesController < Projects::ApplicationController
end
end
end
end
def
module_enabled
render_404
unless
@project
.
feature_available?
(
:issues
,
current_user
)
end
def
issue_params
def
issue_params
params
.
require
(
:issue
).
permit
(
*
issue_params_attributes
)
params
.
require
(
:issue
).
permit
(
*
issue_params_attributes
)
end
end
...
...
app/helpers/issues_helper.rb
View file @
7bee7b84
...
@@ -17,10 +17,10 @@ module IssuesHelper
...
@@ -17,10 +17,10 @@ module IssuesHelper
return
''
if
project
.
nil?
return
''
if
project
.
nil?
url
=
url
=
if
options
[
:
only_path
]
if
options
[
:
internal
]
project
.
issues_tracker
.
issue_path
(
issue_iid
)
url_for_internal_issue
(
issue_iid
,
project
,
options
)
else
else
project
.
issues_tracker
.
issue_url
(
issue_iid
)
url_for_tracker_issue
(
issue_iid
,
project
,
options
)
end
end
# Ensure we return a valid URL to prevent possible XSS.
# Ensure we return a valid URL to prevent possible XSS.
...
@@ -29,6 +29,24 @@ module IssuesHelper
...
@@ -29,6 +29,24 @@ module IssuesHelper
''
''
end
end
def
url_for_tracker_issue
(
issue_iid
,
project
,
options
)
if
options
[
:only_path
]
project
.
issues_tracker
.
issue_path
(
issue_iid
)
else
project
.
issues_tracker
.
issue_url
(
issue_iid
)
end
end
def
url_for_internal_issue
(
issue_iid
,
project
=
@project
,
options
=
{})
helpers
=
Gitlab
::
Routing
.
url_helpers
if
options
[
:only_path
]
helpers
.
namespace_project_issue_path
(
namespace_id:
project
.
namespace
,
project_id:
project
,
id:
issue_iid
)
else
helpers
.
namespace_project_issue_url
(
namespace_id:
project
.
namespace
,
project_id:
project
,
id:
issue_iid
)
end
end
def
bulk_update_milestone_options
def
bulk_update_milestone_options
milestones
=
@project
.
milestones
.
active
.
reorder
(
due_date: :asc
,
title: :asc
).
to_a
milestones
=
@project
.
milestones
.
active
.
reorder
(
due_date: :asc
,
title: :asc
).
to_a
milestones
.
unshift
(
Milestone
::
None
)
milestones
.
unshift
(
Milestone
::
None
)
...
@@ -158,4 +176,6 @@ module IssuesHelper
...
@@ -158,4 +176,6 @@ module IssuesHelper
# Required for Banzai::Filter::IssueReferenceFilter
# Required for Banzai::Filter::IssueReferenceFilter
module_function
:url_for_issue
module_function
:url_for_issue
module_function
:url_for_internal_issue
module_function
:url_for_tracker_issue
end
end
app/models/merge_request.rb
View file @
7bee7b84
...
@@ -596,7 +596,7 @@ class MergeRequest < ActiveRecord::Base
...
@@ -596,7 +596,7 @@ class MergeRequest < ActiveRecord::Base
# running `ReferenceExtractor` on each of them separately.
# running `ReferenceExtractor` on each of them separately.
# This optimization does not apply to issues from external sources.
# This optimization does not apply to issues from external sources.
def
cache_merge_request_closes_issues!
(
current_user
)
def
cache_merge_request_closes_issues!
(
current_user
)
return
if
project
.
has_external_issue_tracker
?
return
unless
project
.
issues_enabled
?
transaction
do
transaction
do
self
.
merge_requests_closing_issues
.
delete_all
self
.
merge_requests_closing_issues
.
delete_all
...
...
app/models/project.rb
View file @
7bee7b84
...
@@ -734,9 +734,11 @@ class Project < ActiveRecord::Base
...
@@ -734,9 +734,11 @@ class Project < ActiveRecord::Base
end
end
def
get_issue
(
issue_id
,
current_user
)
def
get_issue
(
issue_id
,
current_user
)
if
default_issues_tracker?
issue
=
IssuesFinder
.
new
(
current_user
,
project_id:
id
).
find_by
(
iid:
issue_id
)
if
issues_enabled?
IssuesFinder
.
new
(
current_user
,
project_id:
id
).
find_by
(
iid:
issue_id
)
else
if
issue
issue
elsif
external_issue_tracker
ExternalIssue
.
new
(
issue_id
,
self
)
ExternalIssue
.
new
(
issue_id
,
self
)
end
end
end
end
...
@@ -758,7 +760,7 @@ class Project < ActiveRecord::Base
...
@@ -758,7 +760,7 @@ class Project < ActiveRecord::Base
end
end
def
external_issue_reference_pattern
def
external_issue_reference_pattern
external_issue_tracker
.
class
.
reference_pattern
external_issue_tracker
.
class
.
reference_pattern
(
only_long:
issues_enabled?
)
end
end
def
default_issues_tracker?
def
default_issues_tracker?
...
...
app/models/project_services/issue_tracker_service.rb
View file @
7bee7b84
...
@@ -8,8 +8,12 @@ class IssueTrackerService < Service
...
@@ -8,8 +8,12 @@ class IssueTrackerService < Service
# This pattern does not support cross-project references
# This pattern does not support cross-project references
# The other code assumes that this pattern is a superset of all
# The other code assumes that this pattern is a superset of all
# overriden patterns. See ReferenceRegexes::EXTERNAL_PATTERN
# overriden patterns. See ReferenceRegexes::EXTERNAL_PATTERN
def
self
.
reference_pattern
def
self
.
reference_pattern
(
only_long:
false
)
@reference_pattern
||=
%r{(
\b
[A-Z][A-Z0-9_]+-|
#{
Issue
.
reference_prefix
}
)(?<issue>
\d
+)}
if
only_long
%r{(
\b
[A-Z][A-Z0-9_]+-)(?<issue>
\d
+)}
else
%r{(
\b
[A-Z][A-Z0-9_]+-|
#{
Issue
.
reference_prefix
}
)(?<issue>
\d
+)}
end
end
end
def
default?
def
default?
...
...
app/models/project_services/jira_service.rb
View file @
7bee7b84
...
@@ -18,7 +18,7 @@ class JiraService < IssueTrackerService
...
@@ -18,7 +18,7 @@ class JiraService < IssueTrackerService
end
end
# {PROJECT-KEY}-{NUMBER} Examples: JIRA-1, PROJECT-1
# {PROJECT-KEY}-{NUMBER} Examples: JIRA-1, PROJECT-1
def
self
.
reference_pattern
def
self
.
reference_pattern
(
only_long:
true
)
@reference_pattern
||=
%r{(?<issue>
\b
([A-Z][A-Z0-9_]+-)
\d
+)}
@reference_pattern
||=
%r{(?<issue>
\b
([A-Z][A-Z0-9_]+-)
\d
+)}
end
end
...
...
app/services/issues/close_service.rb
View file @
7bee7b84
...
@@ -16,13 +16,13 @@ module Issues
...
@@ -16,13 +16,13 @@ module Issues
# The code calling this method is responsible for ensuring that a user is
# The code calling this method is responsible for ensuring that a user is
# allowed to close the given issue.
# allowed to close the given issue.
def
close_issue
(
issue
,
commit:
nil
,
notifications:
true
,
system_note:
true
)
def
close_issue
(
issue
,
commit:
nil
,
notifications:
true
,
system_note:
true
)
if
project
.
jira_tracker?
&&
project
.
jira_service
.
active
if
project
.
jira_tracker?
&&
project
.
jira_service
.
active
&&
issue
.
is_a?
(
ExternalIssue
)
project
.
jira_service
.
close_issue
(
commit
,
issue
)
project
.
jira_service
.
close_issue
(
commit
,
issue
)
todo_service
.
close_issue
(
issue
,
current_user
)
todo_service
.
close_issue
(
issue
,
current_user
)
return
issue
return
issue
end
end
if
project
.
default_issues_tracker
?
&&
issue
.
close
if
project
.
issues_enabled
?
&&
issue
.
close
event_service
.
close_issue
(
issue
,
current_user
)
event_service
.
close_issue
(
issue
,
current_user
)
create_note
(
issue
,
commit
)
if
system_note
create_note
(
issue
,
commit
)
if
system_note
notification_service
.
close_issue
(
issue
,
current_user
)
if
notifications
notification_service
.
close_issue
(
issue
,
current_user
)
if
notifications
...
...
app/views/layouts/nav/_new_project_sidebar.html.haml
View file @
7bee7b84
...
@@ -75,10 +75,10 @@
...
@@ -75,10 +75,10 @@
Registry
Registry
-
if
project_nav_tab?
:issues
-
if
project_nav_tab?
:issues
=
nav_link
(
controller:
@project
.
default_issues_tracker
?
?
[
:issues
,
:labels
,
:milestones
,
:boards
]
:
:issues
)
do
=
nav_link
(
controller:
@project
.
issues_enabled
?
?
[
:issues
,
:labels
,
:milestones
,
:boards
]
:
:issues
)
do
=
link_to
project_issues_path
(
@project
),
title:
'Issues'
,
class:
'shortcuts-issues'
do
=
link_to
project_issues_path
(
@project
),
title:
'Issues'
,
class:
'shortcuts-issues'
do
%span
%span
-
if
@project
.
default_issues_tracker
?
-
if
@project
.
issues_enabled
?
%span
.badge.count.issue_counter
=
number_with_delimiter
(
IssuesFinder
.
new
(
current_user
,
project_id:
@project
.
id
).
execute
.
opened
.
count
)
%span
.badge.count.issue_counter
=
number_with_delimiter
(
IssuesFinder
.
new
(
current_user
,
project_id:
@project
.
id
).
execute
.
opened
.
count
)
Issues
Issues
...
@@ -113,7 +113,7 @@
...
@@ -113,7 +113,7 @@
Milestones
Milestones
-
if
project_nav_tab?
:merge_requests
-
if
project_nav_tab?
:merge_requests
=
nav_link
(
controller:
@project
.
default_issues_tracker
?
?
:merge_requests
:
[
:merge_requests
,
:labels
,
:milestones
])
do
=
nav_link
(
controller:
@project
.
issues_enabled
?
?
:merge_requests
:
[
:merge_requests
,
:labels
,
:milestones
])
do
=
link_to
project_merge_requests_path
(
@project
),
title:
'Merge Requests'
,
class:
'shortcuts-merge_requests'
do
=
link_to
project_merge_requests_path
(
@project
),
title:
'Merge Requests'
,
class:
'shortcuts-merge_requests'
do
%span
%span
%span
.badge.count.merge_counter.js-merge-counter
=
number_with_delimiter
(
MergeRequestsFinder
.
new
(
current_user
,
project_id:
@project
.
id
).
execute
.
opened
.
count
)
%span
.badge.count.merge_counter.js-merge-counter
=
number_with_delimiter
(
MergeRequestsFinder
.
new
(
current_user
,
project_id:
@project
.
id
).
execute
.
opened
.
count
)
...
...
app/views/layouts/nav/_project.html.haml
View file @
7bee7b84
...
@@ -23,16 +23,16 @@
...
@@ -23,16 +23,16 @@
Registry
Registry
-
if
project_nav_tab?
:issues
-
if
project_nav_tab?
:issues
=
nav_link
(
controller:
@project
.
default_issues_tracker
?
?
[
:issues
,
:labels
,
:milestones
,
:boards
]
:
:issues
)
do
=
nav_link
(
controller:
@project
.
issues_enabled
?
?
[
:issues
,
:labels
,
:milestones
,
:boards
]
:
:issues
)
do
=
link_to
project_issues_path
(
@project
),
title:
'Issues'
,
class:
'shortcuts-issues'
do
=
link_to
project_issues_path
(
@project
),
title:
'Issues'
,
class:
'shortcuts-issues'
do
%span
%span
Issues
Issues
-
if
@project
.
default_issues_tracker
?
-
if
@project
.
issues_enabled
?
%span
.badge.count.issue_counter
=
number_with_delimiter
(
issuables_count_for_state
(
:issues
,
:opened
,
finder:
IssuesFinder
.
new
(
current_user
,
project_id:
@project
.
id
)))
%span
.badge.count.issue_counter
=
number_with_delimiter
(
issuables_count_for_state
(
:issues
,
:opened
,
finder:
IssuesFinder
.
new
(
current_user
,
project_id:
@project
.
id
)))
-
if
project_nav_tab?
:merge_requests
-
if
project_nav_tab?
:merge_requests
-
controllers
=
[
:merge_requests
,
'projects/merge_requests/conflicts'
]
-
controllers
=
[
:merge_requests
,
'projects/merge_requests/conflicts'
]
-
controllers
.
push
(
:merge_requests
,
:labels
,
:milestones
)
unless
@project
.
default_issues_tracker
?
-
controllers
.
push
(
:merge_requests
,
:labels
,
:milestones
)
unless
@project
.
issues_enabled
?
=
nav_link
(
controller:
controllers
)
do
=
nav_link
(
controller:
controllers
)
do
=
link_to
project_merge_requests_path
(
@project
),
title:
'Merge Requests'
,
class:
'shortcuts-merge_requests'
do
=
link_to
project_merge_requests_path
(
@project
),
title:
'Merge Requests'
,
class:
'shortcuts-merge_requests'
do
%span
%span
...
...
app/views/projects/merge_requests/index.html.haml
View file @
7bee7b84
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
-
new_merge_request_path
=
project_new_merge_request_path
(
merge_project
)
if
merge_project
-
new_merge_request_path
=
project_new_merge_request_path
(
merge_project
)
if
merge_project
-
page_title
"Merge Requests"
-
page_title
"Merge Requests"
-
unless
@project
.
default_issues_tracker
?
-
unless
@project
.
issues_enabled
?
=
content_for
:sub_nav
do
=
content_for
:sub_nav
do
=
render
"projects/merge_requests/head"
=
render
"projects/merge_requests/head"
...
...
app/views/shared/_mr_head.html.haml
View file @
7bee7b84
-
if
@project
.
default_issues_tracker
?
-
if
@project
.
issues_enabled
?
=
render
"projects/issues/head"
=
render
"projects/issues/head"
-
else
-
else
=
render
"projects/merge_requests/head"
=
render
"projects/merge_requests/head"
lib/api/entities.rb
View file @
7bee7b84
...
@@ -109,7 +109,7 @@ module API
...
@@ -109,7 +109,7 @@ module API
user
.
avatar_url
(
only_path:
false
)
user
.
avatar_url
(
only_path:
false
)
end
end
expose
:star_count
,
:forks_count
expose
:star_count
,
:forks_count
expose
:open_issues_count
,
if:
lambda
{
|
project
,
options
|
project
.
feature_available?
(
:issues
,
options
[
:current_user
])
&&
project
.
default_issues_tracker?
}
expose
:open_issues_count
,
if:
lambda
{
|
project
,
options
|
project
.
feature_available?
(
:issues
,
options
[
:current_user
])
}
expose
:runners_token
,
if:
lambda
{
|
_project
,
options
|
options
[
:user_can_admin_project
]
}
expose
:runners_token
,
if:
lambda
{
|
_project
,
options
|
options
[
:user_can_admin_project
]
}
expose
:public_builds
,
as: :public_jobs
expose
:public_builds
,
as: :public_jobs
expose
:ci_config_path
expose
:ci_config_path
...
...
lib/api/merge_requests.rb
View file @
7bee7b84
...
@@ -29,14 +29,6 @@ module API
...
@@ -29,14 +29,6 @@ module API
render_api_error!
(
errors
,
400
)
render_api_error!
(
errors
,
400
)
end
end
def
issue_entity
(
project
)
if
project
.
has_external_issue_tracker?
Entities
::
ExternalIssue
else
Entities
::
IssueBasic
end
end
def
find_merge_requests
(
args
=
{})
def
find_merge_requests
(
args
=
{})
args
=
params
.
merge
(
args
)
args
=
params
.
merge
(
args
)
...
@@ -278,7 +270,14 @@ module API
...
@@ -278,7 +270,14 @@ module API
get
':id/merge_requests/:merge_request_iid/closes_issues'
do
get
':id/merge_requests/:merge_request_iid/closes_issues'
do
merge_request
=
find_merge_request_with_access
(
params
[
:merge_request_iid
])
merge_request
=
find_merge_request_with_access
(
params
[
:merge_request_iid
])
issues
=
::
Kaminari
.
paginate_array
(
merge_request
.
closes_issues
(
current_user
))
issues
=
::
Kaminari
.
paginate_array
(
merge_request
.
closes_issues
(
current_user
))
present
paginate
(
issues
),
with:
issue_entity
(
user_project
),
current_user:
current_user
issues
=
paginate
(
issues
)
external_issues
,
internal_issues
=
issues
.
partition
{
|
issue
|
issue
.
is_a?
(
ExternalIssue
)
}
data
=
Entities
::
IssueBasic
.
represent
(
internal_issues
,
current_user:
current_user
)
data
+=
Entities
::
ExternalIssue
.
represent
(
external_issues
,
current_user:
current_user
)
data
.
as_json
end
end
end
end
end
end
...
...
lib/banzai/filter/issue_reference_filter.rb
View file @
7bee7b84
...
@@ -20,7 +20,7 @@ module Banzai
...
@@ -20,7 +20,7 @@ module Banzai
end
end
def
url_for_object
(
issue
,
project
)
def
url_for_object
(
issue
,
project
)
IssuesHelper
.
url_for_issue
(
issue
.
iid
,
project
,
only_path:
context
[
:only_path
])
IssuesHelper
.
url_for_issue
(
issue
.
iid
,
project
,
only_path:
context
[
:only_path
]
,
internal:
true
)
end
end
def
project_from_ref
(
ref
)
def
project_from_ref
(
ref
)
...
...
lib/banzai/reference_parser/external_issue_parser.rb
View file @
7bee7b84
...
@@ -21,10 +21,14 @@ module Banzai
...
@@ -21,10 +21,14 @@ module Banzai
gather_attributes_per_project
(
nodes
,
self
.
class
.
data_attribute
)
gather_attributes_per_project
(
nodes
,
self
.
class
.
data_attribute
)
end
end
private
# we extract only external issue trackers references here, we don't extract cross-project references,
# so we don't need to do anything here.
def
can_read_reference?
(
user
,
ref_project
,
node
)
def
can_read_reference?
(
user
,
ref_project
,
node
)
can?
(
user
,
:read_issue
,
ref_project
)
true
end
def
nodes_visible_to_user
(
user
,
nodes
)
nodes
end
end
end
end
end
end
...
...
lib/gitlab/reference_extractor.rb
View file @
7bee7b84
...
@@ -33,7 +33,12 @@ module Gitlab
...
@@ -33,7 +33,12 @@ module Gitlab
def
issues
def
issues
if
project
&&
project
.
jira_tracker?
if
project
&&
project
.
jira_tracker?
@references
[
:external_issue
]
||=
references
(
:external_issue
)
if
project
.
issues_enabled?
@references
[
:all_issues
]
||=
references
(
:external_issue
)
+
references
(
:issue
)
else
@references
[
:external_issue
]
||=
references
(
:external_issue
)
+
references
(
:issue
).
select
{
|
i
|
i
.
project_id
!=
project
.
id
}
end
else
else
@references
[
:issue
]
||=
references
(
:issue
)
@references
[
:issue
]
||=
references
(
:issue
)
end
end
...
...
lib/gitlab/slash_commands/issue_command.rb
View file @
7bee7b84
...
@@ -2,7 +2,7 @@ module Gitlab
...
@@ -2,7 +2,7 @@ module Gitlab
module
SlashCommands
module
SlashCommands
class
IssueCommand
<
BaseCommand
class
IssueCommand
<
BaseCommand
def
self
.
available?
(
project
)
def
self
.
available?
(
project
)
project
.
issues_enabled?
&&
project
.
default_issues_tracker?
project
.
issues_enabled?
end
end
def
collection
def
collection
...
...
spec/features/issuables/markdown_references_spec.rb
0 → 100644
View file @
7bee7b84
require
'rails_helper'
describe
'Markdown References'
,
:feature
,
:js
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:actual_project
)
{
create
(
:project
,
:public
)
}
let
(
:merge_request
)
{
create
(
:merge_request
,
target_project:
actual_project
,
source_project:
actual_project
)}
let
(
:issue_actual_project
)
{
create
(
:issue
,
project:
actual_project
)
}
let!
(
:other_project
)
{
create
(
:empty_project
,
:public
)
}
let!
(
:issue_other_project
)
{
create
(
:issue
,
project:
other_project
)
}
let
(
:issues
)
{
[
issue_actual_project
,
issue_other_project
]
}
def
build_note
markdown
=
"Referencing internal issue
#{
issue_actual_project
.
to_reference
}
, "
+
"cross-project
#{
issue_other_project
.
to_reference
(
actual_project
)
}
external JIRA-5 "
+
"and non existing #999"
page
.
within
(
'#diff-notes-app'
)
do
fill_in
'note_note'
,
with:
markdown
end
end
shared_examples
'correct references'
do
before
do
remotelink
=
double
(
:remotelink
,
all:
[],
build:
double
(
save!:
true
))
stub_request
(
:get
,
"https://jira.example.com/rest/api/2/issue/JIRA-5"
)
stub_request
(
:post
,
"https://jira.example.com/rest/api/2/issue/JIRA-5/comment"
)
allow_any_instance_of
(
JIRA
::
Resource
::
Issue
).
to
receive
(
:remotelink
).
and_return
(
remotelink
)
sign_in
(
user
)
visit
merge_request_path
(
merge_request
)
build_note
end
def
links_expectations
issues
.
each
do
|
issue
|
if
referenced_issues
.
include?
(
issue
)
expect
(
page
).
to
have_link
(
issue
.
to_reference
,
href:
issue_path
(
issue
))
else
expect
(
page
).
not_to
have_link
(
issue
.
to_reference
,
href:
issue_path
(
issue
))
end
end
if
jira_referenced
expect
(
page
).
to
have_link
(
'JIRA-5'
,
href:
'https://jira.example.com/browse/JIRA-5'
)
else
expect
(
page
).
not_to
have_link
(
'JIRA-5'
,
href:
'https://jira.example.com/browse/JIRA-5'
)
end
expect
(
page
).
not_to
have_link
(
'#999'
)
end
it
'creates a link to the referenced issue on the preview'
do
find
(
'.js-md-preview-button'
).
click
wait_for_requests
page
.
within
(
'.md-preview-holder'
)
do
links_expectations
end
end
it
'creates a link to the referenced issue after submit'
do
click_button
'Comment'
wait_for_requests
page
.
within
(
'#diff-notes-app'
)
do
links_expectations
end
end
it
'creates a note on the referenced issues'
do
click_button
'Comment'
wait_for_requests
if
referenced_issues
.
include?
(
issue_actual_project
)
visit
issue_path
(
issue_actual_project
)
page
.
within
(
'#notes'
)
do
expect
(
page
).
to
have_content
(
"
#{
user
.
to_reference
}
mentioned in merge request
#{
merge_request
.
to_reference
}
"
)
end
end
if
referenced_issues
.
include?
(
issue_other_project
)
visit
issue_path
(
issue_other_project
)
page
.
within
(
'#notes'
)
do
expect
(
page
).
to
have_content
(
"
#{
user
.
to_reference
}
mentioned in merge request
#{
merge_request
.
to_reference
(
other_project
)
}
"
)
end
end
end
end
context
'when internal issues tracker is enabled for the other project'
do
context
'when only internal issues tracker is enabled for the actual project'
do
include_examples
'correct references'
do
let
(
:referenced_issues
)
{
[
issue_actual_project
,
issue_other_project
]
}
let
(
:jira_referenced
)
{
false
}
end
end
context
'when both external and internal issues trackers are enabled for the actual project'
do
before
do
create
(
:jira_service
,
project:
actual_project
)
end
include_examples
'correct references'
do
let
(
:referenced_issues
)
{
[
issue_actual_project
,
issue_other_project
]
}
let
(
:jira_referenced
)
{
true
}
end
end
context
'when only external issues tracker is enabled for the actual project'
do
before
do
create
(
:jira_service
,
project:
actual_project
)
actual_project
.
issues_enabled
=
false
actual_project
.
save!
end
include_examples
'correct references'
do
let
(
:referenced_issues
)
{
[
issue_other_project
]
}
let
(
:jira_referenced
)
{
true
}
end
end
context
'when no tracker is enabled for the actual project'
do
before
do
actual_project
.
issues_enabled
=
false
actual_project
.
save!
end
include_examples
'correct references'
do
let
(
:referenced_issues
)
{
[
issue_other_project
]
}
let
(
:jira_referenced
)
{
false
}
end
end
end
context
'when internal issues tracker is disabled for the other project'
do
before
do
other_project
.
issues_enabled
=
false
other_project
.
save!
end
context
'when only internal issues tracker is enabled for the actual project'
do
include_examples
'correct references'
do
let
(
:referenced_issues
)
{
[
issue_actual_project
]
}
let
(
:jira_referenced
)
{
false
}
end
end
context
'when both external and internal issues trackers are enabled for the actual project'
do
before
do
create
(
:jira_service
,
project:
actual_project
)
end
include_examples
'correct references'
do
let
(
:referenced_issues
)
{
[
issue_actual_project
]
}
let
(
:jira_referenced
)
{
true
}
end
end
context
'when only external issues tracker is enabled for the actual project'
do
before
do
create
(
:jira_service
,
project:
actual_project
)
actual_project
.
issues_enabled
=
false
actual_project
.
save!
end
include_examples
'correct references'
do
let
(
:referenced_issues
)
{
[]
}
let
(
:jira_referenced
)
{
true
}
end
end
context
'when no issues tracker is enabled for the actual project'
do
before
do
actual_project
.
issues_enabled
=
false
actual_project
.
save!
end
include_examples
'correct references'
do
let
(
:referenced_issues
)
{
[]
}
let
(
:jira_referenced
)
{
false
}
end
end
end
end
spec/features/projects/features_visibility_spec.rb
View file @
7bee7b84
...
@@ -55,7 +55,7 @@ describe 'Edit Project Settings', feature: true do
...
@@ -55,7 +55,7 @@ describe 'Edit Project Settings', feature: true do
project
.
save!
project
.
save!
allow_any_instance_of
(
Project
).
to
receive
(
:external_issue_tracker
).
and_return
(
JiraService
.
new
)
allow_any_instance_of
(
Project
).
to
receive
(
:external_issue_tracker
).
and_return
(
JiraService
.
new
)
visit
namespace_project_path
(
project
.
namespace
,
project
)
visit
project_path
(
project
)
expect
(
page
).
not_to
have_selector
(
'.shortcuts-issues'
)
expect
(
page
).
not_to
have_selector
(
'.shortcuts-issues'
)
end
end
...
...
spec/helpers/issues_helper_spec.rb
View file @
7bee7b84
...
@@ -8,7 +8,7 @@ describe IssuesHelper do
...
@@ -8,7 +8,7 @@ describe IssuesHelper do
describe
"url_for_issue"
do
describe
"url_for_issue"
do
let
(
:issues_url
)
{
ext_project
.
external_issue_tracker
.
issues_url
}
let
(
:issues_url
)
{
ext_project
.
external_issue_tracker
.
issues_url
}
let
(
:ext_expected
)
{
issues_url
.
gsub
(
':id'
,
issue
.
iid
.
to_s
).
gsub
(
':project_id'
,
ext_project
.
id
.
to_s
)
}
let
(
:ext_expected
)
{
issues_url
.
gsub
(
':id'
,
issue
.
iid
.
to_s
).
gsub
(
':project_id'
,
ext_project
.
id
.
to_s
)
}
let
(
:int_expected
)
{
polymorphic_path
([
@project
.
namespace
,
project
,
issue
])
}
let
(
:int_expected
)
{
polymorphic_path
([
@project
.
namespace
,
@
project
,
issue
])
}
it
"returns internal path if used internal tracker"
do
it
"returns internal path if used internal tracker"
do
@project
=
project
@project
=
project
...
@@ -22,6 +22,12 @@ describe IssuesHelper do
...
@@ -22,6 +22,12 @@ describe IssuesHelper do
expect
(
url_for_issue
(
issue
.
iid
)).
to
match
(
ext_expected
)
expect
(
url_for_issue
(
issue
.
iid
)).
to
match
(
ext_expected
)
end
end
it
"returns path to internal issue when internal option passed"
do
@project
=
ext_project
expect
(
url_for_issue
(
issue
.
iid
,
ext_project
,
internal:
true
)).
to
match
(
int_expected
)
end
it
"returns empty string if project nil"
do
it
"returns empty string if project nil"
do
@project
=
nil
@project
=
nil
...
...
spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
View file @
7bee7b84
...
@@ -108,6 +108,11 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do
...
@@ -108,6 +108,11 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do
let
(
:issue
)
{
ExternalIssue
.
new
(
"#123"
,
project
)
}
let
(
:issue
)
{
ExternalIssue
.
new
(
"#123"
,
project
)
}
let
(
:reference
)
{
issue
.
to_reference
}
let
(
:reference
)
{
issue
.
to_reference
}
before
do
project
.
issues_enabled
=
false
project
.
save!
end
it_behaves_like
"external issue tracker"
it_behaves_like
"external issue tracker"
end
end
...
...
spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
View file @
7bee7b84
...
@@ -4,26 +4,87 @@ describe Banzai::Pipeline::GfmPipeline do
...
@@ -4,26 +4,87 @@ describe Banzai::Pipeline::GfmPipeline do
describe
'integration between parsing regular and external issue references'
do
describe
'integration between parsing regular and external issue references'
do
let
(
:project
)
{
create
(
:redmine_project
,
:public
)
}
let
(
:project
)
{
create
(
:redmine_project
,
:public
)
}
it
'allows to use shorthand external reference syntax for Redmine'
do
context
'when internal issue tracker is enabled'
do
markdown
=
'#12'
context
'when shorthand pattern #ISSUE_ID is used'
do
it
'links an internal issue if it exists'
do
issue
=
create
(
:issue
,
project:
project
)
markdown
=
issue
.
to_reference
(
project
,
full:
true
)
result
=
described_class
.
call
(
markdown
,
project:
project
)[
:output
]
result
=
described_class
.
call
(
markdown
,
project:
project
)[
:output
]
link
=
result
.
css
(
'a'
).
first
link
=
result
.
css
(
'a'
).
first
expect
(
link
[
'href'
]).
to
eq
'http://redmine/projects/project_name_in_redmine/issues/12'
expect
(
link
[
'href'
]).
to
eq
(
Gitlab
::
Routing
.
url_helpers
.
project_issue_path
(
project
,
issue
)
)
end
it
'does not link any issue if it does not exist on GitLab'
do
markdown
=
'#12'
result
=
described_class
.
call
(
markdown
,
project:
project
)[
:output
]
expect
(
result
.
css
(
'a'
)).
to
be_empty
end
end
it
'allows to use long external reference syntax for Redmine'
do
markdown
=
'API_32-12'
result
=
described_class
.
call
(
markdown
,
project:
project
)[
:output
]
link
=
result
.
css
(
'a'
).
first
expect
(
link
[
'href'
]).
to
eq
'http://redmine/projects/project_name_in_redmine/issues/12'
end
it
'parses cross-project references to regular issues'
do
other_project
=
create
(
:empty_project
,
:public
)
issue
=
create
(
:issue
,
project:
other_project
)
markdown
=
issue
.
to_reference
(
project
,
full:
true
)
result
=
described_class
.
call
(
markdown
,
project:
project
)[
:output
]
link
=
result
.
css
(
'a'
).
first
expect
(
link
[
'href'
]).
to
eq
(
Gitlab
::
Routing
.
url_helpers
.
project_issue_path
(
other_project
,
issue
)
)
end
end
end
it
'parses cross-project references to regular issues'
do
context
'when internal issue tracker is disabled'
do
other_project
=
create
(
:empty_project
,
:public
)
before
do
issue
=
create
(
:issue
,
project:
other_project
)
project
.
issues_enabled
=
false
markdown
=
issue
.
to_reference
(
project
,
full:
true
)
project
.
save!
end
it
'allows to use shorthand external reference syntax for Redmine'
do
markdown
=
'#12'
result
=
described_class
.
call
(
markdown
,
project:
project
)[
:output
]
link
=
result
.
css
(
'a'
).
first
expect
(
link
[
'href'
]).
to
eq
'http://redmine/projects/project_name_in_redmine/issues/12'
end
it
'allows to use long external reference syntax for Redmine'
do
markdown
=
'API_32-12'
result
=
described_class
.
call
(
markdown
,
project:
project
)[
:output
]
link
=
result
.
css
(
'a'
).
first
expect
(
link
[
'href'
]).
to
eq
'http://redmine/projects/project_name_in_redmine/issues/12'
end
it
'parses cross-project references to regular issues'
do
other_project
=
create
(
:empty_project
,
:public
)
issue
=
create
(
:issue
,
project:
other_project
)
markdown
=
issue
.
to_reference
(
project
,
full:
true
)
result
=
described_class
.
call
(
markdown
,
project:
project
)[
:output
]
result
=
described_class
.
call
(
markdown
,
project:
project
)[
:output
]
link
=
result
.
css
(
'a'
).
first
link
=
result
.
css
(
'a'
).
first
expect
(
link
[
'href'
]).
to
eq
(
expect
(
link
[
'href'
]).
to
eq
(
Gitlab
::
Routing
.
url_helpers
.
project_issue_path
(
other_project
,
issue
)
Gitlab
::
Routing
.
url_helpers
.
project_issue_path
(
other_project
,
issue
)
)
)
end
end
end
end
end
end
end
spec/lib/gitlab/reference_extractor_spec.rb
View file @
7bee7b84
...
@@ -183,11 +183,34 @@ describe Gitlab::ReferenceExtractor, lib: true do
...
@@ -183,11 +183,34 @@ describe Gitlab::ReferenceExtractor, lib: true do
context
'with an external issue tracker'
do
context
'with an external issue tracker'
do
let
(
:project
)
{
create
(
:jira_project
)
}
let
(
:project
)
{
create
(
:jira_project
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
context
'when GitLab issues are enabled'
do
it
'returns both JIRA and internal issues'
do
subject
.
analyze
(
"JIRA-123 and FOOBAR-4567 and
#{
issue
.
to_reference
}
"
)
expect
(
subject
.
issues
).
to
eq
[
ExternalIssue
.
new
(
'JIRA-123'
,
project
),
ExternalIssue
.
new
(
'FOOBAR-4567'
,
project
),
issue
]
end
it
'returns only JIRA issues if the internal one does not exists'
do
subject
.
analyze
(
"JIRA-123 and FOOBAR-4567 and #999"
)
expect
(
subject
.
issues
).
to
eq
[
ExternalIssue
.
new
(
'JIRA-123'
,
project
),
ExternalIssue
.
new
(
'FOOBAR-4567'
,
project
)]
end
end
it
'returns JIRA issues for a JIRA-integrated project'
do
context
'when GitLab issues are disabled'
do
subject
.
analyze
(
'JIRA-123 and FOOBAR-4567'
)
before
do
expect
(
subject
.
issues
).
to
eq
[
ExternalIssue
.
new
(
'JIRA-123'
,
project
),
project
.
issues_enabled
=
false
ExternalIssue
.
new
(
'FOOBAR-4567'
,
project
)]
project
.
save!
end
it
'returns only JIRA issues'
do
subject
.
analyze
(
"JIRA-123 and FOOBAR-4567 and
#{
issue
.
to_reference
}
"
)
expect
(
subject
.
issues
).
to
eq
[
ExternalIssue
.
new
(
'JIRA-123'
,
project
),
ExternalIssue
.
new
(
'FOOBAR-4567'
,
project
)]
end
end
end
end
end
...
...
spec/models/concerns/mentionable_spec.rb
View file @
7bee7b84
...
@@ -174,25 +174,25 @@ describe Commit, 'Mentionable' do
...
@@ -174,25 +174,25 @@ describe Commit, 'Mentionable' do
it
"is false when message doesn't reference anything"
do
it
"is false when message doesn't reference anything"
do
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
"WIP: Do something"
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
"WIP: Do something"
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
false
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
_falsey
end
end
it
'is true if issue #number mentioned in title'
do
it
'is true if issue #number mentioned in title'
do
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
"#1"
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
"#1"
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
true
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
_truthy
end
end
it
'is true if references an MR'
do
it
'is true if references an MR'
do
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
"See merge request !12"
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
"See merge request !12"
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
true
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
_truthy
end
end
it
'is true if references a commit'
do
it
'is true if references a commit'
do
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
"a1b2c3d4"
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
"a1b2c3d4"
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
true
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
_truthy
end
end
it
'is true if issue referenced by url'
do
it
'is true if issue referenced by url'
do
...
@@ -200,7 +200,7 @@ describe Commit, 'Mentionable' do
...
@@ -200,7 +200,7 @@ describe Commit, 'Mentionable' do
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
Gitlab
::
UrlBuilder
.
build
(
issue
)
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
Gitlab
::
UrlBuilder
.
build
(
issue
)
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
true
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
_truthy
end
end
context
'with external issue tracker'
do
context
'with external issue tracker'
do
...
@@ -209,7 +209,13 @@ describe Commit, 'Mentionable' do
...
@@ -209,7 +209,13 @@ describe Commit, 'Mentionable' do
it
'is true if external issues referenced'
do
it
'is true if external issues referenced'
do
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
'JIRA-123'
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
'JIRA-123'
expect
(
commit
.
matches_cross_reference_regex?
).
to
be
true
expect
(
commit
.
matches_cross_reference_regex?
).
to
be_truthy
end
it
'is true if internal issues referenced'
do
allow
(
commit
.
raw
).
to
receive
(
:message
).
and_return
'#123'
expect
(
commit
.
matches_cross_reference_regex?
).
to
be_truthy
end
end
end
end
end
end
...
...
spec/models/merge_request_spec.rb
View file @
7bee7b84
...
@@ -155,13 +155,53 @@ describe MergeRequest, models: true do
...
@@ -155,13 +155,53 @@ describe MergeRequest, models: true do
expect
{
subject
.
cache_merge_request_closes_issues!
(
subject
.
author
)
}.
to
change
(
subject
.
merge_requests_closing_issues
,
:count
).
by
(
1
)
expect
{
subject
.
cache_merge_request_closes_issues!
(
subject
.
author
)
}.
to
change
(
subject
.
merge_requests_closing_issues
,
:count
).
by
(
1
)
end
end
it
'does not cache issues from external trackers'
do
context
'when both internal and external issue trackers are enabled'
do
subject
.
project
.
update_attribute
(
:has_external_issue_tracker
,
true
)
before
do
issue
=
ExternalIssue
.
new
(
'JIRA-123'
,
subject
.
project
)
subject
.
project
.
has_external_issue_tracker
=
true
commit
=
double
(
'commit1'
,
safe_message:
"Fixes
#{
issue
.
to_reference
}
"
)
subject
.
project
.
save!
allow
(
subject
).
to
receive
(
:commits
).
and_return
([
commit
])
end
it
'does not cache issues from external trackers'
do
issue
=
ExternalIssue
.
new
(
'JIRA-123'
,
subject
.
project
)
commit
=
double
(
'commit1'
,
safe_message:
"Fixes
#{
issue
.
to_reference
}
"
)
allow
(
subject
).
to
receive
(
:commits
).
and_return
([
commit
])
expect
{
subject
.
cache_merge_request_closes_issues!
(
subject
.
author
)
}.
not_to
change
(
subject
.
merge_requests_closing_issues
,
:count
)
expect
{
subject
.
cache_merge_request_closes_issues!
(
subject
.
author
)
}.
not_to
change
(
subject
.
merge_requests_closing_issues
,
:count
)
end
it
'caches an internal issue'
do
issue
=
create
(
:issue
,
project:
subject
.
project
)
commit
=
double
(
'commit1'
,
safe_message:
"Fixes
#{
issue
.
to_reference
}
"
)
allow
(
subject
).
to
receive
(
:commits
).
and_return
([
commit
])
expect
{
subject
.
cache_merge_request_closes_issues!
(
subject
.
author
)
}
.
to
change
(
subject
.
merge_requests_closing_issues
,
:count
).
by
(
1
)
end
end
context
'when only external issue tracker enabled'
do
before
do
subject
.
project
.
has_external_issue_tracker
=
true
subject
.
project
.
issues_enabled
=
false
subject
.
project
.
save!
end
it
'does not cache issues from external trackers'
do
issue
=
ExternalIssue
.
new
(
'JIRA-123'
,
subject
.
project
)
commit
=
double
(
'commit1'
,
safe_message:
"Fixes
#{
issue
.
to_reference
}
"
)
allow
(
subject
).
to
receive
(
:commits
).
and_return
([
commit
])
expect
{
subject
.
cache_merge_request_closes_issues!
(
subject
.
author
)
}.
not_to
change
(
subject
.
merge_requests_closing_issues
,
:count
)
end
it
'does not cache an internal issue'
do
issue
=
create
(
:issue
,
project:
subject
.
project
)
commit
=
double
(
'commit1'
,
safe_message:
"Fixes
#{
issue
.
to_reference
}
"
)
allow
(
subject
).
to
receive
(
:commits
).
and_return
([
commit
])
expect
{
subject
.
cache_merge_request_closes_issues!
(
subject
.
author
)
}
.
not_to
change
(
subject
.
merge_requests_closing_issues
,
:count
)
end
end
end
end
end
...
...
spec/models/project_spec.rb
View file @
7bee7b84
...
@@ -533,15 +533,48 @@ describe Project, models: true do
...
@@ -533,15 +533,48 @@ describe Project, models: true do
end
end
context
'with external issues tracker'
do
context
'with external issues tracker'
do
let!
(
:internal_issue
)
{
create
(
:issue
,
project:
project
)
}
before
do
before
do
allow
(
project
).
to
receive
(
:
default_issues_tracker?
).
and_return
(
fals
e
)
allow
(
project
).
to
receive
(
:
external_issue_tracker
).
and_return
(
tru
e
)
end
end
it
'returns an ExternalIssue'
do
context
'when internal issues are enabled'
do
issue
=
project
.
get_issue
(
'FOO-1234'
,
user
)
it
'returns interlan issue'
do
expect
(
issue
).
to
be_kind_of
(
ExternalIssue
)
issue
=
project
.
get_issue
(
internal_issue
.
iid
,
user
)
expect
(
issue
.
iid
).
to
eq
'FOO-1234'
expect
(
issue
.
project
).
to
eq
project
expect
(
issue
).
to
be_kind_of
(
Issue
)
expect
(
issue
.
iid
).
to
eq
(
internal_issue
.
iid
)
expect
(
issue
.
project
).
to
eq
(
project
)
end
it
'returns an ExternalIssue when internal issue does not exists'
do
issue
=
project
.
get_issue
(
'FOO-1234'
,
user
)
expect
(
issue
).
to
be_kind_of
(
ExternalIssue
)
expect
(
issue
.
iid
).
to
eq
(
'FOO-1234'
)
expect
(
issue
.
project
).
to
eq
(
project
)
end
end
context
'when internal issues are disabled'
do
before
do
project
.
issues_enabled
=
false
project
.
save!
end
it
'returns always an External issues'
do
issue
=
project
.
get_issue
(
internal_issue
.
iid
,
user
)
expect
(
issue
).
to
be_kind_of
(
ExternalIssue
)
expect
(
issue
.
iid
).
to
eq
(
internal_issue
.
iid
.
to_s
)
expect
(
issue
.
project
).
to
eq
(
project
)
end
it
'returns an ExternalIssue when internal issue does not exists'
do
issue
=
project
.
get_issue
(
'FOO-1234'
,
user
)
expect
(
issue
).
to
be_kind_of
(
ExternalIssue
)
expect
(
issue
.
iid
).
to
eq
(
'FOO-1234'
)
expect
(
issue
.
project
).
to
eq
(
project
)
end
end
end
end
end
end
end
...
...
spec/requests/api/merge_requests_spec.rb
View file @
7bee7b84
...
@@ -794,18 +794,24 @@ describe API::MergeRequests do
...
@@ -794,18 +794,24 @@ describe API::MergeRequests do
it
'handles external issues'
do
it
'handles external issues'
do
jira_project
=
create
(
:jira_project
,
:public
,
name:
'JIR_EXT1'
)
jira_project
=
create
(
:jira_project
,
:public
,
name:
'JIR_EXT1'
)
issue
=
ExternalIssue
.
new
(
"
#{
jira_project
.
name
}
-123"
,
jira_project
)
ext_issue
=
ExternalIssue
.
new
(
"
#{
jira_project
.
name
}
-123"
,
jira_project
)
merge_request
=
create
(
:merge_request
,
:simple
,
author:
user
,
assignee:
user
,
source_project:
jira_project
)
issue
=
create
(
:issue
,
project:
jira_project
)
merge_request
.
update_attribute
(
:description
,
"Closes
#{
issue
.
to_reference
(
jira_project
)
}
"
)
description
=
"Closes
#{
ext_issue
.
to_reference
(
jira_project
)
}
\n
closes
#{
issue
.
to_reference
}
"
merge_request
=
create
(
:merge_request
,
:simple
,
author:
user
,
assignee:
user
,
source_project:
jira_project
,
description:
description
)
get
api
(
"/projects/
#{
jira_project
.
id
}
/merge_requests/
#{
merge_request
.
iid
}
/closes_issues"
,
user
)
get
api
(
"/projects/
#{
jira_project
.
id
}
/merge_requests/
#{
merge_request
.
iid
}
/closes_issues"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
response
).
to
include_pagination_headers
expect
(
response
).
to
include_pagination_headers
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
length
).
to
eq
(
1
)
expect
(
json_response
.
length
).
to
eq
(
2
)
expect
(
json_response
.
second
[
'title'
]).
to
eq
(
ext_issue
.
title
)
expect
(
json_response
.
second
[
'id'
]).
to
eq
(
ext_issue
.
id
)
expect
(
json_response
.
second
[
'confidential'
]).
to
be_nil
expect
(
json_response
.
first
[
'title'
]).
to
eq
(
issue
.
title
)
expect
(
json_response
.
first
[
'title'
]).
to
eq
(
issue
.
title
)
expect
(
json_response
.
first
[
'id'
]).
to
eq
(
issue
.
id
)
expect
(
json_response
.
first
[
'id'
]).
to
eq
(
issue
.
id
)
expect
(
json_response
.
first
[
'confidential'
]).
not_to
be_nil
end
end
it
'returns 403 if the user has no access to the merge request'
do
it
'returns 403 if the user has no access to the merge request'
do
...
...
spec/requests/api/projects_spec.rb
View file @
7bee7b84
...
@@ -159,6 +159,31 @@ describe API::Projects do
...
@@ -159,6 +159,31 @@ describe API::Projects do
expect
(
json_response
.
first
).
to
include
'statistics'
expect
(
json_response
.
first
).
to
include
'statistics'
end
end
context
'when external issue tracker is enabled'
do
let!
(
:jira_service
)
{
create
(
:jira_service
,
project:
project
)
}
it
'includes open_issues_count'
do
get
api
(
'/projects'
,
user
)
expect
(
response
.
status
).
to
eq
200
expect
(
response
).
to
include_pagination_headers
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
first
.
keys
).
to
include
(
'open_issues_count'
)
expect
(
json_response
.
find
{
|
hash
|
hash
[
'id'
]
==
project
.
id
}.
keys
).
to
include
(
'open_issues_count'
)
end
it
'does not include open_issues_count if issues are disabled'
do
project
.
project_feature
.
update_attribute
(
:issues_access_level
,
ProjectFeature
::
DISABLED
)
get
api
(
'/projects'
,
user
)
expect
(
response
.
status
).
to
eq
200
expect
(
response
).
to
include_pagination_headers
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
find
{
|
hash
|
hash
[
'id'
]
==
project
.
id
}.
keys
).
not_to
include
(
'open_issues_count'
)
end
end
context
'and with simple=true'
do
context
'and with simple=true'
do
it
'returns a simplified version of all the projects'
do
it
'returns a simplified version of all the projects'
do
expected_keys
=
%w(id http_url_to_repo web_url name name_with_namespace path path_with_namespace)
expected_keys
=
%w(id http_url_to_repo web_url name name_with_namespace path path_with_namespace)
...
...
spec/services/git_push_service_spec.rb
View file @
7bee7b84
...
@@ -488,21 +488,57 @@ describe GitPushService, services: true do
...
@@ -488,21 +488,57 @@ describe GitPushService, services: true do
end
end
end
end
context
"using wrong markdown"
do
context
"using internal issue reference"
do
let
(
:message
)
{
"this is some work.
\n\n
closes #1"
}
context
'when internal issues are disabled'
do
before
do
project
.
issues_enabled
=
false
project
.
save!
end
let
(
:message
)
{
"this is some work.
\n\n
closes #1"
}
it
"does not initiates one api call to jira server to close the issue"
do
execute_service
(
project
,
commit_author
,
@oldrev
,
@newrev
,
@ref
)
expect
(
WebMock
).
not_to
have_requested
(
:post
,
jira_api_transition_url
(
'JIRA-1'
))
end
it
"does not initiates one api call to jira server to comment on the issue"
do
execute_service
(
project
,
commit_author
,
@oldrev
,
@newrev
,
@ref
)
expect
(
WebMock
).
not_to
have_requested
(
:post
,
jira_api_comment_url
(
'JIRA-1'
)).
with
(
body:
comment_body
).
once
end
end
it
"does not initiates one api call to jira server to close the issue"
do
context
'when internal issues are enabled'
do
execute_service
(
project
,
commit_author
,
@oldrev
,
@newrev
,
@ref
)
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:message
)
{
"this is some work.
\n\n
closes JIRA-1
\n\n
closes
#{
issue
.
to_reference
}
"
}
expect
(
WebMock
).
not_to
have_requested
(
:post
,
jira_api_transition_url
(
'JIRA-1'
))
it
"initiates one api call to jira server to close the jira issue"
do
end
execute_service
(
project
,
commit_author
,
@oldrev
,
@newrev
,
@ref
)
it
"does not initiates one api call to jira server to comment on the issue"
do
expect
(
WebMock
).
to
have_requested
(
:post
,
jira_api_transition_url
(
'JIRA-1'
)).
once
e
xecute_service
(
project
,
commit_author
,
@oldrev
,
@newrev
,
@ref
)
e
nd
expect
(
WebMock
).
not_to
have_requested
(
:post
,
jira_api_comment_url
(
'JIRA-1'
)).
with
(
it
"initiates one api call to jira server to comment on the jira issue"
do
body:
comment_body
execute_service
(
project
,
commit_author
,
@oldrev
,
@newrev
,
@ref
)
).
once
expect
(
WebMock
).
to
have_requested
(
:post
,
jira_api_comment_url
(
'JIRA-1'
)).
with
(
body:
comment_body
).
once
end
it
"closes the internal issue"
do
execute_service
(
project
,
commit_author
,
@oldrev
,
@newrev
,
@ref
)
expect
(
issue
.
reload
).
to
be_closed
end
it
"adds a note indicating that the issue is now closed"
do
expect
(
SystemNoteService
).
to
receive
(
:change_status
)
.
with
(
issue
,
project
,
commit_author
,
"closed"
,
closing_commit
)
execute_service
(
project
,
commit_author
,
@oldrev
,
@newrev
,
@ref
)
end
end
end
end
end
end
end
...
...
spec/services/issues/close_service_spec.rb
View file @
7bee7b84
...
@@ -98,13 +98,13 @@ describe Issues::CloseService, services: true do
...
@@ -98,13 +98,13 @@ describe Issues::CloseService, services: true do
end
end
end
end
context
'
external issue tracker
'
do
context
'
internal issues disabled
'
do
before
do
before
do
allow
(
project
).
to
receive
(
:default_issues_tracker?
).
and_return
(
false
)
project
.
issues_enabled
=
false
described_class
.
new
(
project
,
user
).
close_issue
(
issue
)
project
.
save!
end
end
it
'
closes
the issue'
do
it
'
does not close
the issue'
do
expect
(
issue
).
to
be_valid
expect
(
issue
).
to
be_valid
expect
(
issue
).
to
be_opened
expect
(
issue
).
to
be_opened
expect
(
todo
.
reload
).
to
be_pending
expect
(
todo
.
reload
).
to
be_pending
...
...
spec/services/merge_requests/build_service_spec.rb
View file @
7bee7b84
...
@@ -207,7 +207,7 @@ describe MergeRequests::BuildService, services: true do
...
@@ -207,7 +207,7 @@ describe MergeRequests::BuildService, services: true do
let
(
:source_branch
)
{
'12345-fix-issue'
}
let
(
:source_branch
)
{
'12345-fix-issue'
}
before
do
before
do
allow
(
project
).
to
receive
(
:
default_issues_tracker?
).
and_return
(
fals
e
)
allow
(
project
).
to
receive
(
:
external_issue_tracker
).
and_return
(
tru
e
)
end
end
it
'sets the title to: Resolves External Issue $issue-iid'
do
it
'sets the title to: Resolves External Issue $issue-iid'
do
...
...
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