Commit 1698c5a9 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'nfriend-add-release-progress-link-paths' into 'master'

Add link paths for release progress view to GraphQL

See merge request gitlab-org/gitlab!46161
parents da1f6ae3 7175610f
......@@ -12,12 +12,25 @@ module Types
field :self_url, GraphQL::STRING_TYPE, null: true,
description: 'HTTP URL of the release'
field :merge_requests_url, GraphQL::STRING_TYPE, null: true,
description: 'HTTP URL of the merge request page filtered by this release'
field :issues_url, GraphQL::STRING_TYPE, null: true,
description: 'HTTP URL of the issues page filtered by this release'
field :edit_url, GraphQL::STRING_TYPE, null: true,
description: "HTTP URL of the release's edit page",
authorize: :update_release
field :open_merge_requests_url, GraphQL::STRING_TYPE, null: true,
description: 'HTTP URL of the merge request page, filtered by this release and `state=open`'
field :merged_merge_requests_url, GraphQL::STRING_TYPE, null: true,
description: 'HTTP URL of the merge request page , filtered by this release and `state=merged`'
field :closed_merge_requests_url, GraphQL::STRING_TYPE, null: true,
description: 'HTTP URL of the merge request page , filtered by this release and `state=closed`'
field :open_issues_url, GraphQL::STRING_TYPE, null: true,
description: 'HTTP URL of the issues page, filtered by this release and `state=open`'
field :closed_issues_url, GraphQL::STRING_TYPE, null: true,
description: 'HTTP URL of the issues page, filtered by this release and `state=closed`'
field :merge_requests_url, GraphQL::STRING_TYPE, null: true, method: :open_merge_requests_url,
description: 'HTTP URL of the merge request page filtered by this release',
deprecated: { reason: 'Use `open_merge_requests_url`', milestone: '13.6' }
field :issues_url, GraphQL::STRING_TYPE, null: true, method: :open_issues_url,
description: 'HTTP URL of the issues page filtered by this release',
deprecated: { reason: 'Use `open_issues_url`', milestone: '13.6' }
end
end
......@@ -23,18 +23,36 @@ class ReleasePresenter < Gitlab::View::Presenter::Delegated
project_release_url(project, release)
end
def merge_requests_url
def open_merge_requests_url
return unless release_mr_issue_urls_available?
project_merge_requests_url(project, params_for_issues_and_mrs)
end
def issues_url
def merged_merge_requests_url
return unless release_mr_issue_urls_available?
project_merge_requests_url(project, params_for_issues_and_mrs(state: 'merged'))
end
def closed_merge_requests_url
return unless release_mr_issue_urls_available?
project_merge_requests_url(project, params_for_issues_and_mrs(state: 'closed'))
end
def open_issues_url
return unless release_mr_issue_urls_available?
project_issues_url(project, params_for_issues_and_mrs)
end
def closed_issues_url
return unless release_mr_issue_urls_available?
project_issues_url(project, params_for_issues_and_mrs(state: 'closed'))
end
def edit_url
return unless release_edit_page_available?
......@@ -59,8 +77,8 @@ class ReleasePresenter < Gitlab::View::Presenter::Delegated
can?(current_user, :download_code, project)
end
def params_for_issues_and_mrs
{ scope: 'all', state: 'opened', release_tag: release.tag }
def params_for_issues_and_mrs(state: 'opened')
{ scope: 'all', state: state, release_tag: release.tag }
end
def release_mr_issue_urls_available?
......
---
title: Add links to GraphQL release object for searching related issues and merge
requests
merge_request: 46161
author:
type: added
......@@ -16855,20 +16855,45 @@ type ReleaseEvidenceEdge {
}
type ReleaseLinks {
"""
HTTP URL of the issues page, filtered by this release and `state=closed`
"""
closedIssuesUrl: String
"""
HTTP URL of the merge request page , filtered by this release and `state=closed`
"""
closedMergeRequestsUrl: String
"""
HTTP URL of the release's edit page
"""
editUrl: String
"""
HTTP URL of the issues page filtered by this release
HTTP URL of the issues page filtered by this release. Deprecated in 13.6: Use `open_issues_url`
"""
issuesUrl: String @deprecated(reason: "Use `open_issues_url`. Deprecated in 13.6")
"""
HTTP URL of the merge request page filtered by this release. Deprecated in 13.6: Use `open_merge_requests_url`
"""
mergeRequestsUrl: String @deprecated(reason: "Use `open_merge_requests_url`. Deprecated in 13.6")
"""
HTTP URL of the merge request page , filtered by this release and `state=merged`
"""
mergedMergeRequestsUrl: String
"""
HTTP URL of the issues page, filtered by this release and `state=open`
"""
issuesUrl: String
openIssuesUrl: String
"""
HTTP URL of the merge request page filtered by this release
HTTP URL of the merge request page, filtered by this release and `state=open`
"""
mergeRequestsUrl: String
openMergeRequestsUrl: String
"""
HTTP URL of the release
......
......@@ -48541,6 +48541,34 @@
"name": "ReleaseLinks",
"description": null,
"fields": [
{
"name": "closedIssuesUrl",
"description": "HTTP URL of the issues page, filtered by this release and `state=closed`",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "closedMergeRequestsUrl",
"description": "HTTP URL of the merge request page , filtered by this release and `state=closed`",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "editUrl",
"description": "HTTP URL of the release's edit page",
......@@ -48557,7 +48585,35 @@
},
{
"name": "issuesUrl",
"description": "HTTP URL of the issues page filtered by this release",
"description": "HTTP URL of the issues page filtered by this release. Deprecated in 13.6: Use `open_issues_url`",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": true,
"deprecationReason": "Use `open_issues_url`. Deprecated in 13.6"
},
{
"name": "mergeRequestsUrl",
"description": "HTTP URL of the merge request page filtered by this release. Deprecated in 13.6: Use `open_merge_requests_url`",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": true,
"deprecationReason": "Use `open_merge_requests_url`. Deprecated in 13.6"
},
{
"name": "mergedMergeRequestsUrl",
"description": "HTTP URL of the merge request page , filtered by this release and `state=merged`",
"args": [
],
......@@ -48570,8 +48626,22 @@
"deprecationReason": null
},
{
"name": "mergeRequestsUrl",
"description": "HTTP URL of the merge request page filtered by this release",
"name": "openIssuesUrl",
"description": "HTTP URL of the issues page, filtered by this release and `state=open`",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "openMergeRequestsUrl",
"description": "HTTP URL of the merge request page, filtered by this release and `state=open`",
"args": [
],
......@@ -2230,9 +2230,14 @@ Evidence for a release.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `closedIssuesUrl` | String | HTTP URL of the issues page, filtered by this release and `state=closed` |
| `closedMergeRequestsUrl` | String | HTTP URL of the merge request page , filtered by this release and `state=closed` |
| `editUrl` | String | HTTP URL of the release's edit page |
| `issuesUrl` | String | HTTP URL of the issues page filtered by this release |
| `mergeRequestsUrl` | String | HTTP URL of the merge request page filtered by this release |
| `issuesUrl` **{warning-solid}** | String | **Deprecated:** Use `open_issues_url`. Deprecated in 13.6 |
| `mergeRequestsUrl` **{warning-solid}** | String | **Deprecated:** Use `open_merge_requests_url`. Deprecated in 13.6 |
| `mergedMergeRequestsUrl` | String | HTTP URL of the merge request page , filtered by this release and `state=merged` |
| `openIssuesUrl` | String | HTTP URL of the issues page, filtered by this release and `state=open` |
| `openMergeRequestsUrl` | String | HTTP URL of the merge request page, filtered by this release and `state=open` |
| `selfUrl` | String | HTTP URL of the release |
### ReleaseSource
......
......@@ -30,8 +30,8 @@ module API
expose :evidences, using: Entities::Releases::Evidence, expose_nil: false, if: ->(_, _) { can_download_code? }
expose :_links do
expose :self_url, as: :self, expose_nil: false
expose :merge_requests_url, expose_nil: false
expose :issues_url, expose_nil: false
expose :open_merge_requests_url, as: :merge_requests_url, expose_nil: false
expose :open_issues_url, as: :issues_url, expose_nil: false
expose :edit_url, expose_nil: false
end
......
......@@ -8,9 +8,14 @@ RSpec.describe GitlabSchema.types['ReleaseLinks'] do
it 'has the expected fields' do
expected_fields = %w[
selfUrl
openMergeRequestsUrl
mergedMergeRequestsUrl
closedMergeRequestsUrl
openIssuesUrl
closedIssuesUrl
editUrl
mergeRequestsUrl
issuesUrl
editUrl
]
expect(described_class).to include_graphql_fields(*expected_fields)
......
......@@ -12,6 +12,11 @@ RSpec.describe ReleasePresenter do
let(:release) { create(:release, project: project) }
let(:presenter) { described_class.new(release, current_user: user) }
let(:base_url_params) { { scope: 'all', release_tag: release.tag } }
let(:opened_url_params) { { state: 'opened', **base_url_params } }
let(:merged_url_params) { { state: 'merged', **base_url_params } }
let(:closed_url_params) { { state: 'closed', **base_url_params } }
before do
project.add_developer(developer)
project.add_guest(guest)
......@@ -55,15 +60,63 @@ RSpec.describe ReleasePresenter do
subject { presenter.self_url }
it 'returns its own url' do
is_expected.to match /#{project_release_url(project, release)}/
is_expected.to eq(project_release_url(project, release))
end
end
describe '#open_merge_requests_url' do
subject { presenter.open_merge_requests_url }
it 'returns merge requests url with state=open' do
is_expected.to eq(project_merge_requests_url(project, opened_url_params))
end
context 'when release_mr_issue_urls feature flag is disabled' do
before do
stub_feature_flags(release_mr_issue_urls: false)
end
it { is_expected.to be_nil }
end
end
describe '#merged_merge_requests_url' do
subject { presenter.merged_merge_requests_url }
it 'returns merge requests url with state=merged' do
is_expected.to eq(project_merge_requests_url(project, merged_url_params))
end
context 'when release_mr_issue_urls feature flag is disabled' do
before do
stub_feature_flags(release_mr_issue_urls: false)
end
it { is_expected.to be_nil }
end
end
describe '#closed_merge_requests_url' do
subject { presenter.closed_merge_requests_url }
it 'returns merge requests url with state=closed' do
is_expected.to eq(project_merge_requests_url(project, closed_url_params))
end
context 'when release_mr_issue_urls feature flag is disabled' do
before do
stub_feature_flags(release_mr_issue_urls: false)
end
it { is_expected.to be_nil }
end
end
describe '#merge_requests_url' do
subject { presenter.merge_requests_url }
describe '#open_issues_url' do
subject { presenter.open_issues_url }
it 'returns merge requests url' do
is_expected.to match /#{project_merge_requests_url(project)}/
it 'returns issues url with state=open' do
is_expected.to eq(project_issues_url(project, opened_url_params))
end
context 'when release_mr_issue_urls feature flag is disabled' do
......@@ -75,11 +128,11 @@ RSpec.describe ReleasePresenter do
end
end
describe '#issues_url' do
subject { presenter.issues_url }
describe '#closed_issues_url' do
subject { presenter.closed_issues_url }
it 'returns merge requests url' do
is_expected.to match /#{project_issues_url(project)}/
it 'returns issues url with state=closed' do
is_expected.to eq(project_issues_url(project, closed_url_params))
end
context 'when release_mr_issue_urls feature flag is disabled' do
......@@ -95,7 +148,7 @@ RSpec.describe ReleasePresenter do
subject { presenter.edit_url }
it 'returns release edit url' do
is_expected.to match /#{edit_project_release_url(project, release)}/
is_expected.to eq(edit_project_release_url(project, release))
end
context 'when a user is not allowed to update a release' do
......
......@@ -13,7 +13,11 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
let_it_be(:link_filepath) { '/direct/asset/link/path' }
let_it_be(:released_at) { Time.now - 1.day }
let(:params_for_issues_and_mrs) { { scope: 'all', state: 'opened', release_tag: release.tag } }
let(:base_url_params) { { scope: 'all', release_tag: release.tag } }
let(:opened_url_params) { { state: 'opened', **base_url_params } }
let(:merged_url_params) { { state: 'merged', **base_url_params } }
let(:closed_url_params) { { state: 'closed', **base_url_params } }
let(:post_query) { post_graphql(query, current_user: current_user) }
let(:path_prefix) { %w[project release] }
let(:data) { graphql_data.dig(*path) }
......@@ -180,6 +184,11 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
let(:release_fields) do
query_graphql_field(:links, nil, %{
selfUrl
openMergeRequestsUrl
mergedMergeRequestsUrl
closedMergeRequestsUrl
openIssuesUrl
closedIssuesUrl
mergeRequestsUrl
issuesUrl
})
......@@ -190,8 +199,13 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
expect(data).to eq(
'selfUrl' => project_release_url(project, release),
'mergeRequestsUrl' => project_merge_requests_url(project, params_for_issues_and_mrs),
'issuesUrl' => project_issues_url(project, params_for_issues_and_mrs)
'openMergeRequestsUrl' => project_merge_requests_url(project, opened_url_params),
'mergedMergeRequestsUrl' => project_merge_requests_url(project, merged_url_params),
'closedMergeRequestsUrl' => project_merge_requests_url(project, closed_url_params),
'openIssuesUrl' => project_issues_url(project, opened_url_params),
'closedIssuesUrl' => project_issues_url(project, closed_url_params),
'mergeRequestsUrl' => project_merge_requests_url(project, opened_url_params),
'issuesUrl' => project_issues_url(project, opened_url_params)
)
end
end
......
......@@ -10,6 +10,11 @@ RSpec.describe 'Query.project(fullPath).releases()' do
let_it_be(:reporter) { create(:user) }
let_it_be(:developer) { create(:user) }
let(:base_url_params) { { scope: 'all', release_tag: release.tag } }
let(:opened_url_params) { { state: 'opened', **base_url_params } }
let(:merged_url_params) { { state: 'merged', **base_url_params } }
let(:closed_url_params) { { state: 'closed', **base_url_params } }
let(:query) do
graphql_query_for(:project, { fullPath: project.full_path },
%{
......@@ -37,6 +42,11 @@ RSpec.describe 'Query.project(fullPath).releases()' do
}
links {
selfUrl
openMergeRequestsUrl
mergedMergeRequestsUrl
closedMergeRequestsUrl
openIssuesUrl
closedIssuesUrl
mergeRequestsUrl
issuesUrl
}
......@@ -101,8 +111,13 @@ RSpec.describe 'Query.project(fullPath).releases()' do
},
'links' => {
'selfUrl' => project_release_url(project, release),
'mergeRequestsUrl' => project_merge_requests_url(project, params_for_issues_and_mrs),
'issuesUrl' => project_issues_url(project, params_for_issues_and_mrs)
'openMergeRequestsUrl' => project_merge_requests_url(project, opened_url_params),
'mergedMergeRequestsUrl' => project_merge_requests_url(project, merged_url_params),
'closedMergeRequestsUrl' => project_merge_requests_url(project, closed_url_params),
'openIssuesUrl' => project_issues_url(project, opened_url_params),
'closedIssuesUrl' => project_issues_url(project, closed_url_params),
'mergeRequestsUrl' => project_merge_requests_url(project, opened_url_params),
'issuesUrl' => project_issues_url(project, opened_url_params)
}
)
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