diff options
Diffstat (limited to 'spec/graphql/resolvers')
20 files changed, 297 insertions, 109 deletions
diff --git a/spec/graphql/resolvers/board_lists_resolver_spec.rb b/spec/graphql/resolvers/board_lists_resolver_spec.rb index c882ad7c818..2fb7c5c4717 100644 --- a/spec/graphql/resolvers/board_lists_resolver_spec.rb +++ b/spec/graphql/resolvers/board_lists_resolver_spec.rb @@ -101,7 +101,7 @@ RSpec.describe Resolvers::BoardListsResolver do def resolve_board_lists(args: {}, current_user: user) resolve(described_class, obj: board, args: args, ctx: { current_user: current_user }, - arg_style: :internal + arg_style: :internal ) end end diff --git a/spec/graphql/resolvers/ci/config_resolver_spec.rb b/spec/graphql/resolvers/ci/config_resolver_spec.rb index dc030b1313b..692bdf58784 100644 --- a/spec/graphql/resolvers/ci/config_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/config_resolver_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Resolvers::Ci::ConfigResolver do subject(:response) do resolve(described_class, args: { project_path: project.full_path, content: content, sha: sha }, - ctx: { current_user: user }) + ctx: { current_user: user }) end shared_examples 'a valid config file' do diff --git a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb index f99f48f5b07..57b2fcbea63 100644 --- a/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/group_runners_resolver_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Resolvers::Ci::GroupRunnersResolver do describe '#resolve' do subject do resolve(described_class, obj: obj, ctx: { current_user: user }, args: args, - arg_style: :internal) + arg_style: :internal) end include_context 'runners resolver setup' diff --git a/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb b/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb index ac7cef20df4..1bfd6fbf6b9 100644 --- a/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb @@ -20,10 +20,10 @@ RSpec.describe Resolvers::Ci::JobTokenScopeResolver do project.add_member(current_user, :maintainer) end - it 'returns nil when scope is not enabled' do + it 'returns the same project in the allow list of projects for the Ci Job Token when scope is not enabled' do allow(project).to receive(:ci_job_token_scope_enabled?).and_return(false) - expect(resolve_scope).to eq(nil) + expect(resolve_scope.all_projects).to contain_exactly(project) end it 'returns the same project in the allow list of projects for the Ci Job Token' do @@ -43,8 +43,8 @@ RSpec.describe Resolvers::Ci::JobTokenScopeResolver do project.update!(ci_job_token_scope_enabled: false) end - it 'returns nil' do - expect(resolve_scope).to be_nil + it 'resolves projects' do + expect(resolve_scope.all_projects).to contain_exactly(project) end end end diff --git a/spec/graphql/resolvers/ci/jobs_resolver_spec.rb b/spec/graphql/resolvers/ci/jobs_resolver_spec.rb index 6c228861ddf..80a70938dc4 100644 --- a/spec/graphql/resolvers/ci/jobs_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/jobs_resolver_spec.rb @@ -38,7 +38,7 @@ RSpec.describe Resolvers::Ci::JobsResolver do ::Types::Security::ReportTypeEnum.values['DAST'].value ] jobs = resolve(described_class, obj: pipeline, args: { security_report_types: report_types }, - arg_style: :internal) + arg_style: :internal) expect(jobs).to contain_exactly( have_attributes(name: 'DAST job'), diff --git a/spec/graphql/resolvers/ci/runner_projects_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_projects_resolver_spec.rb new file mode 100644 index 00000000000..952c7337d65 --- /dev/null +++ b/spec/graphql/resolvers/ci/runner_projects_resolver_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::Ci::RunnerProjectsResolver do + include GraphqlHelpers + + let_it_be(:project1) { create(:project, description: 'Project1.1') } + let_it_be(:project2) { create(:project, description: 'Project1.2') } + let_it_be(:project3) { create(:project, description: 'Project2.1') } + let_it_be(:runner) { create(:ci_runner, :project, projects: [project1, project2, project3]) } + + let(:args) { {} } + + subject { resolve_projects(args) } + + describe '#resolve' do + context 'with authorized user', :enable_admin_mode do + let(:current_user) { create(:user, :admin) } + + context 'with search argument' do + let(:args) { { search: 'Project1.' } } + + it 'returns a lazy value with projects containing the specified prefix' do + expect(subject).to be_a(GraphQL::Execution::Lazy) + expect(subject.value).to contain_exactly(project1, project2) + end + end + + context 'with supported arguments' do + let(:args) { { membership: true, search_namespaces: true, topics: %w[xyz] } } + + it 'creates ProjectsFinder with expected arguments' do + expect(ProjectsFinder).to receive(:new).with( + a_hash_including( + params: a_hash_including( + non_public: true, + search_namespaces: true, + topic: %w[xyz] + ) + ) + ).and_call_original + + expect(subject).to be_a(GraphQL::Execution::Lazy) + subject.value + end + end + + context 'without arguments' do + it 'returns a lazy value with all projects' do + expect(subject).to be_a(GraphQL::Execution::Lazy) + expect(subject.value).to contain_exactly(project1, project2, project3) + end + end + end + + context 'with unauthorized user' do + let(:current_user) { create(:user) } + + it { is_expected.to be_nil } + end + end + + private + + def resolve_projects(args = {}, context = { current_user: current_user }) + resolve(described_class, obj: runner, args: args, ctx: context) + end +end diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb index 8586d359336..4038192a68a 100644 --- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Resolvers::Ci::RunnersResolver do subject do resolve(described_class, obj: obj, ctx: { current_user: user }, args: args, - arg_style: :internal) + arg_style: :internal) end include_context 'runners resolver setup' diff --git a/spec/graphql/resolvers/ci/test_suite_resolver_spec.rb b/spec/graphql/resolvers/ci/test_suite_resolver_spec.rb index 606c6eb03a3..4083e77a38f 100644 --- a/spec/graphql/resolvers/ci/test_suite_resolver_spec.rb +++ b/spec/graphql/resolvers/ci/test_suite_resolver_spec.rb @@ -32,11 +32,12 @@ RSpec.describe Resolvers::Ci::TestSuiteResolver do # Each test failure in this pipeline has a matching failure in the default branch recent_failures = test_suite[:test_cases].map { |tc| tc[:recent_failures] } - expect(recent_failures).to eq([ - { count: 1, base_branch: 'master' }, - { count: 1, base_branch: 'master' }, - { count: 1, base_branch: 'master' } - ]) + expect(recent_failures).to eq( + [ + { count: 1, base_branch: 'master' }, + { count: 1, base_branch: 'master' }, + { count: 1, base_branch: 'master' } + ]) end end diff --git a/spec/graphql/resolvers/container_repositories_resolver_spec.rb b/spec/graphql/resolvers/container_repositories_resolver_spec.rb index ed922259903..8cbb366f873 100644 --- a/spec/graphql/resolvers/container_repositories_resolver_spec.rb +++ b/spec/graphql/resolvers/container_repositories_resolver_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Resolvers::ContainerRepositoriesResolver do subject do resolve(described_class, ctx: { current_user: user }, args: args, obj: object, - arg_style: :internal) + arg_style: :internal) end shared_examples 'returning container repositories' do diff --git a/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb b/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb index 9747f663759..3ed3fe76267 100644 --- a/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb +++ b/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb @@ -14,7 +14,7 @@ RSpec.describe Resolvers::ContainerRepositoryTagsResolver do describe '#resolve' do let(:resolver) do resolve(described_class, ctx: { current_user: user }, obj: repository, args: args, - arg_style: :internal) + arg_style: :internal) end before do diff --git a/spec/graphql/resolvers/crm/organization_state_counts_resolver_spec.rb b/spec/graphql/resolvers/crm/organization_state_counts_resolver_spec.rb new file mode 100644 index 00000000000..c6ad4beeee0 --- /dev/null +++ b/spec/graphql/resolvers/crm/organization_state_counts_resolver_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::Crm::OrganizationStateCountsResolver do + include GraphqlHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group, :crm_enabled) } + + before_all do + create(:organization, group: group, name: "ABC Corp") + create(:organization, group: group, name: "123 Corp", state: 'inactive') + create_list(:organization, 3, group: group) + create_list(:organization, 2, group: group, state: 'inactive') + end + + describe '#resolve' do + context 'with unauthorized user' do + it 'does not raise an error and returns nil' do + expect { resolve_counts(group) }.not_to raise_error + expect(resolve_counts(group)).to be_nil + end + end + + context 'with authorized user' do + before do + group.add_reporter(user) + end + + context 'without parent' do + it 'returns nil' do + expect(resolve_counts(nil)).to be_nil + end + end + + context 'with a group' do + context 'when no filter is provided' do + it 'returns the count of all organizations' do + counts = resolve_counts(group) + expect(counts['active']).to eq(4) + expect(counts['inactive']).to eq(3) + end + end + + context 'when search term is provided' do + it 'returns the correct counts' do + counts = resolve_counts(group, { search: "Corp" }) + + expect(counts['active']).to eq(1) + expect(counts['inactive']).to eq(1) + end + end + end + end + end + + def resolve_counts(parent, args = {}, context = { current_user: user }) + resolve(described_class, obj: parent, args: args, ctx: context) + end +end diff --git a/spec/graphql/resolvers/crm/organizations_resolver_spec.rb b/spec/graphql/resolvers/crm/organizations_resolver_spec.rb index 323f134ffc3..d5980bf3c41 100644 --- a/spec/graphql/resolvers/crm/organizations_resolver_spec.rb +++ b/spec/graphql/resolvers/crm/organizations_resolver_spec.rb @@ -55,11 +55,23 @@ RSpec.describe Resolvers::Crm::OrganizationsResolver do end context 'when no filter is provided' do - it 'returns all the organizations in the correct order' do + it 'returns all the organizations in the default order' do expect(resolve_organizations(group)).to eq([organization_a, organization_b]) end end + context 'when a sort is provided' do + it 'returns all the organizations in the correct order' do + expect(resolve_organizations(group, { sort: 'NAME_DESC' })).to eq([organization_b, organization_a]) + end + end + + context 'when filtering for all states' do + it 'returns all the organizations' do + expect(resolve_organizations(group, { state: 'all' })).to contain_exactly(organization_a, organization_b) + end + end + context 'when search term is provided' do it 'returns the correct organizations' do expect(resolve_organizations(group, { search: "def" })).to contain_exactly(organization_b) diff --git a/spec/graphql/resolvers/deployment_resolver_spec.rb b/spec/graphql/resolvers/deployment_resolver_spec.rb new file mode 100644 index 00000000000..9231edefddc --- /dev/null +++ b/spec/graphql/resolvers/deployment_resolver_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::DeploymentResolver do + include GraphqlHelpers + + let_it_be(:project) { create(:project, :repository, :private) } + let_it_be(:environment) { create(:environment, project: project) } + let_it_be(:deployment) { create(:deployment, :created, environment: environment, project: project) } + let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } } + + let(:current_user) { developer } + + describe '#resolve' do + it 'finds the deployment' do + expect(resolve_deployments(iid: deployment.iid)).to contain_exactly(deployment) + end + + it 'does not find the deployment if the IID does not match' do + expect(resolve_deployments(iid: non_existing_record_id)).to be_empty + end + end + + def resolve_deployments(args = {}, context = { current_user: current_user }) + resolve(described_class, obj: project, args: args, ctx: context) + end +end diff --git a/spec/graphql/resolvers/deployments_resolver_spec.rb b/spec/graphql/resolvers/deployments_resolver_spec.rb new file mode 100644 index 00000000000..4e5564aad0b --- /dev/null +++ b/spec/graphql/resolvers/deployments_resolver_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::DeploymentsResolver do + include GraphqlHelpers + + let_it_be(:project) { create(:project, :repository, :private) } + let_it_be(:environment) { create(:environment, project: project) } + let_it_be(:deployment) { create(:deployment, :created, environment: environment, project: project) } + let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } } + + let(:current_user) { developer } + + describe '#resolve' do + it 'finds the deployment' do + expect(resolve_deployments).to contain_exactly(deployment) + end + + it 'finds the deployment when status matches' do + expect(resolve_deployments(statuses: [:created])).to contain_exactly(deployment) + end + + it 'does not find the deployment when status does not match' do + expect(resolve_deployments(statuses: [:success])).to be_empty + end + + it 'transforms order_by for finder' do + expect(DeploymentsFinder) + .to receive(:new) + .with(environment: environment.id, status: ['success'], order_by: 'finished_at', sort: 'asc') + .and_call_original + + resolve_deployments(statuses: [:success], order_by: { finished_at: :asc }) + end + end + + def resolve_deployments(args = {}, context = { current_user: current_user }) + resolve(described_class, obj: environment, args: args, ctx: context) + end +end diff --git a/spec/graphql/resolvers/design_management/versions_resolver_spec.rb b/spec/graphql/resolvers/design_management/versions_resolver_spec.rb index 3a2ed445484..eb39e5bafc5 100644 --- a/spec/graphql/resolvers/design_management/versions_resolver_spec.rb +++ b/spec/graphql/resolvers/design_management/versions_resolver_spec.rb @@ -82,7 +82,7 @@ RSpec.describe Resolvers::DesignManagement::VersionsResolver do let(:params) do { earlier_or_equal_to_sha: first_version.sha, - earlier_or_equal_to_id: global_id_of(first_version) + earlier_or_equal_to_id: global_id_of(first_version) } end @@ -95,7 +95,7 @@ RSpec.describe Resolvers::DesignManagement::VersionsResolver do let(:params) do { earlier_or_equal_to_sha: first_version.sha, - earlier_or_equal_to_id: global_id_of(other_version) + earlier_or_equal_to_id: global_id_of(other_version) } end diff --git a/spec/graphql/resolvers/environments/last_deployment_resolver_spec.rb b/spec/graphql/resolvers/environments/last_deployment_resolver_spec.rb new file mode 100644 index 00000000000..95a1a06730d --- /dev/null +++ b/spec/graphql/resolvers/environments/last_deployment_resolver_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Resolvers::Environments::LastDeploymentResolver do + include GraphqlHelpers + include Gitlab::Graphql::Laziness + + let_it_be(:project) { create(:project, :repository, :private) } + let_it_be(:environment) { create(:environment, project: project) } + let_it_be(:deployment) { create(:deployment, :created, environment: environment, project: project) } + let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } } + + let(:current_user) { developer } + + describe '#resolve' do + it 'finds the deployment when status matches' do + expect(resolve_last_deployment(status: :created)).to eq(deployment) + end + + it 'does not find the deployment when status does not match' do + expect(resolve_last_deployment(status: :success)).to be_nil + end + + it 'raises an error when status is not specified' do + expect { resolve_last_deployment }.to raise_error(ArgumentError) + end + + it 'raises an error when status is not supported' do + expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, + '"skipped" status is not supported.') do + resolve_last_deployment(status: :skipped) + end + end + end + + def resolve_last_deployment(args = {}, context = { current_user: current_user }) + force(resolve(described_class, obj: environment, ctx: context, args: args)) + end +end diff --git a/spec/graphql/resolvers/group_members_resolver_spec.rb b/spec/graphql/resolvers/group_members_resolver_spec.rb index bd0b4870062..d860b87875e 100644 --- a/spec/graphql/resolvers/group_members_resolver_spec.rb +++ b/spec/graphql/resolvers/group_members_resolver_spec.rb @@ -2,9 +2,11 @@ require 'spec_helper' -RSpec.describe Resolvers::GroupMembersResolver do +RSpec.describe 'Resolvers::GroupMembersResolver' do include GraphqlHelpers + let(:described_class) { Resolvers::GroupMembersResolver } + specify do expect(described_class).to have_nullable_graphql_type(Types::GroupMemberType.connection_type) end diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb index 89e45810033..a74b2a3f18c 100644 --- a/spec/graphql/resolvers/issues_resolver_spec.rb +++ b/spec/graphql/resolvers/issues_resolver_spec.rb @@ -311,49 +311,15 @@ RSpec.describe Resolvers::IssuesResolver do end context 'when searching issues' do - it 'returns correct issues' do - expect(resolve_issues(search: 'foo')).to contain_exactly(issue2) - end - - it 'uses project search optimization' do - expected_arguments = a_hash_including( - search: 'foo', - attempt_project_search_optimizations: true - ) - expect(IssuesFinder).to receive(:new).with(anything, expected_arguments).and_call_original - - resolve_issues(search: 'foo') - end - - context 'with anonymous user' do - let_it_be(:public_project) { create(:project, :public) } - let_it_be(:public_issue) { create(:issue, project: public_project, title: 'Test issue') } - - context 'with disable_anonymous_search enabled' do - before do - stub_feature_flags(disable_anonymous_search: true) - end - - it 'generates an error' do - error_message = "User must be authenticated to include the `search` argument." - - expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, error_message) do - resolve(described_class, obj: public_project, args: { search: 'test' }, ctx: { current_user: nil }) - end - end - end - - context 'with disable_anonymous_search disabled' do - before do - stub_feature_flags(disable_anonymous_search: false) - end - - it 'returns correct issues' do - expect( - resolve(described_class, obj: public_project, args: { search: 'test' }, ctx: { current_user: nil }) - ).to contain_exactly(public_issue) - end - end + it_behaves_like 'graphql query for searching issuables' do + let_it_be(:parent) { project } + let_it_be(:issuable1) { create(:issue, project: project, title: 'first created') } + let_it_be(:issuable2) { create(:issue, project: project, title: 'second created', description: 'text 1') } + let_it_be(:issuable3) { create(:issue, project: project, title: 'third', description: 'text 2') } + let_it_be(:issuable4) { create(:issue, project: project) } + + let_it_be(:finder_class) { IssuesFinder } + let_it_be(:optimization_param) { :attempt_project_search_optimizations } end end diff --git a/spec/graphql/resolvers/project_members_resolver_spec.rb b/spec/graphql/resolvers/project_members_resolver_spec.rb index 2f4145b3215..c38cb3d157b 100644 --- a/spec/graphql/resolvers/project_members_resolver_spec.rb +++ b/spec/graphql/resolvers/project_members_resolver_spec.rb @@ -2,9 +2,11 @@ require 'spec_helper' -RSpec.describe Resolvers::ProjectMembersResolver do +RSpec.describe 'Resolvers::ProjectMembersResolver' do include GraphqlHelpers + let(:described_class) { Resolvers::ProjectMembersResolver } + it_behaves_like 'querying members with a group' do let_it_be(:project) { create(:project, group: group_1) } let_it_be(:resource_member) { create(:project_member, user: user_1, project: project) } diff --git a/spec/graphql/resolvers/work_items_resolver_spec.rb b/spec/graphql/resolvers/work_items_resolver_spec.rb index 29eac0ab46e..d89ccc7f806 100644 --- a/spec/graphql/resolvers/work_items_resolver_spec.rb +++ b/spec/graphql/resolvers/work_items_resolver_spec.rb @@ -19,13 +19,13 @@ RSpec.describe Resolvers::WorkItemsResolver do let_it_be(:item2) do create(:work_item, project: project, state: :closed, title: 'foo', - created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: + created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago) end let_it_be(:item3) do create(:work_item, project: other_project, state: :closed, title: 'foo', - created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: + created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago) end @@ -52,49 +52,15 @@ RSpec.describe Resolvers::WorkItemsResolver do end context 'when searching items' do - it 'returns correct items' do - expect(resolve_items(search: 'foo')).to contain_exactly(item2) - end - - it 'uses project search optimization' do - expected_arguments = a_hash_including( - search: 'foo', - attempt_project_search_optimizations: true - ) - expect(::WorkItems::WorkItemsFinder).to receive(:new).with(anything, expected_arguments).and_call_original - - resolve_items(search: 'foo') - end - - context 'with anonymous user' do - let_it_be(:public_project) { create(:project, :public) } - let_it_be(:public_item) { create(:work_item, project: public_project, title: 'Test item') } - - context 'with disable_anonymous_search enabled' do - before do - stub_feature_flags(disable_anonymous_search: true) - end - - it 'generates an error' do - error_message = "User must be authenticated to include the `search` argument." - - expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, error_message) do - resolve(described_class, obj: public_project, args: { search: 'test' }, ctx: { current_user: nil }) - end - end - end - - context 'with disable_anonymous_search disabled' do - before do - stub_feature_flags(disable_anonymous_search: false) - end - - it 'returns correct items' do - expect( - resolve(described_class, obj: public_project, args: { search: 'test' }, ctx: { current_user: nil }) - ).to contain_exactly(public_item) - end - end + it_behaves_like 'graphql query for searching issuables' do + let_it_be(:parent) { project } + let_it_be(:issuable1) { create(:work_item, project: project, title: 'first created') } + let_it_be(:issuable2) { create(:work_item, project: project, title: 'second created', description: 'text 1') } + let_it_be(:issuable3) { create(:work_item, project: project, title: 'third', description: 'text 2') } + let_it_be(:issuable4) { create(:work_item, project: project) } + + let_it_be(:finder_class) { ::WorkItems::WorkItemsFinder } + let_it_be(:optimization_param) { :attempt_project_search_optimizations } end end |