diff options
Diffstat (limited to 'spec/graphql/resolvers')
22 files changed, 255 insertions, 197 deletions
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 } } |