diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-19 15:57:54 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-10-19 15:57:54 +0300 |
commit | 419c53ec62de6e97a517abd5fdd4cbde3a942a34 (patch) | |
tree | 1f43a548b46bca8a5fb8fe0c31cef1883d49c5b6 /spec/graphql | |
parent | 1da20d9135b3ad9e75e65b028bffc921aaf8deb7 (diff) |
Add latest changes from gitlab-org/gitlab@16-5-stable-eev16.5.0-rc42
Diffstat (limited to 'spec/graphql')
71 files changed, 605 insertions, 453 deletions
diff --git a/spec/graphql/features/authorization_spec.rb b/spec/graphql/features/authorization_spec.rb index 4f8ae92ff99..d3a7df8cb00 100644 --- a/spec/graphql/features/authorization_spec.rb +++ b/spec/graphql/features/authorization_spec.rb @@ -386,7 +386,7 @@ RSpec.describe 'DeclarativePolicy authorization in GraphQL ' do issues = Issue.where(project: [visible_project, other_project]).order(id: :asc) type_factory do |type| type.graphql_name 'FakeProjectType' - type.field :test_issues, issue_type.connection_type, + type.field :test_issues, field_type, null: false, resolver: new_resolver(issues) end @@ -398,32 +398,52 @@ RSpec.describe 'DeclarativePolicy authorization in GraphQL ' do end end - let(:query_string) do - <<~QRY - { testProject { testIssues(first: 3) { edges { node { id } } } } } - QRY - end - before do allow(Ability).to receive(:allowed?).and_call_original end - it 'renders the issues the user has access to' do - issue_edges = result.dig('data', 'testProject', 'testIssues', 'edges') - issue_ids = issue_edges.map { |issue_edge| issue_edge['node']&.fetch('id') } + context 'for connection field type' do + let(:field_type) { issue_type.connection_type } + + let(:query_string) do + <<~QRY + { testProject { testIssues(first: 3) { edges { node { id } } } } } + QRY + end + + it 'renders the issues the user has access to' do + issue_edges = result.dig('data', 'testProject', 'testIssues', 'edges') + issue_ids = issue_edges.map { |issue_edge| issue_edge['node']&.fetch('id') } + + expect(issue_edges.size).to eq(visible_issues.size) + expect(issue_ids).to eq(visible_issues.map { |i| i.to_global_id.to_s }) + end + + it 'does not check access on fields that will not be rendered' do + expect(Ability).not_to receive(:allowed?).with(user, :read_issue, other_issues.last) - expect(issue_edges.size).to eq(visible_issues.size) - expect(issue_ids).to eq(visible_issues.map { |i| i.to_global_id.to_s }) + result + end end - it 'does not check access on fields that will not be rendered' do - expect(Ability).not_to receive(:allowed?).with(user, :read_issue, other_issues.last) + context 'for list field type' do + let(:field_type) { [issue_type] } - result + let(:query_string) do + <<~QRY + { testProject { testIssues { id } } } + QRY + end + + it 'renders the issues the user has access to' do + issue_ids = result.dig('data', 'testProject', 'testIssues').pluck('id') + + expect(issue_ids).to eq(visible_issues.map { |i| i.to_global_id.to_s }) + end end end - describe 'Authorization on GraphQL::Execution::Execute::SKIP' do + describe 'Authorization on GraphQL::Execution::SKIP' do let(:type) do type_factory do |type| type.authorize permission_single @@ -432,7 +452,7 @@ RSpec.describe 'DeclarativePolicy authorization in GraphQL ' do let(:query_type) do query_factory do |query| - query.field :item, [type], null: true, resolver: new_resolver(GraphQL::Execution::Execute::SKIP) + query.field :item, [type], null: true, resolver: new_resolver(GraphQL::Execution::SKIP) end end diff --git a/spec/graphql/mutations/alert_management/update_alert_status_spec.rb b/spec/graphql/mutations/alert_management/update_alert_status_spec.rb index fb11ec7065b..8e1b2d90117 100644 --- a/spec/graphql/mutations/alert_management/update_alert_status_spec.rb +++ b/spec/graphql/mutations/alert_management/update_alert_status_spec.rb @@ -52,7 +52,7 @@ RSpec.describe Mutations::AlertManagement::UpdateAlertStatus do allow(alert).to receive(:save).and_return(false) allow(alert).to receive(:errors).and_return( - double(full_messages: %w(foo bar), :[] => nil) + double(full_messages: %w[foo bar], :[] => nil) ) expect(resolve).to eq( alert: alert, diff --git a/spec/graphql/mutations/ci/runner/update_spec.rb b/spec/graphql/mutations/ci/runner/update_spec.rb index 50351321be8..02bb7ee2170 100644 --- a/spec/graphql/mutations/ci/runner/update_spec.rb +++ b/spec/graphql/mutations/ci/runner/update_spec.rb @@ -69,7 +69,7 @@ RSpec.describe Mutations::Ci::Runner::Update, feature_category: :runner_fleet do active: false, locked: true, run_untagged: false, - tag_list: %w(tag1 tag2) + tag_list: %w[tag1 tag2] } end diff --git a/spec/graphql/mutations/commits/create_spec.rb b/spec/graphql/mutations/commits/create_spec.rb index 2c452410cca..8cfd27485e6 100644 --- a/spec/graphql/mutations/commits/create_spec.rb +++ b/spec/graphql/mutations/commits/create_spec.rb @@ -67,7 +67,7 @@ RSpec.describe Mutations::Commits::Create do context 'when service successfully creates a new commit' do it "returns the ETag path for the commit's pipeline" do commit_pipeline_path = subject[:commit_pipeline_path] - expect(commit_pipeline_path).to match(%r(pipelines/sha/\w+)) + expect(commit_pipeline_path).to match(%r{pipelines/sha/\w+}) end it 'returns the content of the commit' do diff --git a/spec/graphql/mutations/container_repositories/destroy_spec.rb b/spec/graphql/mutations/container_repositories/destroy_spec.rb index 85e0ac96e55..b49751985ec 100644 --- a/spec/graphql/mutations/container_repositories/destroy_spec.rb +++ b/spec/graphql/mutations/container_repositories/destroy_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Mutations::ContainerRepositories::Destroy do +RSpec.describe Mutations::ContainerRepositories::Destroy, feature_category: :container_registry do using RSpec::Parameterized::TableSyntax let_it_be_with_reload(:container_repository) { create(:container_repository) } @@ -23,7 +23,6 @@ RSpec.describe Mutations::ContainerRepositories::Destroy do it 'marks the repository as delete_scheduled' do expect(::Packages::CreateEventService) .to receive(:new).with(nil, user, event_name: :delete_repository, scope: :container).and_call_original - expect(DeleteContainerRepositoryWorker).not_to receive(:perform_async) subject expect(container_repository.reload.delete_scheduled?).to be true @@ -32,9 +31,6 @@ RSpec.describe Mutations::ContainerRepositories::Destroy do shared_examples 'denying access to container respository' do it 'raises an error' do - expect(DeleteContainerRepositoryWorker) - .not_to receive(:perform_async).with(user.id, container_repository.id) - expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable) end end diff --git a/spec/graphql/mutations/design_management/delete_spec.rb b/spec/graphql/mutations/design_management/delete_spec.rb index 9a2efb61e55..1b78529fbc7 100644 --- a/spec/graphql/mutations/design_management/delete_spec.rb +++ b/spec/graphql/mutations/design_management/delete_spec.rb @@ -90,7 +90,7 @@ RSpec.describe Mutations::DesignManagement::Delete do allow(Gitlab::Tracking).to receive(:event) # rubocop:disable RSpec/ExpectGitlabTracking filenames.each(&:present?) # ignore setup - # Queries: as of 2022-08-30 + # Queries: as of 2022-09-08 # ------------- # 01. routing query # 02. policy query: find namespace by type and id @@ -101,30 +101,31 @@ RSpec.describe Mutations::DesignManagement::Delete do # 08. find project by id # 09. find namespace by id # 10. find group namespace by id - # 11. project.authorizations for user (same query as 5) - # 12. find user by id - # 13. project.project_features (same query as 3) - # 14. project.authorizations for user (same query as 5) - # 15. current designs by filename and issue - # 16, 17 project.authorizations for user (same query as 5) - # 18. find design_management_repository for project - # 19. find route by id and source_type + # 11. policy query: find namespace by id (same query as 3) + # 12. project.authorizations for user (same query as 5) + # 13. find user by id + # 14. project.project_features (same query as 3) + # 15. project.authorizations for user (same query as 5) + # 16. current designs by filename and issue + # 17, 18 project.authorizations for user (same query as 5) + # 19. find design_management_repository for project + # 20. find route by id and source_type # ------------- our queries are below: - # 20. start transaction - # 21. create version with sha and issue - # 22. create design-version links - # 23. validate version.actions.present? - # 24. validate version.sha is unique - # 25. validate version.issue.present? - # 26. leave transaction - # 27. find project by id (same query as 8) - # 28. find namespace by id (same query as 9) - # 29. find project by id (same query as 8) + # 21. start transaction + # 22. create version with sha and issue + # 23. create design-version links + # 24. validate version.actions.present? + # 25. validate version.sha is unique + # 26. validate version.issue.present? + # 27. leave transaction + # 28. find project by id (same query as 8) + # 29. find namespace by id (same query as 9) # 30. find project by id (same query as 8) - # 31. create event - # 32. find plan for standard context + # 31. find project by id (same query as 8) + # 32. create event + # 33. find plan for standard context # - expect { run_mutation }.not_to exceed_query_limit(32) + expect { run_mutation }.not_to exceed_query_limit(33) end end diff --git a/spec/graphql/mutations/issues/set_assignees_spec.rb b/spec/graphql/mutations/issues/set_assignees_spec.rb index 4cc49e76bc6..9dc152872a6 100644 --- a/spec/graphql/mutations/issues/set_assignees_spec.rb +++ b/spec/graphql/mutations/issues/set_assignees_spec.rb @@ -12,10 +12,12 @@ RSpec.describe Mutations::Issues::SetAssignees do describe '#resolve' do subject do - mutation.resolve(project_path: issue.project.full_path, - iid: issue.iid, - operation_mode: Types::MutationOperationModeEnum.default_mode, - assignee_usernames: [assignee.username]) + mutation.resolve( + project_path: issue.project.full_path, + iid: issue.iid, + operation_mode: Types::MutationOperationModeEnum.default_mode, + assignee_usernames: [assignee.username] + ) end it_behaves_like 'permission level for issue mutation is correctly verified' diff --git a/spec/graphql/mutations/merge_requests/accept_spec.rb b/spec/graphql/mutations/merge_requests/accept_spec.rb index c99b1d988c5..b0d2a9e9c22 100644 --- a/spec/graphql/mutations/merge_requests/accept_spec.rb +++ b/spec/graphql/mutations/merge_requests/accept_spec.rb @@ -28,7 +28,7 @@ RSpec.describe Mutations::MergeRequests::Accept do project.add_maintainer(user) end - def common_args(merge_request) + let(:common_args) do { project_path: project.full_path, iid: merge_request.iid.to_s, @@ -37,136 +37,69 @@ RSpec.describe Mutations::MergeRequests::Accept do } end - it 'merges the merge request' do - merge_request = create(:merge_request, source_project: project) + let(:args) { common_args.merge(additional_args) } + let(:additional_args) { {} } + let(:result) { mutation.resolve(**args) } + let!(:merge_request) { create(:merge_request, source_project: project) } - result = mutation.resolve(**common_args(merge_request)) - - expect(result).to include(errors: be_empty, merge_request: be_merged) - end - - it 'rejects the mutation if the SHA is a mismatch' do - merge_request = create(:merge_request, source_project: project) - args = common_args(merge_request).merge(sha: 'not a good sha') - - result = mutation.resolve(**args) - - expect(result).not_to include(merge_request: be_merged) - expect(result).to include(errors: [described_class::SHA_MISMATCH]) - end - - it 'respects the merge commit message' do - merge_request = create(:merge_request, source_project: project) - args = common_args(merge_request).merge(commit_message: 'my super custom message') - - result = mutation.resolve(**args) - - expect(result).to include(merge_request: be_merged) - expect(project.repository.commit(merge_request.target_branch)).to have_attributes( - message: args[:commit_message] - ) + it 'merges the merge request asynchronously' do + expect_next_found_instance_of(MergeRequest) do |instance| + expect(instance).to receive(:merge_async).with(user.id, args.except(:project_path, :iid)) + end + expect(result).to include(errors: be_empty) end - it 'respects the squash flag' do - merge_request = create(:merge_request, source_project: project) - args = common_args(merge_request).merge(squash: true) + context 'when the squash flag is specified' do + let(:additional_args) { { squash: true } } - result = mutation.resolve(**args) - - expect(result).to include(merge_request: be_merged) - expect(result[:merge_request].squash_commit_sha).to be_present + it 'sets squash on the merge request' do + expect { result }.to change { merge_request.reload.squash }.from(false).to(true) + end end - it 'respects the squash_commit_message argument' do - merge_request = create(:merge_request, source_project: project) - args = common_args(merge_request).merge(squash: true, squash_commit_message: 'squish') - - result = mutation.resolve(**args) - sha = result[:merge_request].squash_commit_sha + context 'when the sha is a mismatch' do + let(:additional_args) { { sha: 'not a good sha' } } - expect(result).to include(merge_request: be_merged) - expect(project.repository.commit(sha)).to have_attributes(message: "squish\n") + it 'rejects the mutation' do + expect_next_found_instance_of(MergeRequest) do |instance| + expect(instance).not_to receive(:merge_async) + end + expect(result).to include(errors: [described_class::SHA_MISMATCH]) + end end - it 'respects the should_remove_source_branch argument when true' do - b = project.repository.add_branch(user, generate(:branch), 'master') - merge_request = create(:merge_request, source_branch: b.name, source_project: project) - args = common_args(merge_request).merge(should_remove_source_branch: true) - - expect(::MergeRequests::DeleteSourceBranchWorker).to receive(:perform_async) - - result = mutation.resolve(**args) - - expect(result).to include(merge_request: be_merged) - end - - it 'respects the should_remove_source_branch argument when false' do - b = project.repository.add_branch(user, generate(:branch), 'master') - merge_request = create(:merge_request, source_branch: b.name, source_project: project) - args = common_args(merge_request).merge(should_remove_source_branch: false) - - expect(::MergeRequests::DeleteSourceBranchWorker).not_to receive(:perform_async) - - result = mutation.resolve(**args) + context 'when MR is unmergeable' do + let(:merge_request) { create(:merge_request, :closed, source_project: project) } - expect(result).to include(merge_request: be_merged) - end - - it 'rejects unmergeable MRs' do - merge_request = create(:merge_request, :closed, source_project: project) - args = common_args(merge_request) - - result = mutation.resolve(**args) - - expect(result).not_to include(merge_request: be_merged) - expect(result).to include(errors: [described_class::NOT_MERGEABLE]) + it 'rejects the MRs' do + expect_next_found_instance_of(MergeRequest) do |instance| + expect(instance).not_to receive(:merge_async) + end + expect(result).to include(errors: [described_class::NOT_MERGEABLE]) + end end it 'rejects merges when we cannot validate the hooks' do - merge_request = create(:merge_request, source_project: project) - args = common_args(merge_request) expect_next(::MergeRequests::MergeService) .to receive(:hooks_validation_pass?).with(merge_request).and_return(false) - result = mutation.resolve(**args) - - expect(result).not_to include(merge_request: be_merged) + expect_next_found_instance_of(MergeRequest) do |instance| + expect(instance).not_to receive(:merge_async) + end expect(result).to include(errors: [described_class::HOOKS_VALIDATION_ERROR]) end - it 'rejects merges when the merge service returns an error' do - merge_request = create(:merge_request, source_project: project) - args = common_args(merge_request) - expect_next(::MergeRequests::MergeService) - .to receive(:execute).with(merge_request).and_return(:failed) - - result = mutation.resolve(**args) - - expect(result).not_to include(merge_request: be_merged) - expect(result).to include(errors: [described_class::MERGE_FAILED]) - end - - it 'rejects merges when the merge service raises merge error' do - merge_request = create(:merge_request, source_project: project) - args = common_args(merge_request) - expect_next(::MergeRequests::MergeService) - .to receive(:execute).and_raise(::MergeRequests::MergeBaseService::MergeError, 'boom') - - result = mutation.resolve(**args) - - expect(result).not_to include(merge_request: be_merged) - expect(result).to include(errors: ['boom']) - end - - it "can use the MERGE_WHEN_PIPELINE_SUCCEEDS strategy" do - enum = ::Types::MergeStrategyEnum.values['MERGE_WHEN_PIPELINE_SUCCEEDS'] - merge_request = create(:merge_request, :with_head_pipeline, source_project: project) - args = common_args(merge_request).merge(auto_merge_strategy: enum.value) - - result = mutation.resolve(**args) - - expect(result).not_to include(merge_request: be_merged) - expect(result).to include(errors: be_empty, merge_request: be_auto_merge_enabled) + context 'when MR has head pipeline' do + let(:merge_request) { create(:merge_request, :with_head_pipeline, source_project: project) } + let(:strategy) { ::Types::MergeStrategyEnum.values['MERGE_WHEN_PIPELINE_SUCCEEDS'].value } + let(:additional_args) { { auto_merge_strategy: strategy } } + + it "can use the MERGE_WHEN_PIPELINE_SUCCEEDS strategy" do + expect_next_found_instance_of(MergeRequest) do |instance| + expect(instance).not_to receive(:merge_async) + end + expect(result).to include(errors: be_empty, merge_request: be_auto_merge_enabled) + end end end end diff --git a/spec/graphql/mutations/merge_requests/create_spec.rb b/spec/graphql/mutations/merge_requests/create_spec.rb index 6e593a5f4be..b8ea913b727 100644 --- a/spec/graphql/mutations/merge_requests/create_spec.rb +++ b/spec/graphql/mutations/merge_requests/create_spec.rb @@ -112,11 +112,13 @@ RSpec.describe Mutations::MergeRequests::Create do context 'when project is public with private merge requests' do let_it_be(:project) do - create(:project, - :public, - :repository, - group: group, - merge_requests_access_level: ProjectFeature::DISABLED) + create( + :project, + :public, + :repository, + group: group, + merge_requests_access_level: ProjectFeature::DISABLED + ) end context 'and user is a guest' do diff --git a/spec/graphql/mutations/merge_requests/set_assignees_spec.rb b/spec/graphql/mutations/merge_requests/set_assignees_spec.rb index 9b0460bc709..42315af75d5 100644 --- a/spec/graphql/mutations/merge_requests/set_assignees_spec.rb +++ b/spec/graphql/mutations/merge_requests/set_assignees_spec.rb @@ -12,10 +12,12 @@ RSpec.describe Mutations::MergeRequests::SetAssignees do describe '#resolve' do subject do - mutation.resolve(project_path: merge_request.project.full_path, - iid: merge_request.iid, - operation_mode: described_class.arguments['operationMode'].default_value, - assignee_usernames: [assignee.username]) + mutation.resolve( + project_path: merge_request.project.full_path, + iid: merge_request.iid, + operation_mode: described_class.arguments['operationMode'].default_value, + assignee_usernames: [assignee.username] + ) end it_behaves_like 'permission level for merge request mutation is correctly verified' diff --git a/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb b/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb index df4aa885bbf..59d3fcbfeda 100644 --- a/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb +++ b/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb @@ -16,10 +16,12 @@ RSpec.describe Mutations::MergeRequests::SetReviewers do let(:mode) { described_class.arguments['operationMode'].default_value } subject do - mutation.resolve(project_path: merge_request.project.full_path, - iid: merge_request.iid, - operation_mode: mode, - reviewer_usernames: reviewer_usernames) + mutation.resolve( + project_path: merge_request.project.full_path, + iid: merge_request.iid, + operation_mode: mode, + reviewer_usernames: reviewer_usernames + ) end it 'does not change reviewers if the merge_request is not accessible to the reviewers' do diff --git a/spec/graphql/mutations/release_asset_links/update_spec.rb b/spec/graphql/mutations/release_asset_links/update_spec.rb index abb091fc68d..2242387cb1a 100644 --- a/spec/graphql/mutations/release_asset_links/update_spec.rb +++ b/spec/graphql/mutations/release_asset_links/update_spec.rb @@ -16,12 +16,14 @@ RSpec.describe Mutations::ReleaseAssetLinks::Update, feature_category: :release_ let_it_be(:link_type) { 'package' } let_it_be(:release_link) do - create(:release_link, - release: release, - name: name, - url: url, - filepath: filepath, - link_type: link_type) + create( + :release_link, + release: release, + name: name, + url: url, + filepath: filepath, + link_type: link_type + ) end let(:current_user) { developer } diff --git a/spec/graphql/mutations/releases/update_spec.rb b/spec/graphql/mutations/releases/update_spec.rb index 0cf10e03fb1..fc323c5a146 100644 --- a/spec/graphql/mutations/releases/update_spec.rb +++ b/spec/graphql/mutations/releases/update_spec.rb @@ -17,9 +17,16 @@ RSpec.describe Mutations::Releases::Update do let_it_be(:milestones) { [milestone_12_3.title, milestone_12_4.title] } let_it_be(:release) do - create(:release, project: project, tag: tag, name: name, - description: description, released_at: released_at, - created_at: created_at, milestones: [milestone_12_3, milestone_12_4]) + create( + :release, + project: project, + tag: tag, + name: name, + description: description, + released_at: released_at, + created_at: created_at, + milestones: [milestone_12_3, milestone_12_4] + ) end let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) } diff --git a/spec/graphql/mutations/users/set_namespace_commit_email_spec.rb b/spec/graphql/mutations/users/set_namespace_commit_email_spec.rb index 6d8e15ac791..93456ec7b93 100644 --- a/spec/graphql/mutations/users/set_namespace_commit_email_spec.rb +++ b/spec/graphql/mutations/users/set_namespace_commit_email_spec.rb @@ -71,5 +71,5 @@ RSpec.describe Mutations::Users::SetNamespaceCommitEmail, feature_category: :use end end - specify { expect(described_class).to require_graphql_authorizations(:read_namespace) } + specify { expect(described_class).to require_graphql_authorizations(:read_namespace_via_membership) } end diff --git a/spec/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver_spec.rb b/spec/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver_spec.rb index 6b5e351a610..6b39f59444f 100644 --- a/spec/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver_spec.rb +++ b/spec/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver_spec.rb @@ -24,7 +24,7 @@ RSpec.describe Resolvers::Admin::Analytics::UsageTrends::MeasurementsResolver do let(:current_user) { admin_user } it 'returns the records, latest first' do - expect(subject).to eq([project_measurement_new, project_measurement_old]) + expect(subject.items).to eq([project_measurement_new, project_measurement_old]) end end @@ -54,7 +54,7 @@ RSpec.describe Resolvers::Admin::Analytics::UsageTrends::MeasurementsResolver do arguments[:recorded_before] = 1.day.ago end - it { is_expected.to match_array([project_measurement_new]) } + it { expect(subject.items).to match_array([project_measurement_new]) } context 'when "incorrect" values are passed' do before do @@ -62,7 +62,7 @@ RSpec.describe Resolvers::Admin::Analytics::UsageTrends::MeasurementsResolver do arguments[:recorded_before] = 4.days.ago end - it { is_expected.to be_empty } + it { expect(subject.items).to be_empty } end end end @@ -71,7 +71,7 @@ RSpec.describe Resolvers::Admin::Analytics::UsageTrends::MeasurementsResolver do let_it_be(:pipelines_succeeded_measurement) { create(:usage_trends_measurement, :pipelines_succeeded_count, recorded_at: 2.days.ago) } let_it_be(:pipelines_skipped_measurement) { create(:usage_trends_measurement, :pipelines_skipped_count, recorded_at: 2.days.ago) } - subject { resolve_measurements({ identifier: identifier }, { current_user: current_user }) } + subject { resolve_measurements({ identifier: identifier }, { current_user: current_user }).items } context 'filter for pipelines_succeeded' do let(:identifier) { 'pipelines_succeeded' } diff --git a/spec/graphql/resolvers/base_resolver_spec.rb b/spec/graphql/resolvers/base_resolver_spec.rb index 27c62da31c3..16b6212a833 100644 --- a/spec/graphql/resolvers/base_resolver_spec.rb +++ b/spec/graphql/resolvers/base_resolver_spec.rb @@ -118,18 +118,16 @@ RSpec.describe Resolvers::BaseResolver, feature_category: :api do end it 'does not apply the block to the resolver' do - expect(resolver.field_options).to include( - arguments: be_empty - ) + expect(resolver.arguments).to be_empty + result = resolve(resolver) expect(result).to eq([1]) end it 'applies the block to the single version of the resolver' do - expect(resolver.single.field_options).to include( - arguments: match('foo' => an_instance_of(::Types::BaseArgument)) - ) + expect(resolver.single.arguments).to match('foo' => an_instance_of(::Types::BaseArgument)) + result = resolve(resolver.single, args: { foo: 7 }) expect(result).to eq(49) @@ -155,9 +153,8 @@ RSpec.describe Resolvers::BaseResolver, feature_category: :api do end it 'applies both blocks to the single version of the resolver' do - expect(resolver.single.field_options).to include( - arguments: match('foo' => ::Types::BaseArgument, 'bar' => ::Types::BaseArgument) - ) + expect(resolver.single.arguments).to match('foo' => ::Types::BaseArgument, 'bar' => ::Types::BaseArgument) + result = resolve(resolver.single, args: { foo: 7, bar: 5 }) expect(result).to eq(35) @@ -178,12 +175,9 @@ RSpec.describe Resolvers::BaseResolver, feature_category: :api do end it 'applies both blocks to the single version of the resolver' do - expect(resolver.single.field_options).to include( - arguments: match('foo' => ::Types::BaseArgument) - ) - expect(subclass.single.field_options).to include( - arguments: match('foo' => ::Types::BaseArgument, 'inc' => ::Types::BaseArgument) - ) + expect(resolver.single.arguments).to match('foo' => ::Types::BaseArgument) + expect(subclass.single.arguments).to match('foo' => ::Types::BaseArgument, 'inc' => ::Types::BaseArgument) + result = resolve(subclass.single, args: { foo: 7, inc: 1 }) expect(result).to eq(64) diff --git a/spec/graphql/resolvers/board_lists_resolver_spec.rb b/spec/graphql/resolvers/board_lists_resolver_spec.rb index 1de59c5f507..5344e70d082 100644 --- a/spec/graphql/resolvers/board_lists_resolver_spec.rb +++ b/spec/graphql/resolvers/board_lists_resolver_spec.rb @@ -41,7 +41,7 @@ RSpec.describe Resolvers::BoardListsResolver do lists = resolve_board_lists expect(lists.count).to eq 3 - expect(lists.map(&:list_type)).to eq %w(backlog label closed) + expect(lists.map(&:list_type)).to eq %w[backlog label closed] end context 'when another user has list preferences' do @@ -100,8 +100,12 @@ RSpec.describe Resolvers::BoardListsResolver do end def resolve_board_lists(args: {}, current_user: user) - resolve(described_class, obj: board, args: args, ctx: { current_user: current_user }, - arg_style: :internal + resolve( + described_class, + obj: board, + args: args, + ctx: { current_user: current_user }, + arg_style: :internal ) end end diff --git a/spec/graphql/resolvers/ci/config_resolver_spec.rb b/spec/graphql/resolvers/ci/config_resolver_spec.rb index 16a2286cb7e..3f21c1f505f 100644 --- a/spec/graphql/resolvers/ci/config_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/config_resolver_spec.rb @@ -15,9 +15,11 @@ RSpec.describe Resolvers::Ci::ConfigResolver, feature_category: :continuous_inte end subject(:response) do - resolve(described_class, - args: { project_path: project.full_path, content: content, sha: sha }, - ctx: { current_user: user }) + resolve( + described_class, + args: { project_path: project.full_path, content: content, sha: sha }, + ctx: { current_user: user } + ) end shared_examples 'a valid config file' do @@ -36,7 +38,8 @@ RSpec.describe Resolvers::Ci::ConfigResolver, feature_category: :continuous_inte 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) + expect(::Gitlab::Ci::Lint).to have_received(:new) + .with(current_user: user, project: project, sha: sha, verify_project_sha: true) end end diff --git a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb index fedae5c86a8..e0fc3b96b93 100644 --- a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb @@ -7,8 +7,13 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl describe '#resolve' do subject(:resolve_scope) do - resolve(described_class, obj: obj, ctx: { current_user: user }, args: args, - arg_style: :internal) + resolve( + described_class, + obj: obj, + ctx: { current_user: user }, + args: args, + arg_style: :internal + ) end include_context 'runners resolver setup' diff --git a/spec/graphql/resolvers/ci/jobs_resolver_spec.rb b/spec/graphql/resolvers/ci/jobs_resolver_spec.rb index b99eb56d6ab..8138ac18938 100644 --- a/spec/graphql/resolvers/ci/jobs_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/jobs_resolver_spec.rb @@ -39,8 +39,12 @@ RSpec.describe Resolvers::Ci::JobsResolver, feature_category: :continuous_integr ::Types::Security::ReportTypeEnum.values['SAST'].value, ::Types::Security::ReportTypeEnum.values['DAST'].value ] - jobs = resolve(described_class, obj: pipeline, args: { security_report_types: report_types }, - arg_style: :internal) + jobs = resolve( + described_class, + obj: pipeline, + args: { security_report_types: report_types }, + arg_style: :internal + ) expect(jobs).to contain_exactly( have_attributes(name: 'DAST job'), diff --git a/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb index 55a98106baf..9d9f0fee04a 100644 --- a/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb @@ -7,8 +7,13 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_ describe '#resolve' do subject(:resolve_scope) do - resolve(described_class, obj: obj, ctx: { current_user: user }, args: args, - arg_style: :internal) + resolve( + described_class, + obj: obj, + ctx: { current_user: user }, + args: args, + arg_style: :internal + ) end include_context 'runners resolver setup' @@ -77,8 +82,10 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_ end it 'calls RunnersFinder with expected arguments' do - allow(::Ci::RunnersFinder).to receive(:new).with(current_user: user, - params: expected_params).once.and_return(finder) + allow(::Ci::RunnersFinder).to receive(:new).with( + current_user: user, params: expected_params + ).once.and_return(finder) + allow(finder).to receive(:execute).once.and_return([:execute_return_value]) expect(resolve_scope.items.to_a).to contain_exactly(:execute_return_value) diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb index 35831579799..c164393d605 100644 --- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb @@ -10,8 +10,13 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d let(:args) { {} } subject(:resolve_scope) do - resolve(described_class, obj: obj, ctx: { current_user: user }, args: args, - arg_style: :internal) + resolve( + described_class, + obj: obj, + ctx: { current_user: user }, + args: args, + arg_style: :internal + ) end include_context 'runners resolver setup' diff --git a/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb b/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb index dfd1addff71..afb10b26907 100644 --- a/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb +++ b/spec/graphql/resolvers/clusters/agent_tokens_resolver_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe Resolvers::Clusters::AgentTokensResolver do include GraphqlHelpers - it { expect(described_class.type).to eq(Types::Clusters::AgentTokenType) } + it { expect(described_class.type).to eq(Types::Clusters::AgentTokenType.connection_type) } it { expect(described_class.null).to be_truthy } it { expect(described_class.arguments.keys).to be_empty } @@ -22,7 +22,7 @@ RSpec.describe Resolvers::Clusters::AgentTokensResolver do subject { resolve(described_class, obj: agent, ctx: ctx) } it 'returns active tokens associated with the agent, ordered by last_used_at' do - expect(subject).to eq([matching_token2, matching_token1]) + expect(subject.items).to eq([matching_token2, matching_token1]) end context 'user does not have permission' do diff --git a/spec/graphql/resolvers/clusters/agents_resolver_spec.rb b/spec/graphql/resolvers/clusters/agents_resolver_spec.rb index 152d7fa22c4..f451a337848 100644 --- a/spec/graphql/resolvers/clusters/agents_resolver_spec.rb +++ b/spec/graphql/resolvers/clusters/agents_resolver_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Resolvers::Clusters::AgentsResolver do end specify do - expect(described_class.field_options).to include(extras: include(:lookahead)) + expect(described_class.extras).to include(:lookahead) end describe '#resolve' do @@ -52,17 +52,9 @@ end RSpec.describe Resolvers::Clusters::AgentsResolver.single do it { expect(described_class).to be < Resolvers::Clusters::AgentsResolver } - describe '.field_options' do - subject { described_class.field_options } - - specify do - expect(subject).to include( - type: ::Types::Clusters::AgentType, - null: true, - extras: [:lookahead] - ) - end - end + it { expect(described_class.type).to eq(::Types::Clusters::AgentType) } + it { expect(described_class.null).to eq(true) } + it { expect(described_class.extras).to include(:lookahead) } describe 'arguments' do subject { described_class.arguments[argument] } diff --git a/spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb b/spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb index 892ab53a53e..d3cda7d9c8f 100644 --- a/spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb +++ b/spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb @@ -206,8 +206,8 @@ RSpec.describe ::CachingArrayResolver do def resolve_users(admin:, resolver: caching_resolver) args = { is_admin: admin } - opts = resolver.field_options - allow(resolver).to receive(:field_options).and_return(opts.merge(max_page_size: max_page_size)) + allow(resolver).to receive(:has_max_page_size?).and_return(true) + allow(resolver).to receive(:max_page_size).and_return(max_page_size) resolve(resolver, args: args, ctx: query_context, schema: schema, arg_style: :internal) end end diff --git a/spec/graphql/resolvers/concerns/looks_ahead_spec.rb b/spec/graphql/resolvers/concerns/looks_ahead_spec.rb index 4c244da5c62..532eff87307 100644 --- a/spec/graphql/resolvers/concerns/looks_ahead_spec.rb +++ b/spec/graphql/resolvers/concerns/looks_ahead_spec.rb @@ -57,10 +57,12 @@ RSpec.describe LooksAhead do end def query(doc = document) - GraphQL::Query.new(schema, - document: doc, - context: { user_db: [the_user] }, - variables: { username: the_user.username }) + GraphQL::Query.new( + schema, + document: doc, + context: { user_db: [the_user] }, + variables: { username: the_user.username } + ) end let(:document) do diff --git a/spec/graphql/resolvers/concerns/resolves_groups_spec.rb b/spec/graphql/resolvers/concerns/resolves_groups_spec.rb index d15c8f2ee42..79f3708da22 100644 --- a/spec/graphql/resolvers/concerns/resolves_groups_spec.rb +++ b/spec/graphql/resolvers/concerns/resolves_groups_spec.rb @@ -18,10 +18,7 @@ RSpec.describe ResolvesGroups do let_it_be(:query_type) do query_factory do |query| - query.field :groups, - Types::GroupType.connection_type, - null: true, - resolver: resolver + query.field :groups, Types::GroupType.connection_type, null: true, resolver: resolver end end diff --git a/spec/graphql/resolvers/container_repositories_resolver_spec.rb b/spec/graphql/resolvers/container_repositories_resolver_spec.rb index df0a98b1536..d2d1d622cf4 100644 --- a/spec/graphql/resolvers/container_repositories_resolver_spec.rb +++ b/spec/graphql/resolvers/container_repositories_resolver_spec.rb @@ -16,8 +16,13 @@ RSpec.describe Resolvers::ContainerRepositoriesResolver do let(:object) { project } subject do - resolve(described_class, ctx: { current_user: user }, args: args, obj: object, - arg_style: :internal) + resolve( + described_class, + ctx: { current_user: user }, + args: args, + obj: object, + arg_style: :internal + ) end shared_examples 'returning container repositories' do diff --git a/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb b/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb index 3ed3fe76267..0408357e8f2 100644 --- a/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb +++ b/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb @@ -13,8 +13,13 @@ RSpec.describe Resolvers::ContainerRepositoryTagsResolver do describe '#resolve' do let(:resolver) do - resolve(described_class, ctx: { current_user: user }, obj: repository, args: args, - arg_style: :internal) + resolve( + described_class, + ctx: { current_user: user }, + obj: repository, + args: args, + arg_style: :internal + ) end before do @@ -25,7 +30,7 @@ RSpec.describe Resolvers::ContainerRepositoryTagsResolver do subject { resolver.map(&:name) } before do - stub_container_registry_tags(repository: repository.path, tags: %w(aaa bab bbb ccc 123), with_manifest: false) + stub_container_registry_tags(repository: repository.path, tags: %w[aaa bab bbb ccc 123], with_manifest: false) end context 'without sort' do @@ -37,19 +42,19 @@ RSpec.describe Resolvers::ContainerRepositoryTagsResolver do context "name_asc" do let(:args) { { sort: :name_asc } } - it { is_expected.to eq(%w(123 aaa bab bbb ccc)) } + it { is_expected.to eq(%w[123 aaa bab bbb ccc]) } end context "name_desc" do let(:args) { { sort: :name_desc } } - it { is_expected.to eq(%w(ccc bbb bab aaa 123)) } + it { is_expected.to eq(%w[ccc bbb bab aaa 123]) } end context 'filter by name' do let(:args) { { sort: :name_desc, name: 'b' } } - it { is_expected.to eq(%w(bbb bab)) } + it { is_expected.to eq(%w[bbb bab]) } end end end diff --git a/spec/graphql/resolvers/environments_resolver_spec.rb b/spec/graphql/resolvers/environments_resolver_spec.rb index b1f7dc1673e..419d0a12462 100644 --- a/spec/graphql/resolvers/environments_resolver_spec.rb +++ b/spec/graphql/resolvers/environments_resolver_spec.rb @@ -23,12 +23,14 @@ RSpec.describe Resolvers::EnvironmentsResolver do describe '#resolve' do it 'finds all environments' do - expect(resolve_environments).to contain_exactly(environment1, - environment2, - environment3, - environment4, - environment5, - environment6) + expect(resolve_environments).to contain_exactly( + environment1, + environment2, + environment3, + environment4, + environment5, + environment6 + ) end context 'with name' do @@ -51,11 +53,13 @@ RSpec.describe Resolvers::EnvironmentsResolver do context 'with states' do it 'searches environments by state' do - expect(resolve_environments(states: ['available'])).to contain_exactly(environment1, - environment3, - environment4, - environment5, - environment6) + expect(resolve_environments(states: ['available'])).to contain_exactly( + environment1, + environment3, + environment4, + environment5, + environment6 + ) end it 'generates an error if requested state is invalid' 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 65b6c551dde..784d1142bf2 100644 --- a/spec/graphql/resolvers/error_tracking/sentry_errors_resolver_spec.rb +++ b/spec/graphql/resolvers/error_tracking/sentry_errors_resolver_spec.rb @@ -99,6 +99,12 @@ RSpec.describe Resolvers::ErrorTracking::SentryErrorsResolver do private def resolve_errors(args = {}, context = { current_user: current_user }) - resolve(described_class, obj: error_collection, args: args, ctx: context) + field = ::Types::BaseField.from_options( + 'dummy_field', + owner: resolver_parent, + resolver: described_class, + connection_extension: Gitlab::Graphql::Extensions::ExternallyPaginatedArrayExtension + ) + resolve_field(field, error_collection, args: args, ctx: context, object_type: resolver_parent) end end diff --git a/spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb b/spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb index e4cf62b0361..dc3721d2e83 100644 --- a/spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb +++ b/spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb @@ -5,9 +5,9 @@ require 'spec_helper' RSpec.describe Resolvers::Kas::AgentConfigurationsResolver do include GraphqlHelpers - it { expect(described_class.type).to eq(Types::Kas::AgentConfigurationType) } + it { expect(described_class.type).to eq(Types::Kas::AgentConfigurationType.connection_type) } it { expect(described_class.null).to be_truthy } - it { expect(described_class.field_options).to include(calls_gitaly: true) } + it { expect(described_class.calls_gitaly?).to eq(true) } describe '#resolve' do let_it_be(:project) { create(:project) } @@ -26,7 +26,7 @@ RSpec.describe Resolvers::Kas::AgentConfigurationsResolver do end it 'returns agents configured for the project' do - expect(subject).to contain_exactly(agent1, agent2) + expect(subject.items).to contain_exactly(agent1, agent2) end context 'an error is returned from the KAS client' do @@ -44,7 +44,7 @@ RSpec.describe Resolvers::Kas::AgentConfigurationsResolver do context 'user does not have permission' do let(:user) { create(:user) } - it { is_expected.to be_empty } + it { expect(subject.items).to be_empty } end end end diff --git a/spec/graphql/resolvers/package_pipelines_resolver_spec.rb b/spec/graphql/resolvers/package_pipelines_resolver_spec.rb index a52dee59bc6..9d5f610c7db 100644 --- a/spec/graphql/resolvers/package_pipelines_resolver_spec.rb +++ b/spec/graphql/resolvers/package_pipelines_resolver_spec.rb @@ -10,6 +10,8 @@ RSpec.describe Resolvers::PackagePipelinesResolver do let(:user) { package.project.first_owner } + it { expect(described_class.extras).to include(:lookahead) } + describe '#resolve' do let(:returned_pipelines) { graphql_dig_at(subject, 'data', 'package', 'pipelines', 'nodes') } let(:returned_errors) { graphql_dig_at(subject, 'errors', 'message') } @@ -156,19 +158,4 @@ RSpec.describe Resolvers::PackagePipelinesResolver do 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/paginated_tree_resolver_spec.rb b/spec/graphql/resolvers/paginated_tree_resolver_spec.rb index 931d4ba132c..7e0e55e8d2a 100644 --- a/spec/graphql/resolvers/paginated_tree_resolver_spec.rb +++ b/spec/graphql/resolvers/paginated_tree_resolver_spec.rb @@ -120,12 +120,13 @@ RSpec.describe Resolvers::PaginatedTreeResolver, feature_category: :source_code_ end def resolve_repository(args, opts = {}) - field_options = described_class.field_options.merge( + field_options = { owner: resolver_parent, - name: 'field_value' - ).merge(opts) + resolver: described_class, + connection_extension: Gitlab::Graphql::Extensions::ExternallyPaginatedArrayExtension + }.merge(opts) - field = ::Types::BaseField.new(**field_options) + field = ::Types::BaseField.from_options('field_value', **field_options) resolve_field(field, repository, args: args, object_type: resolver_parent) end end diff --git a/spec/graphql/resolvers/project_issues_resolver_spec.rb b/spec/graphql/resolvers/project_issues_resolver_spec.rb index faafbc465e3..593489290e0 100644 --- a/spec/graphql/resolvers/project_issues_resolver_spec.rb +++ b/spec/graphql/resolvers/project_issues_resolver_spec.rb @@ -351,9 +351,14 @@ RSpec.describe Resolvers::ProjectIssuesResolver do context 'when filtering by negated author' do let_it_be(:issue_by_reporter) { create(:issue, author: reporter, project: project, state: :opened) } + let_it_be(:other_user) { build_stubbed(:user) } it 'returns issues without the specified author_username' do - expect(resolve_issues(not: { author_username: issue1.author.username })).to contain_exactly(issue_by_reporter) + expect(resolve_issues(not: { author_username: [issue1.author.username] })).to contain_exactly(issue_by_reporter) + end + + it 'returns issues without the specified author_usernames' do + expect(resolve_issues(not: { author_username: [issue1.author.username, other_user.username] })).to contain_exactly(issue_by_reporter) end end end diff --git a/spec/graphql/resolvers/project_merge_requests_resolver_spec.rb b/spec/graphql/resolvers/project_merge_requests_resolver_spec.rb index 45777aa96e1..67bb6411d08 100644 --- a/spec/graphql/resolvers/project_merge_requests_resolver_spec.rb +++ b/spec/graphql/resolvers/project_merge_requests_resolver_spec.rb @@ -11,13 +11,15 @@ RSpec.describe Resolvers::ProjectMergeRequestsResolver do let_it_be(:reviewer) { create(:user) } let_it_be(:merge_request) do - create(:merge_request, - :unique_branches, - source_project: project, - target_project: project, - author: other_user, - assignee: other_user, - reviewers: [reviewer]) + create( + :merge_request, + :unique_branches, + source_project: project, + target_project: project, + author: other_user, + assignee: other_user, + reviewers: [reviewer] + ) end before do diff --git a/spec/graphql/resolvers/project_milestones_resolver_spec.rb b/spec/graphql/resolvers/project_milestones_resolver_spec.rb index af6b16804b0..c7ece114373 100644 --- a/spec/graphql/resolvers/project_milestones_resolver_spec.rb +++ b/spec/graphql/resolvers/project_milestones_resolver_spec.rb @@ -44,10 +44,14 @@ RSpec.describe 'Resolvers::ProjectMilestonesResolver' do end it 'calls MilestonesFinder with correct parameters' do - expect(MilestonesFinder).to receive(:new) - .with(args(project_ids: project.id, group_ids: contain_exactly(group, parent_group), - state: 'all', sort: :due_date_asc)) - .and_call_original + expect(MilestonesFinder).to receive(:new).with( + args( + project_ids: project.id, + group_ids: contain_exactly(group, parent_group), + state: 'all', + sort: :due_date_asc + ) + ).and_call_original resolve_project_milestones(include_ancestors: true) end @@ -99,10 +103,15 @@ RSpec.describe 'Resolvers::ProjectMilestonesResolver' do start_date = now_date end_date = now_date + 5.days - expect(MilestonesFinder).to receive(:new) - .with(args(project_ids: project.id, state: 'all', - sort: :due_date_asc, start_date: start_date, end_date: end_date)) - .and_call_original + expect(MilestonesFinder).to receive(:new).with( + args( + project_ids: project.id, + state: 'all', + sort: :due_date_asc, + start_date: start_date, + end_date: end_date + ) + ).and_call_original resolve_project_milestones(timeframe: { start: start_date, end: end_date }) end diff --git a/spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb b/spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb index ef1b18f0a11..07415077d1f 100644 --- a/spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb +++ b/spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb @@ -38,12 +38,8 @@ RSpec.describe Resolvers::Projects::ForkTargetsResolver do end def resolve_targets(args, opts = {}) - field_options = described_class.field_options.merge( - owner: resolver_parent, - name: 'field_value' - ).merge(opts) - - field = ::Types::BaseField.new(**field_options) + field_options = { owner: resolver_parent, resolver: described_class }.merge(opts) + field = ::Types::BaseField.from_options('field_value', **field_options) resolve_field(field, project, args: args, ctx: { current_user: user }, object_type: resolver_parent) end end diff --git a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb index 6af2f56cef4..b2d5e0b7405 100644 --- a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb +++ b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb @@ -60,9 +60,9 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver, feature_category: :int project_ids = jira_projects.map(&:id) expect(jira_projects.size).to eq 2 - expect(project_keys).to eq(%w(EX ABC)) - expect(project_names).to eq(%w(Example Alphabetical)) - expect(project_ids).to eq(%w(10000 10001)) + expect(project_keys).to eq(%w[EX ABC]) + expect(project_names).to eq(%w[Example Alphabetical]) + expect(project_ids).to eq(%w[10000 10001]) expect(resolver.max_page_size).to eq(2) end @@ -75,9 +75,9 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver, feature_category: :int project_ids = jira_projects.map(&:id) expect(jira_projects.size).to eq 1 - expect(project_keys).to eq(%w(ABC)) - expect(project_names).to eq(%w(Alphabetical)) - expect(project_ids).to eq(%w(10001)) + expect(project_keys).to eq(%w[ABC]) + expect(project_names).to eq(%w[Alphabetical]) + expect(project_ids).to eq(%w[10001]) expect(resolver.max_page_size).to eq(1) end end diff --git a/spec/graphql/resolvers/projects_resolver_spec.rb b/spec/graphql/resolvers/projects_resolver_spec.rb index 77507474170..058d46a5e86 100644 --- a/spec/graphql/resolvers/projects_resolver_spec.rb +++ b/spec/graphql/resolvers/projects_resolver_spec.rb @@ -6,11 +6,11 @@ RSpec.describe Resolvers::ProjectsResolver do include GraphqlHelpers describe '#resolve' do - subject { resolve(described_class, obj: nil, args: filters, ctx: { current_user: current_user }) } + subject { resolve(described_class, obj: nil, args: filters, ctx: { current_user: current_user }).items } let_it_be(:group) { create(:group, name: 'public-group') } let_it_be(:private_group) { create(:group, name: 'private-group') } - let_it_be(:project) { create(:project, :public, topic_list: %w(ruby javascript)) } + let_it_be(:project) { create(:project, :public, topic_list: %w[ruby javascript]) } let_it_be(:other_project) { create(:project, :public) } let_it_be(:group_project) { create(:project, :public, group: group) } let_it_be(:private_project) { create(:project, :private) } @@ -68,7 +68,7 @@ RSpec.describe Resolvers::ProjectsResolver do end context 'when topics filter is provided' do - let(:filters) { { topics: %w(ruby) } } + let(:filters) { { topics: %w[ruby] } } it 'returns matching project' do is_expected.to contain_exactly(project) @@ -148,7 +148,7 @@ RSpec.describe Resolvers::ProjectsResolver do end context 'when topics filter is provided' do - let(:filters) { { topics: %w(ruby) } } + let(:filters) { { topics: %w[ruby] } } it 'returns matching project' do is_expected.to contain_exactly(project) diff --git a/spec/graphql/resolvers/user_notes_count_resolver_spec.rb b/spec/graphql/resolvers/user_notes_count_resolver_spec.rb index b3368d532b2..810dfc9c324 100644 --- a/spec/graphql/resolvers/user_notes_count_resolver_spec.rb +++ b/spec/graphql/resolvers/user_notes_count_resolver_spec.rb @@ -27,6 +27,14 @@ RSpec.describe Resolvers::UserNotesCountResolver do it 'returns the number of non-system notes for the issue' do expect(subject).to eq(2) end + + context 'when not logged in' do + let(:user) { nil } + + it 'returns the number of non-system notes for the issue' do + expect(subject).to eq(2) + end + end end context 'when a user has permission to view notes' do @@ -65,6 +73,14 @@ RSpec.describe Resolvers::UserNotesCountResolver do it 'returns the number of non-system notes for the merge request' do expect(subject).to eq(2) end + + context 'when not logged in' do + let(:user) { nil } + + it 'returns the number of non-system notes for the merge request' do + expect(subject).to eq(2) + end + end end context 'when a user has permission to view notes' do diff --git a/spec/graphql/resolvers/users/participants_resolver_spec.rb b/spec/graphql/resolvers/users/participants_resolver_spec.rb index 22111626c5b..ae23eabaeb0 100644 --- a/spec/graphql/resolvers/users/participants_resolver_spec.rb +++ b/spec/graphql/resolvers/users/participants_resolver_spec.rb @@ -138,7 +138,8 @@ RSpec.describe Resolvers::Users::ParticipantsResolver do # 1 extra query per source (3 emojis + 2 notes) to fetch participables collection # 2 extra queries to load work item widgets collection # 1 extra query to load the project creator to check if they are banned - expect { query.call }.not_to exceed_query_limit(control_count).with_threshold(8) + # 1 extra query to load the invited groups to see if the user is banned from any of them + expect { query.call }.not_to exceed_query_limit(control_count).with_threshold(9) end it 'does not execute N+1 for system note metadata relation' do diff --git a/spec/graphql/resolvers/work_items_resolver_spec.rb b/spec/graphql/resolvers/work_items_resolver_spec.rb index c856f990e7a..d030f543958 100644 --- a/spec/graphql/resolvers/work_items_resolver_spec.rb +++ b/spec/graphql/resolvers/work_items_resolver_spec.rb @@ -13,20 +13,37 @@ RSpec.describe Resolvers::WorkItemsResolver do let_it_be(:other_project) { create(:project, group: group) } let_it_be(:item1) do - create(:work_item, project: project, state: :opened, created_at: - 3.hours.ago, updated_at: 3.hours.ago) + create( + :work_item, + project: project, + state: :opened, + created_at: 3.hours.ago, + updated_at: 3.hours.ago + ) end let_it_be(:item2) do - create(:work_item, project: project, state: :closed, title: 'foo', - created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: - 1.hour.ago) + create( + :work_item, + project: project, + state: :closed, + title: 'foo', + created_at: 1.hour.ago, + updated_at: 1.hour.ago, + closed_at: 1.hour.ago + ) end let_it_be(:item3) do - create(:work_item, project: other_project, state: :closed, title: 'foo', - created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: - 1.hour.ago) + create( + :work_item, + project: other_project, + state: :closed, + title: 'foo', + created_at: 1.hour.ago, + updated_at: 1.hour.ago, + closed_at: 1.hour.ago + ) end let_it_be(:item4) { create(:work_item) } diff --git a/spec/graphql/subscriptions/issuable_updated_spec.rb b/spec/graphql/subscriptions/issuable_updated_spec.rb index bc640e9e3c4..906b7e1f11a 100644 --- a/spec/graphql/subscriptions/issuable_updated_spec.rb +++ b/spec/graphql/subscriptions/issuable_updated_spec.rb @@ -52,8 +52,8 @@ RSpec.describe Subscriptions::IssuableUpdated do let(:current_user) { unauthorized_user } it 'unsubscribes the user' do - # GraphQL::Execution::Execute::Skip is returned when unsubscribed - expect(subject).to be_an(GraphQL::Execution::Execute::Skip) + # GraphQL::Execution::Skip is returned when unsubscribed + expect(subject).to be_an(GraphQL::Execution::Skip) end end end diff --git a/spec/graphql/types/achievements/user_achievement_type_spec.rb b/spec/graphql/types/achievements/user_achievement_type_spec.rb index b7fe4d815f7..bb332c26894 100644 --- a/spec/graphql/types/achievements/user_achievement_type_spec.rb +++ b/spec/graphql/types/achievements/user_achievement_type_spec.rb @@ -15,6 +15,7 @@ RSpec.describe GitlabSchema.types['UserAchievement'], feature_category: :user_pr created_at updated_at revoked_at + priority ] end diff --git a/spec/graphql/types/base_edge_spec.rb b/spec/graphql/types/base_edge_spec.rb index 0cc0c838fac..8aad77a6400 100644 --- a/spec/graphql/types/base_edge_spec.rb +++ b/spec/graphql/types/base_edge_spec.rb @@ -7,8 +7,7 @@ RSpec.describe Types::BaseEdge, feature_category: :api do let_it_be(:test_schema) do project_edge_type = Class.new(described_class) do - field :proof_of_admin_rights, String, - null: true, authorize: :admin_project + field :proof_of_admin_rights, String, null: true, authorize: :admin_project def proof_of_admin_rights 'ok' diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb index 831d36950db..b52d5514368 100644 --- a/spec/graphql/types/base_field_spec.rb +++ b/spec/graphql/types/base_field_spec.rb @@ -31,23 +31,25 @@ RSpec.describe Types::BaseField, feature_category: :api do end it 'only tests the resolver authorization if it authorizes_object?' do - resolver = Class.new + resolver = Class.new(Resolvers::BaseResolver) - field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, - resolver_class: resolver) + field = described_class.new( + name: 'test', type: GraphQL::Types::String, null: true, resolver_class: resolver + ) expect(field).to be_authorized(object, nil, ctx) end it 'tests the resolver authorization, if provided' do - resolver = Class.new do + resolver = Class.new(Resolvers::BaseResolver) do include Gitlab::Graphql::Authorize::AuthorizeResource authorizes_object! end - field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, - resolver_class: resolver) + field = described_class.new( + name: 'test', type: GraphQL::Types::String, null: true, resolver_class: resolver + ) expect(resolver).to receive(:authorized?).with(object, ctx).and_return(false) @@ -55,15 +57,19 @@ RSpec.describe Types::BaseField, feature_category: :api do end it 'tests field authorization before resolver authorization, when field auth fails' do - resolver = Class.new do + resolver = Class.new(Resolvers::BaseResolver) do include Gitlab::Graphql::Authorize::AuthorizeResource authorizes_object! end - field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, - authorize: :foo, - resolver_class: resolver) + field = described_class.new( + name: 'test', + type: GraphQL::Types::String, + null: true, + authorize: :foo, + resolver_class: resolver + ) expect(Ability).to receive(:allowed?).with(current_user, :foo, object).and_return(false) expect(resolver).not_to receive(:authorized?) @@ -72,15 +78,19 @@ RSpec.describe Types::BaseField, feature_category: :api do end it 'tests field authorization before resolver authorization, when field auth succeeds' do - resolver = Class.new do + resolver = Class.new(Resolvers::BaseResolver) do include Gitlab::Graphql::Authorize::AuthorizeResource authorizes_object! end - field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, - authorize: :foo, - resolver_class: resolver) + field = described_class.new( + name: 'test', + type: GraphQL::Types::String, + null: true, + authorize: :foo, + resolver_class: resolver + ) expect(Ability).to receive(:allowed?).with(current_user, :foo, object).and_return(true) expect(resolver).to receive(:authorized?).with(object, ctx).and_return(false) @@ -91,7 +101,7 @@ RSpec.describe Types::BaseField, feature_category: :api do context 'when considering complexity' do let(:resolver) do - Class.new(described_class) do + Class.new(Resolvers::BaseResolver) do def self.resolver_complexity(args, child_complexity:) 2 if args[:foo] end diff --git a/spec/graphql/types/boards/board_issue_input_type_spec.rb b/spec/graphql/types/boards/board_issue_input_type_spec.rb index ed2872c3598..dccd9f1c16c 100644 --- a/spec/graphql/types/boards/board_issue_input_type_spec.rb +++ b/spec/graphql/types/boards/board_issue_input_type_spec.rb @@ -6,8 +6,8 @@ RSpec.describe GitlabSchema.types['BoardIssueInput'] do it { expect(described_class.graphql_name).to eq('BoardIssueInput') } it 'has specific fields' do - allowed_args = %w(labelName milestoneTitle assigneeUsername authorUsername - releaseTag myReactionEmoji not search assigneeWildcardId confidential) + allowed_args = %w[labelName milestoneTitle assigneeUsername authorUsername + releaseTag myReactionEmoji not search assigneeWildcardId confidential] expect(described_class.arguments.keys).to include(*allowed_args) expect(described_class.arguments['not'].type).to eq(Types::Boards::NegatedBoardIssueInputType) diff --git a/spec/graphql/types/ci/ci_cd_setting_type_spec.rb b/spec/graphql/types/ci/ci_cd_setting_type_spec.rb new file mode 100644 index 00000000000..5fdfb405e23 --- /dev/null +++ b/spec/graphql/types/ci/ci_cd_setting_type_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Types::Ci::CiCdSettingType, feature_category: :continuous_integration do + specify { expect(described_class.graphql_name).to eq('ProjectCiCdSetting') } + + it 'exposes the expected fields' do + expected_fields = %w[ + inbound_job_token_scope_enabled job_token_scope_enabled + keep_latest_artifact merge_pipelines_enabled project + ] + + if Gitlab.ee? + expected_fields += %w[ + merge_trains_skip_train_allowed merge_trains_enabled + ] + end + + expect(described_class).to have_graphql_fields(*expected_fields) + end +end diff --git a/spec/graphql/types/ci/detailed_status_type_spec.rb b/spec/graphql/types/ci/detailed_status_type_spec.rb index 81ab1b52552..c069098e5b0 100644 --- a/spec/graphql/types/ci/detailed_status_type_spec.rb +++ b/spec/graphql/types/ci/detailed_status_type_spec.rb @@ -10,9 +10,12 @@ RSpec.describe Types::Ci::DetailedStatusType do specify { expect(described_class.graphql_name).to eq('DetailedStatus') } it 'has all fields' do - expect(described_class).to have_graphql_fields(:id, :group, :icon, :favicon, - :details_path, :has_details, - :label, :text, :tooltip, :action) + expect(described_class).to have_graphql_fields( + :id, :group, :icon, :favicon, + :details_path, :has_details, + :label, :name, :text, :tooltip, + :action + ) end describe 'id field' do @@ -29,12 +32,12 @@ RSpec.describe Types::Ci::DetailedStatusType do status = stage.detailed_status(stage.pipeline.user) expected_status = { - button_title: status.action_button_title, - icon: status.action_icon, - method: status.action_method, - path: status.action_path, - title: status.action_title - } + button_title: status.action_button_title, + icon: status.action_icon, + method: status.action_method, + path: status.action_path, + title: status.action_title + } expect(resolve_field('action', status, arg_style: :internal)).to eq(expected_status) end diff --git a/spec/graphql/types/ci/job_base_field_spec.rb b/spec/graphql/types/ci/job_base_field_spec.rb index 2d283ce854d..ec7d2a7d33a 100644 --- a/spec/graphql/types/ci/job_base_field_spec.rb +++ b/spec/graphql/types/ci/job_base_field_spec.rb @@ -77,7 +77,7 @@ RSpec.describe Types::Ci::JobBaseField, feature_category: :runner_fleet do end context 'with field resolver' do - let(:resolver) { Class.new } + let(:resolver) { Class.new(Resolvers::BaseResolver) } let(:args) { { resolver_class: resolver } } it 'only tests the resolver authorization if it authorizes_object?' do @@ -86,7 +86,7 @@ RSpec.describe Types::Ci::JobBaseField, feature_category: :runner_fleet do context 'when resolver authorizes object' do let(:resolver) do - Class.new do + Class.new(Resolvers::BaseResolver) do include Gitlab::Graphql::Authorize::AuthorizeResource authorizes_object! diff --git a/spec/graphql/types/ci/job_trace_type_spec.rb b/spec/graphql/types/ci/job_trace_type_spec.rb index 69123445b8b..6d1214eafe6 100644 --- a/spec/graphql/types/ci/job_trace_type_spec.rb +++ b/spec/graphql/types/ci/job_trace_type_spec.rb @@ -123,22 +123,6 @@ RSpec.describe GitlabSchema.types['CiJobTrace'], feature_category: :continuous_i end end - context 'when FF graphql_job_trace_html_summary_max_size is disabled' do - before do - stub_feature_flags(graphql_job_trace_html_summary_max_size: false) - end - - let(:args) { { last_lines: 20 } } - - it 'does not limit the read size from the raw trace' do - expect_next_instance_of(Gitlab::Ci::Trace) do |trace| - expect(trace).to receive(:html).with(last_lines: 20, max_size: nil).and_call_original - end - - is_expected.to eq "<span>#{(1..20).map { (1..1024).map { 'a' }.join('') }.join('<br/>')}</span>" - end - end - context 'when trace is cut in middle of a line' do let(:args) { {} } diff --git a/spec/graphql/types/ci/pipeline_type_spec.rb b/spec/graphql/types/ci/pipeline_type_spec.rb index 67209874b54..26dfc0b10c6 100644 --- a/spec/graphql/types/ci/pipeline_type_spec.rb +++ b/spec/graphql/types/ci/pipeline_type_spec.rb @@ -9,18 +9,20 @@ RSpec.describe Types::Ci::PipelineType do it 'contains attributes related to a pipeline' do expected_fields = %w[ - id iid sha before_sha complete status detailed_status config_source + id iid sha before_sha complete status detailed_status config_source name duration queued_duration coverage created_at updated_at started_at finished_at committed_at stages user retryable cancelable jobs source_job job job_artifacts downstream upstream path project active user_permissions warnings commit commit_path uses_needs test_report_summary test_suite ref ref_path warning_messages merge_request_event_type + name total_jobs triggered_by_path child source stuck + latest merge_request ref_text failure_reason ] if Gitlab.ee? expected_fields += %w[ security_report_summary security_report_findings security_report_finding - code_quality_reports dast_profile code_quality_report_summary + code_quality_reports dast_profile code_quality_report_summary compute_minutes ] end diff --git a/spec/graphql/types/current_user_todos_type_spec.rb b/spec/graphql/types/current_user_todos_type_spec.rb index 4ce97e1c006..febbe868f33 100644 --- a/spec/graphql/types/current_user_todos_type_spec.rb +++ b/spec/graphql/types/current_user_todos_type_spec.rb @@ -173,9 +173,7 @@ RSpec.describe GitlabSchema.types['CurrentUserTodos'] do end it 'returns correct data' do - result = execute_query(query_type, - graphql: query_without_state_arguments, - raise_on_error: true).to_h + result = execute_query(query_type, graphql: query_without_state_arguments, raise_on_error: true).to_h expect(result.dig('data', 'a', 'todos', 'nodes')).to contain_exactly( a_graphql_entity_for(todo_a), @@ -198,9 +196,7 @@ RSpec.describe GitlabSchema.types['CurrentUserTodos'] do end it 'returns correct data, when state arguments are supplied' do - result = execute_query(query_type, - raise_on_error: true, - graphql: with_state_arguments).to_h + result = execute_query(query_type, raise_on_error: true, graphql: with_state_arguments).to_h expect(result.dig('data', 'a', 'todos', 'nodes')).to contain_exactly( a_graphql_entity_for(todo_a) diff --git a/spec/graphql/types/design_management/design_collection_copy_state_enum_spec.rb b/spec/graphql/types/design_management/design_collection_copy_state_enum_spec.rb index f536d91aeda..15960407a6f 100644 --- a/spec/graphql/types/design_management/design_collection_copy_state_enum_spec.rb +++ b/spec/graphql/types/design_management/design_collection_copy_state_enum_spec.rb @@ -6,6 +6,6 @@ RSpec.describe GitlabSchema.types['DesignCollectionCopyState'] do it { expect(described_class.graphql_name).to eq('DesignCollectionCopyState') } it 'exposes the correct event states' do - expect(described_class.values.keys).to match_array(%w(READY IN_PROGRESS ERROR)) + expect(described_class.values.keys).to match_array(%w[READY IN_PROGRESS ERROR]) end end diff --git a/spec/graphql/types/issue_type_spec.rb b/spec/graphql/types/issue_type_spec.rb index d4d0eff9adb..f6d461d6a5f 100644 --- a/spec/graphql/types/issue_type_spec.rb +++ b/spec/graphql/types/issue_type_spec.rb @@ -32,7 +32,7 @@ RSpec.describe GitlabSchema.types['Issue'] do let_it_be(:now) { Time.now.change(usec: 0) } let_it_be(:issues) { create_list(:issue, 10, project: project, created_at: now) } - let(:count_path) { %w(data project issues count) } + let(:count_path) { %w[data project issues count] } let(:page_size) { 3 } let(:query) do <<~GRAPHQL @@ -81,8 +81,8 @@ RSpec.describe GitlabSchema.types['Issue'] do end context 'count' do - let(:end_cursor) { %w(data project issues pageInfo endCursor) } - let(:issues_edges) { %w(data project issues edges) } + let(:end_cursor) { %w[data project issues pageInfo endCursor] } + let(:issues_edges) { %w[data project issues edges] } it 'returns total count' do expect(subject.dig(*count_path)).to eq(issues.count) diff --git a/spec/graphql/types/merge_request_type_spec.rb b/spec/graphql/types/merge_request_type_spec.rb index 9742908edf9..be25c5177f6 100644 --- a/spec/graphql/types/merge_request_type_spec.rb +++ b/spec/graphql/types/merge_request_type_spec.rb @@ -37,6 +37,7 @@ RSpec.describe GitlabSchema.types['MergeRequest'], feature_category: :code_revie squash_on_merge available_auto_merge_strategies has_ci mergeable commits committers commits_without_merge_commits squash security_auto_fix default_squash_commit_message auto_merge_strategy merge_user award_emoji prepared_at codequality_reports_comparer supports_lock_on_merge + mergeability_checks ] expect(described_class).to have_graphql_fields(*expected_fields).at_least diff --git a/spec/graphql/types/merge_requests/mergeability_check_identifier_enum_spec.rb b/spec/graphql/types/merge_requests/mergeability_check_identifier_enum_spec.rb new file mode 100644 index 00000000000..093cd670418 --- /dev/null +++ b/spec/graphql/types/merge_requests/mergeability_check_identifier_enum_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Types::MergeRequests::MergeabilityCheckIdentifierEnum, feature_category: :code_review_workflow do + specify { expect(described_class.graphql_name).to eq('MergeabilityCheckIdentifier') } + + it 'exposes all the existing mergeability check identifiers' do + expect(described_class.values.keys).to contain_exactly( + *MergeRequest.all_mergeability_checks.map { |check_class| check_class.identifier.to_s.upcase } + ) + end +end diff --git a/spec/graphql/types/merge_requests/mergeability_check_status_enum_spec.rb b/spec/graphql/types/merge_requests/mergeability_check_status_enum_spec.rb new file mode 100644 index 00000000000..0a15d83f560 --- /dev/null +++ b/spec/graphql/types/merge_requests/mergeability_check_status_enum_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Types::MergeRequests::MergeabilityCheckStatusEnum, feature_category: :code_review_workflow do + specify { expect(described_class.graphql_name).to eq('MergeabilityCheckStatus') } + + it 'exposes all the existing mergeability check statuses' do + expect(described_class.values.keys).to contain_exactly( + *%w[SUCCESS FAILED INACTIVE] + ) + end +end diff --git a/spec/graphql/types/merge_requests/mergeability_check_type_spec.rb b/spec/graphql/types/merge_requests/mergeability_check_type_spec.rb new file mode 100644 index 00000000000..fb6ac0ad271 --- /dev/null +++ b/spec/graphql/types/merge_requests/mergeability_check_type_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Types::MergeRequests::MergeabilityCheckType, feature_category: :code_review_workflow do + let(:fields) { %i[identifier status] } + + specify { expect(described_class.graphql_name).to eq('MergeRequestMergeabilityCheck') } + specify { expect(described_class).to have_graphql_fields(fields) } +end diff --git a/spec/graphql/types/namespace_type_spec.rb b/spec/graphql/types/namespace_type_spec.rb index d80235023ef..9e1a2bfd466 100644 --- a/spec/graphql/types/namespace_type_spec.rb +++ b/spec/graphql/types/namespace_type_spec.rb @@ -15,5 +15,5 @@ RSpec.describe GitlabSchema.types['Namespace'] do expect(described_class).to include_graphql_fields(*expected_fields) end - specify { expect(described_class).to require_graphql_authorizations(:read_namespace) } + specify { expect(described_class).to require_graphql_authorizations(:read_namespace_via_membership) } end diff --git a/spec/graphql/types/packages/package_base_type_spec.rb b/spec/graphql/types/packages/package_base_type_spec.rb index 7156f22c513..ebe29da0539 100644 --- a/spec/graphql/types/packages/package_base_type_spec.rb +++ b/spec/graphql/types/packages/package_base_type_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe GitlabSchema.types['PackageBase'] do +RSpec.describe GitlabSchema.types['PackageBase'], feature_category: :package_registry do specify { expect(described_class.description).to eq('Represents a package in the Package Registry') } specify { expect(described_class).to require_graphql_authorizations(:read_package) } @@ -13,7 +13,7 @@ RSpec.describe GitlabSchema.types['PackageBase'] do created_at updated_at project tags metadata - status can_destroy + status status_message can_destroy ] expect(described_class).to include_graphql_fields(*expected_fields) diff --git a/spec/graphql/types/packages/protection/rule_access_level_enum_spec.rb b/spec/graphql/types/packages/protection/rule_access_level_enum_spec.rb new file mode 100644 index 00000000000..421b5fb0f39 --- /dev/null +++ b/spec/graphql/types/packages/protection/rule_access_level_enum_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['PackagesProtectionRuleAccessLevel'], feature_category: :package_registry do + it 'exposes all options' do + expect(described_class.values.keys).to match_array(%w[DEVELOPER MAINTAINER OWNER]) + end +end diff --git a/spec/graphql/types/packages/protection/rule_package_type_enum_spec.rb b/spec/graphql/types/packages/protection/rule_package_type_enum_spec.rb new file mode 100644 index 00000000000..b0d9772f285 --- /dev/null +++ b/spec/graphql/types/packages/protection/rule_package_type_enum_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['PackagesProtectionRulePackageType'], feature_category: :package_registry do + it 'exposes all options' do + expect(described_class.values.keys).to contain_exactly('NPM') + end +end diff --git a/spec/graphql/types/packages/protection/rule_type_spec.rb b/spec/graphql/types/packages/protection/rule_type_spec.rb new file mode 100644 index 00000000000..a4a458d3568 --- /dev/null +++ b/spec/graphql/types/packages/protection/rule_type_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['PackagesProtectionRule'], feature_category: :package_registry do + specify { expect(described_class.graphql_name).to eq('PackagesProtectionRule') } + + specify { expect(described_class.description).to be_present } + + specify { expect(described_class).to require_graphql_authorizations(:admin_package) } + + describe 'package_name_pattern' do + subject { described_class.fields['packageNamePattern'] } + + it { is_expected.to have_non_null_graphql_type(GraphQL::Types::String) } + end + + describe 'package_type' do + subject { described_class.fields['packageType'] } + + it { is_expected.to have_non_null_graphql_type(Types::Packages::Protection::RulePackageTypeEnum) } + end + + describe 'push_protected_up_to_access_level' do + subject { described_class.fields['pushProtectedUpToAccessLevel'] } + + it { is_expected.to have_non_null_graphql_type(Types::Packages::Protection::RuleAccessLevelEnum) } + end +end diff --git a/spec/graphql/types/project_statistics_type_spec.rb b/spec/graphql/types/project_statistics_type_spec.rb index 558ff41f6f4..f639d042efe 100644 --- a/spec/graphql/types/project_statistics_type_spec.rb +++ b/spec/graphql/types/project_statistics_type_spec.rb @@ -4,9 +4,11 @@ require 'spec_helper' RSpec.describe GitlabSchema.types['ProjectStatistics'] do it 'has the expected fields' do - expect(described_class).to include_graphql_fields(:storage_size, :repository_size, :lfs_objects_size, - :build_artifacts_size, :packages_size, :commit_count, - :wiki_size, :snippets_size, :pipeline_artifacts_size, - :uploads_size, :container_registry_size) + expect(described_class).to include_graphql_fields( + :storage_size, :repository_size, :lfs_objects_size, + :build_artifacts_size, :packages_size, :commit_count, + :wiki_size, :snippets_size, :pipeline_artifacts_size, + :uploads_size, :container_registry_size + ) end end diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb index a20a4767bb5..e295014a2a6 100644 --- a/spec/graphql/types/project_type_spec.rb +++ b/spec/graphql/types/project_type_spec.rb @@ -39,6 +39,7 @@ RSpec.describe GitlabSchema.types['Project'] do recent_issue_boards ci_config_path_or_default packages_cleanup_policy ci_variables timelog_categories fork_targets branch_rules ci_config_variables pipeline_schedules languages incident_management_timeline_event_tags visible_forks inherited_ci_variables autocomplete_users + ci_cd_settings ] expect(described_class).to include_graphql_fields(*expected_fields) @@ -328,30 +329,31 @@ RSpec.describe GitlabSchema.types['Project'] do it { is_expected.to have_graphql_resolver(Resolvers::ProjectMergeRequestsResolver) } it do - is_expected.to have_graphql_arguments(:iids, - :source_branches, - :target_branches, - :state, - :draft, - :approved, - :labels, - :before, - :after, - :first, - :last, - :merged_after, - :merged_before, - :created_after, - :created_before, - :updated_after, - :updated_before, - :author_username, - :assignee_username, - :reviewer_username, - :milestone_title, - :not, - :sort - ) + is_expected.to have_graphql_arguments( + :iids, + :source_branches, + :target_branches, + :state, + :draft, + :approved, + :labels, + :before, + :after, + :first, + :last, + :merged_after, + :merged_before, + :created_after, + :created_before, + :updated_after, + :updated_before, + :author_username, + :assignee_username, + :reviewer_username, + :milestone_title, + :not, + :sort + ) end end @@ -755,23 +757,29 @@ RSpec.describe GitlabSchema.types['Project'] do describe 'timeline_event_tags' do let_it_be(:user) { create(:user) } let_it_be(:project) do - create(:project, - :private, - :repository, - creator_id: user.id, - namespace: user.namespace) + create( + :project, + :private, + :repository, + creator_id: user.id, + namespace: user.namespace + ) end let_it_be(:tag1) do - create(:incident_management_timeline_event_tag, - project: project, - name: 'Tag 1') + create( + :incident_management_timeline_event_tag, + project: project, + name: 'Tag 1' + ) end let_it_be(:tag2) do - create(:incident_management_timeline_event_tag, - project: project, - name: 'Tag 2') + create( + :incident_management_timeline_event_tag, + project: project, + name: 'Tag 2' + ) end let(:query) do @@ -809,11 +817,13 @@ RSpec.describe GitlabSchema.types['Project'] do describe 'languages' do let_it_be(:user) { create(:user) } let_it_be(:project) do - create(:project, - :private, - :repository, - creator_id: user.id, - namespace: user.namespace) + create( + :project, + :private, + :repository, + creator_id: user.id, + namespace: user.namespace + ) end let(:query) do diff --git a/spec/graphql/types/snippet_type_spec.rb b/spec/graphql/types/snippet_type_spec.rb index a46c51e0a27..1fc9bc8b429 100644 --- a/spec/graphql/types/snippet_type_spec.rb +++ b/spec/graphql/types/snippet_type_spec.rb @@ -8,7 +8,7 @@ RSpec.describe GitlabSchema.types['Snippet'] do let_it_be(:user) { create(:user) } it 'has the correct fields' do - expected_fields = [:id, :title, :project, :author, + expected_fields = [:id, :title, :project, :author, :hidden, :file_name, :description, :visibility_level, :created_at, :updated_at, :web_url, :raw_url, :ssh_url_to_repo, :http_url_to_repo, diff --git a/spec/graphql/types/todo_type_spec.rb b/spec/graphql/types/todo_type_spec.rb index 2118a777a45..af1981e804c 100644 --- a/spec/graphql/types/todo_type_spec.rb +++ b/spec/graphql/types/todo_type_spec.rb @@ -32,13 +32,15 @@ RSpec.describe GitlabSchema.types['Todo'] do describe 'project field' do let(:todo) do - create(:todo, - user: current_user, - project: project, - state: :done, - action: Todo::ASSIGNED, - author: author, - target: issue) + create( + :todo, + user: current_user, + project: project, + state: :done, + action: Todo::ASSIGNED, + author: author, + target: issue + ) end let(:query) do @@ -86,13 +88,15 @@ RSpec.describe GitlabSchema.types['Todo'] do describe 'group field' do let(:todo) do - create(:todo, - user: current_user, - group: group, - state: :done, - action: Todo::MENTIONED, - author: author, - target: issue) + create( + :todo, + user: current_user, + group: group, + state: :done, + action: Todo::MENTIONED, + author: author, + target: issue + ) end let(:query) do diff --git a/spec/graphql/types/work_item_type_spec.rb b/spec/graphql/types/work_item_type_spec.rb index 328450084c2..e57f7aa77ce 100644 --- a/spec/graphql/types/work_item_type_spec.rb +++ b/spec/graphql/types/work_item_type_spec.rb @@ -31,6 +31,7 @@ RSpec.describe GitlabSchema.types['WorkItem'], feature_category: :team_planning web_url create_note_email reference + archived ] expect(described_class).to have_graphql_fields(*fields) diff --git a/spec/graphql/types/work_items/widgets/hierarchy_type_spec.rb b/spec/graphql/types/work_items/widgets/hierarchy_type_spec.rb index 20413a35c58..a46ffc3db50 100644 --- a/spec/graphql/types/work_items/widgets/hierarchy_type_spec.rb +++ b/spec/graphql/types/work_items/widgets/hierarchy_type_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Types::WorkItems::Widgets::HierarchyType, feature_category: :team_planning do it 'exposes the expected fields' do - expected_fields = %i[parent children has_children type] + expected_fields = %i[parent children has_children ancestors type] expect(described_class).to have_graphql_fields(*expected_fields) end |