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/gitlab_schema_spec.rb103
-rw-r--r--spec/graphql/graphql_triggers_spec.rb42
-rw-r--r--spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb2
-rw-r--r--spec/graphql/mutations/ci/job_token_scope/remove_project_spec.rb2
-rw-r--r--spec/graphql/mutations/ci/runner/update_spec.rb10
-rw-r--r--spec/graphql/mutations/incident_management/timeline_event/create_spec.rb2
-rw-r--r--spec/graphql/mutations/incident_management/timeline_event/update_spec.rb2
-rw-r--r--spec/graphql/mutations/namespace/package_settings/update_spec.rb37
-rw-r--r--spec/graphql/mutations/work_items/update_widgets_spec.rb58
-rw-r--r--spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb52
-rw-r--r--spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/project_pipeline_schedules_resolver_spec.rb40
-rw-r--r--spec/graphql/resolvers/users/participants_resolver_spec.rb83
-rw-r--r--spec/graphql/types/ci/job_token_scope_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/job_type_spec.rb13
-rw-r--r--spec/graphql/types/ci/pipeline_schedule_status_enum_spec.rb11
-rw-r--r--spec/graphql/types/ci/pipeline_schedule_type_spec.rb30
-rw-r--r--spec/graphql/types/environment_type_spec.rb4
-rw-r--r--spec/graphql/types/namespace/package_settings_type_spec.rb20
-rw-r--r--spec/graphql/types/packages/tag_type_spec.rb2
-rw-r--r--spec/graphql/types/permission_types/ci/pipeline_schedule_type_spec.rb7
-rw-r--r--spec/graphql/types/project_type_spec.rb16
-rw-r--r--spec/graphql/types/projects/branch_rule_type_spec.rb (renamed from spec/graphql/types/branch_rule_type_spec.rb)3
-rw-r--r--spec/graphql/types/subscription_type_spec.rb2
-rw-r--r--spec/graphql/types/work_items/widgets/labels_update_input_type_spec.rb9
25 files changed, 404 insertions, 154 deletions
diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb
index 60b3edfc279..b5c2d4da9ac 100644
--- a/spec/graphql/gitlab_schema_spec.rb
+++ b/spec/graphql/gitlab_schema_spec.rb
@@ -232,11 +232,7 @@ RSpec.describe GitlabSchema do
end
end
- describe '.parse_gid' do
- let_it_be(:global_id) { 'gid://gitlab/TestOne/2147483647' }
-
- subject(:parse_gid) { described_class.parse_gid(global_id) }
-
+ context 'for gid parsing' do
before do
test_base = Class.new
test_one = Class.new(test_base)
@@ -249,66 +245,85 @@ RSpec.describe GitlabSchema do
stub_const('TestThree', test_three)
end
- it 'parses the gid' do
- gid = parse_gid
+ describe '.parse_gid' do
+ let_it_be(:global_id) { 'gid://gitlab/TestOne/2147483647' }
- expect(gid.model_id).to eq '2147483647'
- expect(gid.model_class).to eq TestOne
- end
+ subject(:parse_gid) { described_class.parse_gid(global_id) }
- context 'when gid is malformed' do
- let_it_be(:global_id) { 'malformed://gitlab/TestOne/2147483647' }
+ it 'parses the gid' do
+ gid = parse_gid
- it 'raises an error' do
- expect { parse_gid }
- .to raise_error(Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid GitLab ID.")
+ expect(gid.model_id).to eq '2147483647'
+ expect(gid.model_class).to eq TestOne
end
- end
- context 'when using expected_type' do
- it 'accepts a single type' do
- gid = described_class.parse_gid(global_id, expected_type: TestOne)
+ context 'when gid is malformed' do
+ let_it_be(:global_id) { 'malformed://gitlab/TestOne/2147483647' }
- expect(gid.model_class).to eq TestOne
+ it 'raises an error' do
+ expect { parse_gid }
+ .to raise_error(Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid GitLab ID.")
+ end
end
- it 'accepts an ancestor type' do
- gid = described_class.parse_gid(global_id, expected_type: TestBase)
+ context 'when using expected_type' do
+ it 'accepts a single type' do
+ gid = described_class.parse_gid(global_id, expected_type: TestOne)
- expect(gid.model_class).to eq TestOne
- end
+ expect(gid.model_class).to eq TestOne
+ end
- it 'rejects an unknown type' do
- expect { described_class.parse_gid(global_id, expected_type: TestTwo) }
- .to raise_error(Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid ID for TestTwo.")
- end
+ it 'accepts an ancestor type' do
+ gid = described_class.parse_gid(global_id, expected_type: TestBase)
- context 'when expected_type is an array' do
- subject(:parse_gid) { described_class.parse_gid(global_id, expected_type: [TestOne, TestTwo]) }
+ expect(gid.model_class).to eq TestOne
+ end
- context 'when global_id is of type TestOne' do
- it 'returns an object of an expected type' do
- expect(parse_gid.model_class).to eq TestOne
- end
+ it 'rejects an unknown type' do
+ expect { described_class.parse_gid(global_id, expected_type: TestTwo) }
+ .to raise_error(Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid ID for TestTwo.")
end
- context 'when global_id is of type TestTwo' do
- let_it_be(:global_id) { 'gid://gitlab/TestTwo/2147483647' }
+ context 'when expected_type is an array' do
+ subject(:parse_gid) { described_class.parse_gid(global_id, expected_type: [TestOne, TestTwo]) }
- it 'returns an object of an expected type' do
- expect(parse_gid.model_class).to eq TestTwo
+ context 'when global_id is of type TestOne' do
+ it 'returns an object of an expected type' do
+ expect(parse_gid.model_class).to eq TestOne
+ end
+ end
+
+ context 'when global_id is of type TestTwo' do
+ let_it_be(:global_id) { 'gid://gitlab/TestTwo/2147483647' }
+
+ it 'returns an object of an expected type' do
+ expect(parse_gid.model_class).to eq TestTwo
+ end
end
- end
- context 'when global_id is of type TestThree' do
- let_it_be(:global_id) { 'gid://gitlab/TestThree/2147483647' }
+ context 'when global_id is of type TestThree' do
+ let_it_be(:global_id) { 'gid://gitlab/TestThree/2147483647' }
- it 'rejects an unknown type' do
- expect { parse_gid }
- .to raise_error(Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid ID for TestOne, TestTwo.")
+ it 'rejects an unknown type' do
+ expect { parse_gid }
+ .to raise_error(Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid ID for TestOne, TestTwo.")
+ end
end
end
end
end
+
+ describe '.parse_gids' do
+ let_it_be(:global_ids) { %w[gid://gitlab/TestOne/123 gid://gitlab/TestTwo/456] }
+
+ subject(:parse_gids) { described_class.parse_gids(global_ids, expected_type: [TestOne, TestTwo]) }
+
+ it 'parses the gids' do
+ expect(described_class).to receive(:parse_gid).with('gid://gitlab/TestOne/123', { expected_type: [TestOne, TestTwo] }).and_call_original
+ expect(described_class).to receive(:parse_gid).with('gid://gitlab/TestTwo/456', { expected_type: [TestOne, TestTwo] }).and_call_original
+ expect(parse_gids.map(&:model_id)).to eq %w[123 456]
+ expect(parse_gids.map(&:model_class)).to eq [TestOne, TestTwo]
+ end
+ end
end
end
diff --git a/spec/graphql/graphql_triggers_spec.rb b/spec/graphql/graphql_triggers_spec.rb
index 5e2ab74a0e5..a4a643582f5 100644
--- a/spec/graphql/graphql_triggers_spec.rb
+++ b/spec/graphql/graphql_triggers_spec.rb
@@ -32,6 +32,20 @@ RSpec.describe GraphqlTriggers do
end
end
+ describe '.issuable_description_updated' do
+ it 'triggers the issuableDescriptionUpdated subscription' do
+ work_item = create(:work_item)
+
+ expect(GitlabSchema.subscriptions).to receive(:trigger).with(
+ 'issuableDescriptionUpdated',
+ { issuable_id: work_item.to_gid },
+ work_item
+ ).and_call_original
+
+ GraphqlTriggers.issuable_description_updated(work_item)
+ end
+ end
+
describe '.issuable_labels_updated' do
it 'triggers the issuableLabelsUpdated subscription' do
project = create(:project)
@@ -61,4 +75,32 @@ RSpec.describe GraphqlTriggers do
GraphqlTriggers.issuable_dates_updated(work_item)
end
end
+
+ describe '.merge_request_reviewers_updated' do
+ it 'triggers the mergeRequestReviewersUpdated subscription' do
+ merge_request = build_stubbed(:merge_request)
+
+ expect(GitlabSchema.subscriptions).to receive(:trigger).with(
+ 'mergeRequestReviewersUpdated',
+ { issuable_id: merge_request.to_gid },
+ merge_request
+ ).and_call_original
+
+ GraphqlTriggers.merge_request_reviewers_updated(merge_request)
+ end
+ end
+
+ describe '.merge_request_merge_status_updated' do
+ it 'triggers the mergeRequestMergeStatusUpdated subscription' do
+ merge_request = build_stubbed(:merge_request)
+
+ expect(GitlabSchema.subscriptions).to receive(:trigger).with(
+ 'mergeRequestMergeStatusUpdated',
+ { issuable_id: merge_request.to_gid },
+ merge_request
+ ).and_call_original
+
+ GraphqlTriggers.merge_request_merge_status_updated(merge_request)
+ end
+ end
end
diff --git a/spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb b/spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb
index 412be5f16a4..727db7e2361 100644
--- a/spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb
+++ b/spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Mutations::Ci::JobTokenScope::AddProject do
describe '#resolve' do
let_it_be(:project) do
- create(:project, ci_job_token_scope_enabled: true).tap(&:save!)
+ create(:project, ci_outbound_job_token_scope_enabled: true).tap(&:save!)
end
let_it_be(:target_project) { create(:project) }
diff --git a/spec/graphql/mutations/ci/job_token_scope/remove_project_spec.rb b/spec/graphql/mutations/ci/job_token_scope/remove_project_spec.rb
index 0e706ea6e0c..d399e73f394 100644
--- a/spec/graphql/mutations/ci/job_token_scope/remove_project_spec.rb
+++ b/spec/graphql/mutations/ci/job_token_scope/remove_project_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Mutations::Ci::JobTokenScope::RemoveProject do
end
describe '#resolve' do
- let_it_be(:project) { create(:project, ci_job_token_scope_enabled: true).tap(&:save!) }
+ let_it_be(:project) { create(:project, ci_outbound_job_token_scope_enabled: true).tap(&:save!) }
let_it_be(:target_project) { create(:project) }
let_it_be(:link) do
diff --git a/spec/graphql/mutations/ci/runner/update_spec.rb b/spec/graphql/mutations/ci/runner/update_spec.rb
index 39fe2a53a68..ee65be1e085 100644
--- a/spec/graphql/mutations/ci/runner/update_spec.rb
+++ b/spec/graphql/mutations/ci/runner/update_spec.rb
@@ -45,7 +45,8 @@ RSpec.describe Mutations::Ci::Runner::Update do
end
context 'when user can update runner', :enable_admin_mode do
- let(:admin_user) { create(:user, :admin) }
+ let_it_be(:admin_user) { create(:user, :admin) }
+
let(:current_ctx) { { current_user: admin_user } }
context 'with valid arguments' do
@@ -134,8 +135,7 @@ RSpec.describe Mutations::Ci::Runner::Update do
response
expect(response[:errors]).to match_array(['user not allowed to assign runner'])
- expect(response[:runner]).to be_an_instance_of(Ci::Runner)
- expect(response[:runner]).not_to have_attributes(expected_attributes)
+ expect(response[:runner]).to be_nil
expect(runner.reload).not_to have_attributes(expected_attributes)
expect(runner.projects).to match_array([project1])
end
@@ -164,7 +164,7 @@ RSpec.describe Mutations::Ci::Runner::Update do
let(:mutation_params) do
{
id: runner.to_global_id,
- associated_projects: ['gid://gitlab/Project/-1']
+ associated_projects: ["gid://gitlab/Project/#{non_existing_record_id}"]
}
end
@@ -191,6 +191,7 @@ RSpec.describe Mutations::Ci::Runner::Update do
end
it 'returns a descriptive error' do
+ expect(response[:runner]).to be_nil
expect(response[:errors]).to contain_exactly(
'Maximum timeout needs to be at least 10 minutes',
'Tags list can not be empty when runner is not allowed to pick untagged jobs'
@@ -202,6 +203,7 @@ RSpec.describe Mutations::Ci::Runner::Update do
it 'returns a descriptive error' do
mutation_params[:maintenance_note] = '1' * 1025
+ expect(response[:runner]).to be_nil
expect(response[:errors]).to contain_exactly(
'Maintenance note is too long (maximum is 1024 characters)'
)
diff --git a/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb b/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb
index ea74e427dd6..9254d84b29c 100644
--- a/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb
+++ b/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Mutations::IncidentManagement::TimelineEvent::Create do
let(:args) { {} }
it_behaves_like 'responding with an incident timeline errors',
- errors: ["Occurred at can't be blank, Note can't be blank, and Note html can't be blank"]
+ errors: ["Occurred at can't be blank and Timeline text can't be blank"]
end
end
diff --git a/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb b/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb
index 102d33378c6..7081fb7117e 100644
--- a/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb
+++ b/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb
@@ -65,7 +65,7 @@ RSpec.describe Mutations::IncidentManagement::TimelineEvent::Update do
end
it 'responds with error' do
- expect(resolve).to eq(timeline_event: nil, errors: ["Note can't be blank"])
+ expect(resolve).to eq(timeline_event: nil, errors: ["Timeline text can't be blank"])
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 631e02ff3dc..09ac1c99b10 100644
--- a/spec/graphql/mutations/namespace/package_settings/update_spec.rb
+++ b/spec/graphql/mutations/namespace/package_settings/update_spec.rb
@@ -26,8 +26,29 @@ RSpec.describe Mutations::Namespace::PackageSettings::Update do
RSpec.shared_examples 'updating the namespace package setting' do
it_behaves_like 'updating the namespace package setting attributes',
- from: { maven_duplicates_allowed: true, maven_duplicate_exception_regex: 'SNAPSHOT', generic_duplicates_allowed: true, generic_duplicate_exception_regex: 'foo' },
- to: { maven_duplicates_allowed: false, maven_duplicate_exception_regex: 'RELEASE', generic_duplicates_allowed: false, generic_duplicate_exception_regex: 'bar' }
+ from: {
+ maven_duplicates_allowed: true,
+ maven_duplicate_exception_regex: 'SNAPSHOT',
+ generic_duplicates_allowed: true,
+ generic_duplicate_exception_regex: 'foo',
+ maven_package_requests_forwarding: nil,
+ lock_maven_package_requests_forwarding: false,
+ npm_package_requests_forwarding: nil,
+ lock_npm_package_requests_forwarding: false,
+ pypi_package_requests_forwarding: nil,
+ lock_pypi_package_requests_forwarding: false
+ }, to: {
+ maven_duplicates_allowed: false,
+ maven_duplicate_exception_regex: 'RELEASE',
+ generic_duplicates_allowed: false,
+ generic_duplicate_exception_regex: 'bar',
+ maven_package_requests_forwarding: true,
+ lock_maven_package_requests_forwarding: true,
+ npm_package_requests_forwarding: true,
+ lock_npm_package_requests_forwarding: true,
+ pypi_package_requests_forwarding: true,
+ lock_pypi_package_requests_forwarding: true
+ }
it_behaves_like 'returning a success'
@@ -59,11 +80,19 @@ RSpec.describe Mutations::Namespace::PackageSettings::Update do
context 'with existing namespace package setting' do
let_it_be(:package_settings) { create(:namespace_package_setting, namespace: namespace) }
let_it_be(:params) do
- { namespace_path: namespace.full_path,
+ {
+ namespace_path: namespace.full_path,
maven_duplicates_allowed: false,
maven_duplicate_exception_regex: 'RELEASE',
generic_duplicates_allowed: false,
- generic_duplicate_exception_regex: 'bar' }
+ generic_duplicate_exception_regex: 'bar',
+ maven_package_requests_forwarding: true,
+ lock_maven_package_requests_forwarding: true,
+ npm_package_requests_forwarding: true,
+ lock_npm_package_requests_forwarding: true,
+ pypi_package_requests_forwarding: true,
+ lock_pypi_package_requests_forwarding: true
+ }
end
where(:user_role, :shared_examples_name) do
diff --git a/spec/graphql/mutations/work_items/update_widgets_spec.rb b/spec/graphql/mutations/work_items/update_widgets_spec.rb
deleted file mode 100644
index 2e54b81b5c7..00000000000
--- a/spec/graphql/mutations/work_items/update_widgets_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Mutations::WorkItems::UpdateWidgets do
- include GraphqlHelpers
-
- let_it_be(:project) { create(:project) }
- let_it_be(:developer) { create(:user).tap { |user| project.add_developer(user) } }
-
- let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
-
- describe '#resolve' do
- before do
- stub_spam_services
- end
-
- context 'when no work item matches the given id' do
- let(:current_user) { developer }
- let(:gid) { global_id_of(id: non_existing_record_id, model_name: WorkItem.name) }
-
- it 'raises an error' do
- expect { mutation.resolve(id: gid, resolve: true) }.to raise_error(
- Gitlab::Graphql::Errors::ResourceNotAvailable,
- Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
- )
- end
- end
-
- context 'when user can access the requested work item', :aggregate_failures do
- let(:current_user) { developer }
- let(:args) { {} }
-
- let_it_be(:work_item) { create(:work_item, project: project) }
-
- subject { mutation.resolve(id: work_item.to_global_id, **args) }
-
- context 'when `:work_items` is disabled for a project' do
- let_it_be(:project2) { create(:project) }
-
- it 'returns an error' do
- stub_feature_flags(work_items: project2) # only enable `work_item` for project2
-
- expect(subject[:errors]).to contain_exactly('`work_items` feature flag disabled for this project')
- end
- end
-
- context 'when resolved with an input for description widget' do
- let(:args) { { description_widget: { description: "updated description" } } }
-
- it 'returns the updated work item' do
- expect(subject[:work_item].description).to eq("updated description")
- expect(subject[:errors]).to be_empty
- end
- end
- end
- end
-end
diff --git a/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb b/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb
new file mode 100644
index 00000000000..2a7d0a8171b
--- /dev/null
+++ b/spec/graphql/resolvers/ci/all_jobs_resolver_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::Ci::AllJobsResolver do
+ include GraphqlHelpers
+
+ let_it_be(:successful_job) { create(:ci_build, :success, name: 'Job One') }
+ let_it_be(:successful_job_two) { create(:ci_build, :success, name: 'Job Two') }
+ let_it_be(:failed_job) { create(:ci_build, :failed, name: 'Job Three') }
+ let_it_be(:pending_job) { create(:ci_build, :pending, name: 'Job Three') }
+
+ let(:args) { {} }
+ let(:current_user) { create(:admin) }
+
+ subject { resolve_jobs(args) }
+
+ describe '#resolve' do
+ context 'with authorized user' do
+ context 'with statuses argument' do
+ let(:args) { { statuses: [Types::Ci::JobStatusEnum.coerce_isolated_input('SUCCESS')] } }
+
+ it { is_expected.to contain_exactly(successful_job, successful_job_two) }
+ end
+
+ context 'with multiple statuses' do
+ let(:args) do
+ { statuses: [Types::Ci::JobStatusEnum.coerce_isolated_input('SUCCESS'),
+ Types::Ci::JobStatusEnum.coerce_isolated_input('FAILED')] }
+ end
+
+ it { is_expected.to contain_exactly(successful_job, successful_job_two, failed_job) }
+ end
+
+ context 'without statuses argument' do
+ it { is_expected.to contain_exactly(successful_job, successful_job_two, failed_job, pending_job) }
+ end
+ end
+
+ context 'with unauthorized user' do
+ let(:current_user) { nil }
+
+ it { is_expected.to be_empty }
+ end
+ end
+
+ private
+
+ def resolve_jobs(args = {}, context = { current_user: current_user })
+ resolve(described_class, args: args, ctx: context)
+ end
+end
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 1bfd6fbf6b9..59ece15b745 100644
--- a/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Resolvers::Ci::JobTokenScopeResolver do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
- let_it_be(:project) { create(:project, ci_job_token_scope_enabled: true).tap(&:save!) }
+ let_it_be(:project) { create(:project, ci_outbound_job_token_scope_enabled: true).tap(&:save!) }
specify do
expect(described_class).to have_nullable_graphql_type(::Types::Ci::JobTokenScopeType)
@@ -21,7 +21,7 @@ RSpec.describe Resolvers::Ci::JobTokenScopeResolver do
end
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)
+ allow(project).to receive(:ci_outbound_job_token_scope_enabled?).and_return(false)
expect(resolve_scope.all_projects).to contain_exactly(project)
end
@@ -40,7 +40,7 @@ RSpec.describe Resolvers::Ci::JobTokenScopeResolver do
context 'when job token scope is disabled' do
before do
- project.update!(ci_job_token_scope_enabled: false)
+ project.update!(ci_outbound_job_token_scope_enabled: false)
end
it 'resolves projects' do
diff --git a/spec/graphql/resolvers/project_pipeline_schedules_resolver_spec.rb b/spec/graphql/resolvers/project_pipeline_schedules_resolver_spec.rb
new file mode 100644
index 00000000000..159335adf79
--- /dev/null
+++ b/spec/graphql/resolvers/project_pipeline_schedules_resolver_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::ProjectPipelineSchedulesResolver do
+ include GraphqlHelpers
+
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, public_builds: false) }
+
+ before do
+ project.add_owner(user)
+ end
+
+ describe 'With filters' do
+ let(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project, owner: developer) }
+
+ before do
+ pipeline_schedule.pipelines << build(:ci_pipeline, project: project)
+ end
+
+ it 'shows active pipeline schedules' do
+ schedules = resolve_pipeline_schedules
+
+ expect(schedules).to contain_exactly(pipeline_schedule)
+ end
+
+ it 'shows the inactive pipeline schedules' do
+ schedules = resolve_pipeline_schedules(args:
+ { status: ::Types::Ci::PipelineScheduleStatusEnum.values['INACTIVE'].value })
+
+ expect(schedules).to be_empty
+ end
+ end
+
+ def resolve_pipeline_schedules(args: {})
+ resolve(described_class, obj: project, ctx: { current_user: user }, args: args)
+ end
+end
diff --git a/spec/graphql/resolvers/users/participants_resolver_spec.rb b/spec/graphql/resolvers/users/participants_resolver_spec.rb
index 3f04d157410..eb2418b63f4 100644
--- a/spec/graphql/resolvers/users/participants_resolver_spec.rb
+++ b/spec/graphql/resolvers/users/participants_resolver_spec.rb
@@ -10,18 +10,31 @@ RSpec.describe Resolvers::Users::ParticipantsResolver do
let_it_be(:guest) { create(:user) }
let_it_be(:project) { create(:project, :public) }
let_it_be(:issue) { create(:issue, project: project) }
- let_it_be(:note) do
- create(
- :note,
- :system,
- :confidential,
- project: project,
- noteable: issue,
- author: create(:user)
- )
- end
- let_it_be(:note_metadata) { create(:system_note_metadata, note: note) }
+ let_it_be(:public_note_author) { create(:user) }
+ let_it_be(:public_reply_author) { create(:user) }
+ let_it_be(:internal_note_author) { create(:user) }
+ let_it_be(:internal_reply_author) { create(:user) }
+
+ let_it_be(:public_note) { create(:note, project: project, noteable: issue, author: public_note_author) }
+ let_it_be(:internal_note) { create(:note, :confidential, project: project, noteable: issue, author: internal_note_author) }
+
+ let_it_be(:public_reply) { create(:note, noteable: issue, in_reply_to: public_note, project: project, author: public_reply_author) }
+ let_it_be(:internal_reply) { create(:note, :confidential, noteable: issue, in_reply_to: internal_note, project: project, author: internal_reply_author) }
+
+ let_it_be(:note_metadata2) { create(:system_note_metadata, note: public_note) }
+
+ let_it_be(:issue_emoji) { create(:award_emoji, name: 'thumbsup', awardable: issue) }
+ let_it_be(:note_emoji1) { create(:award_emoji, name: 'thumbsup', awardable: public_note) }
+ let_it_be(:note_emoji2) { create(:award_emoji, name: 'thumbsup', awardable: internal_note) }
+ let_it_be(:note_emoji3) { create(:award_emoji, name: 'thumbsup', awardable: public_reply) }
+ let_it_be(:note_emoji4) { create(:award_emoji, name: 'thumbsup', awardable: internal_reply) }
+
+ let_it_be(:issue_emoji_author) { issue_emoji.user }
+ let_it_be(:public_note_emoji_author) { note_emoji1.user }
+ let_it_be(:internal_note_emoji_author) { note_emoji2.user }
+ let_it_be(:public_reply_emoji_author) { note_emoji3.user }
+ let_it_be(:internal_reply_emoji_author) { note_emoji4.user }
subject(:resolved_items) { resolve(described_class, args: {}, ctx: { current_user: current_user }, obj: issue)&.items }
@@ -34,7 +47,16 @@ RSpec.describe Resolvers::Users::ParticipantsResolver do
let(:current_user) { nil }
it 'returns only publicly visible participants for this user' do
- is_expected.to match_array([issue.author])
+ is_expected.to match_array(
+ [
+ issue.author,
+ issue_emoji_author,
+ public_note_author,
+ public_note_emoji_author,
+ public_reply_author,
+ public_reply_emoji_author
+ ]
+ )
end
end
@@ -42,15 +64,37 @@ RSpec.describe Resolvers::Users::ParticipantsResolver do
let(:current_user) { guest }
it 'returns only publicly visible participants for this user' do
- is_expected.to match_array([issue.author])
+ is_expected.to match_array(
+ [
+ issue.author,
+ issue_emoji_author,
+ public_note_author,
+ public_note_emoji_author,
+ public_reply_author,
+ public_reply_emoji_author
+ ]
+ )
end
end
- context 'when current user has access to confidential notes' do
+ context 'when current user has access to internal notes' do
let(:current_user) { user }
it 'returns all participants for this user' do
- is_expected.to match_array([issue.author, note.author])
+ is_expected.to match_array(
+ [
+ issue.author,
+ issue_emoji_author,
+ public_note_author,
+ public_note_emoji_author,
+ public_reply_author,
+ internal_note_author,
+ internal_note_emoji_author,
+ internal_reply_author,
+ public_reply_emoji_author,
+ internal_reply_emoji_author
+ ]
+ )
end
context 'N+1 queries' do
@@ -64,9 +108,14 @@ RSpec.describe Resolvers::Users::ParticipantsResolver do
it 'does not execute N+1 for project relation' do
control_count = ActiveRecord::QueryRecorder.new { query.call }
- create(:note, :confidential, project: project, noteable: issue, author: create(:user))
+ create(:award_emoji, :upvote, awardable: issue)
+ internal_note = create(:note, :confidential, project: project, noteable: issue, author: create(:user))
+ create(:award_emoji, name: 'thumbsup', awardable: internal_note)
+ public_note = create(:note, project: project, noteable: issue, author: create(:user))
+ create(:award_emoji, name: 'thumbsup', awardable: public_note)
- expect { query.call }.not_to exceed_query_limit(control_count)
+ # 1 extra query per source (3 emojis + 2 notes) to fetch participables collection
+ expect { query.call }.not_to exceed_query_limit(control_count).with_threshold(5)
end
it 'does not execute N+1 for system note metadata relation' do
diff --git a/spec/graphql/types/ci/job_token_scope_type_spec.rb b/spec/graphql/types/ci/job_token_scope_type_spec.rb
index 18f4d762d1e..569b59d6c70 100644
--- a/spec/graphql/types/ci/job_token_scope_type_spec.rb
+++ b/spec/graphql/types/ci/job_token_scope_type_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe GitlabSchema.types['CiJobTokenScopeType'] do
end
describe 'query' do
- let(:project) { create(:project, ci_job_token_scope_enabled: true).tap(&:save!) }
+ let(:project) { create(:project, ci_outbound_job_token_scope_enabled: true).tap(&:save!) }
let_it_be(:current_user) { create(:user) }
let(:query) do
diff --git a/spec/graphql/types/ci/job_type_spec.rb b/spec/graphql/types/ci/job_type_spec.rb
index b3dee082d1f..ce1558c4097 100644
--- a/spec/graphql/types/ci/job_type_spec.rb
+++ b/spec/graphql/types/ci/job_type_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe Types::Ci::JobType do
active
allow_failure
artifacts
+ browse_artifacts_path
cancelable
commitPath
coverage
@@ -64,4 +65,16 @@ RSpec.describe Types::Ci::JobType do
is_expected.to eq("/#{project.full_path}/-/jobs/#{build.id}")
end
end
+
+ describe '#browse_artifacts_path' do
+ subject { resolve_field(:browse_artifacts_path, build, current_user: user, object_type: described_class) }
+
+ let_it_be(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:build) { create(:ci_build, :artifacts, project: project, user: user) }
+
+ it 'returns the path to browse the artifacts of the job' do
+ is_expected.to eq("/#{project.full_path}/-/jobs/#{build.id}/artifacts/browse")
+ end
+ end
end
diff --git a/spec/graphql/types/ci/pipeline_schedule_status_enum_spec.rb b/spec/graphql/types/ci/pipeline_schedule_status_enum_spec.rb
new file mode 100644
index 00000000000..d271e72b17f
--- /dev/null
+++ b/spec/graphql/types/ci/pipeline_schedule_status_enum_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::PipelineScheduleStatusEnum do
+ specify { expect(described_class.graphql_name ).to eq('PipelineScheduleStatus') }
+
+ it 'exposes the status of a pipeline schedule' do
+ expect(described_class.values.keys).to match_array(%w[ACTIVE INACTIVE])
+ end
+end
diff --git a/spec/graphql/types/ci/pipeline_schedule_type_spec.rb b/spec/graphql/types/ci/pipeline_schedule_type_spec.rb
new file mode 100644
index 00000000000..bf1413ef657
--- /dev/null
+++ b/spec/graphql/types/ci/pipeline_schedule_type_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::PipelineScheduleType do
+ include GraphqlHelpers
+
+ specify { expect(described_class.graphql_name).to eq('PipelineSchedule') }
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Ci::PipelineSchedules) }
+
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ id
+ description
+ owner
+ active
+ lastPipeline
+ refForDisplay
+ refPath
+ forTag
+ nextRunAt
+ realNextRun
+ cron
+ cronTimezone
+ userPermissions
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/environment_type_spec.rb b/spec/graphql/types/environment_type_spec.rb
index ae58fe00af7..2605beac95a 100644
--- a/spec/graphql/types/environment_type_spec.rb
+++ b/spec/graphql/types/environment_type_spec.rb
@@ -5,13 +5,13 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['Environment'] do
specify { expect(described_class.graphql_name).to eq('Environment') }
- it 'has the expected fields' do
+ it 'includes the expected fields' do
expected_fields = %w[
name id state metrics_dashboard latest_opened_most_severe_alert path external_url deployments
slug createdAt updatedAt autoStopAt autoDeleteAt tier environmentType lastDeployment
]
- expect(described_class).to have_graphql_fields(*expected_fields)
+ expect(described_class).to include_graphql_fields(*expected_fields)
end
specify { expect(described_class).to require_graphql_authorizations(:read_environment) }
diff --git a/spec/graphql/types/namespace/package_settings_type_spec.rb b/spec/graphql/types/namespace/package_settings_type_spec.rb
index f63a0a7010f..5039f2d6153 100644
--- a/spec/graphql/types/namespace/package_settings_type_spec.rb
+++ b/spec/graphql/types/namespace/package_settings_type_spec.rb
@@ -14,4 +14,24 @@ RSpec.describe GitlabSchema.types['PackageSettings'] do
it { is_expected.to have_graphql_type(Types::UntrustedRegexp) }
end
+
+ it 'includes package setting fields' do
+ expected_fields = %w[
+ maven_duplicates_allowed
+ maven_duplicate_exception_regex
+ generic_duplicates_allowed
+ generic_duplicate_exception_regex
+ maven_package_requests_forwarding
+ lock_maven_package_requests_forwarding
+ npm_package_requests_forwarding
+ lock_npm_package_requests_forwarding
+ pypi_package_requests_forwarding
+ lock_pypi_package_requests_forwarding
+ maven_package_requests_forwarding_locked
+ npm_package_requests_forwarding_locked
+ pypi_package_requests_forwarding_locked
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
end
diff --git a/spec/graphql/types/packages/tag_type_spec.rb b/spec/graphql/types/packages/tag_type_spec.rb
index 83b705157d8..ea0801c7a0f 100644
--- a/spec/graphql/types/packages/tag_type_spec.rb
+++ b/spec/graphql/types/packages/tag_type_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe GitlabSchema.types['PackageTag'] do
it 'includes all the package tag fields' do
expected_fields = %w[
- id name created_at updated_at
+ id name created_at updated_at
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/permission_types/ci/pipeline_schedule_type_spec.rb b/spec/graphql/types/permission_types/ci/pipeline_schedule_type_spec.rb
new file mode 100644
index 00000000000..5929d22b202
--- /dev/null
+++ b/spec/graphql/types/permission_types/ci/pipeline_schedule_type_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::PipelineScheduleType do
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Ci::PipelineSchedules) }
+end
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index 617cbdb07fe..b435f3ed5ff 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe GitlabSchema.types['Project'] do
cluster_agent cluster_agents agent_configurations
ci_template timelogs merge_commit_template squash_commit_template work_item_types
recent_issue_boards ci_config_path_or_default packages_cleanup_policy ci_variables
- timelog_categories fork_targets branch_rules ci_config_variables
+ timelog_categories fork_targets branch_rules ci_config_variables pipeline_schedules
]
expect(described_class).to include_graphql_fields(*expected_fields)
@@ -508,20 +508,6 @@ RSpec.describe GitlabSchema.types['Project'] do
it { is_expected.to have_graphql_resolver(Resolvers::Ci::JobTokenScopeResolver) }
end
- describe 'branch_rules field' do
- subject { described_class.fields['branchRules'] }
-
- let(:br_resolver) { Resolvers::Projects::BranchRulesResolver }
-
- specify do
- is_expected.to have_graphql_type(
- Types::Projects::BranchRuleType.connection_type
- )
- end
-
- specify { is_expected.to have_graphql_resolver(br_resolver) }
- end
-
describe 'agent_configurations' do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/graphql/types/branch_rule_type_spec.rb b/spec/graphql/types/projects/branch_rule_type_spec.rb
index 277901f00bf..119ecf8a097 100644
--- a/spec/graphql/types/branch_rule_type_spec.rb
+++ b/spec/graphql/types/projects/branch_rule_type_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe GitlabSchema.types['BranchRule'] do
let(:fields) do
%i[
name
+ isDefault
branch_protection
created_at
updated_at
@@ -18,5 +19,5 @@ RSpec.describe GitlabSchema.types['BranchRule'] do
specify { is_expected.to require_graphql_authorizations(:read_protected_branch) }
- specify { is_expected.to have_graphql_fields(fields) }
+ specify { is_expected.to have_graphql_fields(fields).at_least }
end
diff --git a/spec/graphql/types/subscription_type_spec.rb b/spec/graphql/types/subscription_type_spec.rb
index 860cbbf0c15..c23a14deaf3 100644
--- a/spec/graphql/types/subscription_type_spec.rb
+++ b/spec/graphql/types/subscription_type_spec.rb
@@ -8,9 +8,11 @@ RSpec.describe GitlabSchema.types['Subscription'] do
issuable_assignees_updated
issue_crm_contacts_updated
issuable_title_updated
+ issuable_description_updated
issuable_labels_updated
issuable_dates_updated
merge_request_reviewers_updated
+ merge_request_merge_status_updated
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/work_items/widgets/labels_update_input_type_spec.rb b/spec/graphql/types/work_items/widgets/labels_update_input_type_spec.rb
new file mode 100644
index 00000000000..3e5f40bde02
--- /dev/null
+++ b/spec/graphql/types/work_items/widgets/labels_update_input_type_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Types::WorkItems::Widgets::LabelsUpdateInputType do
+ it { expect(described_class.graphql_name).to eq('WorkItemWidgetLabelsUpdateInput') }
+
+ it { expect(described_class.arguments.keys).to contain_exactly('addLabelIds', 'removeLabelIds') }
+end