Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-05-19 10:33:21 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-19 10:33:21 +0300
commit36a59d088eca61b834191dacea009677a96c052f (patch)
treee4f33972dab5d8ef79e3944a9f403035fceea43f /spec/graphql/resolvers
parenta1761f15ec2cae7c7f7bbda39a75494add0dfd6f (diff)
Add latest changes from gitlab-org/gitlab@15-0-stable-eev15.0.0-rc42
Diffstat (limited to 'spec/graphql/resolvers')
-rw-r--r--spec/graphql/resolvers/alert_management/alert_resolver_spec.rb4
-rw-r--r--spec/graphql/resolvers/ci/config_resolver_spec.rb7
-rw-r--r--spec/graphql/resolvers/concerns/resolves_ids_spec.rb19
-rw-r--r--spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/design_management/design_resolver_spec.rb13
-rw-r--r--spec/graphql/resolvers/design_management/designs_resolver_spec.rb4
-rw-r--r--spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb9
-rw-r--r--spec/graphql/resolvers/design_management/versions_resolver_spec.rb11
-rw-r--r--spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb50
-rw-r--r--spec/graphql/resolvers/error_tracking/sentry_error_collection_resolver_spec.rb17
-rw-r--r--spec/graphql/resolvers/error_tracking/sentry_errors_resolver_spec.rb31
-rw-r--r--spec/graphql/resolvers/incident_management/timeline_events_resolver_spec.rb70
-rw-r--r--spec/graphql/resolvers/issues_resolver_spec.rb34
-rw-r--r--spec/graphql/resolvers/package_pipelines_resolver_spec.rb147
-rw-r--r--spec/graphql/resolvers/projects/snippets_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/snippets_resolver_spec.rb22
-rw-r--r--spec/graphql/resolvers/timelog_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/users/snippets_resolver_spec.rb10
-rw-r--r--spec/graphql/resolvers/work_item_resolver_spec.rb2
19 files changed, 289 insertions, 171 deletions
diff --git a/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb b/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb
index c042f6dac19..14ebe85d80e 100644
--- a/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb
+++ b/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb
@@ -39,8 +39,8 @@ RSpec.describe Resolvers::AlertManagement::AlertResolver do
end
context 'filtering by domain' do
- let_it_be(:alert1) { create(:alert_management_alert, project: project, monitoring_tool: 'Cilium', domain: :threat_monitoring) }
- let_it_be(:alert2) { create(:alert_management_alert, project: project, monitoring_tool: 'Cilium', domain: :threat_monitoring) }
+ let_it_be(:alert1) { create(:alert_management_alert, project: project, monitoring_tool: 'other', domain: :threat_monitoring) }
+ let_it_be(:alert2) { create(:alert_management_alert, project: project, monitoring_tool: 'other', domain: :threat_monitoring) }
let_it_be(:alert3) { create(:alert_management_alert, project: project, monitoring_tool: 'generic') }
let(:args) { { domain: 'operations' } }
diff --git a/spec/graphql/resolvers/ci/config_resolver_spec.rb b/spec/graphql/resolvers/ci/config_resolver_spec.rb
index 3ff6d8f4347..7a6104fc503 100644
--- a/spec/graphql/resolvers/ci/config_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/config_resolver_spec.rb
@@ -37,13 +37,15 @@ RSpec.describe Resolvers::Ci::ConfigResolver do
merged_yaml: content,
jobs: [],
errors: [],
- warnings: []
+ warnings: [],
+ includes: []
)
end
it 'lints the ci config file and returns the merged yaml file' do
expect(response[:status]).to eq(:valid)
expect(response[:merged_yaml]).to eq(content)
+ expect(response[:includes]).to eq([])
expect(response[:errors]).to be_empty
expect(::Gitlab::Ci::Lint).to have_received(:new).with(current_user: user, project: project, sha: sha)
end
@@ -69,7 +71,8 @@ RSpec.describe Resolvers::Ci::ConfigResolver do
jobs: [],
merged_yaml: content,
errors: ['Invalid configuration format'],
- warnings: []
+ warnings: [],
+ includes: []
)
end
diff --git a/spec/graphql/resolvers/concerns/resolves_ids_spec.rb b/spec/graphql/resolvers/concerns/resolves_ids_spec.rb
index 1dd27c0eff0..84741b7a603 100644
--- a/spec/graphql/resolvers/concerns/resolves_ids_spec.rb
+++ b/spec/graphql/resolvers/concerns/resolves_ids_spec.rb
@@ -3,33 +3,32 @@
require 'spec_helper'
RSpec.describe ResolvesIds do
+ include GraphqlHelpers
+
# gid://gitlab/Project/6
# gid://gitlab/Issue/6
# gid://gitlab/Project/6 gid://gitlab/Issue/6
context 'with a single project' do
- let(:ids) { 'gid://gitlab/Project/6' }
- let(:type) { ::Types::GlobalIDType[::Project] }
+ let(:ids) { global_id_of(model_name: 'Project', id: 6) }
it 'returns the correct array' do
- expect(resolve_ids).to match_array(['6'])
+ expect(resolve_ids).to contain_exactly('6')
end
end
context 'with a single issue' do
- let(:ids) { 'gid://gitlab/Issue/9' }
- let(:type) { ::Types::GlobalIDType[::Issue] }
+ let(:ids) { global_id_of(model_name: 'Issue', id: 9) }
it 'returns the correct array' do
- expect(resolve_ids).to match_array(['9'])
+ expect(resolve_ids).to contain_exactly('9')
end
end
context 'with multiple users' do
- let(:ids) { ['gid://gitlab/User/7', 'gid://gitlab/User/13', 'gid://gitlab/User/21'] }
- let(:type) { ::Types::GlobalIDType[::User] }
+ let(:ids) { [7, 13, 21].map { global_id_of(model_name: 'User', id: _1) } }
it 'returns the correct array' do
- expect(resolve_ids).to match_array(%w[7 13 21])
+ expect(resolve_ids).to eq %w[7 13 21]
end
end
@@ -38,6 +37,6 @@ RSpec.describe ResolvesIds do
end
def resolve_ids
- mock_resolver.resolve_ids(ids, type)
+ mock_resolver.resolve_ids(ids)
end
end
diff --git a/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb b/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
index a16e8821cb5..3fe1ec4b5a4 100644
--- a/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Resolvers::DesignManagement::DesignAtVersionResolver do
let(:current_user) { user }
let(:object) { issue.design_collection }
- let(:global_id) { GitlabSchema.id_from_object(design_at_version).to_s }
+ let(:global_id) { GitlabSchema.id_from_object(design_at_version) }
let(:design_at_version) { ::DesignManagement::DesignAtVersion.new(design: design_a, version: version_a) }
diff --git a/spec/graphql/resolvers/design_management/design_resolver_spec.rb b/spec/graphql/resolvers/design_management/design_resolver_spec.rb
index 4c8b3116875..0915dddf438 100644
--- a/spec/graphql/resolvers/design_management/design_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/design_resolver_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe Resolvers::DesignManagement::DesignResolver do
create(:design, issue: create(:issue, project: project), versions: [create(:design_version)])
end
- let(:args) { { id: GitlabSchema.id_from_object(first_design).to_s } }
+ let(:args) { { id: GitlabSchema.id_from_object(first_design) } }
let(:gql_context) { { current_user: current_user } }
before do
@@ -50,7 +50,7 @@ RSpec.describe Resolvers::DesignManagement::DesignResolver do
end
context 'when both arguments have been passed' do
- let(:args) { { filename: first_design.filename, id: GitlabSchema.id_from_object(first_design).to_s } }
+ let(:args) { { filename: first_design.filename, id: GitlabSchema.id_from_object(first_design) } }
it 'generates an error' do
expect_graphql_error_to_be_created(::Gitlab::Graphql::Errors::ArgumentError, /may/) do
@@ -71,15 +71,6 @@ RSpec.describe Resolvers::DesignManagement::DesignResolver do
expect(resolve_design).to be_nil
end
end
-
- context 'the ID does not belong to a design at all' do
- let(:args) { { id: global_id_of(issue) } }
- let(:msg) { /does not represent an instance of DesignManagement::Design/ }
-
- it 'complains meaningfully' do
- expect { resolve_design }.to raise_error(msg)
- end
- end
end
context 'by filename' do
diff --git a/spec/graphql/resolvers/design_management/designs_resolver_spec.rb b/spec/graphql/resolvers/design_management/designs_resolver_spec.rb
index b091e58b06f..64eae14d888 100644
--- a/spec/graphql/resolvers/design_management/designs_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/designs_resolver_spec.rb
@@ -109,6 +109,8 @@ RSpec.describe Resolvers::DesignManagement::DesignsResolver do
end
def resolve_designs
- resolve(described_class, obj: issue.design_collection, args: args, ctx: gql_context)
+ Gitlab::Graphql::Lazy.force(
+ resolve(described_class, obj: issue.design_collection, args: args, ctx: gql_context)
+ )
end
end
diff --git a/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb b/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb
index 8b9874c3580..00f37a8e5f6 100644
--- a/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb
@@ -50,15 +50,6 @@ RSpec.describe Resolvers::DesignManagement::VersionInCollectionResolver do
it { is_expected.to be_nil }
end
-
- context 'we pass the id of something that is not a design_version' do
- let(:params) { { id: global_id_of(project) } }
- let(:appropriate_error) { ::GraphQL::CoercionError }
-
- it 'raises an appropriate error' do
- expect { result }.to raise_error(appropriate_error)
- end
- end
end
def resolve_version(obj, context = { current_user: current_user })
diff --git a/spec/graphql/resolvers/design_management/versions_resolver_spec.rb b/spec/graphql/resolvers/design_management/versions_resolver_spec.rb
index d98138f6385..8eab0222cf6 100644
--- a/spec/graphql/resolvers/design_management/versions_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/versions_resolver_spec.rb
@@ -18,8 +18,7 @@ RSpec.describe Resolvers::DesignManagement::VersionsResolver do
let(:project) { issue.project }
let(:params) { {} }
let(:current_user) { authorized_user }
- let(:parent_args) { { irrelevant: 1.2 } }
- let(:parent) { double('Parent', parent: nil, irep_node: double(arguments: parent_args)) }
+ let(:query_context) { { current_user: current_user } }
before do
enable_design_management
@@ -107,7 +106,9 @@ RSpec.describe Resolvers::DesignManagement::VersionsResolver do
end
context 'by at_version in parent' do
- let(:parent_args) { { atVersion: global_id_of(first_version) } }
+ before do
+ query_context[:at_version_argument] = first_version.to_global_id
+ end
it_behaves_like 'a query for all_versions up to the first_version'
end
@@ -126,8 +127,8 @@ RSpec.describe Resolvers::DesignManagement::VersionsResolver do
it_behaves_like 'a source of versions'
end
- def resolve_versions(obj, context = { current_user: current_user })
- eager_resolve(resolver, obj: obj, parent: parent, args: params, ctx: context)
+ def resolve_versions(obj)
+ eager_resolve(resolver, obj: obj, args: params, ctx: query_context)
end
end
end
diff --git a/spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb b/spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb
index 2aef483ac95..f80b33e644e 100644
--- a/spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb
+++ b/spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb
@@ -8,28 +8,23 @@ RSpec.describe Resolvers::ErrorTracking::SentryDetailedErrorResolver do
let_it_be(:project) { create(:project) }
let_it_be(:current_user) { create(:user) }
- let(:issue_details_service) { spy('ErrorTracking::IssueDetailsService') }
+ let(:issue_details_service) { instance_double('ErrorTracking::IssueDetailsService') }
+ let(:service_response) { {} }
- specify do
- expect(described_class).to have_nullable_graphql_type(Types::ErrorTracking::SentryDetailedErrorType)
+ before_all do
+ project.add_developer(current_user)
end
before do
- project.add_developer(current_user)
-
allow(ErrorTracking::IssueDetailsService)
.to receive(:new)
- .and_return issue_details_service
- end
+ .and_return(issue_details_service)
- shared_examples 'it resolves to nil' do
- it 'resolves to nil' do
- allow(issue_details_service).to receive(:execute)
- .and_return(issue: nil)
+ allow(issue_details_service).to receive(:execute).and_return(service_response)
+ end
- result = resolve_error(args)
- expect(result).to be_nil
- end
+ specify do
+ expect(described_class).to have_nullable_graphql_type(Types::ErrorTracking::SentryDetailedErrorType)
end
describe '#resolve' do
@@ -41,13 +36,9 @@ RSpec.describe Resolvers::ErrorTracking::SentryDetailedErrorResolver do
expect(issue_details_service).to have_received(:execute)
end
- context 'error matched' do
- let(:detailed_error) { build(:error_tracking_sentry_detailed_error) }
-
- before do
- allow(issue_details_service).to receive(:execute)
- .and_return(issue: detailed_error)
- end
+ context 'when error matches' do
+ let(:detailed_error) { build_stubbed(:error_tracking_sentry_detailed_error) }
+ let(:service_response) { { issue: detailed_error } }
it 'resolves to a detailed error' do
expect(resolve_error(args)).to eq detailed_error
@@ -58,24 +49,23 @@ RSpec.describe Resolvers::ErrorTracking::SentryDetailedErrorResolver do
end
end
- context 'if id does not match issue' do
- it_behaves_like 'it resolves to nil'
- end
-
- context 'blank id' do
- let(:args) { { id: '' } }
+ context 'when id does not match issue' do
+ let(:service_response) { { issue: nil } }
- it 'responds with an error' do
- expect { resolve_error(args) }.to raise_error(::GraphQL::CoercionError)
+ it 'resolves to nil' do
+ result = resolve_error(args)
+ expect(result).to be_nil
end
end
end
+ private
+
def resolve_error(args = {}, context = { current_user: current_user })
resolve(described_class, obj: project, args: args, ctx: context)
end
def issue_global_id(issue_id)
- Gitlab::ErrorTracking::DetailedError.new(id: issue_id).to_global_id.to_s
+ Gitlab::ErrorTracking::DetailedError.new(id: issue_id).to_global_id
end
end
diff --git a/spec/graphql/resolvers/error_tracking/sentry_error_collection_resolver_spec.rb b/spec/graphql/resolvers/error_tracking/sentry_error_collection_resolver_spec.rb
index 20c2bdcd4e1..5834faea97e 100644
--- a/spec/graphql/resolvers/error_tracking/sentry_error_collection_resolver_spec.rb
+++ b/spec/graphql/resolvers/error_tracking/sentry_error_collection_resolver_spec.rb
@@ -8,18 +8,22 @@ RSpec.describe Resolvers::ErrorTracking::SentryErrorCollectionResolver do
let_it_be(:project) { create(:project) }
let_it_be(:current_user) { create(:user) }
- let(:list_issues_service) { spy('ErrorTracking::ListIssuesService') }
+ let(:list_issues_service) { instance_double('ErrorTracking::ListIssuesService') }
- specify do
- expect(described_class).to have_nullable_graphql_type(Types::ErrorTracking::SentryErrorCollectionType)
+ before_all do
+ project.add_developer(current_user)
end
before do
- project.add_developer(current_user)
-
allow(ErrorTracking::ListIssuesService)
.to receive(:new)
.and_return list_issues_service
+
+ allow(list_issues_service).to receive(:external_url)
+ end
+
+ specify do
+ expect(described_class).to have_nullable_graphql_type(Types::ErrorTracking::SentryErrorCollectionType)
end
describe '#resolve' do
@@ -34,8 +38,7 @@ RSpec.describe Resolvers::ErrorTracking::SentryErrorCollectionResolver do
.to receive(:external_url)
.and_return(fake_url)
- result = resolve_error_collection
- expect(result.external_url).to eq fake_url
+ expect(resolve_error_collection.external_url).to eq fake_url
end
it 'provides the project' do
diff --git a/spec/graphql/resolvers/error_tracking/sentry_errors_resolver_spec.rb b/spec/graphql/resolvers/error_tracking/sentry_errors_resolver_spec.rb
index 68badb8e333..65b6c551dde 100644
--- a/spec/graphql/resolvers/error_tracking/sentry_errors_resolver_spec.rb
+++ b/spec/graphql/resolvers/error_tracking/sentry_errors_resolver_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Resolvers::ErrorTracking::SentryErrorsResolver do
let_it_be(:current_user) { create(:user) }
let_it_be(:error_collection) { Gitlab::ErrorTracking::ErrorCollection.new(project: project) }
- let(:list_issues_service) { spy('ErrorTracking::ListIssuesService') }
+ let(:list_issues_service) { instance_double('ErrorTracking::ListIssuesService') }
let(:issues) { nil }
let(:pagination) { nil }
@@ -19,23 +19,25 @@ RSpec.describe Resolvers::ErrorTracking::SentryErrorsResolver do
end
describe '#resolve' do
+ before do
+ allow(ErrorTracking::ListIssuesService)
+ .to receive(:new)
+ .and_return list_issues_service
+
+ allow(list_issues_service).to receive(:execute).and_return({})
+ end
+
context 'with insufficient user permission' do
- let(:user) { create(:user) }
+ let(:current_user) { create(:user) }
it 'returns nil' do
- context = { current_user: user }
-
- expect(resolve_errors({}, context)).to eq nil
+ expect(resolve_errors).to eq nil
end
end
context 'with sufficient permission' do
- before do
+ before_all do
project.add_developer(current_user)
-
- allow(ErrorTracking::ListIssuesService)
- .to receive(:new)
- .and_return list_issues_service
end
context 'when after arg given' do
@@ -52,14 +54,9 @@ RSpec.describe Resolvers::ErrorTracking::SentryErrorsResolver do
end
context 'when no issues fetched' do
- before do
- allow(list_issues_service)
- .to receive(:execute)
- .and_return(
- issues: nil
- )
- end
it 'returns nil' do
+ expect(list_issues_service).to receive(:execute).and_return(issues: nil)
+
expect(resolve_errors).to eq nil
end
end
diff --git a/spec/graphql/resolvers/incident_management/timeline_events_resolver_spec.rb b/spec/graphql/resolvers/incident_management/timeline_events_resolver_spec.rb
new file mode 100644
index 00000000000..046cf242d56
--- /dev/null
+++ b/spec/graphql/resolvers/incident_management/timeline_events_resolver_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::IncidentManagement::TimelineEventsResolver do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:incident) { create(:incident, project: project) }
+ let_it_be(:first_timeline_event) do
+ create(:incident_management_timeline_event, project: project, incident: incident)
+ end
+
+ let_it_be(:second_timeline_event) do
+ create(:incident_management_timeline_event, project: project, incident: incident)
+ end
+
+ let(:args) { { incident_id: incident.to_global_id } }
+ let(:resolver) { described_class }
+
+ subject(:resolved_timeline_events) { sync(resolve_timeline_events(args, current_user: current_user).to_a) }
+
+ before do
+ project.add_guest(current_user)
+ end
+
+ specify do
+ expect(resolver).to have_nullable_graphql_type(Types::IncidentManagement::TimelineEventType.connection_type)
+ end
+
+ it 'returns timeline events', :aggregate_failures do
+ expect(resolved_timeline_events.length).to eq(2)
+ expect(resolved_timeline_events.first).to be_a(::IncidentManagement::TimelineEvent)
+ end
+
+ context 'when user does not have permissions' do
+ let(:non_member) { create(:user) }
+
+ subject(:resolved_timeline_events) { sync(resolve_timeline_events(args, current_user: non_member).to_a) }
+
+ before do
+ project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE)
+ end
+
+ it 'returns no timeline events' do
+ expect(resolved_timeline_events.length).to eq(0)
+ end
+ end
+
+ context 'when resolving a single item' do
+ let(:resolver) { described_class.single }
+
+ subject(:resolved_timeline_event) { sync(resolve_timeline_events(args, current_user: current_user)) }
+
+ context 'when id given' do
+ let(:args) { { incident_id: incident.to_global_id, id: first_timeline_event.to_global_id } }
+
+ it 'returns the timeline event' do
+ expect(resolved_timeline_event).to eq(first_timeline_event)
+ end
+ end
+ end
+
+ private
+
+ def resolve_timeline_events(args = {}, context = { current_user: current_user })
+ resolve(resolver, obj: incident, args: args, ctx: context)
+ end
+end
diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb
index 81aeee0a3d2..e6ec9d8c895 100644
--- a/spec/graphql/resolvers/issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/issues_resolver_spec.rb
@@ -389,6 +389,34 @@ RSpec.describe Resolvers::IssuesResolver do
end
end
+ describe 'filtering by crm' do
+ let_it_be(:organization) { create(:organization, group: group) }
+ let_it_be(:contact1) { create(:contact, group: group, organization: organization) }
+ let_it_be(:contact2) { create(:contact, group: group, organization: organization) }
+ let_it_be(:contact3) { create(:contact, group: group) }
+ let_it_be(:crm_issue1) { create(:issue, project: project) }
+ let_it_be(:crm_issue2) { create(:issue, project: project) }
+ let_it_be(:crm_issue3) { create(:issue, project: project) }
+
+ before_all do
+ create(:issue_customer_relations_contact, issue: crm_issue1, contact: contact1)
+ create(:issue_customer_relations_contact, issue: crm_issue2, contact: contact2)
+ create(:issue_customer_relations_contact, issue: crm_issue3, contact: contact3)
+ end
+
+ context 'contact' do
+ it 'returns only the issues for the contact' do
+ expect(resolve_issues({ crm_contact_id: contact1.id })).to contain_exactly(crm_issue1)
+ end
+ end
+
+ context 'organization' do
+ it 'returns only the issues for the contact' do
+ expect(resolve_issues({ crm_organization_id: organization.id })).to contain_exactly(crm_issue1, crm_issue2)
+ end
+ end
+ end
+
describe 'sorting' do
context 'when sorting by created' do
it 'sorts issues ascending' do
@@ -603,13 +631,13 @@ RSpec.describe Resolvers::IssuesResolver do
end
it 'finds a specific issue with iid', :request_store do
- result = batch_sync(max_queries: 6) { resolve_issues(iid: issue1.iid).to_a }
+ result = batch_sync(max_queries: 7) { resolve_issues(iid: issue1.iid).to_a }
expect(result).to contain_exactly(issue1)
end
it 'batches queries that only include IIDs', :request_store do
- result = batch_sync(max_queries: 6) do
+ result = batch_sync(max_queries: 7) do
[issue1, issue2]
.map { |issue| resolve_issues(iid: issue.iid.to_s) }
.flat_map(&:to_a)
@@ -619,7 +647,7 @@ RSpec.describe Resolvers::IssuesResolver do
end
it 'finds a specific issue with iids', :request_store do
- result = batch_sync(max_queries: 6) do
+ result = batch_sync(max_queries: 7) do
resolve_issues(iids: [issue1.iid]).to_a
end
diff --git a/spec/graphql/resolvers/package_pipelines_resolver_spec.rb b/spec/graphql/resolvers/package_pipelines_resolver_spec.rb
index c757c876616..a52dee59bc6 100644
--- a/spec/graphql/resolvers/package_pipelines_resolver_spec.rb
+++ b/spec/graphql/resolvers/package_pipelines_resolver_spec.rb
@@ -9,10 +9,23 @@ RSpec.describe Resolvers::PackagePipelinesResolver do
let_it_be(:pipelines) { create_list(:ci_pipeline, 3, project: package.project) }
let(:user) { package.project.first_owner }
- let(:args) { {} }
describe '#resolve' do
- subject { resolve(described_class, obj: package, args: args, ctx: { current_user: user }) }
+ let(:returned_pipelines) { graphql_dig_at(subject, 'data', 'package', 'pipelines', 'nodes') }
+ let(:returned_errors) { graphql_dig_at(subject, 'errors', 'message') }
+ let(:pagination_args) { {} }
+ let(:query) do
+ pipelines_nodes = 'nodes { id }'
+ graphql_query_for(
+ :package,
+ { id: global_id_of(package) },
+ query_graphql_field('pipelines', pagination_args, pipelines_nodes)
+ )
+ end
+
+ subject do
+ GitlabSchema.execute(query, context: { current_user: user })
+ end
before do
pipelines.each do |pipeline|
@@ -20,67 +33,115 @@ RSpec.describe Resolvers::PackagePipelinesResolver do
end
end
- it { is_expected.to contain_exactly(*pipelines) }
+ it 'contains the expected pipelines' do
+ expect_to_contain_exactly(*pipelines)
+ end
+
+ context 'with valid after' do
+ let(:pagination_args) { { first: 1, after: encode_cursor(id: pipelines[1].id) } }
+
+ it 'contains the expected pipelines' do
+ expect_to_contain_exactly(pipelines[0])
+ end
+ end
+
+ context 'with valid before' do
+ let(:pagination_args) { { last: 1, before: encode_cursor(id: pipelines[1].id) } }
+
+ it 'contains the expected pipelines' do
+ expect_to_contain_exactly(pipelines[2])
+ end
+ end
context 'with invalid after' do
- let(:args) { { first: 1, after: 'not_json_string' } }
+ let(:pagination_args) { { first: 1, after: 'not_json_string' } }
it 'generates an argument error' do
- expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
- subject
- end
+ expect(returned_errors).to include('Please provide a valid cursor')
end
end
context 'with invalid after key' do
- let(:args) { { first: 1, after: encode_cursor(foo: 3) } }
+ let(:pagination_args) { { first: 1, after: encode_cursor(foo: 3) } }
it 'generates an argument error' do
- expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
- subject
- end
+ expect(returned_errors).to include('Please provide a valid cursor')
end
end
context 'with invalid before' do
- let(:args) { { last: 1, before: 'not_json_string' } }
+ let(:pagination_args) { { last: 1, before: 'not_json_string' } }
it 'generates an argument error' do
- expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
- subject
- end
+ expect(returned_errors).to include('Please provide a valid cursor')
end
end
context 'with invalid before key' do
- let(:args) { { last: 1, before: encode_cursor(foo: 3) } }
+ let(:pagination_args) { { last: 1, before: encode_cursor(foo: 3) } }
it 'generates an argument error' do
- expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
- subject
- end
+ expect(returned_errors).to include('Please provide a valid cursor')
end
end
- context 'field options' do
- let(:field) do
- field_options = described_class.field_options.merge(
- owner: resolver_parent,
- name: 'dummy_field'
- )
- ::Types::BaseField.new(**field_options)
- end
+ context 'with unauthorized user' do
+ let_it_be(:user) { create(:user) }
- it 'sets them properly' do
- expect(field).not_to be_connection
- expect(field.extras).to match_array([:lookahead])
+ it 'returns nothing' do
+ expect(returned_pipelines).to be_nil
end
end
- context 'with unauthorized user' do
- let_it_be(:user) { create(:user) }
+ context 'with many packages' do
+ let_it_be_with_reload(:other_package) { create(:package, project: package.project) }
+ let_it_be(:other_pipelines) { create_list(:ci_pipeline, 3, project: package.project) }
+
+ let(:returned_pipelines) do
+ graphql_dig_at(subject, 'data', 'project', 'packages', 'nodes', 'pipelines', 'nodes')
+ end
- it { is_expected.to be_nil }
+ let(:query) do
+ pipelines_query = query_graphql_field('pipelines', pagination_args, 'nodes { id }')
+ <<~QUERY
+ {
+ project(fullPath: "#{package.project.full_path}") {
+ packages {
+ nodes { #{pipelines_query} }
+ }
+ }
+ }
+ QUERY
+ end
+
+ before do
+ other_pipelines.each do |pipeline|
+ create(:package_build_info, package: other_package, pipeline: pipeline)
+ end
+ end
+
+ it 'contains the expected pipelines' do
+ expect_to_contain_exactly(*(pipelines + other_pipelines))
+ end
+
+ it 'handles n+1 situations' do
+ control = ActiveRecord::QueryRecorder.new do
+ GitlabSchema.execute(query, context: { current_user: user })
+ end
+
+ create_package_with_pipelines(package.project)
+
+ expectation = expect { GitlabSchema.execute(query, context: { current_user: user }) }
+
+ expectation.not_to exceed_query_limit(control)
+ end
+
+ def create_package_with_pipelines(project)
+ extra_package = create(:package, project: project)
+ create_list(:ci_pipeline, 3, project: project).each do |pipeline|
+ create(:package_build_info, package: extra_package, pipeline: pipeline)
+ end
+ end
end
def encode_cursor(json)
@@ -89,5 +150,25 @@ RSpec.describe Resolvers::PackagePipelinesResolver do
nonce: true
)
end
+
+ def expect_to_contain_exactly(*pipelines)
+ entities = pipelines.map { |pipeline| a_graphql_entity_for(pipeline) }
+ expect(returned_pipelines).to match_array(entities)
+ end
+ end
+
+ describe '.field options' do
+ let(:field) do
+ field_options = described_class.field_options.merge(
+ owner: resolver_parent,
+ name: 'dummy_field'
+ )
+ ::Types::BaseField.new(**field_options)
+ end
+
+ it 'sets them properly' do
+ expect(field).not_to be_connection
+ expect(field.extras).to match_array([:lookahead])
+ end
end
end
diff --git a/spec/graphql/resolvers/projects/snippets_resolver_spec.rb b/spec/graphql/resolvers/projects/snippets_resolver_spec.rb
index b963f2509db..1d04db3ea6e 100644
--- a/spec/graphql/resolvers/projects/snippets_resolver_spec.rb
+++ b/spec/graphql/resolvers/projects/snippets_resolver_spec.rb
@@ -58,12 +58,6 @@ RSpec.describe Resolvers::Projects::SnippetsResolver do
expect(snippets).to contain_exactly(project_snippet, other_project_snippet)
end
-
- it 'returns an error if the gid is invalid' do
- expect do
- resolve_snippets(args: { ids: ['foo'] })
- end.to raise_error(GraphQL::CoercionError)
- end
end
context 'when no project is provided' do
diff --git a/spec/graphql/resolvers/snippets_resolver_spec.rb b/spec/graphql/resolvers/snippets_resolver_spec.rb
index f9feb8901cd..ee9a6e67243 100644
--- a/spec/graphql/resolvers/snippets_resolver_spec.rb
+++ b/spec/graphql/resolvers/snippets_resolver_spec.rb
@@ -40,12 +40,6 @@ RSpec.describe Resolvers::SnippetsResolver do
expect(snippets).to contain_exactly(personal_snippet, project_snippet)
end
-
- it 'returns an error if the param id is invalid' do
- expect do
- resolve_snippets(args: { author_id: 'foo' })
- end.to raise_error(GraphQL::CoercionError)
- end
end
it 'returns the snippets by type' do
@@ -61,12 +55,6 @@ RSpec.describe Resolvers::SnippetsResolver do
expect(snippets).to contain_exactly(project_snippet, other_project_snippet)
end
-
- it 'returns an error if the param id is invalid' do
- expect do
- resolve_snippets(args: { project_id: 'foo' })
- end.to raise_error(GraphQL::CoercionError)
- end
end
it 'returns the snippets by visibility' do
@@ -98,16 +86,6 @@ RSpec.describe Resolvers::SnippetsResolver do
expect(found).to match_array(snippets)
end
- it 'returns an error if the id cannot be coerced' do
- args = {
- ids: [personal_snippet.to_global_id, 'foo']
- }
-
- expect do
- resolve_snippets(args: args)
- end.to raise_error(GraphQL::CoercionError, '"foo" is not a valid Global ID')
- end
-
it 'generates an error if both project and author are provided' do
expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
args = {
diff --git a/spec/graphql/resolvers/timelog_resolver_spec.rb b/spec/graphql/resolvers/timelog_resolver_spec.rb
index 84fa2932829..da2747fdf72 100644
--- a/spec/graphql/resolvers/timelog_resolver_spec.rb
+++ b/spec/graphql/resolvers/timelog_resolver_spec.rb
@@ -265,7 +265,7 @@ RSpec.describe Resolvers::TimelogResolver do
context 'when > `default_max_page_size` records' do
let(:object) { nil }
let!(:timelog_list) { create_list(:timelog, 101, issue: issue) }
- let(:args) { { project_id: "gid://gitlab/Project/#{project.id}" } }
+ let(:args) { { project_id: global_id_of(project) } }
let(:extra_args) { {} }
it 'pagination returns `default_max_page_size` and sets `has_next_page` true' do
diff --git a/spec/graphql/resolvers/users/snippets_resolver_spec.rb b/spec/graphql/resolvers/users/snippets_resolver_spec.rb
index 04fe3213a99..12baed2560e 100644
--- a/spec/graphql/resolvers/users/snippets_resolver_spec.rb
+++ b/spec/graphql/resolvers/users/snippets_resolver_spec.rb
@@ -64,16 +64,6 @@ RSpec.describe Resolvers::Users::SnippetsResolver do
expect(found).to match_array(snippets)
end
-
- it 'returns an error if the gid is invalid' do
- args = {
- ids: [global_id_of(private_personal_snippet), 'foo']
- }
-
- expect do
- resolve_snippets(args: args)
- end.to raise_error(GraphQL::CoercionError)
- end
end
context 'when user profile is private' do
diff --git a/spec/graphql/resolvers/work_item_resolver_spec.rb b/spec/graphql/resolvers/work_item_resolver_spec.rb
index bfa0cf1d8a2..c44ed395102 100644
--- a/spec/graphql/resolvers/work_item_resolver_spec.rb
+++ b/spec/graphql/resolvers/work_item_resolver_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Resolvers::WorkItemResolver do
let(:current_user) { developer }
- subject(:resolved_work_item) { resolve_work_item('id' => work_item.to_gid.to_s) }
+ subject(:resolved_work_item) { resolve_work_item('id' => work_item.to_gid) }
context 'when the user can read the work item' do
it { is_expected.to eq(work_item) }