Commit ef0809ac authored by Sean McGivern's avatar Sean McGivern

Merge branch 'link-types-api-rest' into 'master'

Expose issue link type in REST API

See merge request gitlab-org/gitlab!21375
parents b8bc2883 9f952833
---
title: Expose issue link type in REST API
merge_request: 21375
author:
type: added
......@@ -48,6 +48,7 @@ Parameters:
"web_url": "http://example.com/example/example/issues/14",
"confidential": false,
"weight": null,
"link_type": "relates_to"
}
]
```
......@@ -66,6 +67,7 @@ POST /projects/:id/issues/:issue_iid/links
| `issue_iid` | integer | yes | The internal ID of a project's issue |
| `target_project_id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) of a target project |
| `target_issue_iid` | integer/string | yes | The internal ID of a target project's issue |
| `link_type` | string | no | The type of the relation ("relates_to", "blocks", "is_blocked_by"), defaults to "relates_to"). Ignored unless `issue_link_types` feature flag is enabled. |
```bash
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues/1/links?target_project_id=5&target_issue_iid=1"
......@@ -134,7 +136,8 @@ Example response:
"web_url": "http://example.com/example/example/issues/14",
"confidential": false,
"weight": null,
}
},
"link_type": "relates_to"
}
```
......@@ -151,6 +154,7 @@ DELETE /projects/:id/issues/:issue_iid/links/:issue_link_id
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `issue_iid` | integer | yes | The internal ID of a project's issue |
| `issue_link_id` | integer/string | yes | The ID of an issue relationship |
| `link_type` | string | no | The type of the relation ('relates_to', 'blocks', 'is_blocked_by'), defaults to 'relates_to' |
```json
{
......@@ -213,6 +217,7 @@ DELETE /projects/:id/issues/:issue_iid/links/:issue_link_id
"web_url": "http://example.com/example/example/issues/14",
"confidential": false,
"weight": null,
}
},
"link_type": "relates_to"
}
```
......@@ -30,6 +30,8 @@ module API
params do
requires :target_project_id, type: String, desc: 'The ID of the target project'
requires :target_issue_iid, type: Integer, desc: 'The IID of the target issue'
optional :link_type, type: String, values: IssueLink.link_types.keys,
desc: 'The type of the relation. Ignored unless `issue_link_types` feature flag is enabled.'
end
# rubocop: disable CodeReuse/ActiveRecord
post ':id/issues/:issue_iid/links' do
......@@ -37,7 +39,7 @@ module API
target_issue = find_project_issue(declared_params[:target_issue_iid],
declared_params[:target_project_id])
create_params = { target_issuable: target_issue }
create_params = { target_issuable: target_issue, link_type: declared_params[:link_type] }
result = ::IssueLinks::CreateService
.new(source_issue, current_user, create_params)
......
......@@ -269,6 +269,7 @@ module EE
class RelatedIssue < ::API::Entities::Issue
expose :issue_link_id
expose :issue_link_type, as: :link_type
end
class LinkedEpic < Grape::Entity
......@@ -395,6 +396,7 @@ module EE
class IssueLink < Grape::Entity
expose :source, as: :source_issue, using: ::API::Entities::IssueBasic
expose :target, as: :target_issue, using: ::API::Entities::IssueBasic
expose :link_type
end
class SpecialBoardFilter < Grape::Entity
......
{
"type": "object",
"properties" : {
"source_issue": {
"allOf": [
{ "$ref": "../../../../../../../spec/fixtures/api/schemas/public_api/v4/issue.json" }
]
},
"target_issue": {
"allOf": [
{ "$ref": "../../../../../../../spec/fixtures/api/schemas/public_api/v4/issue.json" }
]
},
"link_type": {
"type": "string",
"enum": ["relates_to", "blocks", "is_blocked_by"]
}
},
"required" : [ "source_issue", "target_issue", "link_type" ]
}
{
"type": "array",
"items": {
"type": "object",
"properties" : {
"$ref": "./issue_link.json"
}
}
}
......@@ -3,9 +3,9 @@
require 'spec_helper'
describe API::IssueLinks do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:issue) { create(:issue, project: project) }
before do
project.add_guest(user)
......@@ -30,7 +30,7 @@ describe API::IssueLinks do
expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first).to include('iid', 'title', 'issue_link_id')
expect(response).to match_response_schema('public_api/v4/issue_links')
end
end
end
......@@ -113,26 +113,43 @@ describe API::IssueLinks do
end
context 'when user has ability to create an issue link' do
it 'returns 201' do
target_issue = create(:issue, project: project)
let_it_be(:target_issue) { create(:issue, project: project) }
before do
project.add_reporter(user)
end
it 'returns 201 status and contains the expected link response' do
post api("/projects/#{project.id}/issues/#{issue.iid}/links", user),
params: { target_project_id: project.id, target_issue_iid: target_issue.iid }
params: { target_project_id: project.id, target_issue_iid: target_issue.iid, link_type: 'blocks' }
expect(response).to have_gitlab_http_status(201)
expect(json_response).to include('source_issue', 'target_issue')
expect_link_response(link_type: 'blocks')
end
it 'returns 201 when sending full path of target project' do
target_issue = create(:issue, project: project)
project.add_reporter(user)
context 'when `issue_link_types` is disabled' do
before do
stub_feature_flags(issue_link_types: false)
end
it 'ignores `link_type` parameter' do
post api("/projects/#{project.id}/issues/#{issue.iid}/links", user),
params: { target_project_id: project.id, target_issue_iid: target_issue.iid, link_type: 'blocks' }
expect_link_response
end
end
it 'returns 201 when sending full path of target project' do
post api("/projects/#{project.id}/issues/#{issue.iid}/links", user),
params: { target_project_id: project.to_reference(full: true), target_issue_iid: target_issue.iid }
expect_link_response
end
def expect_link_response(link_type: 'relates_to')
expect(response).to have_gitlab_http_status(201)
expect(json_response).to include('source_issue', 'target_issue')
expect(response).to match_response_schema('public_api/v4/issue_link')
expect(json_response['link_type']).to eq(link_type)
end
end
end
......@@ -195,7 +212,7 @@ describe API::IssueLinks do
delete api("/projects/#{project.id}/issues/#{issue.iid}/links/#{issue_link.id}", user)
expect(response).to have_gitlab_http_status(200)
expect(json_response).to include('source_issue', 'target_issue')
expect(response).to match_response_schema('public_api/v4/issue_link')
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment