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/features/feature_flag_spec.rb2
-rw-r--r--spec/graphql/graphql_triggers_spec.rb14
-rw-r--r--spec/graphql/mutations/ci/runner/bulk_delete_spec.rb91
-rw-r--r--spec/graphql/mutations/ci/runner/update_spec.rb3
-rw-r--r--spec/graphql/mutations/incident_management/timeline_event/update_spec.rb39
-rw-r--r--spec/graphql/mutations/merge_requests/set_labels_spec.rb2
-rw-r--r--spec/graphql/mutations/merge_requests/set_reviewers_spec.rb140
-rw-r--r--spec/graphql/mutations/releases/create_spec.rb6
-rw-r--r--spec/graphql/mutations/releases/delete_spec.rb2
-rw-r--r--spec/graphql/mutations/releases/update_spec.rb4
-rw-r--r--spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/crm/contact_state_counts_resolver_spec.rb63
-rw-r--r--spec/graphql/resolvers/crm/contacts_resolver_spec.rb21
-rw-r--r--spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/project_jobs_resolver_spec.rb2
-rw-r--r--spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb49
-rw-r--r--spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb4
-rw-r--r--spec/graphql/resolvers/projects_resolver_spec.rb2
-rw-r--r--spec/graphql/types/base_field_spec.rb10
-rw-r--r--spec/graphql/types/ci/group_variable_type_spec.rb9
-rw-r--r--spec/graphql/types/ci/instance_variable_type_spec.rb9
-rw-r--r--spec/graphql/types/ci/job_token_scope_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/manual_variable_type_spec.rb7
-rw-r--r--spec/graphql/types/ci/project_variable_type_spec.rb9
-rw-r--r--spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb (renamed from spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb)4
-rw-r--r--spec/graphql/types/ci/variable_input_type_spec.rb11
-rw-r--r--spec/graphql/types/ci/variable_interface_spec.rb (renamed from spec/graphql/types/ci/variable_type_spec.rb)6
-rw-r--r--spec/graphql/types/customer_relations/contact_sort_enum_spec.rb28
-rw-r--r--spec/graphql/types/customer_relations/contact_state_counts_type_spec.rb17
-rw-r--r--spec/graphql/types/global_id_type_spec.rb6
-rw-r--r--spec/graphql/types/group_type_spec.rb51
-rw-r--r--spec/graphql/types/issue_type_spec.rb6
-rw-r--r--spec/graphql/types/namespace_type_spec.rb1
-rw-r--r--spec/graphql/types/notes/note_type_spec.rb1
-rw-r--r--spec/graphql/types/project_type_spec.rb6
-rw-r--r--spec/graphql/types/projects/service_type_enum_spec.rb1
-rw-r--r--spec/graphql/types/subscription_type_spec.rb1
-rw-r--r--spec/graphql/types/time_tracking/timelog_category_type_spec.rb22
-rw-r--r--spec/graphql/types/upload_type_spec.rb13
-rw-r--r--spec/graphql/types/user_type_spec.rb2
-rw-r--r--spec/graphql/types/work_item_type_spec.rb5
-rw-r--r--spec/graphql/types/work_items/widget_interface_spec.rb1
-rw-r--r--spec/graphql/types/work_items/widgets/assignees_input_type_spec.rb9
-rw-r--r--spec/graphql/types/work_items/widgets/labels_type_spec.rb11
-rw-r--r--spec/graphql/types/work_items/widgets/start_and_due_date_type_spec.rb11
-rw-r--r--spec/graphql/types/work_items/widgets/start_and_due_date_update_input_type_spec.rb9
46 files changed, 670 insertions, 46 deletions
diff --git a/spec/graphql/features/feature_flag_spec.rb b/spec/graphql/features/feature_flag_spec.rb
index e5560fccf89..b06718eb16a 100644
--- a/spec/graphql/features/feature_flag_spec.rb
+++ b/spec/graphql/features/feature_flag_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe 'Graphql Field feature flags' do
let(:query_type) do
query_factory do |query|
- query.field :item, type, null: true, feature_flag: feature_flag, resolver: new_resolver(test_object)
+ query.field :item, type, null: true, _deprecated_feature_flag: feature_flag, resolver: new_resolver(test_object)
end
end
diff --git a/spec/graphql/graphql_triggers_spec.rb b/spec/graphql/graphql_triggers_spec.rb
index 84af33a5cb3..5e2ab74a0e5 100644
--- a/spec/graphql/graphql_triggers_spec.rb
+++ b/spec/graphql/graphql_triggers_spec.rb
@@ -47,4 +47,18 @@ RSpec.describe GraphqlTriggers do
GraphqlTriggers.issuable_labels_updated(issue)
end
end
+
+ describe '.issuable_dates_updated' do
+ it 'triggers the issuableDatesUpdated subscription' do
+ work_item = create(:work_item)
+
+ expect(GitlabSchema.subscriptions).to receive(:trigger).with(
+ 'issuableDatesUpdated',
+ { issuable_id: work_item.to_gid },
+ work_item
+ ).and_call_original
+
+ GraphqlTriggers.issuable_dates_updated(work_item)
+ end
+ end
end
diff --git a/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb b/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb
new file mode 100644
index 00000000000..f47f1b9869e
--- /dev/null
+++ b/spec/graphql/mutations/ci/runner/bulk_delete_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::Ci::Runner::BulkDelete do
+ include GraphqlHelpers
+
+ let_it_be(:admin_user) { create(:user, :admin) }
+ let_it_be(:user) { create(:user) }
+
+ let(:current_ctx) { { current_user: user } }
+
+ let(:mutation_params) do
+ {}
+ end
+
+ describe '#resolve' do
+ subject(:response) do
+ sync(resolve(described_class, args: mutation_params, ctx: current_ctx))
+ end
+
+ context 'when the user cannot admin the runner' do
+ let(:runner) { create(:ci_runner) }
+ let(:mutation_params) do
+ { ids: [runner.to_global_id] }
+ end
+
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) { response }
+ end
+ end
+
+ context 'when user can delete runners' do
+ let(:user) { admin_user }
+ let!(:runners) do
+ create_list(:ci_runner, 2, :instance)
+ end
+
+ context 'when required arguments are missing' do
+ let(:mutation_params) { {} }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'does not return an error' do
+ is_expected.to match a_hash_including(errors: [])
+ end
+ end
+ end
+
+ context 'with runners specified by id' do
+ let(:mutation_params) do
+ { ids: runners.map(&:to_global_id) }
+ end
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'deletes runners', :aggregate_failures do
+ expect_next_instance_of(
+ ::Ci::Runners::BulkDeleteRunnersService, { runners: runners }
+ ) do |service|
+ expect(service).to receive(:execute).once.and_call_original
+ end
+
+ expect { response }.to change { Ci::Runner.count }.by(-2)
+ expect(response[:errors]).to be_empty
+ end
+
+ context 'when runner list is is above limit' do
+ before do
+ stub_const('::Ci::Runners::BulkDeleteRunnersService::RUNNER_LIMIT', 1)
+ end
+
+ it 'only deletes up to the defined limit', :aggregate_failures do
+ expect { response }.to change { Ci::Runner.count }
+ .by(-::Ci::Runners::BulkDeleteRunnersService::RUNNER_LIMIT)
+ expect(response[:errors]).to be_empty
+ end
+ end
+ end
+
+ context 'when admin mode is disabled', :aggregate_failures do
+ it 'returns error', :aggregate_failures do
+ expect do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ response
+ end
+ end.not_to change { Ci::Runner.count }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/mutations/ci/runner/update_spec.rb b/spec/graphql/mutations/ci/runner/update_spec.rb
index ffaa6e93d1b..b8efd4213fa 100644
--- a/spec/graphql/mutations/ci/runner/update_spec.rb
+++ b/spec/graphql/mutations/ci/runner/update_spec.rb
@@ -2,12 +2,11 @@
require 'spec_helper'
-RSpec.describe 'Mutations::Ci::Runner::Update' do
+RSpec.describe Mutations::Ci::Runner::Update do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
let_it_be(:runner) { create(:ci_runner, active: true, locked: false, run_untagged: true) }
- let_it_be(:described_class) { Mutations::Ci::Runner::Update }
let(:current_ctx) { { current_user: user } }
let(:mutated_runner) { subject[:runner] }
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 8296e5c6c15..102d33378c6 100644
--- a/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb
+++ b/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb
@@ -57,17 +57,40 @@ RSpec.describe Mutations::IncidentManagement::TimelineEvent::Update do
end
context 'when there is a validation error' do
- let(:occurred_at) { 'invalid date' }
+ context 'when note is blank' do
+ let(:note) { '' }
- it 'does not update the timeline event' do
- expect { resolve }.not_to change { timeline_event.reload.updated_at }
+ it 'does not update the timeline event' do
+ expect { resolve }.not_to change { timeline_event.reload.updated_at }
+ end
+
+ it 'responds with error' do
+ expect(resolve).to eq(timeline_event: nil, errors: ["Note can't be blank"])
+ end
end
- it 'responds with error' do
- expect(resolve).to eq(
- timeline_event: nil,
- errors: ["Occurred at can't be blank"]
- )
+ context 'when occurred_at is blank' do
+ let(:occurred_at) { '' }
+
+ it 'does not update the timeline event' do
+ expect { resolve }.not_to change { timeline_event.reload.updated_at }
+ end
+
+ it 'responds with error' do
+ expect(resolve).to eq(timeline_event: nil, errors: ["Occurred at can't be blank"])
+ end
+ end
+
+ context 'when occurred_at is invalid' do
+ let(:occurred_at) { 'invalid date' }
+
+ it 'does not update the timeline event' do
+ expect { resolve }.not_to change { timeline_event.reload.updated_at }
+ end
+
+ it 'responds with error' do
+ expect(resolve).to eq(timeline_event: nil, errors: ["Occurred at can't be blank"])
+ end
end
end
end
diff --git a/spec/graphql/mutations/merge_requests/set_labels_spec.rb b/spec/graphql/mutations/merge_requests/set_labels_spec.rb
index 1bb303cf99b..44bd9342b8e 100644
--- a/spec/graphql/mutations/merge_requests/set_labels_spec.rb
+++ b/spec/graphql/mutations/merge_requests/set_labels_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe Mutations::MergeRequests::SetLabels do
end
context 'when passing operation_mode as REMOVE' do
- subject { mutation.resolve(project_path: merge_request.project.full_path, iid: merge_request.iid, label_ids: label_ids, operation_mode: Types::MutationOperationModeEnum.enum[:remove])}
+ subject { mutation.resolve(project_path: merge_request.project.full_path, iid: merge_request.iid, label_ids: label_ids, operation_mode: Types::MutationOperationModeEnum.enum[:remove]) }
it 'removes the labels, without removing others' do
merge_request.update!(labels: [label, label2])
diff --git a/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb b/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb
new file mode 100644
index 00000000000..df4aa885bbf
--- /dev/null
+++ b/spec/graphql/mutations/merge_requests/set_reviewers_spec.rb
@@ -0,0 +1,140 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::MergeRequests::SetReviewers do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:merge_request, reload: true) { create(:merge_request) }
+ let_it_be(:reviewer) { create(:user) }
+ let_it_be(:reviewer2) { create(:user) }
+
+ subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+
+ describe '#resolve' do
+ let(:reviewer_usernames) { [reviewer.username] }
+ let(:mutated_merge_request) { subject[:merge_request] }
+ let(:mode) { described_class.arguments['operationMode'].default_value }
+
+ subject do
+ mutation.resolve(project_path: merge_request.project.full_path,
+ iid: merge_request.iid,
+ operation_mode: mode,
+ reviewer_usernames: reviewer_usernames)
+ end
+
+ it 'does not change reviewers if the merge_request is not accessible to the reviewers' do
+ merge_request.project.add_developer(user)
+
+ expect { subject }.not_to change { merge_request.reload.reviewer_ids }
+ end
+
+ it 'returns an operational error if the merge_request is not accessible to the reviewers' do
+ merge_request.project.add_developer(user)
+
+ result = subject
+
+ expect(result[:errors]).to include a_string_matching(/Cannot assign/)
+ end
+
+ context 'when the user does not have permissions' do
+ it_behaves_like 'permission level for merge request mutation is correctly verified'
+ end
+
+ context 'when the user can update the merge_request' do
+ before do
+ merge_request.project.add_developer(reviewer)
+ merge_request.project.add_developer(reviewer2)
+ merge_request.project.add_developer(user)
+ end
+
+ it 'replaces the reviewer' do
+ merge_request.reviewers = [reviewer2]
+ merge_request.save!
+
+ expect(mutated_merge_request).to eq(merge_request)
+ expect(mutated_merge_request.reviewers).to contain_exactly(reviewer)
+ expect(subject[:errors]).to be_empty
+ end
+
+ it 'returns errors when merge_request could not be updated' do
+ allow(merge_request).to receive(:errors_on_object).and_return(['foo'])
+
+ expect(subject[:errors]).not_to match_array(['foo'])
+ end
+
+ context 'when passing an empty reviewer list' do
+ let(:reviewer_usernames) { [] }
+
+ before do
+ merge_request.reviewers = [reviewer]
+ merge_request.save!
+ end
+
+ it 'removes all reviewers' do
+ expect(mutated_merge_request).to eq(merge_request)
+ expect(mutated_merge_request.reviewers).to eq([])
+ expect(subject[:errors]).to be_empty
+ end
+ end
+
+ context 'when passing "append" as true' do
+ subject do
+ mutation.resolve(
+ project_path: merge_request.project.full_path,
+ iid: merge_request.iid,
+ reviewer_usernames: reviewer_usernames,
+ operation_mode: Types::MutationOperationModeEnum.enum[:append]
+ )
+ end
+
+ before do
+ merge_request.reviewers = [reviewer2]
+ merge_request.save!
+
+ # In CE, APPEND is a NOOP as you can't have multiple reviewers
+ # We test multiple assignment in EE specs
+ stub_licensed_features(multiple_merge_request_reviewers: false)
+ end
+
+ it 'is a NO-OP in FOSS' do
+ expect(mutated_merge_request).to eq(merge_request)
+ expect(mutated_merge_request.reviewers).to contain_exactly(reviewer2)
+ expect(subject[:errors]).to be_empty
+ end
+ end
+
+ context 'when passing "remove" as true' do
+ before do
+ merge_request.reviewers = [reviewer]
+ merge_request.save!
+ end
+
+ it 'removes named reviewer' do
+ mutated_merge_request = mutation.resolve(
+ project_path: merge_request.project.full_path,
+ iid: merge_request.iid,
+ reviewer_usernames: reviewer_usernames,
+ operation_mode: Types::MutationOperationModeEnum.enum[:remove]
+ )[:merge_request]
+
+ expect(mutated_merge_request).to eq(merge_request)
+ expect(mutated_merge_request.reviewers).to eq([])
+ expect(subject[:errors]).to be_empty
+ end
+
+ it 'does not remove unnamed reviewer' do
+ mutated_merge_request = mutation.resolve(
+ project_path: merge_request.project.full_path,
+ iid: merge_request.iid,
+ reviewer_usernames: [reviewer2.username],
+ operation_mode: Types::MutationOperationModeEnum.enum[:remove]
+ )[:merge_request]
+
+ expect(mutated_merge_request).to eq(merge_request)
+ expect(mutated_merge_request.reviewers).to contain_exactly(reviewer)
+ expect(subject[:errors]).to be_empty
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/mutations/releases/create_spec.rb b/spec/graphql/mutations/releases/create_spec.rb
index 1f2c3ed537f..b6b9449aa39 100644
--- a/spec/graphql/mutations/releases/create_spec.rb
+++ b/spec/graphql/mutations/releases/create_spec.rb
@@ -11,9 +11,9 @@ RSpec.describe Mutations::Releases::Create do
let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
- let(:tag) { 'v1.1.0'}
- let(:ref) { 'master'}
- let(:name) { 'Version 1.0'}
+ let(:tag) { 'v1.1.0' }
+ let(:ref) { 'master' }
+ let(:name) { 'Version 1.0' }
let(:description) { 'The first release :rocket:' }
let(:released_at) { Time.parse('2018-12-10') }
let(:milestones) { [milestone_12_3.title, milestone_12_4.title] }
diff --git a/spec/graphql/mutations/releases/delete_spec.rb b/spec/graphql/mutations/releases/delete_spec.rb
index 9934aea0031..09b420fe1ea 100644
--- a/spec/graphql/mutations/releases/delete_spec.rb
+++ b/spec/graphql/mutations/releases/delete_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Mutations::Releases::Delete do
let_it_be(:reporter) { create(:user) }
let_it_be(:developer) { create(:user) }
let_it_be(:maintainer) { create(:user) }
- let_it_be(:tag) { 'v1.1.0'}
+ let_it_be(:tag) { 'v1.1.0' }
let_it_be(:release) { create(:release, project: project, tag: tag) }
let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
diff --git a/spec/graphql/mutations/releases/update_spec.rb b/spec/graphql/mutations/releases/update_spec.rb
index 9fae703b85a..15b10ea0648 100644
--- a/spec/graphql/mutations/releases/update_spec.rb
+++ b/spec/graphql/mutations/releases/update_spec.rb
@@ -9,8 +9,8 @@ RSpec.describe Mutations::Releases::Update do
let_it_be(:reporter) { create(:user) }
let_it_be(:developer) { create(:user) }
- let_it_be(:tag) { 'v1.1.0'}
- let_it_be(:name) { 'Version 1.0'}
+ let_it_be(:tag) { 'v1.1.0' }
+ let_it_be(:name) { 'Version 1.0' }
let_it_be(:description) { 'The first release :rocket:' }
let_it_be(:released_at) { Time.parse('2018-12-10').utc }
let_it_be(:created_at) { Time.parse('2018-11-05').utc }
diff --git a/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb b/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb
index 53b673e255b..ba8a127bec5 100644
--- a/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runner_jobs_resolver_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Resolvers::Ci::RunnerJobsResolver do
let!(:build_one) { create(:ci_build, :success, name: 'Build One', runner: runner, pipeline: pipeline) }
let!(:build_two) { create(:ci_build, :success, name: 'Build Two', runner: runner, pipeline: pipeline) }
let!(:build_three) { create(:ci_build, :failed, name: 'Build Three', runner: runner, pipeline: pipeline) }
- let!(:irrelevant_build) { create(:ci_build, name: 'Irrelevant Build', pipeline: irrelevant_pipeline)}
+ let!(:irrelevant_build) { create(:ci_build, name: 'Irrelevant Build', pipeline: irrelevant_pipeline) }
let(:args) { {} }
let(:runner) { create(:ci_runner, :project, projects: [project]) }
diff --git a/spec/graphql/resolvers/crm/contact_state_counts_resolver_spec.rb b/spec/graphql/resolvers/crm/contact_state_counts_resolver_spec.rb
new file mode 100644
index 00000000000..0128ec792b3
--- /dev/null
+++ b/spec/graphql/resolvers/crm/contact_state_counts_resolver_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::Crm::ContactStateCountsResolver do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
+
+ before_all do
+ create(:contact, group: group, email: "x@test.com")
+ create(:contact, group: group, email: "y@test.com", state: 'inactive')
+ create_list(:contact, 3, group: group)
+ create_list(:contact, 2, group: group, state: 'inactive')
+ end
+
+ describe '#resolve' do
+ context 'with unauthorized user' do
+ it 'does not raise an error and returns no counts' do
+ expect { resolve_counts(group) }.not_to raise_error
+ expect(resolve_counts(group).all).to be(0)
+ end
+ end
+
+ context 'with authorized user' do
+ before do
+ group.add_reporter(user)
+ end
+
+ context 'without parent' do
+ it 'returns no counts' do
+ expect(resolve_counts(nil).all).to be(0)
+ end
+ end
+
+ context 'with a group' do
+ context 'when no filter is provided' do
+ it 'returns the count of all contacts' do
+ counts = resolve_counts(group)
+ expect(counts.all).to eq(7)
+ 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: "@test.com" })
+
+ expect(counts.all).to be(2)
+ expect(counts.active).to be(1)
+ expect(counts.inactive).to be(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/contacts_resolver_spec.rb b/spec/graphql/resolvers/crm/contacts_resolver_spec.rb
index 98da4aeac28..c7c2d11e114 100644
--- a/spec/graphql/resolvers/crm/contacts_resolver_spec.rb
+++ b/spec/graphql/resolvers/crm/contacts_resolver_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe Resolvers::Crm::ContactsResolver do
last_name: "DEF",
email: "ghi@test.com",
description: "LMNO",
+ organization: create(:organization, group: group),
state: "inactive"
)
end
@@ -61,11 +62,29 @@ RSpec.describe Resolvers::Crm::ContactsResolver do
end
context 'when no filter is provided' do
- it 'returns all the contacts in the correct order' do
+ it 'returns all the contacts in the default order' do
expect(resolve_contacts(group)).to eq([contact_a, contact_b])
end
end
+ context 'when a sort is provided' do
+ it 'returns all the contacts in the correct order' do
+ expect(resolve_contacts(group, { sort: 'EMAIL_DESC' })).to eq([contact_b, contact_a])
+ end
+ end
+
+ context 'when a sort is provided needing offset_pagination' do
+ it 'returns all the contacts in the correct order' do
+ expect(resolve_contacts(group, { sort: 'ORGANIZATION_ASC' })).to eq([contact_a, contact_b])
+ end
+ end
+
+ context 'when filtering for all states' do
+ it 'returns all the contacts in the correct order' do
+ expect(resolve_contacts(group, { state: 'all' })).to eq([contact_a, contact_b])
+ end
+ end
+
context 'when search term is provided' do
it 'returns the correct contacts' do
expect(resolve_contacts(group, { search: "x@test.com" })).to contain_exactly(contact_b)
diff --git a/spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb b/spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb
index 8d0b8f9398d..e1c67bc7c18 100644
--- a/spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb
+++ b/spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Resolvers::GroupMembers::NotificationEmailResolver do
expect(described_class).to have_nullable_graphql_type(GraphQL::Types::String)
end
- subject { batch_sync { resolve_notification_email(developer.group_members.first, current_user) }}
+ subject { batch_sync { resolve_notification_email(developer.group_members.first, current_user) } }
context 'when current_user is admin' do
let(:current_user) { create(:user, :admin) }
diff --git a/spec/graphql/resolvers/project_jobs_resolver_spec.rb b/spec/graphql/resolvers/project_jobs_resolver_spec.rb
index bb711a4c857..eb9d31ea7e5 100644
--- a/spec/graphql/resolvers/project_jobs_resolver_spec.rb
+++ b/spec/graphql/resolvers/project_jobs_resolver_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Resolvers::ProjectJobsResolver do
let_it_be(:failed_build) { create(:ci_build, :failed, name: 'Build Three', pipeline: pipeline) }
let_it_be(:pending_build) { create(:ci_build, :pending, name: 'Build Three', pipeline: pipeline) }
- let(:irrelevant_build) { create(:ci_build, name: 'Irrelevant Build', pipeline: irrelevant_pipeline)}
+ let(:irrelevant_build) { create(:ci_build, name: 'Irrelevant Build', pipeline: irrelevant_pipeline) }
let(:args) { {} }
let(:current_user) { create(:user) }
diff --git a/spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb b/spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb
new file mode 100644
index 00000000000..ef1b18f0a11
--- /dev/null
+++ b/spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::Projects::ForkTargetsResolver do
+ include GraphqlHelpers
+
+ let_it_be(:group) { create(:group, path: 'namespace-group') }
+ let_it_be(:another_group) { create(:group, path: 'namespace-another-group') }
+ let_it_be(:project) { create(:project, :private, group: group) }
+ let_it_be(:user) { create(:user, username: 'namespace-user', maintainer_projects: [project]) }
+
+ let(:args) { { search: 'namespace' } }
+
+ describe '#resolve' do
+ before_all do
+ group.add_owner(user)
+ another_group.add_owner(user)
+ end
+
+ it 'returns forkable namespaces' do
+ expect_next_instance_of(ForkTargetsFinder) do |finder|
+ expect(finder).to receive(:execute).with(args).and_call_original
+ end
+
+ expect(resolve_targets(args).items).to match_array([user.namespace, project.namespace, another_group])
+ end
+ end
+
+ context 'when a user cannot fork the project' do
+ let(:user) { create(:user) }
+
+ it 'does not return results' do
+ project.add_guest(user)
+
+ expect(resolve_targets(args)).to be_nil
+ end
+ end
+
+ def resolve_targets(args, opts = {})
+ field_options = described_class.field_options.merge(
+ owner: resolver_parent,
+ name: 'field_value'
+ ).merge(opts)
+
+ field = ::Types::BaseField.new(**field_options)
+ resolve_field(field, project, args: args, ctx: { current_user: user }, object_type: resolver_parent)
+ end
+end
diff --git a/spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb b/spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb
index 854e763fbdd..546b8592546 100644
--- a/spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb
+++ b/spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Resolvers::Projects::GrafanaIntegrationResolver do
let_it_be(:project) { create(:project) }
let_it_be(:current_user) { create(:user) }
- let_it_be(:grafana_integration) { create(:grafana_integration, project: project)}
+ let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
describe '#resolve' do
context 'when object is not a project' do
@@ -19,7 +19,7 @@ RSpec.describe Resolvers::Projects::GrafanaIntegrationResolver do
end
context 'when object is nil' do
- it { expect(resolve_integration(obj: nil)).to eq nil}
+ it { expect(resolve_integration(obj: nil)).to eq nil }
end
end
diff --git a/spec/graphql/resolvers/projects_resolver_spec.rb b/spec/graphql/resolvers/projects_resolver_spec.rb
index 2685115d1a2..453fafb9590 100644
--- a/spec/graphql/resolvers/projects_resolver_spec.rb
+++ b/spec/graphql/resolvers/projects_resolver_spec.rb
@@ -142,7 +142,7 @@ RSpec.describe Resolvers::ProjectsResolver do
context 'when no sort is provided' do
it 'returns projects in descending order by id' do
- is_expected.to match_array((visible_projecs + named_projects).sort_by { |p| p[:id]}.reverse )
+ is_expected.to match_array((visible_projecs + named_projects).sort_by { |p| p[:id] }.reverse )
end
end
end
diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb
index 439678e7e16..b85716e4d21 100644
--- a/spec/graphql/types/base_field_spec.rb
+++ b/spec/graphql/types/base_field_spec.rb
@@ -209,7 +209,7 @@ RSpec.describe Types::BaseField do
describe '#visible?' do
context 'and has a feature_flag' do
let(:flag) { :test_feature }
- let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String, feature_flag: flag, null: false) }
+ let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String, _deprecated_feature_flag: flag, null: false) }
let(:context) { {} }
before do
@@ -253,7 +253,7 @@ RSpec.describe Types::BaseField do
describe '#description' do
context 'feature flag given' do
- let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String, feature_flag: flag, null: false, description: 'Test description.') }
+ let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String, _deprecated_feature_flag: flag, null: false, description: 'Test description.') }
let(:flag) { :test_flag }
it 'prepends the description' do
@@ -299,7 +299,7 @@ RSpec.describe Types::BaseField do
end
it 'returns the correct availability in the description' do
- expect(field.description). to eq expected_description
+ expect(field.description).to eq expected_description
end
end
end
@@ -313,11 +313,11 @@ RSpec.describe Types::BaseField do
described_class.new(**base_args.merge(args))
end
- it 'interacts well with the `feature_flag` property' do
+ it 'interacts well with the `_deprecated_feature_flag` property' do
field = subject(
deprecated: { milestone: '1.10', reason: 'Deprecation reason' },
description: 'Field description.',
- feature_flag: 'foo_flag'
+ _deprecated_feature_flag: 'foo_flag'
)
expect(field.description).to start_with('Field description. Available only when feature flag `foo_flag` is enabled.')
diff --git a/spec/graphql/types/ci/group_variable_type_spec.rb b/spec/graphql/types/ci/group_variable_type_spec.rb
new file mode 100644
index 00000000000..106935642f2
--- /dev/null
+++ b/spec/graphql/types/ci/group_variable_type_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CiGroupVariable'] do
+ specify { expect(described_class.interfaces).to contain_exactly(Types::Ci::VariableInterface) }
+
+ specify { expect(described_class).to have_graphql_fields(:environment_scope, :masked, :protected).at_least }
+end
diff --git a/spec/graphql/types/ci/instance_variable_type_spec.rb b/spec/graphql/types/ci/instance_variable_type_spec.rb
new file mode 100644
index 00000000000..cf4aaed31f1
--- /dev/null
+++ b/spec/graphql/types/ci/instance_variable_type_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CiInstanceVariable'] do
+ specify { expect(described_class.interfaces).to contain_exactly(Types::Ci::VariableInterface) }
+
+ specify { expect(described_class).to have_graphql_fields(:masked, :protected).at_least }
+end
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 c1a3c4dd54d..457d46b6896 100644
--- a/spec/graphql/types/ci/job_token_scope_type_spec.rb
+++ b/spec/graphql/types/ci/job_token_scope_type_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe GitlabSchema.types['CiJobTokenScopeType'] do
subject { GitlabSchema.execute(query, context: { current_user: current_user }).as_json }
let(:projects_field) { subject.dig('data', 'project', 'ciJobTokenScope', 'projects', 'nodes') }
- let(:returned_project_paths) { projects_field.map { |project| project['path']} }
+ let(:returned_project_paths) { projects_field.map { |project| project['path'] } }
context 'with access to scope' do
before do
diff --git a/spec/graphql/types/ci/manual_variable_type_spec.rb b/spec/graphql/types/ci/manual_variable_type_spec.rb
new file mode 100644
index 00000000000..2884c818a52
--- /dev/null
+++ b/spec/graphql/types/ci/manual_variable_type_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CiManualVariable'] do
+ specify { expect(described_class.interfaces).to contain_exactly(Types::Ci::VariableInterface) }
+end
diff --git a/spec/graphql/types/ci/project_variable_type_spec.rb b/spec/graphql/types/ci/project_variable_type_spec.rb
new file mode 100644
index 00000000000..e6e045b2bca
--- /dev/null
+++ b/spec/graphql/types/ci/project_variable_type_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CiProjectVariable'] do
+ specify { expect(described_class.interfaces).to contain_exactly(Types::Ci::VariableInterface) }
+
+ specify { expect(described_class).to have_graphql_fields(:environment_scope, :masked, :protected).at_least }
+end
diff --git a/spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb b/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb
index 03c784dcbe7..ef378f3fc5a 100644
--- a/spec/graphql/types/ci/runner_upgrade_status_type_enum_spec.rb
+++ b/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb
@@ -2,13 +2,13 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerUpgradeStatusTypeEnum do
+RSpec.describe Types::Ci::RunnerUpgradeStatusEnum do
let(:model_only_enum_values) { %w[not_processed] }
let(:expected_graphql_source_values) do
Ci::RunnerVersion.statuses.keys - model_only_enum_values
end
- specify { expect(described_class.graphql_name).to eq('CiRunnerUpgradeStatusType') }
+ specify { expect(described_class.graphql_name).to eq('CiRunnerUpgradeStatus') }
it 'exposes all upgrade status values except not_processed' do
expect(described_class.values.keys).to match_array(
diff --git a/spec/graphql/types/ci/variable_input_type_spec.rb b/spec/graphql/types/ci/variable_input_type_spec.rb
new file mode 100644
index 00000000000..a56b6287dee
--- /dev/null
+++ b/spec/graphql/types/ci/variable_input_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CiVariableInput'] do
+ include GraphqlHelpers
+
+ it 'has the correct arguments' do
+ expect(described_class.arguments.keys).to match_array(%w[key value])
+ end
+end
diff --git a/spec/graphql/types/ci/variable_type_spec.rb b/spec/graphql/types/ci/variable_interface_spec.rb
index a81e6adbab6..8cef0ac2a14 100644
--- a/spec/graphql/types/ci/variable_type_spec.rb
+++ b/spec/graphql/types/ci/variable_interface_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['CiVariable'] do
- it 'contains attributes related to CI variables' do
+ specify do
expect(described_class).to have_graphql_fields(
- :id, :key, :value, :variable_type, :protected, :masked, :raw, :environment_scope
- )
+ :id, :key, :value, :variable_type, :raw
+ ).at_least
end
end
diff --git a/spec/graphql/types/customer_relations/contact_sort_enum_spec.rb b/spec/graphql/types/customer_relations/contact_sort_enum_spec.rb
new file mode 100644
index 00000000000..5b0538042c8
--- /dev/null
+++ b/spec/graphql/types/customer_relations/contact_sort_enum_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['ContactSort'] do
+ specify { expect(described_class.graphql_name).to eq('ContactSort') }
+
+ it_behaves_like 'common sort values'
+
+ it 'exposes all the contact sort values' do
+ expect(described_class.values.keys).to include(
+ *%w[
+ FIRST_NAME_ASC
+ FIRST_NAME_DESC
+ LAST_NAME_ASC
+ LAST_NAME_DESC
+ EMAIL_ASC
+ EMAIL_DESC
+ PHONE_ASC
+ PHONE_DESC
+ DESCRIPTION_ASC
+ DESCRIPTION_DESC
+ ORGANIZATION_ASC
+ ORGANIZATION_DESC
+ ]
+ )
+ end
+end
diff --git a/spec/graphql/types/customer_relations/contact_state_counts_type_spec.rb b/spec/graphql/types/customer_relations/contact_state_counts_type_spec.rb
new file mode 100644
index 00000000000..b022febb90f
--- /dev/null
+++ b/spec/graphql/types/customer_relations/contact_state_counts_type_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['ContactStateCounts'] do
+ let(:fields) do
+ %w[
+ all
+ active
+ inactive
+ ]
+ end
+
+ it { expect(described_class.graphql_name).to eq('ContactStateCounts') }
+ it { expect(described_class).to have_graphql_fields(fields) }
+ it { expect(described_class).to require_graphql_authorizations(:read_crm_contact) }
+end
diff --git a/spec/graphql/types/global_id_type_spec.rb b/spec/graphql/types/global_id_type_spec.rb
index a57db9234f1..fa0b34113bc 100644
--- a/spec/graphql/types/global_id_type_spec.rb
+++ b/spec/graphql/types/global_id_type_spec.rb
@@ -114,7 +114,11 @@ RSpec.describe Types::GlobalIDType do
end
before do
- deprecation = Gitlab::GlobalId::Deprecations::Deprecation.new(old_model_name: 'OldIssue', new_model_name: 'Issue', milestone: '10.0')
+ deprecation = Gitlab::GlobalId::Deprecations::NameDeprecation.new(
+ old_name: 'OldIssue',
+ new_name: 'Issue',
+ milestone: '10.0'
+ )
stub_global_id_deprecations(deprecation)
end
diff --git a/spec/graphql/types/group_type_spec.rb b/spec/graphql/types/group_type_spec.rb
index 69c7eaf111f..72b3bb90194 100644
--- a/spec/graphql/types/group_type_spec.rb
+++ b/spec/graphql/types/group_type_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['Group'] do
+ include GraphqlHelpers
+
specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Group) }
specify { expect(described_class.graphql_name).to eq('Group') }
@@ -22,8 +24,8 @@ RSpec.describe GitlabSchema.types['Group'] do
dependency_proxy_blobs dependency_proxy_image_count
dependency_proxy_blob_count dependency_proxy_total_size
dependency_proxy_image_prefix dependency_proxy_image_ttl_policy
- shared_runners_setting timelogs organizations contacts work_item_types
- recent_issue_boards ci_variables
+ shared_runners_setting timelogs organizations contacts contact_state_counts
+ work_item_types recent_issue_boards ci_variables
]
expect(described_class).to include_graphql_fields(*expected_fields)
@@ -53,7 +55,52 @@ RSpec.describe GitlabSchema.types['Group'] do
end
end
+ describe 'contact_state_counts field' do
+ subject { described_class.fields['contactStateCounts'] }
+
+ it { is_expected.to have_graphql_type(Types::CustomerRelations::ContactStateCountsType) }
+ it { is_expected.to have_graphql_resolver(Resolvers::Crm::ContactStateCountsResolver) }
+ end
+
it_behaves_like 'a GraphQL type with labels' do
let(:labels_resolver_arguments) { [:search_term, :includeAncestorGroups, :includeDescendantGroups, :onlyGroupLabels] }
end
+
+ describe 'milestones' do
+ let(:user) { create(:user) }
+ let(:subgroup) { create(:group, parent: create(:group)) }
+ let(:query) do
+ %(
+ query {
+ group(fullPath: "#{subgroup.full_path}") {
+ milestones {
+ nodes {
+ id
+ title
+ projectMilestone
+ groupMilestone
+ subgroupMilestone
+ }
+ }
+ }
+ }
+ )
+ end
+
+ def clean_state_query
+ run_with_clean_state(query, context: { current_user: user })
+ end
+
+ it 'avoids N+1 queries' do
+ subgroup.add_reporter(user)
+
+ create(:milestone, group: subgroup)
+
+ control = ActiveRecord::QueryRecorder.new(skip_cached: false) { clean_state_query }
+
+ create_list(:milestone, 2, group: subgroup)
+
+ expect { clean_state_query }.not_to exceed_all_query_limit(control)
+ end
+ end
end
diff --git a/spec/graphql/types/issue_type_spec.rb b/spec/graphql/types/issue_type_spec.rb
index e7454b85357..2a0ae79b2c4 100644
--- a/spec/graphql/types/issue_type_spec.rb
+++ b/spec/graphql/types/issue_type_spec.rb
@@ -167,7 +167,7 @@ RSpec.describe GitlabSchema.types['Issue'] do
shared_examples_for 'does not include private notes' do
it "does not return private notes" do
notes = subject.dig("data", "project", "issue", "notes", 'edges')
- notes_body = notes.map {|n| n.dig('node', 'body')}
+ notes_body = notes.map { |n| n.dig('node', 'body') }
expect(notes.size).to eq 1
expect(notes_body).not_to include(private_note_body)
@@ -178,7 +178,7 @@ RSpec.describe GitlabSchema.types['Issue'] do
shared_examples_for 'includes private notes' do
it "returns all notes" do
notes = subject.dig("data", "project", "issue", "notes", 'edges')
- notes_body = notes.map {|n| n.dig('node', 'body')}
+ notes_body = notes.map { |n| n.dig('node', 'body') }
expect(notes.size).to eq 2
expect(notes_body).to include(private_note_body)
@@ -209,7 +209,7 @@ RSpec.describe GitlabSchema.types['Issue'] do
end
describe 'hidden', :enable_admin_mode do
- let_it_be(:admin) { create(:user, :admin)}
+ let_it_be(:admin) { create(:user, :admin) }
let_it_be(:banned_user) { create(:user, :banned) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/graphql/types/namespace_type_spec.rb b/spec/graphql/types/namespace_type_spec.rb
index 3b7f7e65e4b..168a6ba4eaa 100644
--- a/spec/graphql/types/namespace_type_spec.rb
+++ b/spec/graphql/types/namespace_type_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe GitlabSchema.types['Namespace'] do
expected_fields = %w[
id name path full_name full_path description description_html visibility
lfs_enabled request_access_enabled projects root_storage_statistics shared_runners_setting
+ timelog_categories
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/notes/note_type_spec.rb b/spec/graphql/types/notes/note_type_spec.rb
index 03ff7828cf5..cbf7f086dbe 100644
--- a/spec/graphql/types/notes/note_type_spec.rb
+++ b/spec/graphql/types/notes/note_type_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe GitlabSchema.types['Note'] do
body
body_html
confidential
+ internal
created_at
discussion
id
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index ed93d31da0f..5ff7653ce39 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -37,7 +37,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
- recent_issue_boards ci_config_path_or_default ci_variables
+ timelog_categories fork_targets
]
expect(described_class).to include_graphql_fields(*expected_fields)
@@ -195,8 +195,8 @@ RSpec.describe GitlabSchema.types['Project'] do
expect(secure_analyzers['type']).to eq('string')
expect(secure_analyzers['field']).to eq('SECURE_ANALYZERS_PREFIX')
expect(secure_analyzers['label']).to eq('Image prefix')
- expect(secure_analyzers['defaultValue']).to eq(secure_analyzers_prefix)
- expect(secure_analyzers['value']).to eq(secure_analyzers_prefix)
+ expect(secure_analyzers['defaultValue']).to eq('$CI_TEMPLATE_REGISTRY_HOST/security-products')
+ expect(secure_analyzers['value']).to eq('$CI_TEMPLATE_REGISTRY_HOST/security-products')
expect(secure_analyzers['size']).to eq('LARGE')
expect(secure_analyzers['options']).to be_nil
end
diff --git a/spec/graphql/types/projects/service_type_enum_spec.rb b/spec/graphql/types/projects/service_type_enum_spec.rb
index ead69e60f6c..f7256910bb0 100644
--- a/spec/graphql/types/projects/service_type_enum_spec.rb
+++ b/spec/graphql/types/projects/service_type_enum_spec.rb
@@ -35,6 +35,7 @@ RSpec.describe GitlabSchema.types['ServiceType'] do
PIPELINES_EMAIL_SERVICE
PIVOTALTRACKER_SERVICE
PROMETHEUS_SERVICE
+ PUMBLE_SERVICE
PUSHOVER_SERVICE
REDMINE_SERVICE
SHIMO_SERVICE
diff --git a/spec/graphql/types/subscription_type_spec.rb b/spec/graphql/types/subscription_type_spec.rb
index 1a2629ed422..9b043fa52cf 100644
--- a/spec/graphql/types/subscription_type_spec.rb
+++ b/spec/graphql/types/subscription_type_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe GitlabSchema.types['Subscription'] do
issue_crm_contacts_updated
issuable_title_updated
issuable_labels_updated
+ issuable_dates_updated
]
expect(described_class).to have_graphql_fields(*expected_fields).only
diff --git a/spec/graphql/types/time_tracking/timelog_category_type_spec.rb b/spec/graphql/types/time_tracking/timelog_category_type_spec.rb
new file mode 100644
index 00000000000..a14069e8b58
--- /dev/null
+++ b/spec/graphql/types/time_tracking/timelog_category_type_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['TimeTrackingTimelogCategory'] do
+ let(:fields) do
+ %w[
+ id
+ name
+ description
+ color
+ billable
+ billing_rate
+ created_at
+ updated_at
+ ]
+ end
+
+ it { expect(described_class.graphql_name).to eq('TimeTrackingTimelogCategory') }
+ it { expect(described_class).to have_graphql_fields(fields) }
+ it { expect(described_class).to require_graphql_authorizations(:read_timelog_category) }
+end
diff --git a/spec/graphql/types/upload_type_spec.rb b/spec/graphql/types/upload_type_spec.rb
new file mode 100644
index 00000000000..2b959fbf105
--- /dev/null
+++ b/spec/graphql/types/upload_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['FileUpload'] do
+ it { expect(described_class).to require_graphql_authorizations(:read_upload) }
+
+ it 'has the expected fields' do
+ expected_fields = %w[id size path]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/user_type_spec.rb b/spec/graphql/types/user_type_spec.rb
index fec6a771640..dcf25ff0667 100644
--- a/spec/graphql/types/user_type_spec.rb
+++ b/spec/graphql/types/user_type_spec.rb
@@ -49,7 +49,7 @@ RSpec.describe GitlabSchema.types['User'] do
end
describe 'name field' do
- let_it_be(:admin) { create(:user, :admin)}
+ let_it_be(:admin) { create(:user, :admin) }
let_it_be(:user) { create(:user) }
let_it_be(:requested_user) { create(:user, name: 'John Smith') }
let_it_be(:requested_project_bot) { create(:user, :project_bot, name: 'Project bot') }
diff --git a/spec/graphql/types/work_item_type_spec.rb b/spec/graphql/types/work_item_type_spec.rb
index 7ed58786b5b..c556424b0b4 100644
--- a/spec/graphql/types/work_item_type_spec.rb
+++ b/spec/graphql/types/work_item_type_spec.rb
@@ -11,16 +11,21 @@ RSpec.describe GitlabSchema.types['WorkItem'] do
it 'has specific fields' do
fields = %i[
+ confidential
description
description_html
id
iid
lock_version
+ project
state title
title_html
userPermissions
widgets
work_item_type
+ created_at
+ updated_at
+ closed_at
]
fields.each do |field_name|
diff --git a/spec/graphql/types/work_items/widget_interface_spec.rb b/spec/graphql/types/work_items/widget_interface_spec.rb
index caf986c961f..b9e8edacf15 100644
--- a/spec/graphql/types/work_items/widget_interface_spec.rb
+++ b/spec/graphql/types/work_items/widget_interface_spec.rb
@@ -18,6 +18,7 @@ RSpec.describe Types::WorkItems::WidgetInterface do
WorkItems::Widgets::Description | Types::WorkItems::Widgets::DescriptionType
WorkItems::Widgets::Hierarchy | Types::WorkItems::Widgets::HierarchyType
WorkItems::Widgets::Assignees | Types::WorkItems::Widgets::AssigneesType
+ WorkItems::Widgets::Labels | Types::WorkItems::Widgets::LabelsType
end
with_them do
diff --git a/spec/graphql/types/work_items/widgets/assignees_input_type_spec.rb b/spec/graphql/types/work_items/widgets/assignees_input_type_spec.rb
new file mode 100644
index 00000000000..2fcda2a43be
--- /dev/null
+++ b/spec/graphql/types/work_items/widgets/assignees_input_type_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Types::WorkItems::Widgets::AssigneesInputType do
+ it { expect(described_class.graphql_name).to eq('WorkItemWidgetAssigneesInput') }
+
+ it { expect(described_class.arguments.keys).to match_array(%w[assigneeIds]) }
+end
diff --git a/spec/graphql/types/work_items/widgets/labels_type_spec.rb b/spec/graphql/types/work_items/widgets/labels_type_spec.rb
new file mode 100644
index 00000000000..028ebe979f3
--- /dev/null
+++ b/spec/graphql/types/work_items/widgets/labels_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::WorkItems::Widgets::LabelsType do
+ it 'exposes the expected fields' do
+ expected_fields = %i[labels allowsScopedLabels type]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/work_items/widgets/start_and_due_date_type_spec.rb b/spec/graphql/types/work_items/widgets/start_and_due_date_type_spec.rb
new file mode 100644
index 00000000000..ddc26d964be
--- /dev/null
+++ b/spec/graphql/types/work_items/widgets/start_and_due_date_type_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::WorkItems::Widgets::StartAndDueDateType do
+ it 'exposes the expected fields' do
+ expected_fields = %i[due_date start_date type]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/work_items/widgets/start_and_due_date_update_input_type_spec.rb b/spec/graphql/types/work_items/widgets/start_and_due_date_update_input_type_spec.rb
new file mode 100644
index 00000000000..91631093e4e
--- /dev/null
+++ b/spec/graphql/types/work_items/widgets/start_and_due_date_update_input_type_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Types::WorkItems::Widgets::StartAndDueDateUpdateInputType do
+ it { expect(described_class.graphql_name).to eq('WorkItemWidgetStartAndDueDateUpdateInput') }
+
+ it { expect(described_class.arguments.keys).to contain_exactly('startDate', 'dueDate') }
+end