Commit 77ffac17 authored by Alexandru Croitor's avatar Alexandru Croitor

Expose issuable references

Expose issuable references in 3 options: short, relative and full.
Short and full aways display corresponding issuable reference,
while relative displays the reference depending on the context
from which it was referenced.
parent 13adffbc
---
title: Expose full reference path for issuables in API
merge_request: 20354
author:
type: changed
......@@ -29,6 +29,14 @@ are paginated.
Read more on [pagination](README.md#pagination).
CAUTION: **Deprecation**
> `reference` attribute in response is deprecated in favour of `references`.
> Introduced [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/merge_requests/20354)
NOTE: **Note**
> `references.relative` is relative to the group that the epic is being requested. When epic is fetched from its origin group
> `relative` format would be the same as `short` format and when requested cross groups it is expected to be the same as `full` format.
## List epics for a group
Gets all epics of the requested group and its subgroups.
......@@ -73,6 +81,51 @@ Example response:
"state": "opened",
"web_url": "http://localhost:3001/groups/test/-/epics/4",
"reference": "&4",
"references": {
"short": "&4",
"relative": "&4",
"full": "test&4"
},
"author": {
"id": 10,
"name": "Lu Mayer",
"username": "kam",
"state": "active",
"avatar_url": "http://www.gravatar.com/avatar/018729e129a6f31c80a6327a30196823?s=80&d=identicon",
"web_url": "http://localhost:3001/kam"
},
"start_date": null,
"start_date_is_fixed": false,
"start_date_fixed": null,
"start_date_from_milestones": null, //deprecated in favor of start_date_from_inherited_source
"start_date_from_inherited_source": null,
"end_date": "2018-07-31", //deprecated in favor of due_date
"due_date": "2018-07-31",
"due_date_is_fixed": false,
"due_date_fixed": null,
"due_date_from_milestones": "2018-07-31", //deprecated in favor of start_date_from_inherited_source
"due_date_from_inherited_source": "2018-07-31",
"created_at": "2018-07-17T13:36:22.770Z",
"updated_at": "2018-07-18T12:22:05.239Z",
"closed_at": "2018-08-18T12:22:05.239Z",
"labels": [],
"upvotes": 4,
"downvotes": 0
},
{
"id": 50,
"iid": 35,
"group_id": 17,
"title": "Accusamus iste et ullam ratione voluptatem omnis debitis dolor est.",
"description": "Molestias dolorem eos vitae expedita impedit necessitatibus quo voluptatum.",
"state": "opened",
"web_url": "http://localhost:3001/groups/test/sample/-/epics/4",
"reference": "&4",
"references": {
"short": "&4",
"relative": "sample&4",
"full": "test/sample&4"
},
"author": {
"id": 10,
"name": "Lu Mayer",
......@@ -131,6 +184,11 @@ Example response:
"state": "opened",
"web_url": "http://localhost:3001/groups/test/-/epics/5",
"reference": "&5",
"references": {
"short": "&5",
"relative": "&5",
"full": "test&5"
},
"author":{
"id": 7,
"name": "Pamella Huel",
......@@ -199,8 +257,13 @@ Example response:
"title": "Epic",
"description": "Epic description",
"state": "opened",
"web_url": "http://localhost:3001/groups/test/-/epics/5",
"web_url": "http://localhost:3001/groups/test/-/epics/6",
"reference": "&6",
"references": {
"short": "&6",
"relative": "&6",
"full": "test&6"
},
"author": {
"name" : "Alexandra Bashirian",
"avatar_url" : null,
......@@ -269,8 +332,13 @@ Example response:
"title": "New Title",
"description": "Epic description",
"state": "opened",
"web_url": "http://localhost:3001/groups/test/-/epics/5",
"web_url": "http://localhost:3001/groups/test/-/epics/6",
"reference": "&6",
"references": {
"short": "&6",
"relative": "&6",
"full": "test&6"
},
"author": {
"name" : "Alexandra Bashirian",
"avatar_url" : null,
......@@ -372,6 +440,13 @@ Example response:
"avatar_url": "http://www.gravatar.com/avatar/a2f5c6fcef64c9c69cb8779cb292be1b?s=80&d=identicon",
"web_url": "http://localhost:3001/arnita"
},
"web_url": "http://localhost:3001/groups/test/-/epics/5",
"reference": "&5",
"references": {
"short": "&5",
"relative": "&5",
"full": "test&5"
},
"start_date": null,
"end_date": null,
"created_at": "2018-01-21T06:21:13.165Z",
......
......@@ -12,6 +12,14 @@ are paginated.
Read more on [pagination](README.md#pagination).
CAUTION: **Deprecation**
> `reference` attribute in response is deprecated in favour of `references`.
> Introduced [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/merge_requests/20354)
NOTE: **Note**
> `references.relative` is relative to the group / project that the issue is being requested. When issue is fetched from its project
> `relative` format would be the same as `short` format and when requested across groups / projects it is expected to be the same as `full` format.
## List issues
Get all issues the authenticated user has access to. By default it
......@@ -121,7 +129,12 @@ Example response:
"merge_requests_count": 0,
"user_notes_count": 1,
"due_date": "2016-07-22",
"web_url": "http://example.com/example/example/issues/6",
"web_url": "http://example.com/my-group/my-project/issues/6",
"references": {
"short": "#6",
"relative": "my-group/my-project#6",
"full": "my-group/my-project#6"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -270,7 +283,12 @@ Example response:
"closed_by" : null,
"user_notes_count": 1,
"due_date": null,
"web_url": "http://example.com/example/example/issues/1",
"web_url": "http://example.com/my-group/my-project/issues/1",
"references": {
"short": "#1",
"relative": "my-project#1",
"full": "my-group/my-project#1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -426,7 +444,12 @@ Example response:
},
"user_notes_count": 1,
"due_date": "2016-07-22",
"web_url": "http://example.com/example/example/issues/1",
"web_url": "http://example.com/my-group/my-project/issues/1",
"references": {
"short": "#1",
"relative": "#1",
"full": "my-group/my-project#1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -543,7 +566,12 @@ Example response:
"subscribed": false,
"user_notes_count": 1,
"due_date": null,
"web_url": "http://example.com/example/example/issues/1",
"web_url": "http://example.com/my-group/my-project/issues/1",
"references": {
"short": "#1",
"relative": "#1",
"full": "my-group/my-project#1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -668,7 +696,12 @@ Example response:
"subscribed" : true,
"user_notes_count": 0,
"due_date": null,
"web_url": "http://example.com/example/example/issues/14",
"web_url": "http://example.com/my-group/my-project/issues/14",
"references": {
"short": "#14",
"relative": "#14",
"full": "my-group/my-project#14"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -778,7 +811,12 @@ Example response:
"subscribed" : true,
"user_notes_count": 0,
"due_date": "2016-07-22",
"web_url": "http://example.com/example/example/issues/15",
"web_url": "http://example.com/my-group/my-project/issues/15",
"references": {
"short": "#15",
"relative": "#15",
"full": "my-group/my-project#15"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -900,7 +938,12 @@ Example response:
"web_url": "https://gitlab.example.com/solon.cremin"
},
"due_date": null,
"web_url": "http://example.com/example/example/issues/11",
"web_url": "http://example.com/my-group/my-project/issues/11",
"references": {
"short": "#11",
"relative": "#11",
"full": "my-group/my-project#11"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -1001,7 +1044,12 @@ Example response:
"web_url": "https://gitlab.example.com/solon.cremin"
},
"due_date": null,
"web_url": "http://example.com/example/example/issues/11",
"web_url": "http://example.com/my-group/my-project/issues/11",
"references": {
"short": "#11",
"relative": "#11",
"full": "my-group/my-project#11"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -1095,7 +1143,12 @@ Example response:
},
"subscribed": false,
"due_date": null,
"web_url": "http://example.com/example/example/issues/12",
"web_url": "http://example.com/my-group/my-project/issues/12",
"references": {
"short": "#12",
"relative": "#12",
"full": "my-group/my-project#12"
},
"confidential": false,
"discussion_locked": false,
"task_completion_status":{
......@@ -1197,7 +1250,12 @@ Example response:
"downvotes": 0,
"merge_requests_count": 0,
"due_date": null,
"web_url": "http://example.com/example/example/issues/110",
"web_url": "http://example.com/my-group/my-project/issues/10",
"references": {
"short": "#10",
"relative": "#10",
"full": "my-group/my-project#10"
},
"confidential": false,
"discussion_locked": false,
"task_completion_status":{
......@@ -1436,6 +1494,11 @@ Example response:
"force_remove_source_branch": false,
"reference": "!11",
"web_url": "https://gitlab.example.com/twitter/flight/merge_requests/4",
"references": {
"short": "!4",
"relative": "!4",
"full": "twitter/flight!4"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -1566,6 +1629,12 @@ Example response:
"should_remove_source_branch": null,
"force_remove_source_branch": false,
"web_url": "https://gitlab.example.com/gitlab-org/gitlab-test/merge_requests/6432",
"reference": "!6432",
"references": {
"short": "!6432",
"relative": "!6432",
"full": "gitlab-org/gitlab-test!6432"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......
......@@ -2,6 +2,14 @@
Every API call to merge requests must be authenticated.
CAUTION: **Deprecation**
> `reference` attribute in response is deprecated in favour of `references`.
> Introduced [GitLab 12.6](https://gitlab.com/gitlab-org/gitlab/merge_requests/20354)
NOTE: **Note**
> `references.relative` is relative to the group / project that the merge request is being requested. When merge request is fetched from its project
> `relative` format would be the same as `short` format and when requested across groups / projects it is expected to be the same as `full` format.
## List merge requests
> [Introduced][ce-13060] in GitLab 9.5.
......@@ -134,6 +142,11 @@ Parameters:
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "my-group/my-project!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -296,6 +309,11 @@ Parameters:
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -448,6 +466,11 @@ Parameters:
"should_remove_source_branch": true,
"force_remove_source_branch": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "my-project!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -574,6 +597,11 @@ Parameters:
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -779,7 +807,12 @@ Parameters:
"should_remove_source_branch": true,
"force_remove_source_branch": false,
"squash": false,
"web_url": "http://example.com/example/example/merge_requests/1",
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"discussion_locked": false,
"time_stats": {
"time_estimate": 0,
......@@ -989,6 +1022,11 @@ order for it to take effect:
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -1143,6 +1181,11 @@ Must include at least one non-required attribute from above.
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -1313,6 +1356,11 @@ Parameters:
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -1486,6 +1534,11 @@ Parameters:
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -1772,6 +1825,11 @@ Example response:
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -1918,6 +1976,11 @@ Example response:
"allow_collaboration": false,
"allow_maintainer_to_push": false,
"web_url": "http://gitlab.example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
"time_stats": {
"time_estimate": 0,
"total_time_spent": 0,
......@@ -2078,7 +2141,12 @@ Example response:
"should_remove_source_branch": true,
"force_remove_source_branch": false,
"squash": false,
"web_url": "http://example.com/example/example/merge_requests/1"
"web_url": "http://example.com/my-group/my-project/merge_requests/1",
"references": {
"short": "!1",
"relative": "!1",
"full": "my-group/my-project!1"
},
},
"target_url": "https://gitlab.example.com/gitlab-org/gitlab-ci/merge_requests/7",
"body": "Et voluptas laudantium minus nihil recusandae ut accusamus earum aut non.",
......
......@@ -42,7 +42,8 @@ module API
epics = paginate(find_epics(finder_params: { group_id: user_group.id })).with_api_entity_associations
# issuable_metadata is the standard used by the Todo API
present epics, with: EE::API::Entities::Epic, user: current_user, issuable_metadata: issuable_meta_data(epics, 'Epic')
present epics, epic_options.merge(issuable_metadata: issuable_meta_data(epics, 'Epic'))
end
desc 'Get details of an epic' do
......@@ -54,9 +55,7 @@ module API
get ':id/(-/)epics/:epic_iid' do
authorize_can_read!
present epic, options, user: current_user,
with: EE::API::Entities::Epic,
include_subscribed: true
present epic, epic_options.merge(include_subscribed: true)
end
desc 'Create a new epic' do
......@@ -77,7 +76,7 @@ module API
epic = ::Epics::CreateService.new(user_group, current_user, declared_params(include_missing: false)).execute
if epic.valid?
present epic, with: EE::API::Entities::Epic, user: current_user
present epic, epic_options
else
render_validation_error!(epic)
end
......@@ -106,7 +105,7 @@ module API
result = ::Epics::UpdateService.new(user_group, current_user, update_params).execute(epic)
if result.valid?
present result, with: EE::API::Entities::Epic, user: current_user
present result, epic_options
else
render_validation_error!(result)
end
......
......@@ -41,6 +41,14 @@ module API
end
end
# rubocop: enable CodeReuse/ActiveRecord
def epic_options
{
with: EE::API::Entities::Epic,
user: current_user,
group: user_group
}
end
end
end
end
......@@ -325,6 +325,11 @@ module EE
expose :state
expose :web_edit_url, if: can_admin_epic # @deprecated
expose :web_url
expose :references, with: ::API::Entities::IssuableReferences do |epic|
epic
end
# reference is deprecated in favour of references
# Introduced [Gitlab 12.6](https://gitlab.com/gitlab-org/gitlab/merge_requests/20354)
expose :reference, if: { with_reference: true } do |epic|
epic.to_reference(full: true)
end
......
......@@ -45,6 +45,11 @@
"web_edit_url": { "type": "string" },
"web_url": { "type": "string" },
"reference": { "type": "string" },
"references": {
"short": {"type": "string"},
"relative": {"type": "string"},
"full": {"type": "string"}
},
"subscribed": { "type": ["boolean", "null"] }
},
"required": [
......
......@@ -294,6 +294,32 @@ describe API::Epics do
expect_paginated_array_response(epic.id)
end
context "#to_reference" do
it 'exposes reference path' do
get api(url)
expect(json_response.first['references']['short']).to eq("&#{epic2.iid}")
expect(json_response.first['references']['relative']).to eq("&#{epic2.iid}")
expect(json_response.first['references']['full']).to eq("#{epic2.group.path}&#{epic2.iid}")
end
context 'referencing from parent group' do
let(:parent_group) { create(:group) }
before do
group.update(parent_id: parent_group.id)
end
it 'exposes full reference path' do
get api("/groups/#{parent_group.path}/epics")
expect(json_response.first['references']['short']).to eq("&#{epic2.iid}")
expect(json_response.first['references']['relative']).to eq("#{parent_group.path}/#{epic2.group.path}&#{epic2.iid}")
expect(json_response.first['references']['full']).to eq("#{parent_group.path}/#{epic2.group.path}&#{epic2.iid}")
end
end
end
it_behaves_like 'can admin epics'
end
......@@ -437,6 +463,14 @@ describe API::Epics do
expect(json_response['closed_at']).to be_present
end
it 'exposes full reference path' do
get api(url)
expect(json_response['references']['short']).to eq("&#{epic.iid}")
expect(json_response['references']['relative']).to eq("&#{epic.iid}")
expect(json_response['references']['full']).to eq("#{epic.group.path}&#{epic.iid}")
end
it_behaves_like 'can admin epics'
end
end
......
......@@ -569,6 +569,20 @@ module API
end
end
class IssuableReferences < Grape::Entity
expose :short do |issuable|
issuable.to_reference
end
expose :relative do |issuable, options|
issuable.to_reference(options[:group] || options[:project])
end
expose :full do |issuable|
issuable.to_reference(full: true)
end
end
class Diff < Grape::Entity
expose :old_path, :new_path, :a_mode, :b_mode
expose :new_file?, as: :new_file
......@@ -676,6 +690,10 @@ module API
end
end
expose :references, with: IssuableReferences do |issue|
issue
end
# Calculating the value of subscribed field triggers Markdown
# processing. We can't do that for multiple issues / merge
# requests in a single API request.
......@@ -787,10 +805,16 @@ module API
# Deprecated
expose :allow_collaboration, as: :allow_maintainer_to_push, if: -> (merge_request, _) { merge_request.for_fork? }
# reference is deprecated in favour of references
# Introduced [Gitlab 12.6](https://gitlab.com/gitlab-org/gitlab/merge_requests/20354)
expose :reference do |merge_request, options|
merge_request.to_reference(options[:project])
end
expose :references, with: IssuableReferences do |merge_request|
merge_request
end
expose :web_url do |merge_request|
Gitlab::UrlBuilder.build(merge_request)
end
......
......@@ -122,16 +122,15 @@ module API
use :issues_params
end
get ":id/issues" do
group = find_group!(params[:id])
issues = paginate(find_issues(group_id: group.id, include_subgroups: true))
issues = paginate(find_issues(group_id: user_group.id, include_subgroups: true))
options = {
with: Entities::Issue,
with_labels_details: declared_params[:with_labels_details],
current_user: current_user,
issuable_metadata: issuable_meta_data(issues, 'Issue', current_user),
include_subscribed: false
include_subscribed: false,
group: user_group
}
present issues, options
......@@ -142,9 +141,7 @@ module API
use :issues_stats_params
end
get ":id/issues_statistics" do
group = find_group!(params[:id])
present issues_statistics(group_id: group.id, include_subgroups: true), with: Grape::Presenters::Presenter
present issues_statistics(group_id: user_group.id, include_subgroups: true), with: Grape::Presenters::Presenter
end
end
......@@ -161,9 +158,7 @@ module API
use :issues_params
end
get ":id/issues" do
project = find_project!(params[:id])
issues = paginate(find_issues(project_id: project.id))
issues = paginate(find_issues(project_id: user_project.id))
options = {
with: Entities::Issue,
......@@ -182,9 +177,7 @@ module API
use :issues_stats_params
end
get ":id/issues_statistics" do
project = find_project!(params[:id])
present issues_statistics(project_id: project.id), with: Grape::Presenters::Presenter
present issues_statistics(project_id: user_project.id), with: Grape::Presenters::Presenter
end
desc 'Get a single project issue' do
......
......@@ -157,11 +157,9 @@ module API
use :merge_requests_params
end
get ":id/merge_requests" do
group = find_group!(params[:id])
merge_requests = find_merge_requests(group_id: user_group.id, include_subgroups: true)
merge_requests = find_merge_requests(group_id: group.id, include_subgroups: true)
present merge_requests, serializer_options_for(merge_requests)
present merge_requests, serializer_options_for(merge_requests).merge(group: user_group)
end
end
......@@ -215,7 +213,7 @@ module API
merge_requests = find_merge_requests(project_id: user_project.id)
options = serializer_options_for(merge_requests)
options = serializer_options_for(merge_requests).merge(project: user_project)
options[:project] = user_project
present merge_requests, options
......
......@@ -84,6 +84,11 @@
"total_time_spent": { "type": "integer" },
"human_time_estimate": { "type": ["string", "null"] },
"human_total_time_spent": { "type": ["string", "null"] }
},
"references": {
"short": {"type": "string"},
"relative": {"type": "string"},
"full": {"type": "string"}
}
},
"required": [
......
......@@ -113,7 +113,12 @@
"human_total_time_spent": { "type": ["string", "null"] }
},
"allow_collaboration": { "type": ["boolean", "null"] },
"allow_maintainer_to_push": { "type": ["boolean", "null"] }
"allow_maintainer_to_push": { "type": ["boolean", "null"] },
"references": {
"short": {"type": "string"},
"relative": {"type": "string"},
"full": {"type": "string"}
}
},
"required": [
"id", "iid", "project_id", "title", "description",
......
......@@ -688,5 +688,32 @@ describe API::Issues do
end
end
end
context "#to_reference" do
it 'exposes reference path in context of group' do
get api(base_url, user)
expect(json_response.first['references']['short']).to eq("##{group_closed_issue.iid}")
expect(json_response.first['references']['relative']).to eq("#{group_closed_issue.project.path}##{group_closed_issue.iid}")
expect(json_response.first['references']['full']).to eq("#{group_closed_issue.project.full_path}##{group_closed_issue.iid}")
end
context 'referencing from parent group' do
let(:parent_group) { create(:group) }
before do
group.update(parent_id: parent_group.id)
group_closed_issue.reload
end
it 'exposes reference path in context of parent group' do
get api("/groups/#{parent_group.id}/issues")
expect(json_response.first['references']['short']).to eq("##{group_closed_issue.iid}")
expect(json_response.first['references']['relative']).to eq("#{group_closed_issue.project.full_path}##{group_closed_issue.iid}")
expect(json_response.first['references']['full']).to eq("#{group_closed_issue.project.full_path}##{group_closed_issue.iid}")
end
end
end
end
end
......@@ -805,6 +805,17 @@ describe API::Issues do
end
end
describe 'GET /projects/:id/issues/:issue_iid' do
it 'exposes full reference path' do
get api("/projects/#{project.id}/issues/#{issue.iid}", user)
expect(response).to have_gitlab_http_status(200)
expect(json_response['references']['short']).to eq("##{issue.iid}")
expect(json_response['references']['relative']).to eq("##{issue.iid}")
expect(json_response['references']['full']).to eq("#{project.parent.path}/#{project.path}##{issue.iid}")
end
end
describe 'DELETE /projects/:id/issues/:issue_iid' do
it 'rejects a non member from deleting an issue' do
delete api("/projects/#{project.id}/issues/#{issue.iid}", non_member)
......
......@@ -736,6 +736,33 @@ describe API::MergeRequests do
it_behaves_like 'merge requests list'
end
context "#to_reference" do
it 'exposes reference path in context of group' do
get api("/groups/#{group.id}/merge_requests", user)
expect(json_response.first['references']['short']).to eq("!#{merge_request_merged.iid}")
expect(json_response.first['references']['relative']).to eq("#{merge_request_merged.target_project.path}!#{merge_request_merged.iid}")
expect(json_response.first['references']['full']).to eq("#{merge_request_merged.target_project.full_path}!#{merge_request_merged.iid}")
end
context 'referencing from parent group' do
let(:parent_group) { create(:group) }
before do
group.update(parent_id: parent_group.id)
merge_request_merged.reload
end
it 'exposes reference path in context of parent group' do
get api("/groups/#{parent_group.id}/merge_requests")
expect(json_response.first['references']['short']).to eq("!#{merge_request_merged.iid}")
expect(json_response.first['references']['relative']).to eq("#{merge_request_merged.target_project.full_path}!#{merge_request_merged.iid}")
expect(json_response.first['references']['full']).to eq("#{merge_request_merged.target_project.full_path}!#{merge_request_merged.iid}")
end
end
end
end
describe "GET /projects/:id/merge_requests/:merge_request_iid" do
......@@ -783,6 +810,9 @@ describe API::MergeRequests do
expect(json_response).not_to include('rebase_in_progress')
expect(json_response['has_conflicts']).to be_falsy
expect(json_response['blocking_discussions_resolved']).to be_truthy
expect(json_response['references']['short']).to eq("!#{merge_request.iid}")
expect(json_response['references']['relative']).to eq("!#{merge_request.iid}")
expect(json_response['references']['full']).to eq("#{merge_request.target_project.full_path}!#{merge_request.iid}")
end
it 'exposes description and title html when render_html is true' do
......
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