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:
Diffstat (limited to 'spec/graphql')
-rw-r--r--spec/graphql/mutations/base_mutation_spec.rb2
-rw-r--r--spec/graphql/mutations/design_management/delete_spec.rb35
-rw-r--r--spec/graphql/mutations/work_items/linked_items/base_spec.rb3
-rw-r--r--spec/graphql/resolvers/base_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/blame_resolver_spec.rb81
-rw-r--r--spec/graphql/resolvers/branch_commit_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb117
-rw-r--r--spec/graphql/resolvers/ci/group_runners_resolver_spec.rb20
-rw-r--r--spec/graphql/resolvers/ci/project_runners_resolver_spec.rb16
-rw-r--r--spec/graphql/resolvers/ci/runners_resolver_spec.rb30
-rw-r--r--spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb16
-rw-r--r--spec/graphql/resolvers/work_items_resolver_spec.rb5
-rw-r--r--spec/graphql/types/base_argument_spec.rb2
-rw-r--r--spec/graphql/types/base_edge_spec.rb2
-rw-r--r--spec/graphql/types/base_enum_spec.rb2
-rw-r--r--spec/graphql/types/base_field_spec.rb2
-rw-r--r--spec/graphql/types/base_object_spec.rb2
-rw-r--r--spec/graphql/types/blame/blame_type_spec.rb16
-rw-r--r--spec/graphql/types/blame/commit_data_type_spec.rb21
-rw-r--r--spec/graphql/types/blame/groups_type_spec.rb19
-rw-r--r--spec/graphql/types/ci/job_base_field_spec.rb143
-rw-r--r--spec/graphql/types/ci/job_kind_enum_spec.rb2
-rw-r--r--spec/graphql/types/ci/job_trace_type_spec.rb184
-rw-r--r--spec/graphql/types/ci/job_type_spec.rb1
-rw-r--r--spec/graphql/types/issue_type_spec.rb2
-rw-r--r--spec/graphql/types/label_type_spec.rb1
-rw-r--r--spec/graphql/types/merge_request_type_spec.rb2
-rw-r--r--spec/graphql/types/organizations/group_sort_enum_spec.rb26
-rw-r--r--spec/graphql/types/organizations/organization_type_spec.rb11
-rw-r--r--spec/graphql/types/organizations/organization_user_type_spec.rb11
-rw-r--r--spec/graphql/types/permission_types/work_item_spec.rb2
-rw-r--r--spec/graphql/types/project_type_spec.rb11
-rw-r--r--spec/graphql/types/query_type_spec.rb10
-rw-r--r--spec/graphql/types/repository/blob_type_spec.rb1
-rw-r--r--spec/graphql/types/security/codequality_reports_comparer/degradation_type_spec.rb13
-rw-r--r--spec/graphql/types/security/codequality_reports_comparer/report_type_spec.rb13
-rw-r--r--spec/graphql/types/security/codequality_reports_comparer/status_enum_spec.rb11
-rw-r--r--spec/graphql/types/security/codequality_reports_comparer/summary_type_spec.rb13
-rw-r--r--spec/graphql/types/security/codequality_reports_comparer_type_spec.rb11
39 files changed, 758 insertions, 105 deletions
diff --git a/spec/graphql/mutations/base_mutation_spec.rb b/spec/graphql/mutations/base_mutation_spec.rb
index 6b366b0c234..a73d914f48f 100644
--- a/spec/graphql/mutations/base_mutation_spec.rb
+++ b/spec/graphql/mutations/base_mutation_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe ::Mutations::BaseMutation do
+RSpec.describe ::Mutations::BaseMutation, feature_category: :api do
include GraphqlHelpers
describe 'argument nullability' do
diff --git a/spec/graphql/mutations/design_management/delete_spec.rb b/spec/graphql/mutations/design_management/delete_spec.rb
index a76943b9ff8..9a2efb61e55 100644
--- a/spec/graphql/mutations/design_management/delete_spec.rb
+++ b/spec/graphql/mutations/design_management/delete_spec.rb
@@ -90,12 +90,12 @@ 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-06-15
+ # Queries: as of 2022-08-30
# -------------
# 01. routing query
- # 02. find project by id
- # 03. project.project_features
- # 04. find namespace by id and type
+ # 02. policy query: find namespace by type and id
+ # 03. policy query: find namespace by id
+ # 04. policy query: project.project_feature
# 05,06. project.authorizations for user (same query twice)
# 07. find issue by iid
# 08. find project by id
@@ -109,21 +109,22 @@ RSpec.describe Mutations::DesignManagement::Delete do
# 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
- # 20. find plan for standard context
# ------------- our queries are below:
- # 21. start transaction 1
- # 22. start transaction 2
- # 23. find version by sha and issue
- # 24. exists version with sha and issue?
- # 25. leave transaction 2
- # 26. create version with sha and issue
- # 27. create design-version links
- # 28. validate version.actions.present?
- # 29. validate version.issue.present?
- # 30. validate version.sha is unique
- # 31. leave transaction 1
+ # 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)
+ # 30. find project by id (same query as 8)
+ # 31. create event
+ # 32. find plan for standard context
#
- expect { run_mutation }.not_to exceed_query_limit(31)
+ expect { run_mutation }.not_to exceed_query_limit(32)
end
end
diff --git a/spec/graphql/mutations/work_items/linked_items/base_spec.rb b/spec/graphql/mutations/work_items/linked_items/base_spec.rb
index 7061c37abd3..bc52aee443e 100644
--- a/spec/graphql/mutations/work_items/linked_items/base_spec.rb
+++ b/spec/graphql/mutations/work_items/linked_items/base_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe Mutations::WorkItems::LinkedItems::Base, feature_category: :group
it 'raises a NotImplementedError error if the update_links method is called on the base class' do
mutation = described_class.new(context: { current_user: user }, object: nil, field: nil)
- expect { mutation.resolve(id: work_item.to_gid) }.to raise_error(NotImplementedError)
+ expect { mutation.resolve(id: work_item.to_gid) }
+ .to raise_error(NotImplementedError, "#{described_class} does not implement update_links")
end
end
diff --git a/spec/graphql/resolvers/base_resolver_spec.rb b/spec/graphql/resolvers/base_resolver_spec.rb
index d80a61fd318..27c62da31c3 100644
--- a/spec/graphql/resolvers/base_resolver_spec.rb
+++ b/spec/graphql/resolvers/base_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::BaseResolver do
+RSpec.describe Resolvers::BaseResolver, feature_category: :api do
include GraphqlHelpers
let(:resolver) do
diff --git a/spec/graphql/resolvers/blame_resolver_spec.rb b/spec/graphql/resolvers/blame_resolver_spec.rb
new file mode 100644
index 00000000000..a3344132928
--- /dev/null
+++ b/spec/graphql/resolvers/blame_resolver_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::BlameResolver, feature_category: :source_code_management do
+ include GraphqlHelpers
+
+ describe '#resolve' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:path) { 'files/ruby/popen.rb' }
+ let(:commit) { project.commit('master') }
+ let(:blob) { project.repository.blob_at(commit.id, path) }
+ let(:args) { { from_line: 1, to_line: 2 } }
+
+ subject(:resolve_blame) { resolve(described_class, obj: blob, args: args, ctx: { current_user: user }) }
+
+ context 'when unauthorized' do
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_blame
+ end
+ end
+ end
+
+ context 'when authorized' do
+ before_all do
+ project.add_developer(user)
+ end
+
+ context 'when feature is disabled' do
+ before do
+ stub_feature_flags(graphql_git_blame: false)
+ end
+
+ it 'returns nothing' do
+ expect(subject).to be_nil
+ end
+ end
+
+ shared_examples 'argument error' do
+ it 'raises an ArgumentError' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError,
+ '`from_line` and `to_line` must be greater than or equal to 1') do
+ resolve_blame
+ end
+ end
+ end
+
+ context 'when feature is enabled' do
+ context 'when from_line is below 1' do
+ let(:args) { { from_line: 0, to_line: 2 } }
+
+ it_behaves_like 'argument error'
+ end
+
+ context 'when to_line is below 1' do
+ let(:args) { { from_line: 1, to_line: 0 } }
+
+ it_behaves_like 'argument error'
+ end
+
+ context 'when to_line less than from_line' do
+ let(:args) { { from_line: 3, to_line: 1 } }
+
+ it 'returns blame object' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError,
+ '`to_line` must be greater than or equal to `from_line`') do
+ resolve_blame
+ end
+ end
+ end
+
+ it 'returns blame object' do
+ expect(resolve_blame).to be_an_instance_of(Gitlab::Blame)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/branch_commit_resolver_spec.rb b/spec/graphql/resolvers/branch_commit_resolver_spec.rb
index 3d5702539fa..f901306a355 100644
--- a/spec/graphql/resolvers/branch_commit_resolver_spec.rb
+++ b/spec/graphql/resolvers/branch_commit_resolver_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe Resolvers::BranchCommitResolver do
commit_a = repository.commits('master', limit: 1).last
commit_b = repository.commits('spooky-stuff', limit: 1).last
- commits = batch_sync(max_queries: 1) do
+ commits = batch_sync(max_queries: 2) do
[
resolve(described_class, obj: branch),
resolve(described_class, obj: repository.find_branch('spooky-stuff'))
diff --git a/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb b/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb
index fddc73fadfe..6b9e3a484b1 100644
--- a/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb
@@ -5,37 +5,114 @@ require 'spec_helper'
RSpec.describe Resolvers::Ci::AllJobsResolver, feature_category: :continuous_integration do
include GraphqlHelpers
- let_it_be(:successful_job) { create(:ci_build, :success, name: 'Job One') }
- let_it_be(:successful_job_two) { create(:ci_build, :success, name: 'Job Two') }
- let_it_be(:failed_job) { create(:ci_build, :failed, name: 'Job Three') }
- let_it_be(:pending_job) { create(:ci_build, :pending, name: 'Job Three') }
+ let_it_be(:instance_runner) { create(:ci_runner, :instance) }
+ let_it_be(:successful_job) { create(:ci_build, :success, name: 'successful_job') }
+ let_it_be(:successful_job_two) { create(:ci_build, :success, name: 'successful_job_two') }
+ let_it_be(:failed_job) { create(:ci_build, :failed, name: 'failed_job') }
+ let_it_be(:pending_job) { create(:ci_build, :pending, name: 'pending_job') }
let(:args) { {} }
- subject { resolve_jobs(args) }
-
describe '#resolve' do
- context 'with admin' do
- let(:current_user) { create(:admin) }
+ subject(:request) { resolve_jobs(args) }
+
+ context 'when current user is an admin' do
+ let_it_be(:current_user) { create(:admin) }
shared_examples 'executes as admin' do
- context 'with statuses argument' do
- let(:args) { { statuses: [Types::Ci::JobStatusEnum.coerce_isolated_input('SUCCESS')] } }
+ context "with argument `statuses`" do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:statuses, :expected_jobs) do
+ nil | lazy { [successful_job, successful_job_two, failed_job, pending_job] }
+ %w[SUCCESS] | lazy { [successful_job, successful_job_two] }
+ %w[SUCCESS FAILED] | lazy { [successful_job, successful_job_two, failed_job] }
+ %w[CANCELED] | lazy { [] }
+ end
- it { is_expected.to contain_exactly(successful_job, successful_job_two) }
+ with_them do
+ let(:args) do
+ { statuses: statuses&.map { |status| Types::Ci::JobStatusEnum.coerce_isolated_input(status) } }
+ end
+
+ it { is_expected.to contain_exactly(*expected_jobs) }
+ end
end
- context 'with multiple statuses' do
- let(:args) do
- { statuses: [Types::Ci::JobStatusEnum.coerce_isolated_input('SUCCESS'),
- Types::Ci::JobStatusEnum.coerce_isolated_input('FAILED')] }
+ context "with argument `runner_types`" do
+ let_it_be(:successful_job_with_instance_runner) do
+ create(:ci_build, :success, name: 'successful_job_with_instance_runner', runner: instance_runner)
end
- it { is_expected.to contain_exactly(successful_job, successful_job_two, failed_job) }
+ context 'with feature flag :admin_jobs_filter_runner_type enabled' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:runner_types, :expected_jobs) do
+ nil | lazy do
+ [
+ successful_job,
+ successful_job_two,
+ failed_job,
+ pending_job,
+ successful_job_with_instance_runner
+ ]
+ end
+ %w[INSTANCE_TYPE] | lazy { [successful_job_with_instance_runner] }
+ %w[INSTANCE_TYPE GROUP_TYPE] | lazy { [successful_job_with_instance_runner] }
+ %w[PROJECT_TYPE] | lazy { [] }
+ end
+
+ with_them do
+ let(:args) do
+ {
+ runner_types: runner_types&.map { |type| Types::Ci::RunnerTypeEnum.coerce_isolated_input(type) }
+ }
+ end
+
+ it { is_expected.to match_array(expected_jobs) }
+ end
+ end
end
- context 'without statuses argument' do
- it { is_expected.to contain_exactly(successful_job, successful_job_two, failed_job, pending_job) }
+ context "with argument combination" do
+ let_it_be(:successful_job_with_instance_runner) do
+ create(
+ :ci_build,
+ :success,
+ name: 'successful_job_with_instance_runner',
+ runner: instance_runner
+ )
+ end
+
+ let_it_be(:running_job_with_group_runner) do
+ create(:ci_build, :running, name: 'running_job_with_instance_runner', runner: create(:ci_runner, :group))
+ end
+
+ context 'with feature flag :admin_jobs_filter_runner_type enabled' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:statuses, :runner_types, :expected_jobs) do
+ %w[SUCCESS] | %w[INSTANCE_TYPE] | lazy { [successful_job_with_instance_runner] }
+ %w[CANCELED] | %w[INSTANCE_TYPE] | lazy { [] }
+ %w[SUCCESS RUNNING] | %w[INSTANCE_TYPE GROUP_TYPE] | lazy do
+ [
+ successful_job_with_instance_runner,
+ running_job_with_group_runner
+ ]
+ end
+ end
+
+ with_them do
+ let(:args) do
+ {
+ statuses: statuses&.map { |status| Types::Ci::JobStatusEnum.coerce_isolated_input(status) },
+ runner_types: runner_types&.map { |type| Types::Ci::RunnerTypeEnum.coerce_isolated_input(type) }
+ }
+ end
+
+ it { is_expected.to contain_exactly(*expected_jobs) }
+ end
+ end
end
end
@@ -55,7 +132,9 @@ RSpec.describe Resolvers::Ci::AllJobsResolver, feature_category: :continuous_int
end
context 'with unauthorized user' do
- let(:current_user) { nil }
+ let_it_be(:unauth_user) { create(:user) }
+
+ let(:current_user) { unauth_user }
it { is_expected.to be_empty }
end
diff --git a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb
index ff343f3f43d..fedae5c86a8 100644
--- a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl
include GraphqlHelpers
describe '#resolve' do
- subject do
+ subject(:resolve_scope) do
resolve(described_class, obj: obj, ctx: { current_user: user }, args: args,
arg_style: :internal)
end
@@ -18,8 +18,10 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl
# First, we can do a couple of basic real tests to verify common cases. That ensures that the code works.
context 'when user cannot see runners' do
- it 'returns no runners' do
- expect(subject.items.to_a).to eq([])
+ it 'returns Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_scope
+ end
end
end
@@ -29,14 +31,16 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl
end
it 'returns all the runners' do
- expect(subject.items.to_a).to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, subgroup_runner)
+ expect(resolve_scope.items.to_a).to contain_exactly(
+ inactive_project_runner, offline_project_runner, group_runner, subgroup_runner
+ )
end
context 'with membership direct' do
let(:args) { { membership: :direct } }
it 'returns only direct runners' do
- expect(subject.items.to_a).to contain_exactly(group_runner)
+ expect(resolve_scope.items.to_a).to contain_exactly(group_runner)
end
end
end
@@ -46,7 +50,7 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl
let(:obj) { nil }
it 'raises an error' do
- expect { subject }.to raise_error('Expected group missing')
+ expect { resolve_scope }.to raise_error('Expected group missing')
end
end
@@ -54,7 +58,7 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl
let(:obj) { build(:project) }
it 'raises an error' do
- expect { subject }.to raise_error('Expected group missing')
+ expect { resolve_scope }.to raise_error('Expected group missing')
end
end
@@ -90,7 +94,7 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fl
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(subject.items.to_a).to eq([:execute_return_value])
+ expect(resolve_scope.items.to_a).to eq([:execute_return_value])
end
end
end
diff --git a/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb
index 83435db2ea7..55a98106baf 100644
--- a/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_
include GraphqlHelpers
describe '#resolve' do
- subject do
+ subject(:resolve_scope) do
resolve(described_class, obj: obj, ctx: { current_user: user }, args: args,
arg_style: :internal)
end
@@ -17,8 +17,10 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_
let(:args) { {} }
context 'when user cannot see runners' do
- it 'returns no runners' do
- expect(subject.items.to_a).to eq([])
+ it 'returns Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_scope
+ end
end
end
@@ -30,7 +32,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_
let(:available_runners) { [inactive_project_runner, offline_project_runner, group_runner, instance_runner] }
it 'returns all runners available to the project' do
- expect(subject.items.to_a).to match_array(available_runners)
+ expect(resolve_scope.items.to_a).to match_array(available_runners)
end
end
@@ -38,7 +40,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_
let(:obj) { nil }
it 'raises an error' do
- expect { subject }.to raise_error('Expected project missing')
+ expect { resolve_scope }.to raise_error('Expected project missing')
end
end
@@ -46,7 +48,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_
let(:obj) { build(:group) }
it 'raises an error' do
- expect { subject }.to raise_error('Expected project missing')
+ expect { resolve_scope }.to raise_error('Expected project missing')
end
end
@@ -79,7 +81,7 @@ RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_
params: expected_params).once.and_return(finder)
allow(finder).to receive(:execute).once.and_return([:execute_return_value])
- expect(subject.items.to_a).to eq([:execute_return_value])
+ expect(resolve_scope.items.to_a).to contain_exactly(:execute_return_value)
end
end
end
diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
index 02fc7d28255..35831579799 100644
--- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
@@ -20,8 +20,10 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d
context 'when user cannot see runners' do
let(:user) { build(:user) }
- it 'returns no runners' do
- expect(subject.items.to_a).to eq([])
+ it 'returns Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_scope
+ end
end
end
@@ -30,20 +32,26 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d
context 'when admin mode setting is disabled', :do_not_mock_admin_mode_setting do
it 'returns all the runners' do
- expect(subject.items.to_a).to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, subgroup_runner, instance_runner)
+ expect(resolve_scope.items.to_a).to contain_exactly(
+ inactive_project_runner, offline_project_runner, group_runner, subgroup_runner, instance_runner
+ )
end
end
context 'when admin mode setting is enabled' do
context 'when in admin mode', :enable_admin_mode do
it 'returns all the runners' do
- expect(subject.items.to_a).to contain_exactly(inactive_project_runner, offline_project_runner, group_runner, subgroup_runner, instance_runner)
+ expect(resolve_scope.items.to_a).to contain_exactly(
+ inactive_project_runner, offline_project_runner, group_runner, subgroup_runner, instance_runner
+ )
end
end
context 'when not in admin mode' do
- it 'returns no runners' do
- expect(subject.items.to_a).to eq([])
+ it 'returns Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_scope
+ end
end
end
end
@@ -54,7 +62,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d
let(:obj) { build(:project) }
it 'raises an error' do
- expect { subject }.to raise_error(a_string_including('Unexpected parent type'))
+ expect { resolve_scope }.to raise_error(a_string_including('Unexpected parent type'))
end
end
@@ -93,7 +101,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d
expect(::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(subject.items.to_a).to eq([:execute_return_value])
+ expect(resolve_scope.items.to_a).to contain_exactly :execute_return_value
end
end
@@ -116,7 +124,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d
expect(::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(subject.items.to_a).to eq([:execute_return_value])
+ expect(resolve_scope.items.to_a).to contain_exactly :execute_return_value
end
end
@@ -136,7 +144,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d
expect(::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(subject.items.to_a).to eq([:execute_return_value])
+ expect(resolve_scope.items.to_a).to contain_exactly :execute_return_value
end
end
@@ -153,7 +161,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet d
expect(::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(subject.items.to_a).to eq([:execute_return_value])
+ expect(resolve_scope.items.to_a).to contain_exactly :execute_return_value
end
end
end
diff --git a/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb b/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb
index 75e0a816086..a4b957ef8e9 100644
--- a/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb
+++ b/spec/graphql/resolvers/metrics/dashboards/annotation_resolver_spec.rb
@@ -24,22 +24,8 @@ RSpec.describe Resolvers::Metrics::Dashboards::AnnotationResolver, feature_categ
environment.project.add_developer(current_user)
end
- before do
- stub_feature_flags(remove_monitor_metrics: false)
- end
-
context 'with annotation records' do
- context 'when metrics dashboard feature is unavailable' do
- before do
- stub_feature_flags(remove_monitor_metrics: true)
- end
-
- it 'returns nothing' do
- expect(resolve_annotations).to be_nil
- end
- end
-
- it 'returns [] all the time' do
+ it 'returns empty all the time' do
expect(resolve_annotations).to be_empty
end
end
diff --git a/spec/graphql/resolvers/work_items_resolver_spec.rb b/spec/graphql/resolvers/work_items_resolver_spec.rb
index 6da62e3adb7..c856f990e7a 100644
--- a/spec/graphql/resolvers/work_items_resolver_spec.rb
+++ b/spec/graphql/resolvers/work_items_resolver_spec.rb
@@ -46,11 +46,6 @@ RSpec.describe Resolvers::WorkItemsResolver do
expect(resolve_items).to contain_exactly(item1, item2)
end
- it 'filters by state' do
- expect(resolve_items(state: 'opened')).to contain_exactly(item1)
- expect(resolve_items(state: 'closed')).to contain_exactly(item2)
- end
-
context 'when searching items' do
it_behaves_like 'graphql query for searching issuables' do
let_it_be(:parent) { project }
diff --git a/spec/graphql/types/base_argument_spec.rb b/spec/graphql/types/base_argument_spec.rb
index 8f5f2e08799..0ce6aa3667d 100644
--- a/spec/graphql/types/base_argument_spec.rb
+++ b/spec/graphql/types/base_argument_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::BaseArgument do
+RSpec.describe Types::BaseArgument, feature_category: :api do
let_it_be(:field) do
Types::BaseField.new(name: 'field', type: String, null: true)
end
diff --git a/spec/graphql/types/base_edge_spec.rb b/spec/graphql/types/base_edge_spec.rb
index b02ccbaffef..0cc0c838fac 100644
--- a/spec/graphql/types/base_edge_spec.rb
+++ b/spec/graphql/types/base_edge_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::BaseEdge do
+RSpec.describe Types::BaseEdge, feature_category: :api do
include GraphqlHelpers
let_it_be(:test_schema) do
diff --git a/spec/graphql/types/base_enum_spec.rb b/spec/graphql/types/base_enum_spec.rb
index 65a345052c7..db8fb877390 100644
--- a/spec/graphql/types/base_enum_spec.rb
+++ b/spec/graphql/types/base_enum_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::BaseEnum do
+RSpec.describe Types::BaseEnum, feature_category: :api do
describe '.from_rails_enum' do
let(:enum_type) { Class.new(described_class) }
let(:template) { "The name is '%{name}', James %{name}." }
diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb
index 9f8a8717efb..831d36950db 100644
--- a/spec/graphql/types/base_field_spec.rb
+++ b/spec/graphql/types/base_field_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::BaseField do
+RSpec.describe Types::BaseField, feature_category: :api do
describe 'authorized?' do
let(:object) { double }
let(:current_user) { nil }
diff --git a/spec/graphql/types/base_object_spec.rb b/spec/graphql/types/base_object_spec.rb
index 3c42c708187..af0639e84d3 100644
--- a/spec/graphql/types/base_object_spec.rb
+++ b/spec/graphql/types/base_object_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::BaseObject do
+RSpec.describe Types::BaseObject, feature_category: :api do
include GraphqlHelpers
describe 'scoping items' do
diff --git a/spec/graphql/types/blame/blame_type_spec.rb b/spec/graphql/types/blame/blame_type_spec.rb
new file mode 100644
index 00000000000..15846130edb
--- /dev/null
+++ b/spec/graphql/types/blame/blame_type_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Blame::BlameType, feature_category: :source_code_management do
+ include GraphqlHelpers
+
+ specify { expect(described_class.graphql_name).to eq('Blame') }
+
+ specify do
+ expect(described_class).to have_graphql_fields(
+ :first_line,
+ :groups
+ ).at_least
+ end
+end
diff --git a/spec/graphql/types/blame/commit_data_type_spec.rb b/spec/graphql/types/blame/commit_data_type_spec.rb
new file mode 100644
index 00000000000..432f09bf8f7
--- /dev/null
+++ b/spec/graphql/types/blame/commit_data_type_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Blame::CommitDataType,
+ feature_category: :source_code_management do
+ include GraphqlHelpers
+
+ specify { expect(described_class.graphql_name).to eq('CommitData') }
+
+ specify do
+ expect(described_class).to have_graphql_fields(
+ :age_map_class,
+ :author_avatar,
+ :commit_author_link,
+ :commit_link,
+ :project_blame_link,
+ :time_ago_tooltip
+ ).at_least
+ end
+end
diff --git a/spec/graphql/types/blame/groups_type_spec.rb b/spec/graphql/types/blame/groups_type_spec.rb
new file mode 100644
index 00000000000..9e870e1cdc0
--- /dev/null
+++ b/spec/graphql/types/blame/groups_type_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Blame::GroupsType, feature_category: :source_code_management do
+ include GraphqlHelpers
+
+ specify { expect(described_class.graphql_name).to eq('Groups') }
+
+ specify do
+ expect(described_class).to have_graphql_fields(
+ :commit,
+ :commit_data,
+ :lineno,
+ :lines,
+ :span
+ ).at_least
+ end
+end
diff --git a/spec/graphql/types/ci/job_base_field_spec.rb b/spec/graphql/types/ci/job_base_field_spec.rb
new file mode 100644
index 00000000000..2d283ce854d
--- /dev/null
+++ b/spec/graphql/types/ci/job_base_field_spec.rb
@@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::JobBaseField, feature_category: :runner_fleet do
+ describe 'authorized?' do
+ let_it_be(:current_user) { create(:user) }
+
+ let(:object) { double }
+ let(:ctx) { { current_user: current_user, current_field: current_field } }
+ let(:current_field) { instance_double(described_class, original_name: current_field_name.to_sym) }
+ let(:args) { {} }
+
+ subject(:field) do
+ described_class.new(name: current_field_name, type: GraphQL::Types::String, null: true, **args)
+ end
+
+ context 'when :job_field_authorization is specified' do
+ let(:ctx) { { current_user: current_user, current_field: current_field, job_field_authorization: :foo } }
+
+ context 'with public field' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:current_field_name) do
+ %i[allow_failure duration id kind status created_at finished_at queued_at queued_duration updated_at runner]
+ end
+
+ with_them do
+ it 'returns true without authorizing' do
+ is_expected.to be_authorized(object, nil, ctx)
+ end
+ end
+ end
+
+ context 'with private field' do
+ let(:current_field_name) { 'short_sha' }
+
+ context 'when permission is not allowed' do
+ it 'returns false' do
+ expect(Ability).to receive(:allowed?).with(current_user, :foo, object).and_return(false)
+
+ is_expected.not_to be_authorized(object, nil, ctx)
+ end
+ end
+
+ context 'when permission is allowed' do
+ it 'returns true' do
+ expect(Ability).to receive(:allowed?).with(current_user, :foo, object).and_return(true)
+
+ is_expected.to be_authorized(object, nil, ctx)
+ end
+ end
+ end
+ end
+
+ context 'when :job_field_authorization is not specified' do
+ let(:current_field_name) { 'status' }
+
+ it 'defaults to true' do
+ is_expected.to be_authorized(object, nil, ctx)
+ end
+
+ context 'when field is authorized' do
+ let(:args) { { authorize: :foo } }
+
+ it 'tests the field authorization' do
+ expect(Ability).to receive(:allowed?).with(current_user, :foo, object).and_return(false)
+
+ expect(field).not_to be_authorized(object, nil, ctx)
+ end
+
+ it 'tests the field authorization, if provided, when it succeeds' do
+ expect(Ability).to receive(:allowed?).with(current_user, :foo, object).and_return(true)
+
+ expect(field).to be_authorized(object, nil, ctx)
+ end
+ end
+
+ context 'with field resolver' do
+ let(:resolver) { Class.new }
+ let(:args) { { resolver_class: resolver } }
+
+ it 'only tests the resolver authorization if it authorizes_object?' do
+ is_expected.to be_authorized(object, nil, ctx)
+ end
+
+ context 'when resolver authorizes object' do
+ let(:resolver) do
+ Class.new do
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ authorizes_object!
+ end
+ end
+
+ it 'tests the resolver authorization, if provided' do
+ expect(resolver).to receive(:authorized?).with(object, ctx).and_return(false)
+
+ expect(field).not_to be_authorized(object, nil, ctx)
+ end
+
+ context 'when field is authorized' do
+ let(:args) { { authorize: :foo, resolver_class: resolver } }
+
+ it 'tests field authorization before resolver authorization, when field auth fails' do
+ expect(Ability).to receive(:allowed?).with(current_user, :foo, object).and_return(false)
+ expect(resolver).not_to receive(:authorized?)
+
+ expect(field).not_to be_authorized(object, nil, ctx)
+ end
+
+ it 'tests field authorization before resolver authorization, when field auth succeeds' do
+ expect(Ability).to receive(:allowed?).with(current_user, :foo, object).and_return(true)
+ expect(resolver).to receive(:authorized?).with(object, ctx).and_return(false)
+
+ expect(field).not_to be_authorized(object, nil, ctx)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ describe '#resolve' do
+ context 'when late_extensions is given' do
+ it 'registers the late extensions after the regular extensions' do
+ extension_class = Class.new(GraphQL::Schema::Field::ConnectionExtension)
+ field = described_class.new(name: 'private_field', type: GraphQL::Types::String.connection_type,
+ null: true, late_extensions: [extension_class])
+
+ expect(field.extensions.last.class).to be(extension_class)
+ end
+ end
+ end
+
+ include_examples 'Gitlab-style deprecations' do
+ def subject(args = {})
+ base_args = { name: 'private_field', type: GraphQL::Types::String, null: true }
+
+ described_class.new(**base_args.merge(args))
+ end
+ end
+end
diff --git a/spec/graphql/types/ci/job_kind_enum_spec.rb b/spec/graphql/types/ci/job_kind_enum_spec.rb
index b48d20b71e2..a09cd89ec8b 100644
--- a/spec/graphql/types/ci/job_kind_enum_spec.rb
+++ b/spec/graphql/types/ci/job_kind_enum_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['CiJobKind'] do
it 'exposes some job type values' do
expect(described_class.values.keys).to match_array(
- (%w[BRIDGE BUILD])
+ %w[BRIDGE BUILD]
)
end
end
diff --git a/spec/graphql/types/ci/job_trace_type_spec.rb b/spec/graphql/types/ci/job_trace_type_spec.rb
index 71803aa9ece..69123445b8b 100644
--- a/spec/graphql/types/ci/job_trace_type_spec.rb
+++ b/spec/graphql/types/ci/job_trace_type_spec.rb
@@ -13,15 +13,187 @@ RSpec.describe GitlabSchema.types['CiJobTrace'], feature_category: :continuous_i
expect(described_class).to have_graphql_fields(*expected_fields)
end
- it 'shows the correct trace contents' do
- job.trace.set('BUILD TRACE')
+ describe 'htmlSummary' do
+ subject(:resolved_field) { resolve_field(:html_summary, job.trace, args: args) }
- expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
- expect(trace).to receive(:html).with(last_lines: 10).and_call_original
+ context 'when trace contains few lines' do
+ before do
+ job.trace.set('BUILD TRACE')
+ end
+
+ context 'when last_lines is set to 10' do
+ let(:args) { { last_lines: 10 } }
+
+ it 'shows the correct trace contents' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 10, max_size: 16384).and_call_original
+ end
+
+ is_expected.to eq('<span>BUILD TRACE</span>')
+ end
+ end
+ end
+
+ context 'when trace contains many lines' do
+ before do
+ job.trace.set((1..200).map { |i| "Line #{i}" }.join("\n"))
+ end
+
+ def expected_html_trace_contents(line_count)
+ "<span>#{((200 - (line_count - 1))..200).map { |i| "Line #{i}" }.join('<br/>')}</span>"
+ end
+
+ context 'when last_lines is not set' do
+ let(:args) { {} }
+
+ it 'shows the last 10 lines of trace contents' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 10, max_size: 16384).and_call_original
+ end
+
+ is_expected.to eq expected_html_trace_contents(10)
+ end
+ end
+
+ context 'when last_lines is set to a negative number' do
+ let(:args) { { last_lines: -10 } }
+
+ it 'shows the last line of trace contents' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 1, max_size: 16384).and_call_original
+ end
+
+ is_expected.to eq expected_html_trace_contents(1)
+ end
+ end
+
+ context 'when last_lines is set to 10' do
+ let(:args) { { last_lines: 10 } }
+
+ it 'shows the correct trace contents' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 10, max_size: 16384).and_call_original
+ end
+
+ is_expected.to eq expected_html_trace_contents(10)
+ end
+ end
+
+ context 'when last_lines is set to 150' do
+ let(:args) { { last_lines: 150 } }
+
+ it 'shows the last 100 lines of trace contents' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 100, max_size: 16384).and_call_original
+ end
+
+ is_expected.to eq expected_html_trace_contents(100)
+ end
+ end
+ end
+
+ context 'when trace contains long lines' do
+ before do
+ # Creates lines of "aaaaaaaa...aaaaaaaa"
+ job.trace.set((1..20).map { (1..1024).map { "a" }.join("") }.join("\n"))
+ end
+
+ context 'when last_lines is lower than 16KB' do
+ let(:args) { {} }
+
+ it 'shows the whole lines' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 10, max_size: 16384).and_call_original
+ end
+
+ is_expected.to eq "<span>#{(1..10).map { (1..1024).map { 'a' }.join('') }.join('<br/>')}</span>"
+ end
+ end
+
+ context 'when last_lines is higher than 16KB' do
+ let(:args) { { last_lines: 20 } }
+
+ it 'shows only the latest byte' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 20, max_size: 16384).and_call_original
+ end
+
+ is_expected.to eq "<span>#{(1..1009).map { 'a' }.join('')}<br/>" \
+ "#{(1..15).map { (1..1024).map { 'a' }.join('') }.join('<br/>')}</span>"
+ 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) { {} }
+
+ before do
+ stub_const('Types::Ci::JobTraceType::MAX_SIZE_B', 1536)
+ end
+
+ it 'shows only the latest byte' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 10, max_size: 1536).and_call_original
+ end
+
+ is_expected.to eq "<span>#{(1..511).map { 'a' }.join('')}<br/>#{(1..1024).map { 'a' }.join('')}</span>"
+ end
+ end
+
+ context 'when trace is cut at end of a line' do
+ let(:args) { {} }
+
+ before do
+ stub_const('Types::Ci::JobTraceType::MAX_SIZE_B', 2050)
+ end
+
+ it 'shows only the latest byte' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 10, max_size: 2050).and_call_original
+ end
+
+ is_expected.to eq "<span><br/>#{(1..2).map { (1..1024).map { 'a' }.join('') }.join('<br/>')}</span>"
+ end
+ end
end
- resolved_field = resolve_field(:html_summary, job.trace)
+ context 'when trace contains multi-bytes UTF-8' do
+ before do
+ # Creates lines of 4 pound symbol, pound symbol is 2 byte wise in UTF-8
+ # Append an "a" (1 byte character) at the end to cut in the middle of UTF-8
+ job.trace.set((1..20).map { (1..4).map { "£" }.join("") }.join("\n"))
+ end
+
+ context 'when cut in the middle of a codepoint' do
+ before do
+ stub_const('Types::Ci::JobTraceType::MAX_SIZE_B', 5)
+ end
+
+ let(:args) { {} }
- expect(resolved_field).to eq("<span>BUILD TRACE</span>")
+ it 'shows a single "invalid utf-8" symbol' do
+ expect_next_instance_of(Gitlab::Ci::Trace) do |trace|
+ expect(trace).to receive(:html).with(last_lines: 10, max_size: 5).and_call_original
+ end
+
+ is_expected.to eq "<span>�££</span>"
+ end
+ end
+ end
end
end
diff --git a/spec/graphql/types/ci/job_type_spec.rb b/spec/graphql/types/ci/job_type_spec.rb
index f31c0d5255c..a69c6f37ee1 100644
--- a/spec/graphql/types/ci/job_type_spec.rb
+++ b/spec/graphql/types/ci/job_type_spec.rb
@@ -32,6 +32,7 @@ RSpec.describe Types::Ci::JobType, feature_category: :continuous_integration do
needs
pipeline
playable
+ previousStageJobs
previousStageJobsOrNeeds
project
queued_at
diff --git a/spec/graphql/types/issue_type_spec.rb b/spec/graphql/types/issue_type_spec.rb
index 6c4e68fba6b..d4d0eff9adb 100644
--- a/spec/graphql/types/issue_type_spec.rb
+++ b/spec/graphql/types/issue_type_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe GitlabSchema.types['Issue'] do
confidential hidden discussion_locked upvotes downvotes merge_requests_count user_notes_count user_discussions_count web_path web_url relative_position
emails_disabled emails_enabled subscribed time_estimate total_time_spent human_time_estimate human_total_time_spent closed_at created_at updated_at task_completion_status
design_collection alert_management_alert alert_management_alerts severity current_user_todos moved moved_to
- closed_as_duplicate_of create_note_email timelogs project_id customer_relations_contacts escalation_status]
+ closed_as_duplicate_of create_note_email timelogs project_id customer_relations_contacts escalation_status external_author]
fields.each do |field_name|
expect(described_class).to have_graphql_field(field_name)
diff --git a/spec/graphql/types/label_type_spec.rb b/spec/graphql/types/label_type_spec.rb
index 427b5d2dcef..d68945b01e6 100644
--- a/spec/graphql/types/label_type_spec.rb
+++ b/spec/graphql/types/label_type_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe GitlabSchema.types['Label'] do
:description_html,
:title,
:color,
+ :lock_on_merge,
:text_color,
:created_at,
:updated_at
diff --git a/spec/graphql/types/merge_request_type_spec.rb b/spec/graphql/types/merge_request_type_spec.rb
index bd271da55a9..9742908edf9 100644
--- a/spec/graphql/types/merge_request_type_spec.rb
+++ b/spec/graphql/types/merge_request_type_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe GitlabSchema.types['MergeRequest'], feature_category: :code_revie
commit_count current_user_todos conflicts auto_merge_enabled approved_by source_branch_protected
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
+ auto_merge_strategy merge_user award_emoji prepared_at codequality_reports_comparer supports_lock_on_merge
]
expect(described_class).to have_graphql_fields(*expected_fields).at_least
diff --git a/spec/graphql/types/organizations/group_sort_enum_spec.rb b/spec/graphql/types/organizations/group_sort_enum_spec.rb
new file mode 100644
index 00000000000..57915d95c45
--- /dev/null
+++ b/spec/graphql/types/organizations/group_sort_enum_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['OrganizationGroupSort'], feature_category: :cell do
+ let(:sort_values) do
+ %w[
+ ID_ASC
+ ID_DESC
+ NAME_ASC
+ NAME_DESC
+ PATH_ASC
+ PATH_DESC
+ UPDATED_AT_ASC
+ UPDATED_AT_DESC
+ CREATED_AT_ASC
+ CREATED_AT_DESC
+ ]
+ end
+
+ specify { expect(described_class.graphql_name).to eq('OrganizationGroupSort') }
+
+ it 'exposes all the organization groups sort values' do
+ expect(described_class.values.keys).to include(*sort_values)
+ end
+end
diff --git a/spec/graphql/types/organizations/organization_type_spec.rb b/spec/graphql/types/organizations/organization_type_spec.rb
new file mode 100644
index 00000000000..26d7c10a715
--- /dev/null
+++ b/spec/graphql/types/organizations/organization_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['Organization'], feature_category: :cell do
+ let(:expected_fields) { %w[groups id name organization_users path] }
+
+ specify { expect(described_class.graphql_name).to eq('Organization') }
+ specify { expect(described_class).to require_graphql_authorizations(:read_organization) }
+ specify { expect(described_class).to have_graphql_fields(*expected_fields) }
+end
diff --git a/spec/graphql/types/organizations/organization_user_type_spec.rb b/spec/graphql/types/organizations/organization_user_type_spec.rb
new file mode 100644
index 00000000000..876080b0f15
--- /dev/null
+++ b/spec/graphql/types/organizations/organization_user_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['OrganizationUser'], feature_category: :cell do
+ let(:expected_fields) { %w[badges id user] }
+
+ specify { expect(described_class.graphql_name).to eq('OrganizationUser') }
+ specify { expect(described_class).to require_graphql_authorizations(:read_organization_user) }
+ specify { expect(described_class).to have_graphql_fields(*expected_fields) }
+end
diff --git a/spec/graphql/types/permission_types/work_item_spec.rb b/spec/graphql/types/permission_types/work_item_spec.rb
index 3ee42e2e3ad..cdbf94304de 100644
--- a/spec/graphql/types/permission_types/work_item_spec.rb
+++ b/spec/graphql/types/permission_types/work_item_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Types::PermissionTypes::WorkItem do
it do
expected_permissions = [
:read_work_item, :update_work_item, :delete_work_item, :admin_work_item,
- :admin_parent_link, :set_work_item_metadata, :create_note
+ :admin_parent_link, :set_work_item_metadata, :create_note, :admin_work_item_link
]
expected_permissions.each do |permission|
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index cd9a0642ae6..a20a4767bb5 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -892,22 +892,25 @@ RSpec.describe GitlabSchema.types['Project'] do
subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }
- before do
+ before_all do
fork_reporter.add_reporter(user)
fork_developer.add_developer(user)
fork_group_developer.group.add_developer(user)
+ fork_private.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
end
it 'contains all forks' do
- expect(forks.count).to eq(5)
+ expect(forks.count).to eq(4)
end
context 'with minimum_access_level DEVELOPER' do
let(:minimum_access_level) { '(minimumAccessLevel: DEVELOPER)' }
it 'contains forks with developer access' do
- expect(forks).to contain_exactly(a_hash_including('fullPath' => fork_developer.full_path),
-a_hash_including('fullPath' => fork_group_developer.full_path))
+ expect(forks).to contain_exactly(
+ a_hash_including('fullPath' => fork_developer.full_path),
+ a_hash_including('fullPath' => fork_group_developer.full_path)
+ )
end
context 'when current user is not set' do
diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb
index 100ecc94f35..8bda738751d 100644
--- a/spec/graphql/types/query_type_spec.rb
+++ b/spec/graphql/types/query_type_spec.rb
@@ -23,6 +23,16 @@ RSpec.describe GitlabSchema.types['Query'], feature_category: :shared do
end
end
+ describe 'organization field' do
+ subject { described_class.fields['organization'] }
+
+ it 'finds organization by path' do
+ is_expected.to have_graphql_arguments(:id)
+ is_expected.to have_graphql_type(Types::Organizations::OrganizationType)
+ is_expected.to have_graphql_resolver(Resolvers::Organizations::OrganizationResolver)
+ end
+ end
+
describe 'project field' do
subject { described_class.fields['project'] }
diff --git a/spec/graphql/types/repository/blob_type_spec.rb b/spec/graphql/types/repository/blob_type_spec.rb
index 9537fca7322..104093bd909 100644
--- a/spec/graphql/types/repository/blob_type_spec.rb
+++ b/spec/graphql/types/repository/blob_type_spec.rb
@@ -30,6 +30,7 @@ RSpec.describe Types::Repository::BlobType, feature_category: :source_code_manag
:gitpod_blob_url,
:find_file_path,
:blame_path,
+ :blame,
:history_path,
:permalink_path,
:environment_formatted_external_url,
diff --git a/spec/graphql/types/security/codequality_reports_comparer/degradation_type_spec.rb b/spec/graphql/types/security/codequality_reports_comparer/degradation_type_spec.rb
new file mode 100644
index 00000000000..9ae1b3fcf94
--- /dev/null
+++ b/spec/graphql/types/security/codequality_reports_comparer/degradation_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CodequalityReportsComparerReportDegradation'], feature_category: :code_quality do
+ specify { expect(described_class.graphql_name).to eq('CodequalityReportsComparerReportDegradation') }
+
+ it 'has expected fields' do
+ expected_fields = %i[description fingerprint severity file_path line web_url engine_name]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/security/codequality_reports_comparer/report_type_spec.rb b/spec/graphql/types/security/codequality_reports_comparer/report_type_spec.rb
new file mode 100644
index 00000000000..a1788126f1b
--- /dev/null
+++ b/spec/graphql/types/security/codequality_reports_comparer/report_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CodequalityReportsComparerReport'], feature_category: :code_quality do
+ specify { expect(described_class.graphql_name).to eq('CodequalityReportsComparerReport') }
+
+ it 'has expected fields' do
+ expected_fields = %i[status new_errors resolved_errors existing_errors summary]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/security/codequality_reports_comparer/status_enum_spec.rb b/spec/graphql/types/security/codequality_reports_comparer/status_enum_spec.rb
new file mode 100644
index 00000000000..6e5bdd1e91d
--- /dev/null
+++ b/spec/graphql/types/security/codequality_reports_comparer/status_enum_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CodequalityReportsComparerReportStatus'], feature_category: :code_quality do
+ specify { expect(described_class.graphql_name).to eq('CodequalityReportsComparerReportStatus') }
+
+ it 'exposes all codequality report status values' do
+ expect(described_class.values.keys).to contain_exactly('SUCCESS', 'FAILED', 'NOT_FOUND')
+ end
+end
diff --git a/spec/graphql/types/security/codequality_reports_comparer/summary_type_spec.rb b/spec/graphql/types/security/codequality_reports_comparer/summary_type_spec.rb
new file mode 100644
index 00000000000..41de93b27ad
--- /dev/null
+++ b/spec/graphql/types/security/codequality_reports_comparer/summary_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CodequalityReportsComparerReportSummary'], feature_category: :code_quality do
+ specify { expect(described_class.graphql_name).to eq('CodequalityReportsComparerReportSummary') }
+
+ it 'has expected fields' do
+ expected_fields = %i[total resolved errored]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/security/codequality_reports_comparer_type_spec.rb b/spec/graphql/types/security/codequality_reports_comparer_type_spec.rb
new file mode 100644
index 00000000000..02f7a9d6925
--- /dev/null
+++ b/spec/graphql/types/security/codequality_reports_comparer_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CodequalityReportsComparer'], feature_category: :code_quality do
+ specify { expect(described_class.graphql_name).to eq('CodequalityReportsComparer') }
+
+ it 'has expected fields' do
+ expect(described_class).to have_graphql_fields(:report)
+ end
+end