Commit 2dc68a48 authored by Lee Tickett's avatar Lee Tickett

Expose issue contacts via GraphQL

Changelog: added
parent b69d0567
...@@ -47,7 +47,8 @@ module Resolvers ...@@ -47,7 +47,8 @@ module Resolvers
alert_management_alert: [:alert_management_alert], alert_management_alert: [:alert_management_alert],
labels: [:labels], labels: [:labels],
assignees: [:assignees], assignees: [:assignees],
timelogs: [:timelogs] timelogs: [:timelogs],
customer_relations_contacts: { customer_relations_contacts: [:group] }
} }
end end
......
...@@ -136,6 +136,9 @@ module Types ...@@ -136,6 +136,9 @@ module Types
field :project_id, GraphQL::Types::Int, null: false, method: :project_id, field :project_id, GraphQL::Types::Int, null: false, method: :project_id,
description: 'ID of the issue project.' description: 'ID of the issue project.'
field :customer_relations_contacts, Types::CustomerRelations::ContactType.connection_type, null: true,
description: 'Customer relations contacts of the issue.'
def author def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end end
......
...@@ -9778,6 +9778,7 @@ Relationship between an epic and an issue. ...@@ -9778,6 +9778,7 @@ Relationship between an epic and an issue.
| <a id="epicissueconfidential"></a>`confidential` | [`Boolean!`](#boolean) | Indicates the issue is confidential. | | <a id="epicissueconfidential"></a>`confidential` | [`Boolean!`](#boolean) | Indicates the issue is confidential. |
| <a id="epicissuecreatenoteemail"></a>`createNoteEmail` | [`String`](#string) | User specific email address for the issue. | | <a id="epicissuecreatenoteemail"></a>`createNoteEmail` | [`String`](#string) | User specific email address for the issue. |
| <a id="epicissuecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of when the issue was created. | | <a id="epicissuecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of when the issue was created. |
| <a id="epicissuecustomerrelationscontacts"></a>`customerRelationsContacts` | [`CustomerRelationsContactConnection`](#customerrelationscontactconnection) | Customer relations contacts of the issue. (see [Connections](#connections)) |
| <a id="epicissuedescription"></a>`description` | [`String`](#string) | Description of the issue. | | <a id="epicissuedescription"></a>`description` | [`String`](#string) | Description of the issue. |
| <a id="epicissuedescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. | | <a id="epicissuedescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
| <a id="epicissuedesigncollection"></a>`designCollection` | [`DesignCollection`](#designcollection) | Collection of design images associated with this issue. | | <a id="epicissuedesigncollection"></a>`designCollection` | [`DesignCollection`](#designcollection) | Collection of design images associated with this issue. |
...@@ -10941,6 +10942,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount). ...@@ -10941,6 +10942,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
| <a id="issueconfidential"></a>`confidential` | [`Boolean!`](#boolean) | Indicates the issue is confidential. | | <a id="issueconfidential"></a>`confidential` | [`Boolean!`](#boolean) | Indicates the issue is confidential. |
| <a id="issuecreatenoteemail"></a>`createNoteEmail` | [`String`](#string) | User specific email address for the issue. | | <a id="issuecreatenoteemail"></a>`createNoteEmail` | [`String`](#string) | User specific email address for the issue. |
| <a id="issuecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of when the issue was created. | | <a id="issuecreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of when the issue was created. |
| <a id="issuecustomerrelationscontacts"></a>`customerRelationsContacts` | [`CustomerRelationsContactConnection`](#customerrelationscontactconnection) | Customer relations contacts of the issue. (see [Connections](#connections)) |
| <a id="issuedescription"></a>`description` | [`String`](#string) | Description of the issue. | | <a id="issuedescription"></a>`description` | [`String`](#string) | Description of the issue. |
| <a id="issuedescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. | | <a id="issuedescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
| <a id="issuedesigncollection"></a>`designCollection` | [`DesignCollection`](#designcollection) | Collection of design images associated with this issue. | | <a id="issuedesigncollection"></a>`designCollection` | [`DesignCollection`](#designcollection) | Collection of design images associated with this issue. |
......
...@@ -18,7 +18,7 @@ RSpec.describe GitlabSchema.types['Issue'] do ...@@ -18,7 +18,7 @@ RSpec.describe GitlabSchema.types['Issue'] do
confidential hidden discussion_locked upvotes downvotes merge_requests_count user_notes_count user_discussions_count web_path web_url relative_position confidential hidden discussion_locked upvotes downvotes merge_requests_count user_notes_count user_discussions_count web_path web_url relative_position
emails_disabled subscribed time_estimate total_time_spent human_time_estimate human_total_time_spent closed_at created_at updated_at task_completion_status emails_disabled subscribed time_estimate total_time_spent human_time_estimate human_total_time_spent closed_at created_at updated_at task_completion_status
design_collection alert_management_alert severity current_user_todos moved moved_to design_collection alert_management_alert severity current_user_todos moved moved_to
create_note_email timelogs project_id] create_note_email timelogs project_id customer_relations_contacts]
fields.each do |field_name| fields.each do |field_name|
expect(described_class).to have_graphql_field(field_name) expect(described_class).to have_graphql_field(field_name)
......
...@@ -5,7 +5,8 @@ require 'spec_helper' ...@@ -5,7 +5,8 @@ require 'spec_helper'
RSpec.describe 'getting an issue list for a project' do RSpec.describe 'getting an issue list for a project' do
include GraphqlHelpers include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) } let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, :repository, :public, group: group) }
let_it_be(:current_user) { create(:user) } let_it_be(:current_user) { create(:user) }
let_it_be(:issue_a, reload: true) { create(:issue, project: project, discussion_locked: true) } let_it_be(:issue_a, reload: true) { create(:issue, project: project, discussion_locked: true) }
let_it_be(:issue_b, reload: true) { create(:issue, :with_alert, project: project) } let_it_be(:issue_b, reload: true) { create(:issue, :with_alert, project: project) }
...@@ -409,6 +410,35 @@ RSpec.describe 'getting an issue list for a project' do ...@@ -409,6 +410,35 @@ RSpec.describe 'getting an issue list for a project' do
end end
end end
context 'when fetching customer_relations_contacts' do
let(:fields) do
<<~QUERY
nodes {
id
customerRelationsContacts {
nodes {
firstName
}
}
}
QUERY
end
def clean_state_query
run_with_clean_state(query, context: { current_user: current_user })
end
it 'avoids N+1 queries' do
create(:contact, group_id: group.id, issues: [issue_a])
control = ActiveRecord::QueryRecorder.new(skip_cached: false) { clean_state_query }
create(:contact, group_id: group.id, issues: [issue_a])
expect { clean_state_query }.not_to exceed_all_query_limit(control)
end
end
context 'when fetching labels' do context 'when fetching labels' do
let(:fields) do let(:fields) do
<<~QUERY <<~QUERY
......
...@@ -1228,6 +1228,7 @@ ...@@ -1228,6 +1228,7 @@
- "./spec/requests/api/commit_statuses_spec.rb" - "./spec/requests/api/commit_statuses_spec.rb"
- "./spec/requests/api/graphql/ci/runner_spec.rb" - "./spec/requests/api/graphql/ci/runner_spec.rb"
- "./spec/requests/api/graphql/mutations/ci/pipeline_destroy_spec.rb" - "./spec/requests/api/graphql/mutations/ci/pipeline_destroy_spec.rb"
- "./spec/requests/api/graphql/project/issues_spec.rb"
- "./spec/requests/api/graphql/project/merge_request_spec.rb" - "./spec/requests/api/graphql/project/merge_request_spec.rb"
- "./spec/requests/api/graphql/project_query_spec.rb" - "./spec/requests/api/graphql/project_query_spec.rb"
- "./spec/requests/api/issues/issues_spec.rb" - "./spec/requests/api/issues/issues_spec.rb"
......
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