Commit bab063af authored by Sean McGivern's avatar Sean McGivern

Merge branch 'graphql-expose-merge-request-at-root' into 'master'

Add merge_request to GraphQL query

See merge request gitlab-org/gitlab!60190
parents 82ac7980 c70c9094
...@@ -79,8 +79,14 @@ module Types ...@@ -79,8 +79,14 @@ module Types
field :issue, Types::IssueType, field :issue, Types::IssueType,
null: true, null: true,
description: 'Find an Issue.' do description: 'Find an issue.' do
argument :id, ::Types::GlobalIDType[::Issue], required: true, description: 'The global ID of the Issue.' argument :id, ::Types::GlobalIDType[::Issue], required: true, description: 'The global ID of the issue.'
end
field :merge_request, Types::MergeRequestType,
null: true,
description: 'Find a merge request.' do
argument :id, ::Types::GlobalIDType[::MergeRequest], required: true, description: 'The global ID of the merge request.'
end end
field :instance_statistics_measurements, field :instance_statistics_measurements,
...@@ -119,6 +125,13 @@ module Types ...@@ -119,6 +125,13 @@ module Types
GitlabSchema.find_by_gid(id) GitlabSchema.find_by_gid(id)
end end
def merge_request(id:)
# TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
id = ::Types::GlobalIDType[::MergeRequest].coerce_isolated_input(id)
GitlabSchema.find_by_gid(id)
end
def milestone(id:) def milestone(id:)
# TODO: remove this line when the compatibility layer is removed # TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883 # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
......
---
title: Allow merge request search via GraphQL
merge_request: 60190
author: Lee Tickett @leetickett
type: added
...@@ -165,7 +165,7 @@ four standard [pagination arguments](#connection-pagination-arguments): ...@@ -165,7 +165,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
### `Query.issue` ### `Query.issue`
Find an Issue. Find an issue.
Returns [`Issue`](#issue). Returns [`Issue`](#issue).
...@@ -173,7 +173,7 @@ Returns [`Issue`](#issue). ...@@ -173,7 +173,7 @@ Returns [`Issue`](#issue).
| Name | Type | Description | | Name | Type | Description |
| ---- | ---- | ----------- | | ---- | ---- | ----------- |
| <a id="queryissueid"></a>`id` | [`IssueID!`](#issueid) | The global ID of the Issue. | | <a id="queryissueid"></a>`id` | [`IssueID!`](#issueid) | The global ID of the issue. |
### `Query.iteration` ### `Query.iteration`
...@@ -197,6 +197,18 @@ This field returns a [connection](#connections). It accepts the ...@@ -197,6 +197,18 @@ This field returns a [connection](#connections). It accepts the
four standard [pagination arguments](#connection-pagination-arguments): four standard [pagination arguments](#connection-pagination-arguments):
`before: String`, `after: String`, `first: Int`, `last: Int`. `before: String`, `after: String`, `first: Int`, `last: Int`.
### `Query.mergeRequest`
Find a merge request.
Returns [`MergeRequest`](#mergerequest).
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="querymergerequestid"></a>`id` | [`MergeRequestID!`](#mergerequestid) | The global ID of the merge request. |
### `Query.metadata` ### `Query.metadata`
Metadata about GitLab. Metadata about GitLab.
......
...@@ -21,6 +21,7 @@ RSpec.describe GitlabSchema.types['Query'] do ...@@ -21,6 +21,7 @@ RSpec.describe GitlabSchema.types['Query'] do
user user
users users
issue issue
merge_request
usage_trends_measurements usage_trends_measurements
runner_platforms runner_platforms
] ]
...@@ -60,11 +61,21 @@ RSpec.describe GitlabSchema.types['Query'] do ...@@ -60,11 +61,21 @@ RSpec.describe GitlabSchema.types['Query'] do
describe 'issue field' do describe 'issue field' do
subject { described_class.fields['issue'] } subject { described_class.fields['issue'] }
it 'returns issue' do it "finds an issue by it's gid" do
is_expected.to have_graphql_arguments(:id)
is_expected.to have_graphql_type(Types::IssueType) is_expected.to have_graphql_type(Types::IssueType)
end end
end end
describe 'merge_request field' do
subject { described_class.fields['mergeRequest'] }
it "finds a merge_request by it's gid" do
is_expected.to have_graphql_arguments(:id)
is_expected.to have_graphql_type(Types::MergeRequestType)
end
end
describe 'usage_trends_measurements field' do describe 'usage_trends_measurements field' do
subject { described_class.fields['usageTrendsMeasurements'] } subject { described_class.fields['usageTrendsMeasurements'] }
......
...@@ -76,7 +76,7 @@ RSpec.describe 'Query.issue(id)' do ...@@ -76,7 +76,7 @@ RSpec.describe 'Query.issue(id)' do
post_graphql(query, current_user: current_user) post_graphql(query, current_user: current_user)
end end
it "returns the Issue and field #{params['field']}" do it "returns the issue and field #{params['field']}" do
expect(issue_data.keys).to eq([field]) expect(issue_data.keys).to eq([field])
end end
end end
...@@ -86,7 +86,7 @@ RSpec.describe 'Query.issue(id)' do ...@@ -86,7 +86,7 @@ RSpec.describe 'Query.issue(id)' do
context 'when selecting multiple fields' do context 'when selecting multiple fields' do
let(:issue_fields) { ['title', 'description', 'updatedBy { username }'] } let(:issue_fields) { ['title', 'description', 'updatedBy { username }'] }
it 'returns the Issue with the specified fields' do it 'returns the issue with the specified fields' do
post_graphql(query, current_user: current_user) post_graphql(query, current_user: current_user)
expect(issue_data.keys).to eq %w[title description updatedBy] expect(issue_data.keys).to eq %w[title description updatedBy]
...@@ -115,7 +115,7 @@ RSpec.describe 'Query.issue(id)' do ...@@ -115,7 +115,7 @@ RSpec.describe 'Query.issue(id)' do
end end
end end
context 'when passed a non-Issue gid' do context 'when passed a non-issue gid' do
let(:mr) { create(:merge_request) } let(:mr) { create(:merge_request) }
it 'returns an error' do it 'returns an error' do
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Query.merge_request(id)' do
include GraphqlHelpers
let_it_be(:project) { create(:project, :empty_repo) }
let_it_be(:merge_request) { create(:merge_request, source_project: project) }
let_it_be(:current_user) { create(:user) }
let_it_be(:merge_request_params) { { 'id' => merge_request.to_global_id.to_s } }
let(:merge_request_data) { graphql_data['mergeRequest'] }
let(:merge_request_fields) { all_graphql_fields_for('MergeRequest'.classify) }
let(:query) do
graphql_query_for('mergeRequest', merge_request_params, merge_request_fields)
end
it_behaves_like 'a working graphql query' do
before do
post_graphql(query, current_user: current_user)
end
end
it_behaves_like 'a noteable graphql type we can query' do
let(:noteable) { merge_request }
let(:project) { merge_request.project }
let(:path_to_noteable) { [:merge_request] }
before do
project.add_reporter(current_user)
end
def query(fields)
graphql_query_for('mergeRequest', merge_request_params, fields)
end
end
context 'when the user does not have access to the merge request' do
it 'returns nil' do
post_graphql(query)
expect(merge_request_data).to be nil
end
end
context 'when the user does have access' do
before do
project.add_reporter(current_user)
end
it 'returns the merge request' do
post_graphql(query, current_user: current_user)
expect(merge_request_data).to include(
'title' => merge_request.title,
'description' => merge_request.description
)
end
context 'when selecting any single field' do
where(:field) do
scalar_fields_of('MergeRequest').map { |name| [name] }
end
with_them do
it_behaves_like 'a working graphql query' do
let(:merge_request_fields) do
field
end
before do
post_graphql(query, current_user: current_user)
end
it "returns the merge request and field #{params['field']}" do
expect(merge_request_data.keys).to eq([field])
end
end
end
end
context 'when selecting multiple fields' do
let(:merge_request_fields) { ['title', 'description', 'author { username }'] }
it 'returns the merge request with the specified fields' do
post_graphql(query, current_user: current_user)
expect(merge_request_data.keys).to eq %w[title description author]
expect(merge_request_data['title']).to eq(merge_request.title)
expect(merge_request_data['description']).to eq(merge_request.description)
expect(merge_request_data['author']['username']).to eq(merge_request.author.username)
end
end
context 'when passed a non-merge request gid' do
let(:issue) { create(:issue) }
it 'returns an error' do
gid = issue.to_global_id.to_s
merge_request_params['id'] = gid
post_graphql(query, current_user: current_user)
expect(graphql_errors).not_to be nil
expect(graphql_errors.first['message']).to eq("\"#{gid}\" does not represent an instance of MergeRequest")
end
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