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/ci/runner/bulk_delete_spec.rb2
-rw-r--r--spec/graphql/mutations/ci/runner/delete_spec.rb2
-rw-r--r--spec/graphql/mutations/ci/runner/update_spec.rb2
-rw-r--r--spec/graphql/mutations/design_management/delete_spec.rb69
-rw-r--r--spec/graphql/mutations/namespace/package_settings/update_spec.rb9
-rw-r--r--spec/graphql/mutations/projects/star_spec.rb73
-rw-r--r--spec/graphql/resolvers/blame_resolver_spec.rb28
-rw-r--r--spec/graphql/resolvers/ci/catalog/resource_resolver_spec.rb12
-rw-r--r--spec/graphql/resolvers/ci/catalog/resources/versions_resolver_spec.rb69
-rw-r--r--spec/graphql/resolvers/ci/catalog/resources_resolver_spec.rb103
-rw-r--r--spec/graphql/resolvers/ci/catalog/versions_resolver_spec.rb66
-rw-r--r--spec/graphql/resolvers/ci/group_runners_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/project_runners_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/runner_groups_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/runner_job_count_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/runner_platforms_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/runner_projects_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/runner_setup_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/runner_status_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/ci/runners_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/container_repository_tags_resolver_spec.rb8
-rw-r--r--spec/graphql/resolvers/group_milestones_resolver_spec.rb73
-rw-r--r--spec/graphql/resolvers/group_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/kas/agent_connections_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/ml/model_detail_resolver_spec.rb41
-rw-r--r--spec/graphql/resolvers/project_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/timelog_resolver_spec.rb22
-rw-r--r--spec/graphql/types/analytics/cycle_analytics/value_stream_type_spec.rb2
-rw-r--r--spec/graphql/types/analytics/cycle_analytics/value_streams/stage_type_spec.rb15
-rw-r--r--spec/graphql/types/ci/catalog/resource_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/catalog/resources/component_type_spec.rb18
-rw-r--r--spec/graphql/types/ci/catalog/resources/components/input_type_spec.rb17
-rw-r--r--spec/graphql/types/ci/catalog/resources/version_sort_enum_spec.rb13
-rw-r--r--spec/graphql/types/ci/catalog/resources/version_type_spec.rb22
-rw-r--r--spec/graphql/types/ci/job_base_field_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_countable_connection_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_manager_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_platform_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_setup_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_web_url_edge_spec.rb2
-rw-r--r--spec/graphql/types/container_registry/protection/rule_type_spec.rb4
-rw-r--r--spec/graphql/types/container_repository_details_type_spec.rb2
-rw-r--r--spec/graphql/types/container_repository_tag_type_spec.rb6
-rw-r--r--spec/graphql/types/container_repository_type_spec.rb6
-rw-r--r--spec/graphql/types/current_user_type_spec.rb11
-rw-r--r--spec/graphql/types/group_type_spec.rb33
-rw-r--r--spec/graphql/types/issue_type_enum_spec.rb2
-rw-r--r--spec/graphql/types/ml/candidate_links_type_spec.rb11
-rw-r--r--spec/graphql/types/ml/candidate_type_spec.rb13
-rw-r--r--spec/graphql/types/ml/model_type_spec.rb13
-rw-r--r--spec/graphql/types/ml/model_version_links_type_spec.rb11
-rw-r--r--spec/graphql/types/ml/model_version_type_spec.rb13
-rw-r--r--spec/graphql/types/namespace/package_settings_type_spec.rb1
-rw-r--r--spec/graphql/types/organizations/organization_type_spec.rb2
-rw-r--r--spec/graphql/types/permission_types/abuse_report_spec.rb15
-rw-r--r--spec/graphql/types/permission_types/container_repository_spec.rb11
-rw-r--r--spec/graphql/types/permission_types/container_repository_tag_spec.rb11
-rw-r--r--spec/graphql/types/project_feature_access_level_enum_spec.rb11
-rw-r--r--spec/graphql/types/project_feature_access_level_type_spec.rb14
-rw-r--r--spec/graphql/types/project_type_spec.rb65
-rw-r--r--spec/graphql/types/projects/service_type_enum_spec.rb1
-rw-r--r--spec/graphql/types/query_type_spec.rb18
-rw-r--r--spec/graphql/types/root_storage_statistics_type_spec.rb2
-rw-r--r--spec/graphql/types/user_preferences_type_spec.rb1
-rw-r--r--spec/graphql/types/work_item_state_counts_type_spec.rb12
-rw-r--r--spec/graphql/types/work_items/widget_definition_interface_spec.rb35
-rw-r--r--spec/graphql/types/work_items/widget_definitions/assignees_type_spec.rb13
-rw-r--r--spec/graphql/types/work_items/widget_definitions/generic_type_spec.rb11
70 files changed, 784 insertions, 276 deletions
diff --git a/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb b/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb
index aaa74fa78aa..0dcfaa9b8ac 100644
--- a/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb
+++ b/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::Ci::Runner::BulkDelete, feature_category: :runner_fleet do
+RSpec.describe Mutations::Ci::Runner::BulkDelete, feature_category: :fleet_visibility do
include GraphqlHelpers
let_it_be(:admin_user) { create(:user, :admin) }
diff --git a/spec/graphql/mutations/ci/runner/delete_spec.rb b/spec/graphql/mutations/ci/runner/delete_spec.rb
index beff18e1dfd..3617c751165 100644
--- a/spec/graphql/mutations/ci/runner/delete_spec.rb
+++ b/spec/graphql/mutations/ci/runner/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::Ci::Runner::Delete, feature_category: :runner_fleet do
+RSpec.describe Mutations::Ci::Runner::Delete, feature_category: :fleet_visibility do
include GraphqlHelpers
let_it_be(:runner) { create(:ci_runner) }
diff --git a/spec/graphql/mutations/ci/runner/update_spec.rb b/spec/graphql/mutations/ci/runner/update_spec.rb
index 03bfd4d738b..32c4e6952e4 100644
--- a/spec/graphql/mutations/ci/runner/update_spec.rb
+++ b/spec/graphql/mutations/ci/runner/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::Ci::Runner::Update, feature_category: :runner_fleet do
+RSpec.describe Mutations::Ci::Runner::Update, feature_category: :fleet_visibility do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/graphql/mutations/design_management/delete_spec.rb b/spec/graphql/mutations/design_management/delete_spec.rb
index 1b78529fbc7..7f499301543 100644
--- a/spec/graphql/mutations/design_management/delete_spec.rb
+++ b/spec/graphql/mutations/design_management/delete_spec.rb
@@ -86,46 +86,47 @@ RSpec.describe Mutations::DesignManagement::Delete do
end
end
- it 'runs no more than 31 queries' do
+ it 'runs no more than 34 queries' do
allow(Gitlab::Tracking).to receive(:event) # rubocop:disable RSpec/ExpectGitlabTracking
filenames.each(&:present?) # ignore setup
- # Queries: as of 2022-09-08
+ # Queries: as of 2022-12-01
# -------------
- # 01. routing query
- # 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
- # 09. find namespace by id
- # 10. find group namespace by id
- # 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
+ # 01. for routes to find routes.source_id of projects matching paths
+ # 02. Find projects with the above source id.
+ # 03. preload routes of the above projects
+ # 04. policy query: find namespace by type and id
+ # 05. policy query: namespace_bans
+ # 06. policy query: project.project_feature
+ # 07,08. project.authorizations for user (same query twice)
+ # 09. find issue by iid
+ # 10. find project by id
+ # 11. find namespace by id
+ # 12. policy query: find namespace by type and id (same query as 4)
+ # 13. project.authorizations for user (same query as 7)
+ # 14. find user by id
+ # 15. project.project_features (same query as 6)
+ # 16. project.authorizations for user (same query as 7)
+ # 17. current designs by filename and issue
+ # 18, 19 project.authorizations for user (same query as 7)
+ # 20. find design_management_repository for project
+ # 21. find route by source_id and source_type
# ------------- our queries are below:
- # 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. find project by id (same query as 8)
- # 32. create event
- # 33. find plan for standard context
+ # 22. start transaction
+ # 23. create version with sha and issue
+ # 24. create design-version links
+ # 25. validate version.actions.present?
+ # 26. validate version.sha is unique
+ # 27. validate version.issue.present?
+ # 28. leave transaction
+ # 29. find project by id (same query as 10)
+ # 30. find namespace by id (same query as 11)
+ # 31. find project by id (same query as 10)
+ # 32. find project by id (same query as 10)
+ # 33. create event
+ # 34. find plan for standard context
#
- expect { run_mutation }.not_to exceed_query_limit(33)
+ expect { run_mutation }.not_to exceed_query_limit(34)
end
end
diff --git a/spec/graphql/mutations/namespace/package_settings/update_spec.rb b/spec/graphql/mutations/namespace/package_settings/update_spec.rb
index f4e79481d44..b184baaca3e 100644
--- a/spec/graphql/mutations/namespace/package_settings/update_spec.rb
+++ b/spec/graphql/mutations/namespace/package_settings/update_spec.rb
@@ -38,7 +38,8 @@ RSpec.describe Mutations::Namespace::PackageSettings::Update, feature_category:
npm_package_requests_forwarding: nil,
lock_npm_package_requests_forwarding: false,
pypi_package_requests_forwarding: nil,
- lock_pypi_package_requests_forwarding: false
+ lock_pypi_package_requests_forwarding: false,
+ nuget_symbol_server_enabled: false
}, to: {
maven_duplicates_allowed: false,
maven_duplicate_exception_regex: 'RELEASE',
@@ -51,7 +52,8 @@ RSpec.describe Mutations::Namespace::PackageSettings::Update, feature_category:
npm_package_requests_forwarding: true,
lock_npm_package_requests_forwarding: true,
pypi_package_requests_forwarding: true,
- lock_pypi_package_requests_forwarding: true
+ lock_pypi_package_requests_forwarding: true,
+ nuget_symbol_server_enabled: true
}
it_behaves_like 'returning a success'
@@ -106,7 +108,8 @@ RSpec.describe Mutations::Namespace::PackageSettings::Update, feature_category:
npm_package_requests_forwarding: true,
lock_npm_package_requests_forwarding: true,
pypi_package_requests_forwarding: true,
- lock_pypi_package_requests_forwarding: true
+ lock_pypi_package_requests_forwarding: true,
+ nuget_symbol_server_enabled: true
}
end
diff --git a/spec/graphql/mutations/projects/star_spec.rb b/spec/graphql/mutations/projects/star_spec.rb
new file mode 100644
index 00000000000..6b1811dcd39
--- /dev/null
+++ b/spec/graphql/mutations/projects/star_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::Projects::Star, feature_category: :groups_and_projects do
+ describe '#resolve' do
+ let_it_be(:user, freeze: true) { create(:user) }
+
+ subject(:mutation) do
+ described_class
+ .new(object: nil, context: { current_user: user }, field: nil)
+ .resolve(project_id: project.to_global_id, starred: starred)
+ end
+
+ context 'when the user has read access to the project' do
+ let_it_be_with_reload(:project) { create(:project, :public) }
+
+ context 'and the project is not starred' do
+ context 'and the user stars the project' do
+ let(:starred) { true }
+
+ it 'stars the project for the current user' do
+ expect(mutation).to include(count: 1)
+ expect(project.reset.starrers).to include(user)
+ end
+ end
+
+ context 'and the user unstars the project' do
+ let(:starred) { false }
+
+ it 'does not raise an error or change the number of stars' do
+ expect(mutation).to include(count: 0)
+ expect(project.reset.starrers).not_to include(user)
+ end
+ end
+ end
+
+ context 'and the project is starred' do
+ before do
+ user.toggle_star(project)
+ end
+
+ context 'and the user stars the project' do
+ let(:starred) { true }
+
+ it 'does not raise an error or change the number of stars' do
+ expect(mutation).to include(count: 1)
+ expect(project.reset.starrers).to include(user)
+ end
+ end
+
+ context 'and the user unstars the project' do
+ let(:starred) { false }
+
+ it 'unstars the project for the current user' do
+ expect(mutation).to include(count: 0)
+ expect(project.reset.starrers).not_to include(user)
+ end
+ end
+ end
+ end
+
+ context 'when the user does not have read access to the project' do
+ let_it_be(:project, freeze: true) { create(:project, :private) }
+ let(:starred) { true }
+
+ it 'raises an error' do
+ expect { mutation }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ expect(project.starrers).not_to include(user)
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/blame_resolver_spec.rb b/spec/graphql/resolvers/blame_resolver_spec.rb
index a3344132928..ff6bfa97def 100644
--- a/spec/graphql/resolvers/blame_resolver_spec.rb
+++ b/spec/graphql/resolvers/blame_resolver_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Resolvers::BlameResolver, feature_category: :source_code_manageme
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 } }
+ let(:args) { { from_line: 1, to_line: 100 } }
subject(:resolve_blame) { resolve(described_class, obj: blob, args: args, ctx: { current_user: user }) }
@@ -39,10 +39,10 @@ RSpec.describe Resolvers::BlameResolver, feature_category: :source_code_manageme
end
end
- shared_examples 'argument error' do
+ shared_examples 'argument error' do |error_message|
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
+ error_message) do
resolve_blame
end
end
@@ -52,23 +52,33 @@ RSpec.describe Resolvers::BlameResolver, feature_category: :source_code_manageme
context 'when from_line is below 1' do
let(:args) { { from_line: 0, to_line: 2 } }
- it_behaves_like 'argument error'
+ it_behaves_like 'argument error', '`from_line` and `to_line` must be greater than or equal to 1'
end
context 'when to_line is below 1' do
let(:args) { { from_line: 1, to_line: 0 } }
- it_behaves_like 'argument error'
+ it_behaves_like 'argument error', '`from_line` and `to_line` must be greater than or equal to 1'
end
context 'when to_line less than from_line' do
let(:args) { { from_line: 3, to_line: 1 } }
+ it_behaves_like 'argument error', '`to_line` must be greater than or equal to `from_line`'
+ end
+
+ context 'when difference between to_line and from_line is greater then 99' do
+ let(:args) { { from_line: 3, to_line: 103 } }
+
+ it_behaves_like 'argument error',
+ '`to_line` must be greater than or equal to `from_line` and smaller than `from_line` + 100'
+ end
+
+ context 'when to_line and from_line are the same' do
+ let(:args) { { from_line: 1, 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
+ expect(resolve_blame).to be_an_instance_of(Gitlab::Blame)
end
end
diff --git a/spec/graphql/resolvers/ci/catalog/resource_resolver_spec.rb b/spec/graphql/resolvers/ci/catalog/resource_resolver_spec.rb
index 19fc0c7fc4c..313d1d337da 100644
--- a/spec/graphql/resolvers/ci/catalog/resource_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/catalog/resource_resolver_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Resolvers::Ci::Catalog::ResourceResolver, feature_category: :pipe
let_it_be(:namespace) { create(:group) }
let_it_be(:project) { create(:project, :private, namespace: namespace) }
- let_it_be(:resource) { create(:ci_catalog_resource, project: project) }
+ let_it_be(:resource) { create(:ci_catalog_resource, :published, project: project) }
let_it_be(:user) { create(:user) }
describe '#resolve' do
@@ -20,7 +20,7 @@ RSpec.describe Resolvers::Ci::Catalog::ResourceResolver, feature_category: :pipe
context 'when resource is found' do
it 'returns a single CI/CD Catalog resource' do
result = resolve(described_class, ctx: { current_user: user },
- args: { id: resource.to_global_id.to_s })
+ args: { id: resource.to_global_id })
expect(result.id).to eq(resource.id)
expect(result.class).to eq(Ci::Catalog::Resource)
@@ -30,7 +30,9 @@ RSpec.describe Resolvers::Ci::Catalog::ResourceResolver, feature_category: :pipe
context 'when resource is not found' do
it 'raises ResourceNotAvailable error' do
result = resolve(described_class, ctx: { current_user: user },
- args: { id: "gid://gitlab/Ci::Catalog::Resource/not-a-real-id" })
+ args: { id: GlobalID.new(
+ ::Gitlab::GlobalId.build(model_name: '::Ci::Catalog::Resource', id: "not-a-real-id")
+ ) })
expect(result).to be_a(::Gitlab::Graphql::Errors::ResourceNotAvailable)
end
@@ -40,7 +42,7 @@ RSpec.describe Resolvers::Ci::Catalog::ResourceResolver, feature_category: :pipe
context 'when user is not authorised to view the resource' do
it 'raises ResourceNotAvailable error' do
result = resolve(described_class, ctx: { current_user: user },
- args: { id: resource.to_global_id.to_s })
+ args: { id: resource.to_global_id })
expect(result).to be_a(::Gitlab::Graphql::Errors::ResourceNotAvailable)
end
@@ -115,7 +117,7 @@ RSpec.describe Resolvers::Ci::Catalog::ResourceResolver, feature_category: :pipe
expect_graphql_error_to_be_created(::Gitlab::Graphql::Errors::ArgumentError,
"Exactly one of 'id' or 'full_path' arguments is required.") do
resolve(described_class, ctx: { current_user: user },
- args: { full_path: resource.project.full_path, id: resource.to_global_id.to_s })
+ args: { full_path: resource.project.full_path, id: resource.to_global_id })
end
end
end
diff --git a/spec/graphql/resolvers/ci/catalog/resources/versions_resolver_spec.rb b/spec/graphql/resolvers/ci/catalog/resources/versions_resolver_spec.rb
new file mode 100644
index 00000000000..1ce0e91765f
--- /dev/null
+++ b/spec/graphql/resolvers/ci/catalog/resources/versions_resolver_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::Ci::Catalog::Resources::VersionsResolver, feature_category: :pipeline_composition do
+ include GraphqlHelpers
+
+ include_context 'when there are catalog resources with versions'
+
+ let(:sort) { nil }
+ let(:args) { { sort: sort }.compact }
+ let(:ctx) { { current_user: current_user } }
+
+ subject(:result) { resolve(described_class, ctx: ctx, obj: resource1, args: args) }
+
+ describe '#resolve' do
+ context 'when the user is authorized to read project releases' do
+ before_all do
+ resource1.project.add_guest(current_user)
+ end
+
+ context 'when sort argument is not provided' do
+ it 'returns versions ordered by released_at descending' do
+ expect(result.items).to eq([v1_1, v1_0])
+ end
+ end
+
+ context 'when sort argument is provided' do
+ context 'when sort is CREATED_ASC' do
+ let(:sort) { 'CREATED_ASC' }
+
+ it 'returns versions ordered by created_at ascending' do
+ expect(result.items.to_a).to eq([v1_1, v1_0])
+ end
+ end
+
+ context 'when sort is CREATED_DESC' do
+ let(:sort) { 'CREATED_DESC' }
+
+ it 'returns versions ordered by created_at descending' do
+ expect(result.items).to eq([v1_0, v1_1])
+ end
+ end
+
+ context 'when sort is RELEASED_AT_ASC' do
+ let(:sort) { 'RELEASED_AT_ASC' }
+
+ it 'returns versions ordered by released_at ascending' do
+ expect(result.items).to eq([v1_0, v1_1])
+ end
+ end
+
+ context 'when sort is RELEASED_AT_DESC' do
+ let(:sort) { 'RELEASED_AT_DESC' }
+
+ it 'returns versions ordered by released_at descending' do
+ expect(result.items).to eq([v1_1, v1_0])
+ end
+ end
+ end
+ end
+
+ context 'when the user is not authorized to read project releases' do
+ it 'returns empty response' do
+ expect(result).to be_empty
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/ci/catalog/resources_resolver_spec.rb b/spec/graphql/resolvers/ci/catalog/resources_resolver_spec.rb
index 97105db686f..a55724b5611 100644
--- a/spec/graphql/resolvers/ci/catalog/resources_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/catalog/resources_resolver_spec.rb
@@ -6,23 +6,31 @@ RSpec.describe Resolvers::Ci::Catalog::ResourcesResolver, feature_category: :pip
include GraphqlHelpers
let_it_be(:namespace) { create(:group) }
- let_it_be(:project_1) { create(:project, name: 'Z', namespace: namespace) }
- let_it_be(:project_2) { create(:project, name: 'A_Test', namespace: namespace) }
- let_it_be(:project_3) { create(:project, name: 'L', description: 'Test', namespace: namespace) }
- let_it_be(:resource_1) { create(:ci_catalog_resource, project: project_1) }
- let_it_be(:resource_2) { create(:ci_catalog_resource, project: project_2) }
- let_it_be(:resource_3) { create(:ci_catalog_resource, project: project_3) }
+ let_it_be(:private_namespace_project) { create(:project, :private, name: 'z private test', namespace: namespace) }
+ let_it_be(:private_namespace_project_2) { create(:project, :private, name: 'a private test', namespace: namespace) }
+ let_it_be(:public_namespace_project) do
+ create(:project, :public, name: 'public', description: 'Test', namespace: namespace)
+ end
+
+ let_it_be(:internal_project) { create(:project, :internal, name: 'internal') }
+ let_it_be(:private_resource) { create(:ci_catalog_resource, :published, project: private_namespace_project) }
+ let_it_be(:private_resource_2) { create(:ci_catalog_resource, project: private_namespace_project_2) }
+ let_it_be(:public_resource) { create(:ci_catalog_resource, :published, project: public_namespace_project) }
+ let_it_be(:internal_resource) { create(:ci_catalog_resource, :published, project: internal_project) }
let_it_be(:user) { create(:user) }
let(:ctx) { { current_user: user } }
let(:search) { nil }
let(:sort) { nil }
+ let(:scope) { nil }
+ let(:project_path) { nil }
let(:args) do
{
- project_path: project_1.full_path,
+ project_path: project_path,
sort: sort,
- search: search
+ search: search,
+ scope: scope
}.compact
end
@@ -31,40 +39,89 @@ RSpec.describe Resolvers::Ci::Catalog::ResourcesResolver, feature_category: :pip
describe '#resolve' do
context 'with an authorized user' do
before_all do
- namespace.add_owner(user)
+ namespace.add_reporter(user)
+ internal_project.add_reporter(user)
end
- it 'returns all catalog resources visible to the current user in the namespace' do
- expect(result.items.count).to be(3)
- expect(result.items.pluck(:name)).to contain_exactly('Z', 'A_Test', 'L')
+ context 'when the project path argument is provided' do
+ let(:project_path) { private_namespace_project.full_path }
+
+ it 'returns all catalog resources visible to the current user in the namespace' do
+ expect(result.items.count).to be(2)
+ expect(result.items.pluck(:name)).to contain_exactly('z private test', 'public')
+ end
end
- context 'when the sort parameter is not provided' do
+ context 'when sort argument is not provided' do
it 'returns all catalog resources sorted by descending created date' do
- expect(result.items.pluck(:name)).to eq(%w[L A_Test Z])
+ expect(result.items.pluck(:name)).to eq(['internal', 'public', 'z private test'])
end
end
- context 'when the sort parameter is provided' do
+ context 'when the sort argument is provided' do
let(:sort) { 'NAME_DESC' }
- it 'returns all catalog resources sorted by descending name' do
- expect(result.items.pluck(:name)).to eq(%w[Z L A_Test])
+ it 'returns all published catalog resources sorted by descending name' do
+ expect(result.items.pluck(:name)).to eq(['z private test', 'public', 'internal'])
end
end
- context 'when the search parameter is provided' do
+ context 'when the search argument is provided' do
let(:search) { 'test' }
- it 'returns the catalog resources that match the search term' do
- expect(result.items.pluck(:name)).to contain_exactly('A_Test', 'L')
+ it 'returns published catalog resources that match the search term' do
+ expect(result.items.pluck(:name)).to contain_exactly('z private test', 'public')
+ end
+ end
+
+ context 'with scope argument' do
+ it 'defaults to :all and returns all catalog resources' do
+ expect(result.items.count).to be(3)
+ expect(result.items.pluck(:name)).to contain_exactly('public', 'internal', 'z private test')
+ end
+
+ context 'when the scope argument is :namespaces' do
+ let(:scope) { 'NAMESPACES' }
+
+ it 'returns projects of the namespaces the user is a member of' do
+ namespace = create(:namespace, owner: user)
+ internal_public_project = create(:project, :internal, name: 'internal public', namespace: namespace)
+ create(:ci_catalog_resource, :published, project: internal_public_project)
+
+ expect(result.items.count).to be(4)
+ expect(result.items.pluck(:name)).to contain_exactly('public', 'internal public', 'internal',
+ 'z private test')
+ end
+ end
+
+ context 'and the ci_guard_for_catalog_resource_scope FF is disabled' do
+ before do
+ stub_feature_flags(ci_guard_for_catalog_resource_scope: false)
+ end
+
+ it 'returns all the catalog resources' do
+ expect(result.items.count).to be(3)
+ expect(result.items.pluck(:name)).to contain_exactly('public', 'internal', 'z private test')
+ end
+ end
+
+ context 'when the scope is invalid' do
+ let(:scope) { 'INVALID' }
+
+ it 'defaults to :all and returns all catalog resources' do
+ expect(result.items.count).to be(3)
+ expect(result.items.pluck(:name)).to contain_exactly('public', 'internal', 'z private test')
+ end
end
end
end
- context 'when the current user cannot read the namespace catalog' do
- it 'returns empty response' do
- expect(result).to be_empty
+ context 'when the user is anonymous' do
+ let_it_be(:user) { nil }
+
+ it 'returns only public projects' do
+ expect(result.items.count).to be(1)
+ expect(result.items.pluck(:name)).to contain_exactly('public')
end
end
end
diff --git a/spec/graphql/resolvers/ci/catalog/versions_resolver_spec.rb b/spec/graphql/resolvers/ci/catalog/versions_resolver_spec.rb
deleted file mode 100644
index 02fb3dfaee4..00000000000
--- a/spec/graphql/resolvers/ci/catalog/versions_resolver_spec.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-# In this context, a `version` is equivalent to a `release`
-RSpec.describe Resolvers::Ci::Catalog::VersionsResolver, feature_category: :pipeline_composition do
- include GraphqlHelpers
-
- let_it_be(:today) { Time.now }
- let_it_be(:yesterday) { today - 1.day }
- let_it_be(:tomorrow) { today + 1.day }
-
- let_it_be(:project) { create(:project, :private) }
- # rubocop: disable Layout/LineLength
- let_it_be(:version1) { create(:release, project: project, tag: 'v1.0.0', released_at: yesterday, created_at: tomorrow) }
- let_it_be(:version2) { create(:release, project: project, tag: 'v2.0.0', released_at: today, created_at: yesterday) }
- let_it_be(:version3) { create(:release, project: project, tag: 'v3.0.0', released_at: tomorrow, created_at: today) }
- # rubocop: enable Layout/LineLength
- let_it_be(:developer) { create(:user) }
- let_it_be(:public_user) { create(:user) }
-
- let(:args) { { sort: :released_at_desc } }
- let(:all_releases) { [version1, version2, version3] }
-
- before_all do
- project.add_developer(developer)
- end
-
- describe '#resolve' do
- it_behaves_like 'releases and group releases resolver'
-
- describe 'when order_by is created_at' do
- let(:current_user) { developer }
-
- context 'with sort: desc' do
- let(:args) { { sort: :created_desc } }
-
- it 'returns the releases ordered by created_at in descending order' do
- expect(resolve_releases.to_a)
- .to match_array(all_releases)
- .and be_sorted(:created_at, :desc)
- end
- end
-
- context 'with sort: asc' do
- let(:args) { { sort: :created_asc } }
-
- it 'returns the releases ordered by created_at in ascending order' do
- expect(resolve_releases.to_a)
- .to match_array(all_releases)
- .and be_sorted(:created_at, :asc)
- end
- end
- end
- end
-
- private
-
- def resolve_versions
- context = { current_user: current_user }
- resolve(described_class, obj: project, args: args, ctx: context, arg_style: :internal)
- end
-
- # Required for shared examples
- alias_method :resolve_releases, :resolve_versions
-end
diff --git a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb
index e0fc3b96b93..d1eec0baeea 100644
--- a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::GroupRunnersResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
describe '#resolve' do
diff --git a/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb
index 9d9f0fee04a..85b55521174 100644
--- a/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/project_runners_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::ProjectRunnersResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
describe '#resolve' do
diff --git a/spec/graphql/resolvers/ci/runner_groups_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_groups_resolver_spec.rb
index 9272689ef0b..f535f6e415d 100644
--- a/spec/graphql/resolvers/ci/runner_groups_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runner_groups_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::RunnerGroupsResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::RunnerGroupsResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
let_it_be(:group1) { create(:group) }
diff --git a/spec/graphql/resolvers/ci/runner_job_count_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_job_count_resolver_spec.rb
index 6336ea883f7..18501d4add5 100644
--- a/spec/graphql/resolvers/ci/runner_job_count_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runner_job_count_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::RunnerJobCountResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::RunnerJobCountResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb
index 322bead0d3c..4af87b6882f 100644
--- a/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::RunnerJobsResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::RunnerJobsResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/graphql/resolvers/ci/runner_platforms_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_platforms_resolver_spec.rb
index da6a84cec44..e6238c41445 100644
--- a/spec/graphql/resolvers/ci/runner_platforms_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runner_platforms_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::RunnerPlatformsResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::RunnerPlatformsResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
describe '#resolve' do
diff --git a/spec/graphql/resolvers/ci/runner_projects_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_projects_resolver_spec.rb
index 44203fb2912..c75d7fb831c 100644
--- a/spec/graphql/resolvers/ci/runner_projects_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runner_projects_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::RunnerProjectsResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::RunnerProjectsResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
let_it_be(:project1) { create(:project, description: 'Project1.1') }
diff --git a/spec/graphql/resolvers/ci/runner_setup_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_setup_resolver_spec.rb
index 734337f7c92..1724623e5c4 100644
--- a/spec/graphql/resolvers/ci/runner_setup_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runner_setup_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::RunnerSetupResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::RunnerSetupResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
describe '#resolve' do
diff --git a/spec/graphql/resolvers/ci/runner_status_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_status_resolver_spec.rb
index 97a10a7da33..d541bbddfe5 100644
--- a/spec/graphql/resolvers/ci/runner_status_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runner_status_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::RunnerStatusResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::RunnerStatusResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
describe '#resolve' do
diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
index 7d37d13366c..85a90924384 100644
--- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :runner_fleet do
+RSpec.describe Resolvers::Ci::RunnersResolver, feature_category: :fleet_visibility do
include GraphqlHelpers
describe '#resolve' do
diff --git a/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb b/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb
index 48be1c29184..5f12e8649b7 100644
--- a/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb
+++ b/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb
@@ -114,14 +114,6 @@ RSpec.describe Resolvers::ContainerRepositoryTagsResolver, feature_category: :co
expect(resolver(args)).is_a? Gitlab::Graphql::ExternallyPaginatedArray
end
-
- context 'when feature use_repository_list_tags_on_graphql is disabled' do
- before do
- stub_feature_flags(use_repository_list_tags_on_graphql: false)
- end
-
- it_behaves_like 'fetching via tags and filter in place'
- end
end
context 'when Gitlab API is not supported' do
diff --git a/spec/graphql/resolvers/group_milestones_resolver_spec.rb b/spec/graphql/resolvers/group_milestones_resolver_spec.rb
index b9b8ef1870b..e9caf91ecb7 100644
--- a/spec/graphql/resolvers/group_milestones_resolver_spec.rb
+++ b/spec/graphql/resolvers/group_milestones_resolver_spec.rb
@@ -102,76 +102,7 @@ RSpec.describe Resolvers::GroupMilestonesResolver, feature_category: :team_plann
end
end
- context 'when including descendant milestones in a public group' do
- let_it_be(:group) { create(:group, :public) }
-
- let(:args) { { include_descendants: true } }
-
- it 'finds milestones only in accessible projects and groups' do
- accessible_group = create(:group, :private, parent: group)
- accessible_project = create(:project, group: accessible_group)
- accessible_group.add_developer(current_user)
- inaccessible_group = create(:group, :private, parent: group)
- inaccessible_project = create(:project, :private, group: group)
- milestone1 = create(:milestone, group: group)
- milestone2 = create(:milestone, group: accessible_group)
- milestone3 = create(:milestone, project: accessible_project)
- create(:milestone, group: inaccessible_group)
- create(:milestone, project: inaccessible_project)
-
- expect(resolve_group_milestones(args: args)).to match_array([milestone1, milestone2, milestone3])
- end
- end
-
- describe 'include_descendants and include_ancestors' do
- let_it_be(:parent_group) { create(:group, :public) }
- let_it_be(:group) { create(:group, :public, parent: parent_group) }
- let_it_be(:accessible_group) { create(:group, :private, parent: group) }
- let_it_be(:accessible_project) { create(:project, group: accessible_group) }
- let_it_be(:inaccessible_group) { create(:group, :private, parent: group) }
- let_it_be(:inaccessible_project) { create(:project, :private, group: group) }
- let_it_be(:milestone1) { create(:milestone, group: group) }
- let_it_be(:milestone2) { create(:milestone, group: accessible_group) }
- let_it_be(:milestone3) { create(:milestone, project: accessible_project) }
- let_it_be(:milestone4) { create(:milestone, group: inaccessible_group) }
- let_it_be(:milestone5) { create(:milestone, project: inaccessible_project) }
- let_it_be(:milestone6) { create(:milestone, group: parent_group) }
-
- before do
- accessible_group.add_developer(current_user)
- end
-
- context 'when including neither ancestor or descendant milestones in a public group' do
- let(:args) { {} }
-
- it 'finds milestones only in accessible projects and groups' do
- expect(resolve_group_milestones(args: args)).to match_array([milestone1])
- end
- end
-
- context 'when including descendant milestones in a public group' do
- let(:args) { { include_descendants: true } }
-
- it 'finds milestones only in accessible projects and groups' do
- expect(resolve_group_milestones(args: args)).to match_array([milestone1, milestone2, milestone3])
- end
- end
-
- context 'when including ancestor milestones in a public group' do
- let(:args) { { include_ancestors: true } }
-
- it 'finds milestones only in accessible projects and groups' do
- expect(resolve_group_milestones(args: args)).to match_array([milestone1, milestone6])
- end
- end
-
- context 'when including both ancestor or descendant milestones in a public group' do
- let(:args) { { include_descendants: true, include_ancestors: true } }
-
- it 'finds milestones only in accessible projects and groups' do
- expect(resolve_group_milestones(args: args)).to match_array([milestone1, milestone2, milestone3, milestone6])
- end
- end
- end
+ # testing for include_descendants and include_ancestors moved into
+ # `spec/requests/api/graphql/milestone_spec.rb`
end
end
diff --git a/spec/graphql/resolvers/group_resolver_spec.rb b/spec/graphql/resolvers/group_resolver_spec.rb
index ed406d14772..c04961b4804 100644
--- a/spec/graphql/resolvers/group_resolver_spec.rb
+++ b/spec/graphql/resolvers/group_resolver_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Resolvers::GroupResolver do
it 'batch-resolves groups by full path' do
paths = [group1.full_path, group2.full_path]
- result = batch_sync(max_queries: 1) do
+ result = batch_sync(max_queries: 3) do
paths.map { |path| resolve_group(path) }
end
diff --git a/spec/graphql/resolvers/kas/agent_connections_resolver_spec.rb b/spec/graphql/resolvers/kas/agent_connections_resolver_spec.rb
index fe6509bcb3c..58333037e4c 100644
--- a/spec/graphql/resolvers/kas/agent_connections_resolver_spec.rb
+++ b/spec/graphql/resolvers/kas/agent_connections_resolver_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Resolvers::Kas::AgentConnectionsResolver do
let(:connection2) { double(agent_id: agent1.id) }
let(:connection3) { double(agent_id: agent2.id) }
let(:connected_agents) { [connection1, connection2, connection3] }
- let(:kas_client) { instance_double(Gitlab::Kas::Client, get_connected_agents: connected_agents) }
+ let(:kas_client) { instance_double(Gitlab::Kas::Client, get_connected_agents_by_agent_ids: connected_agents) }
subject do
batch_sync do
@@ -37,7 +37,7 @@ RSpec.describe Resolvers::Kas::AgentConnectionsResolver do
end
it 'queries KAS once when multiple agents are requested' do
- expect(kas_client).to receive(:get_connected_agents).once
+ expect(kas_client).to receive(:get_connected_agents_by_agent_ids).once
response = batch_sync do
resolve(described_class, obj: agent1, ctx: ctx)
@@ -49,7 +49,7 @@ RSpec.describe Resolvers::Kas::AgentConnectionsResolver do
context 'an error is returned from the KAS client' do
before do
- allow(kas_client).to receive(:get_connected_agents).and_raise(GRPC::DeadlineExceeded)
+ allow(kas_client).to receive(:get_connected_agents_by_agent_ids).and_raise(GRPC::DeadlineExceeded)
end
it 'raises a graphql error' do
diff --git a/spec/graphql/resolvers/ml/model_detail_resolver_spec.rb b/spec/graphql/resolvers/ml/model_detail_resolver_spec.rb
new file mode 100644
index 00000000000..1da208eb4d8
--- /dev/null
+++ b/spec/graphql/resolvers/ml/model_detail_resolver_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::Ml::ModelDetailResolver, feature_category: :mlops do
+ include GraphqlHelpers
+
+ describe '#resolve' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:model) { create(:ml_models, project: project) }
+ let_it_be(:user) { project.owner }
+
+ let(:args) { { id: global_id_of(model) } }
+ let(:read_model_registry) { true }
+
+ before do
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?)
+ .with(user, :read_model_registry, project)
+ .and_return(read_model_registry)
+ end
+
+ subject { force(resolve(described_class, ctx: { current_user: user }, args: args)) }
+
+ context 'when user is allowed and model exists' do
+ it { is_expected.to eq(model) }
+ end
+
+ context 'when user does not have permission' do
+ let(:read_model_registry) { false }
+
+ it { is_expected.to be_nil }
+ end
+
+ context 'when model does not exist' do
+ let(:args) { { id: global_id_of(id: non_existing_record_id, model_name: 'Ml::Model') } }
+
+ it { is_expected.to be_nil }
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/project_resolver_spec.rb b/spec/graphql/resolvers/project_resolver_spec.rb
index dec9d4701e1..03febc75d3f 100644
--- a/spec/graphql/resolvers/project_resolver_spec.rb
+++ b/spec/graphql/resolvers/project_resolver_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Resolvers::ProjectResolver do
it 'batch-resolves projects by full path' do
paths = [project1.full_path, project2.full_path]
- result = batch_sync(max_queries: 1) do
+ result = batch_sync(max_queries: 3) do
paths.map { |path| resolve_project(path) }
end
diff --git a/spec/graphql/resolvers/timelog_resolver_spec.rb b/spec/graphql/resolvers/timelog_resolver_spec.rb
index 798d8a56cf5..c4253f4b9bc 100644
--- a/spec/graphql/resolvers/timelog_resolver_spec.rb
+++ b/spec/graphql/resolvers/timelog_resolver_spec.rb
@@ -29,6 +29,14 @@ RSpec.describe Resolvers::TimelogResolver, feature_category: :team_planning do
expect(timelogs).to contain_exactly(timelog1)
end
+ context 'when the project does not exist' do
+ let(:extra_args) { { project_id: "gid://gitlab/Project/#{non_existing_record_id}" } }
+
+ it 'returns an empty set' do
+ expect(timelogs).to be_empty
+ end
+ end
+
context 'when no dates specified' do
let(:args) { {} }
@@ -137,6 +145,20 @@ RSpec.describe Resolvers::TimelogResolver, feature_category: :team_planning do
expect(timelogs).to contain_exactly(timelog1)
end
+ context 'when the group does not exist' do
+ let_it_be(:error_class) { Gitlab::Graphql::Errors::ResourceNotAvailable }
+
+ let(:extra_args) { { group_id: "gid://gitlab/Group/#{non_existing_record_id}" } }
+
+ it 'returns an error' do
+ expect_graphql_error_to_be_created(error_class,
+ "The resource that you are attempting to access does not exist or " \
+ "you don't have permission to perform this action") do
+ timelogs
+ end
+ end
+ end
+
context 'when only start_date is present' do
let(:args) { { start_date: short_time_ago } }
diff --git a/spec/graphql/types/analytics/cycle_analytics/value_stream_type_spec.rb b/spec/graphql/types/analytics/cycle_analytics/value_stream_type_spec.rb
index 5e2638210d3..1d5a8dbebd6 100644
--- a/spec/graphql/types/analytics/cycle_analytics/value_stream_type_spec.rb
+++ b/spec/graphql/types/analytics/cycle_analytics/value_stream_type_spec.rb
@@ -7,5 +7,5 @@ RSpec.describe Types::Analytics::CycleAnalytics::ValueStreamType, feature_catego
specify { expect(described_class).to require_graphql_authorizations(:read_cycle_analytics) }
- specify { expect(described_class).to have_graphql_fields(:id, :name, :namespace, :project) }
+ specify { expect(described_class).to have_graphql_fields(:id, :name, :namespace, :project, :stages) }
end
diff --git a/spec/graphql/types/analytics/cycle_analytics/value_streams/stage_type_spec.rb b/spec/graphql/types/analytics/cycle_analytics/value_streams/stage_type_spec.rb
new file mode 100644
index 00000000000..92276647e1b
--- /dev/null
+++ b/spec/graphql/types/analytics/cycle_analytics/value_streams/stage_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Analytics::CycleAnalytics::ValueStreams::StageType, feature_category: :value_stream_management do
+ let(:fields) do
+ %i[
+ name start_event_identifier
+ end_event_identifier hidden custom
+ ]
+ end
+
+ specify { expect(described_class.graphql_name).to eq('ValueStreamStage') }
+ specify { expect(described_class).to have_graphql_fields(fields).at_least }
+end
diff --git a/spec/graphql/types/ci/catalog/resource_type_spec.rb b/spec/graphql/types/ci/catalog/resource_type_spec.rb
index 5f5732c5237..7e15efca644 100644
--- a/spec/graphql/types/ci/catalog/resource_type_spec.rb
+++ b/spec/graphql/types/ci/catalog/resource_type_spec.rb
@@ -16,8 +16,6 @@ RSpec.describe Types::Ci::Catalog::ResourceType, feature_category: :pipeline_com
latest_version
latest_released_at
star_count
- forks_count
- root_namespace
readme_html
open_issues_count
open_merge_requests_count
diff --git a/spec/graphql/types/ci/catalog/resources/component_type_spec.rb b/spec/graphql/types/ci/catalog/resources/component_type_spec.rb
new file mode 100644
index 00000000000..93ab926d406
--- /dev/null
+++ b/spec/graphql/types/ci/catalog/resources/component_type_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::Catalog::Resources::ComponentType, feature_category: :pipeline_composition do
+ specify { expect(described_class.graphql_name).to eq('CiCatalogResourceComponent') }
+
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ id
+ inputs
+ name
+ path
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/ci/catalog/resources/components/input_type_spec.rb b/spec/graphql/types/ci/catalog/resources/components/input_type_spec.rb
new file mode 100644
index 00000000000..cb716cfff8c
--- /dev/null
+++ b/spec/graphql/types/ci/catalog/resources/components/input_type_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::Catalog::Resources::Components::InputType, feature_category: :pipeline_composition do
+ specify { expect(described_class.graphql_name).to eq('CiCatalogResourceComponentInput') }
+
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ name
+ default
+ required
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/ci/catalog/resources/version_sort_enum_spec.rb b/spec/graphql/types/ci/catalog/resources/version_sort_enum_spec.rb
new file mode 100644
index 00000000000..fd0f1a1e553
--- /dev/null
+++ b/spec/graphql/types/ci/catalog/resources/version_sort_enum_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CiCatalogResourceVersionSort'], feature_category: :pipeline_composition do
+ it { expect(described_class.graphql_name).to eq('CiCatalogResourceVersionSort') }
+
+ it 'exposes all the existing catalog resource version sort options' do
+ expect(described_class.values.keys).to include(
+ *%w[RELEASED_AT_ASC RELEASED_AT_DESC CREATED_ASC CREATED_DESC]
+ )
+ end
+end
diff --git a/spec/graphql/types/ci/catalog/resources/version_type_spec.rb b/spec/graphql/types/ci/catalog/resources/version_type_spec.rb
new file mode 100644
index 00000000000..088973cf8f7
--- /dev/null
+++ b/spec/graphql/types/ci/catalog/resources/version_type_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::Catalog::Resources::VersionType, feature_category: :pipeline_composition do
+ specify { expect(described_class.graphql_name).to eq('CiCatalogResourceVersion') }
+
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ id
+ created_at
+ released_at
+ tag_name
+ tag_path
+ author
+ commit
+ components
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/ci/job_base_field_spec.rb b/spec/graphql/types/ci/job_base_field_spec.rb
index ec7d2a7d33a..c2bf73526d2 100644
--- a/spec/graphql/types/ci/job_base_field_spec.rb
+++ b/spec/graphql/types/ci/job_base_field_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::JobBaseField, feature_category: :runner_fleet do
+RSpec.describe Types::Ci::JobBaseField, feature_category: :fleet_visibility do
describe 'authorized?' do
let_it_be(:current_user) { create(:user) }
diff --git a/spec/graphql/types/ci/runner_countable_connection_type_spec.rb b/spec/graphql/types/ci/runner_countable_connection_type_spec.rb
index 49254ed0f93..9f24909e110 100644
--- a/spec/graphql/types/ci/runner_countable_connection_type_spec.rb
+++ b/spec/graphql/types/ci/runner_countable_connection_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerCountableConnectionType, feature_category: :runner_fleet do
+RSpec.describe Types::Ci::RunnerCountableConnectionType, feature_category: :fleet_visibility do
it 'contains attributes related to a runner connection' do
expected_fields = %w[count]
diff --git a/spec/graphql/types/ci/runner_manager_type_spec.rb b/spec/graphql/types/ci/runner_manager_type_spec.rb
index ff7297b0a0e..ce55d6fee03 100644
--- a/spec/graphql/types/ci/runner_manager_type_spec.rb
+++ b/spec/graphql/types/ci/runner_manager_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe GitlabSchema.types['CiRunnerManager'], feature_category: :runner_fleet do
+RSpec.describe GitlabSchema.types['CiRunnerManager'], feature_category: :fleet_visibility do
specify { expect(described_class.graphql_name).to eq('CiRunnerManager') }
specify { expect(described_class).to require_graphql_authorizations(:read_runner_manager) }
diff --git a/spec/graphql/types/ci/runner_platform_type_spec.rb b/spec/graphql/types/ci/runner_platform_type_spec.rb
index 1b0f5a5ec71..f4acfc1f8ca 100644
--- a/spec/graphql/types/ci/runner_platform_type_spec.rb
+++ b/spec/graphql/types/ci/runner_platform_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerPlatformType, feature_category: :runner_fleet do
+RSpec.describe Types::Ci::RunnerPlatformType, feature_category: :fleet_visibility do
specify { expect(described_class.graphql_name).to eq('RunnerPlatform') }
it 'exposes the expected fields' do
diff --git a/spec/graphql/types/ci/runner_setup_type_spec.rb b/spec/graphql/types/ci/runner_setup_type_spec.rb
index d3e47b52a80..66469a35a94 100644
--- a/spec/graphql/types/ci/runner_setup_type_spec.rb
+++ b/spec/graphql/types/ci/runner_setup_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerSetupType, feature_category: :runner_fleet do
+RSpec.describe Types::Ci::RunnerSetupType, feature_category: :fleet_visibility do
specify { expect(described_class.graphql_name).to eq('RunnerSetup') }
it 'exposes the expected fields' do
diff --git a/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb b/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb
index 4aa9ad094a6..3f6a867de39 100644
--- a/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb
+++ b/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerUpgradeStatusEnum, feature_category: :runner_fleet do
+RSpec.describe Types::Ci::RunnerUpgradeStatusEnum, feature_category: :fleet_visibility do
let(:model_only_enum_values) { %w[not_processed] }
let(:expected_graphql_source_values) do
Ci::RunnerVersion.statuses.keys - model_only_enum_values
diff --git a/spec/graphql/types/ci/runner_web_url_edge_spec.rb b/spec/graphql/types/ci/runner_web_url_edge_spec.rb
index 07a9655b3e1..fc4e5428360 100644
--- a/spec/graphql/types/ci/runner_web_url_edge_spec.rb
+++ b/spec/graphql/types/ci/runner_web_url_edge_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerWebUrlEdge, feature_category: :runner_fleet do
+RSpec.describe Types::Ci::RunnerWebUrlEdge, feature_category: :fleet_visibility do
specify { expect(described_class.graphql_name).to eq('RunnerWebUrlEdge') }
it 'contains URL attributes' do
diff --git a/spec/graphql/types/container_registry/protection/rule_type_spec.rb b/spec/graphql/types/container_registry/protection/rule_type_spec.rb
index 58b53af80fb..40a45609345 100644
--- a/spec/graphql/types/container_registry/protection/rule_type_spec.rb
+++ b/spec/graphql/types/container_registry/protection/rule_type_spec.rb
@@ -15,8 +15,8 @@ RSpec.describe GitlabSchema.types['ContainerRegistryProtectionRule'], feature_ca
it { is_expected.to have_non_null_graphql_type(::Types::GlobalIDType[::ContainerRegistry::Protection::Rule]) }
end
- describe 'container_path_pattern' do
- subject { described_class.fields['containerPathPattern'] }
+ describe 'repository_path_pattern' do
+ subject { described_class.fields['repositoryPathPattern'] }
it { is_expected.to have_non_null_graphql_type(GraphQL::Types::String) }
end
diff --git a/spec/graphql/types/container_repository_details_type_spec.rb b/spec/graphql/types/container_repository_details_type_spec.rb
index 62e72089e09..2253b07f5c8 100644
--- a/spec/graphql/types/container_repository_details_type_spec.rb
+++ b/spec/graphql/types/container_repository_details_type_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['ContainerRepositoryDetails'] do
fields = %i[id name path location created_at updated_at expiration_policy_started_at
status tags_count can_delete expiration_policy_cleanup_status tags size
- project migration_state last_cleanup_deleted_tags_count]
+ project migration_state last_cleanup_deleted_tags_count userPermissions]
it { expect(described_class.graphql_name).to eq('ContainerRepositoryDetails') }
diff --git a/spec/graphql/types/container_repository_tag_type_spec.rb b/spec/graphql/types/container_repository_tag_type_spec.rb
index 1d1a76d6916..596a221b5c0 100644
--- a/spec/graphql/types/container_repository_tag_type_spec.rb
+++ b/spec/graphql/types/container_repository_tag_type_spec.rb
@@ -2,8 +2,8 @@
require 'spec_helper'
-RSpec.describe GitlabSchema.types['ContainerRepositoryTag'] do
- fields = %i[name path location digest revision short_revision total_size created_at can_delete]
+RSpec.describe GitlabSchema.types['ContainerRepositoryTag'], feature_category: :container_registry do
+ fields = %i[name path location digest revision short_revision total_size created_at can_delete user_permissions]
it { expect(described_class.graphql_name).to eq('ContainerRepositoryTag') }
@@ -12,4 +12,6 @@ RSpec.describe GitlabSchema.types['ContainerRepositoryTag'] do
it { expect(described_class).to require_graphql_authorizations(:read_container_image) }
it { expect(described_class).to have_graphql_fields(fields) }
+
+ it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::ContainerRepositoryTag) }
end
diff --git a/spec/graphql/types/container_repository_type_spec.rb b/spec/graphql/types/container_repository_type_spec.rb
index bc92fa24050..0c7879c3f2a 100644
--- a/spec/graphql/types/container_repository_type_spec.rb
+++ b/spec/graphql/types/container_repository_type_spec.rb
@@ -2,10 +2,10 @@
require 'spec_helper'
-RSpec.describe GitlabSchema.types['ContainerRepository'] do
+RSpec.describe GitlabSchema.types['ContainerRepository'], feature_category: :container_registry do
fields = %i[id name path location created_at updated_at expiration_policy_started_at
status tags_count can_delete expiration_policy_cleanup_status project
- migration_state last_cleanup_deleted_tags_count]
+ migration_state last_cleanup_deleted_tags_count user_permissions]
it { expect(described_class.graphql_name).to eq('ContainerRepository') }
@@ -15,6 +15,8 @@ RSpec.describe GitlabSchema.types['ContainerRepository'] do
it { expect(described_class).to have_graphql_fields(fields) }
+ it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::ContainerRepository) }
+
describe 'status field' do
subject { described_class.fields['status'] }
diff --git a/spec/graphql/types/current_user_type_spec.rb b/spec/graphql/types/current_user_type_spec.rb
new file mode 100644
index 00000000000..ff7a529a057
--- /dev/null
+++ b/spec/graphql/types/current_user_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CurrentUser'], feature_category: :user_profile do
+ specify { expect(described_class.graphql_name).to eq('CurrentUser') }
+
+ it "inherits authorization policies from the UserType superclass" do
+ expect(described_class).to require_graphql_authorizations(:read_user)
+ end
+end
diff --git a/spec/graphql/types/group_type_spec.rb b/spec/graphql/types/group_type_spec.rb
index 6622551f063..d3f9053faf3 100644
--- a/spec/graphql/types/group_type_spec.rb
+++ b/spec/graphql/types/group_type_spec.rb
@@ -125,4 +125,37 @@ RSpec.describe GitlabSchema.types['Group'] do
expect { clean_state_query }.not_to exceed_all_query_limit(control)
end
end
+
+ describe 'custom emoji' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:subgroup) { create(:group, parent: group) }
+ let_it_be(:custom_emoji) { create(:custom_emoji, group: group) }
+ let_it_be(:custom_emoji_subgroup) { create(:custom_emoji, group: subgroup) }
+ let(:query) do
+ %(
+ query {
+ group(fullPath: "#{subgroup.full_path}") {
+ customEmoji(includeAncestorGroups: true) {
+ nodes {
+ id
+ }
+ }
+ }
+ }
+ )
+ end
+
+ before_all do
+ group.add_reporter(user)
+ end
+
+ describe 'when includeAncestorGroups is true' do
+ it 'returns emoji from ancestor groups' do
+ result = GitlabSchema.execute(query, context: { current_user: user }).as_json
+
+ expect(result.dig('data', 'group', 'customEmoji', 'nodes').count).to eq(2)
+ end
+ end
+ end
end
diff --git a/spec/graphql/types/issue_type_enum_spec.rb b/spec/graphql/types/issue_type_enum_spec.rb
index 5b1bc9c3d9c..f0370e275cd 100644
--- a/spec/graphql/types/issue_type_enum_spec.rb
+++ b/spec/graphql/types/issue_type_enum_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Types::IssueTypeEnum, feature_category: :team_planning do
it 'exposes all the existing issue type values except epic' do
expect(described_class.values.keys).to match_array(
- %w[ISSUE INCIDENT TEST_CASE REQUIREMENT TASK OBJECTIVE KEY_RESULT]
+ %w[ISSUE INCIDENT TEST_CASE REQUIREMENT TASK OBJECTIVE KEY_RESULT EPIC]
)
end
end
diff --git a/spec/graphql/types/ml/candidate_links_type_spec.rb b/spec/graphql/types/ml/candidate_links_type_spec.rb
new file mode 100644
index 00000000000..489079cc717
--- /dev/null
+++ b/spec/graphql/types/ml/candidate_links_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MLCandidateLinks'], feature_category: :mlops do
+ it 'has the expected fields' do
+ expected_fields = %w[showPath artifact_path]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/ml/candidate_type_spec.rb b/spec/graphql/types/ml/candidate_type_spec.rb
new file mode 100644
index 00000000000..e000ada1309
--- /dev/null
+++ b/spec/graphql/types/ml/candidate_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MlCandidate'], feature_category: :mlops do
+ specify { expect(described_class.description).to eq('Candidate for a model version in the model registry') }
+
+ it 'includes all the package fields' do
+ expected_fields = %w[id name created_at _links]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/ml/model_type_spec.rb b/spec/graphql/types/ml/model_type_spec.rb
new file mode 100644
index 00000000000..ee0473ccafe
--- /dev/null
+++ b/spec/graphql/types/ml/model_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MlModel'], feature_category: :mlops do
+ specify { expect(described_class.description).to eq('Machine learning model in the model registry') }
+
+ it 'includes all the package fields' do
+ expected_fields = %w[id name versions candidates]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/ml/model_version_links_type_spec.rb b/spec/graphql/types/ml/model_version_links_type_spec.rb
new file mode 100644
index 00000000000..d2a11643c35
--- /dev/null
+++ b/spec/graphql/types/ml/model_version_links_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MLModelVersionLinks'], feature_category: :mlops do
+ it 'has the expected fields' do
+ expected_fields = %w[showPath]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/ml/model_version_type_spec.rb b/spec/graphql/types/ml/model_version_type_spec.rb
new file mode 100644
index 00000000000..03652c55e20
--- /dev/null
+++ b/spec/graphql/types/ml/model_version_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MlModelVersion'], feature_category: :mlops do
+ specify { expect(described_class.description).to eq('Version of a machine learning model') }
+
+ it 'includes all the package fields' do
+ expected_fields = %w[id version created_at _links]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/namespace/package_settings_type_spec.rb b/spec/graphql/types/namespace/package_settings_type_spec.rb
index d823f2017b6..0e731c1e2bf 100644
--- a/spec/graphql/types/namespace/package_settings_type_spec.rb
+++ b/spec/graphql/types/namespace/package_settings_type_spec.rb
@@ -32,6 +32,7 @@ RSpec.describe GitlabSchema.types['PackageSettings'], feature_category: :package
maven_package_requests_forwarding_locked
npm_package_requests_forwarding_locked
pypi_package_requests_forwarding_locked
+ nuget_symbol_server_enabled
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/organizations/organization_type_spec.rb b/spec/graphql/types/organizations/organization_type_spec.rb
index 62787ad220d..6bc4bac6ba2 100644
--- a/spec/graphql/types/organizations/organization_type_spec.rb
+++ b/spec/graphql/types/organizations/organization_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['Organization'], feature_category: :cell do
- let(:expected_fields) { %w[groups id name organization_users path web_url] }
+ let(:expected_fields) { %w[avatar_url description description_html groups id name organization_users path web_url] }
specify { expect(described_class.graphql_name).to eq('Organization') }
specify { expect(described_class).to require_graphql_authorizations(:read_organization) }
diff --git a/spec/graphql/types/permission_types/abuse_report_spec.rb b/spec/graphql/types/permission_types/abuse_report_spec.rb
deleted file mode 100644
index 399df137a78..00000000000
--- a/spec/graphql/types/permission_types/abuse_report_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Types::PermissionTypes::AbuseReport, feature_category: :insider_threat do
- it do
- expected_permissions = [
- :read_abuse_report, :create_note
- ]
-
- expected_permissions.each do |permission|
- expect(described_class).to have_graphql_field(permission)
- end
- end
-end
diff --git a/spec/graphql/types/permission_types/container_repository_spec.rb b/spec/graphql/types/permission_types/container_repository_spec.rb
new file mode 100644
index 00000000000..1d8d9e994ed
--- /dev/null
+++ b/spec/graphql/types/permission_types/container_repository_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['ContainerRepositoryPermissions'], feature_category: :container_registry do
+ it 'has the expected fields' do
+ expected_permissions = [:destroy_container_repository]
+
+ expect(described_class).to have_graphql_fields(expected_permissions).only
+ end
+end
diff --git a/spec/graphql/types/permission_types/container_repository_tag_spec.rb b/spec/graphql/types/permission_types/container_repository_tag_spec.rb
new file mode 100644
index 00000000000..69d60ba621b
--- /dev/null
+++ b/spec/graphql/types/permission_types/container_repository_tag_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['ContainerRepositoryTagPermissions'], feature_category: :container_registry do
+ it 'has the expected fields' do
+ expected_permissions = [:destroy_container_repository_tag]
+
+ expect(described_class).to have_graphql_fields(expected_permissions).only
+ end
+end
diff --git a/spec/graphql/types/project_feature_access_level_enum_spec.rb b/spec/graphql/types/project_feature_access_level_enum_spec.rb
new file mode 100644
index 00000000000..a13b3be3f8f
--- /dev/null
+++ b/spec/graphql/types/project_feature_access_level_enum_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['ProjectFeatureAccessLevel'], feature_category: :groups_and_projects do
+ specify { expect(described_class.graphql_name).to eq('ProjectFeatureAccessLevel') }
+
+ it 'exposes all the existing access levels' do
+ expect(described_class.values.keys).to include(*%w[DISABLED PRIVATE ENABLED])
+ end
+end
diff --git a/spec/graphql/types/project_feature_access_level_type_spec.rb b/spec/graphql/types/project_feature_access_level_type_spec.rb
new file mode 100644
index 00000000000..fae9de63d93
--- /dev/null
+++ b/spec/graphql/types/project_feature_access_level_type_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['ProjectFeatureAccess'], feature_category: :groups_and_projects do
+ specify { expect(described_class.graphql_name).to eq('ProjectFeatureAccess') }
+ specify { expect(described_class).to require_graphql_authorizations(nil) }
+
+ it 'has expected fields' do
+ expected_fields = [:integer_value, :string_value]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index 7b4bcf4b1b0..3965312316b 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -2,9 +2,10 @@
require 'spec_helper'
-RSpec.describe GitlabSchema.types['Project'] do
+RSpec.describe GitlabSchema.types['Project'], feature_category: :groups_and_projects do
include GraphqlHelpers
include ProjectForksHelper
+ using RSpec::Parameterized::TableSyntax
specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Project) }
@@ -21,7 +22,8 @@ RSpec.describe GitlabSchema.types['Project'] do
container_registry_enabled shared_runners_enabled
lfs_enabled merge_requests_ff_only_enabled avatar_url
issues_enabled merge_requests_enabled wiki_enabled
- snippets_enabled jobs_enabled public_jobs open_issues_count import_status
+ forking_access_level issues_access_level merge_requests_access_level
+ snippets_enabled jobs_enabled public_jobs open_issues_count open_merge_requests_count import_status
only_allow_merge_if_pipeline_succeeds request_access_enabled
only_allow_merge_if_all_discussions_are_resolved printing_merge_request_link_enabled
namespace group statistics statistics_details_paths repository merge_requests merge_request issues
@@ -39,7 +41,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 detailed_import_status
+ ci_cd_settings detailed_import_status value_streams
]
expect(described_class).to include_graphql_fields(*expected_fields)
@@ -704,6 +706,63 @@ RSpec.describe GitlabSchema.types['Project'] do
end
end
+ describe 'project features access level' do
+ let_it_be(:project) { create(:project, :public) }
+
+ where(project_feature: %w[forkingAccessLevel issuesAccessLevel mergeRequestsAccessLevel])
+
+ with_them do
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ #{project_feature} {
+ integerValue
+ stringValue
+ }
+ }
+ }
+ )
+ end
+
+ subject { GitlabSchema.execute(query).as_json.dig('data', 'project', project_feature) }
+
+ it { is_expected.to eq({ "integerValue" => ProjectFeature::ENABLED, "stringValue" => "ENABLED" }) }
+ end
+ end
+
+ describe 'open_merge_requests_count' do
+ let_it_be(:project, reload: true) { create(:project, :public) }
+ let_it_be(:open_merge_request) { create(:merge_request, source_project: project) }
+ let_it_be(:closed_merge_request) { create(:merge_request, :closed, source_project: project) }
+
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ openMergeRequestsCount
+ }
+ }
+ )
+ end
+
+ subject(:open_merge_requests_count) do
+ GitlabSchema.execute(query).as_json.dig('data', 'project', 'openMergeRequestsCount')
+ end
+
+ context 'when the user can access merge requests' do
+ it { is_expected.to eq(1) }
+ end
+
+ context 'when the user cannot access merge requests' do
+ before do
+ project.project_feature.update!(merge_requests_access_level: ProjectFeature::PRIVATE)
+ end
+
+ it { is_expected.to be_nil }
+ end
+ end
+
describe 'branch_rules' do
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project, :public) }
diff --git a/spec/graphql/types/projects/service_type_enum_spec.rb b/spec/graphql/types/projects/service_type_enum_spec.rb
index a5b1ba24a44..40376afc7f7 100644
--- a/spec/graphql/types/projects/service_type_enum_spec.rb
+++ b/spec/graphql/types/projects/service_type_enum_spec.rb
@@ -38,7 +38,6 @@ RSpec.describe GitlabSchema.types['ServiceType'] do
PUMBLE_SERVICE
PUSHOVER_SERVICE
REDMINE_SERVICE
- SHIMO_SERVICE
SLACK_SERVICE
SLACK_SLASH_COMMANDS_SERVICE
TEAMCITY_SERVICE
diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb
index 8bda738751d..0b5739be9a1 100644
--- a/spec/graphql/types/query_type_spec.rb
+++ b/spec/graphql/types/query_type_spec.rb
@@ -13,6 +13,14 @@ RSpec.describe GitlabSchema.types['Query'], feature_category: :shared do
expect(described_class).to have_graphql_fields(*expected_foss_fields).at_least
end
+ describe 'current_user field' do
+ subject { described_class.fields['currentUser'] }
+
+ it 'returns current user' do
+ is_expected.to have_graphql_type(Types::CurrentUserType)
+ end
+ end
+
describe 'namespace field' do
subject { described_class.fields['namespace'] }
@@ -137,4 +145,14 @@ RSpec.describe GitlabSchema.types['Query'], feature_category: :shared do
is_expected.to have_graphql_resolver(Resolvers::BoardListResolver)
end
end
+
+ describe 'mlModel field' do
+ subject { described_class.fields['mlModel'] }
+
+ it 'returns metadata', :aggregate_failures do
+ is_expected.to have_graphql_type(Types::Ml::ModelType)
+ is_expected.to have_graphql_arguments(:id)
+ is_expected.to have_graphql_resolver(Resolvers::Ml::ModelDetailResolver)
+ end
+ end
end
diff --git a/spec/graphql/types/root_storage_statistics_type_spec.rb b/spec/graphql/types/root_storage_statistics_type_spec.rb
index 00f4092baf4..8ac3b32948f 100644
--- a/spec/graphql/types/root_storage_statistics_type_spec.rb
+++ b/spec/graphql/types/root_storage_statistics_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe GitlabSchema.types['RootStorageStatistics'] do
+RSpec.describe GitlabSchema.types['RootStorageStatistics'], feature_category: :consumables_cost_management do
specify { expect(described_class.graphql_name).to eq('RootStorageStatistics') }
it 'has the expected fields' do
diff --git a/spec/graphql/types/user_preferences_type_spec.rb b/spec/graphql/types/user_preferences_type_spec.rb
index 06749dda239..87fac17a5ba 100644
--- a/spec/graphql/types/user_preferences_type_spec.rb
+++ b/spec/graphql/types/user_preferences_type_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe Types::UserPreferencesType, feature_category: :user_profile do
expected_fields = %i[
issues_sort
visibility_pipeline_id_type
+ use_web_ide_extension_marketplace
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/work_item_state_counts_type_spec.rb b/spec/graphql/types/work_item_state_counts_type_spec.rb
new file mode 100644
index 00000000000..bab2e124222
--- /dev/null
+++ b/spec/graphql/types/work_item_state_counts_type_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['WorkItemStateCountsType'], feature_category: :portfolio_management do
+ specify { expect(described_class.graphql_name).to eq('WorkItemStateCountsType') }
+
+ it 'exposes the expected fields' do
+ expected_fields = %i[all opened closed]
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/work_items/widget_definition_interface_spec.rb b/spec/graphql/types/work_items/widget_definition_interface_spec.rb
new file mode 100644
index 00000000000..59320a75eba
--- /dev/null
+++ b/spec/graphql/types/work_items/widget_definition_interface_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::WorkItems::WidgetDefinitionInterface, feature_category: :team_planning do
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ type
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+
+ describe '.resolve_type' do
+ subject { described_class.resolve_type(object, {}) }
+
+ context 'for assignees widget' do
+ let(:object) { WorkItems::Widgets::Assignees }
+
+ it { is_expected.to eq(Types::WorkItems::WidgetDefinitions::AssigneesType) }
+ end
+
+ context 'for hierarchy widget' do
+ let(:object) { WorkItems::Widgets::Hierarchy }
+
+ it { is_expected.to eq(Types::WorkItems::WidgetDefinitions::HierarchyType) }
+ end
+
+ context 'for other widgets' do
+ let(:object) { WorkItems::Widgets::Description }
+
+ it { is_expected.to eq(Types::WorkItems::WidgetDefinitions::GenericType) }
+ end
+ end
+end
diff --git a/spec/graphql/types/work_items/widget_definitions/assignees_type_spec.rb b/spec/graphql/types/work_items/widget_definitions/assignees_type_spec.rb
new file mode 100644
index 00000000000..3a1feee960c
--- /dev/null
+++ b/spec/graphql/types/work_items/widget_definitions/assignees_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::WorkItems::WidgetDefinitions::AssigneesType, feature_category: :team_planning do
+ it 'exposes the expected fields' do
+ expected_fields = %i[type can_invite_members]
+
+ expected_fields.each do |field|
+ expect(described_class).to have_graphql_field(field)
+ end
+ end
+end
diff --git a/spec/graphql/types/work_items/widget_definitions/generic_type_spec.rb b/spec/graphql/types/work_items/widget_definitions/generic_type_spec.rb
new file mode 100644
index 00000000000..19e962e71fd
--- /dev/null
+++ b/spec/graphql/types/work_items/widget_definitions/generic_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::WorkItems::WidgetDefinitions::GenericType, feature_category: :team_planning do
+ it 'exposes the expected fields' do
+ expected_fields = %i[type]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end