summaryrefslogtreecommitdiff
path: root/spec/graphql
diff options
context:
space:
mode:
Diffstat (limited to 'spec/graphql')
-rw-r--r--spec/graphql/gitlab_schema_spec.rb16
-rw-r--r--spec/graphql/mutations/alert_management/create_alert_issue_spec.rb60
-rw-r--r--spec/graphql/mutations/alert_management/update_alert_status_spec.rb73
-rw-r--r--spec/graphql/mutations/branches/create_spec.rb55
-rw-r--r--spec/graphql/mutations/design_management/delete_spec.rb145
-rw-r--r--spec/graphql/mutations/design_management/upload_spec.rb136
-rw-r--r--spec/graphql/mutations/issues/set_confidential_spec.rb2
-rw-r--r--spec/graphql/mutations/issues/set_due_date_spec.rb2
-rw-r--r--spec/graphql/mutations/issues/update_spec.rb2
-rw-r--r--spec/graphql/mutations/merge_requests/set_labels_spec.rb2
-rw-r--r--spec/graphql/mutations/merge_requests/set_locked_spec.rb2
-rw-r--r--spec/graphql/mutations/merge_requests/set_milestone_spec.rb2
-rw-r--r--spec/graphql/mutations/merge_requests/set_subscription_spec.rb2
-rw-r--r--spec/graphql/mutations/merge_requests/set_wip_spec.rb2
-rw-r--r--spec/graphql/mutations/todos/mark_all_done_spec.rb2
-rw-r--r--spec/graphql/mutations/todos/mark_done_spec.rb2
-rw-r--r--spec/graphql/mutations/todos/restore_spec.rb2
-rw-r--r--spec/graphql/resolvers/alert_management/alert_status_counts_resolver_spec.rb24
-rw-r--r--spec/graphql/resolvers/alert_management_alert_resolver_spec.rb63
-rw-r--r--spec/graphql/resolvers/board_lists_resolver_spec.rb82
-rw-r--r--spec/graphql/resolvers/branch_commit_resolver_spec.rb26
-rw-r--r--spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb69
-rw-r--r--spec/graphql/resolvers/design_management/design_resolver_spec.rb88
-rw-r--r--spec/graphql/resolvers/design_management/designs_resolver_spec.rb93
-rw-r--r--spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb93
-rw-r--r--spec/graphql/resolvers/design_management/version/designs_at_version_resolver_spec.rb86
-rw-r--r--spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb64
-rw-r--r--spec/graphql/resolvers/design_management/version_resolver_spec.rb43
-rw-r--r--spec/graphql/resolvers/design_management/versions_resolver_spec.rb117
-rw-r--r--spec/graphql/resolvers/issues_resolver_spec.rb78
-rw-r--r--spec/graphql/resolvers/milestone_resolver_spec.rb28
-rw-r--r--spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb8
-rw-r--r--spec/graphql/resolvers/projects_resolver_spec.rb77
-rw-r--r--spec/graphql/resolvers/release_resolver_spec.rb51
-rw-r--r--spec/graphql/resolvers/releases_resolver_spec.rb42
-rw-r--r--spec/graphql/types/alert_management/alert_status_count_type_spec.rb20
-rw-r--r--spec/graphql/types/alert_management/alert_type_spec.rb31
-rw-r--r--spec/graphql/types/alert_management/severity_enum_spec.rb11
-rw-r--r--spec/graphql/types/alert_management/status_enum_spec.rb24
-rw-r--r--spec/graphql/types/award_emojis/award_emoji_type_spec.rb6
-rw-r--r--spec/graphql/types/blob_viewers/type_enum_spec.rb2
-rw-r--r--spec/graphql/types/board_list_type_spec.rb13
-rw-r--r--spec/graphql/types/board_type_spec.rb4
-rw-r--r--spec/graphql/types/branch_type_spec.rb9
-rw-r--r--spec/graphql/types/ci/detailed_status_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/pipeline_type_spec.rb4
-rw-r--r--spec/graphql/types/commit_type_spec.rb6
-rw-r--r--spec/graphql/types/design_management/design_at_version_type_spec.rb16
-rw-r--r--spec/graphql/types/design_management/design_collection_type_spec.rb13
-rw-r--r--spec/graphql/types/design_management/design_type_spec.rb13
-rw-r--r--spec/graphql/types/design_management/design_version_event_enum_spec.rb11
-rw-r--r--spec/graphql/types/design_management/version_type_spec.rb13
-rw-r--r--spec/graphql/types/design_management_type_spec.rb7
-rw-r--r--spec/graphql/types/diff_refs_type_spec.rb10
-rw-r--r--spec/graphql/types/environment_type_spec.rb4
-rw-r--r--spec/graphql/types/error_tracking/sentry_detailed_error_type_spec.rb4
-rw-r--r--spec/graphql/types/error_tracking/sentry_error_collection_type_spec.rb4
-rw-r--r--spec/graphql/types/error_tracking/sentry_error_stack_trace_entry_type_spec.rb2
-rw-r--r--spec/graphql/types/error_tracking/sentry_error_stack_trace_type_spec.rb4
-rw-r--r--spec/graphql/types/error_tracking/sentry_error_type_spec.rb2
-rw-r--r--spec/graphql/types/grafana_integration_type_spec.rb6
-rw-r--r--spec/graphql/types/group_type_spec.rb6
-rw-r--r--spec/graphql/types/issuable_sort_enum_spec.rb15
-rw-r--r--spec/graphql/types/issuable_state_enum_spec.rb2
-rw-r--r--spec/graphql/types/issue_sort_enum_spec.rb6
-rw-r--r--spec/graphql/types/issue_state_enum_spec.rb2
-rw-r--r--spec/graphql/types/issue_type_spec.rb11
-rw-r--r--spec/graphql/types/jira_import_type_spec.rb4
-rw-r--r--spec/graphql/types/label_type_spec.rb2
-rw-r--r--spec/graphql/types/merge_request_state_enum_spec.rb2
-rw-r--r--spec/graphql/types/merge_request_type_spec.rb6
-rw-r--r--spec/graphql/types/metadata_type_spec.rb4
-rw-r--r--spec/graphql/types/metrics/dashboard_type_spec.rb2
-rw-r--r--spec/graphql/types/metrics/dashboards/annotation_type_spec.rb4
-rw-r--r--spec/graphql/types/milestone_type_spec.rb4
-rw-r--r--spec/graphql/types/namespace_type_spec.rb4
-rw-r--r--spec/graphql/types/notes/discussion_type_spec.rb4
-rw-r--r--spec/graphql/types/notes/note_type_spec.rb4
-rw-r--r--spec/graphql/types/notes/noteable_type_spec.rb3
-rw-r--r--spec/graphql/types/permission_types/issue_spec.rb5
-rw-r--r--spec/graphql/types/permission_types/merge_request_type_spec.rb2
-rw-r--r--spec/graphql/types/permission_types/project_spec.rb2
-rw-r--r--spec/graphql/types/project_type_spec.rb23
-rw-r--r--spec/graphql/types/projects/base_service_type_spec.rb4
-rw-r--r--spec/graphql/types/projects/jira_service_type_spec.rb4
-rw-r--r--spec/graphql/types/projects/service_type_spec.rb2
-rw-r--r--spec/graphql/types/projects/services_enum_spec.rb2
-rw-r--r--spec/graphql/types/query_type_spec.rb2
-rw-r--r--spec/graphql/types/release_type_spec.rb37
-rw-r--r--spec/graphql/types/repository_type_spec.rb8
-rw-r--r--spec/graphql/types/root_storage_statistics_type_spec.rb4
-rw-r--r--spec/graphql/types/snippet_type_spec.rb10
-rw-r--r--spec/graphql/types/snippets/blob_type_spec.rb16
-rw-r--r--spec/graphql/types/snippets/blob_viewer_type_spec.rb81
-rw-r--r--spec/graphql/types/time_type_spec.rb2
-rw-r--r--spec/graphql/types/todo_type_spec.rb2
-rw-r--r--spec/graphql/types/tree/blob_type_spec.rb4
-rw-r--r--spec/graphql/types/tree/submodule_type_spec.rb4
-rw-r--r--spec/graphql/types/tree/tree_entry_type_spec.rb4
-rw-r--r--spec/graphql/types/tree/tree_type_spec.rb4
-rw-r--r--spec/graphql/types/tree/type_enum_spec.rb2
-rw-r--r--spec/graphql/types/user_type_spec.rb6
102 files changed, 2061 insertions, 134 deletions
diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb
index 0f21a55f7e9..8960ad91543 100644
--- a/spec/graphql/gitlab_schema_spec.rb
+++ b/spec/graphql/gitlab_schema_spec.rb
@@ -191,13 +191,17 @@ describe GitlabSchema do
context 'for other classes' do
# We cannot use an anonymous class here as `GlobalID` expects `.name` not
# to return `nil`
- class TestGlobalId
- include GlobalID::Identification
- attr_accessor :id
-
- def initialize(id)
- @id = id
+ before do
+ test_global_id = Class.new do
+ include GlobalID::Identification
+ attr_accessor :id
+
+ def initialize(id)
+ @id = id
+ end
end
+
+ stub_const('TestGlobalId', test_global_id)
end
it 'falls back to a regular find' do
diff --git a/spec/graphql/mutations/alert_management/create_alert_issue_spec.rb b/spec/graphql/mutations/alert_management/create_alert_issue_spec.rb
new file mode 100644
index 00000000000..1e51767cf0e
--- /dev/null
+++ b/spec/graphql/mutations/alert_management/create_alert_issue_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Mutations::AlertManagement::CreateAlertIssue do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered') }
+ let(:args) { { project_path: project.full_path, iid: alert.iid } }
+
+ specify { expect(described_class).to require_graphql_authorizations(:update_alert_management_alert) }
+
+ describe '#resolve' do
+ subject(:resolve) { mutation_for(project, current_user).resolve(args) }
+
+ context 'user has access to project' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ context 'when CreateAlertIssueService responds with success' do
+ it 'returns the issue with no errors' do
+ expect(resolve).to eq(
+ alert: alert.reload,
+ issue: Issue.last!,
+ errors: []
+ )
+ end
+ end
+
+ context 'when CreateAlertIssue responds with an error' do
+ before do
+ allow_any_instance_of(::AlertManagement::CreateAlertIssueService)
+ .to receive(:execute)
+ .and_return(ServiceResponse.error(payload: { issue: nil }, message: 'An issue already exists'))
+ end
+
+ it 'returns errors' do
+ expect(resolve).to eq(
+ alert: alert,
+ issue: nil,
+ errors: ['An issue already exists']
+ )
+ end
+ end
+ end
+
+ context 'when resource is not accessible to the user' do
+ it 'raises an error if the resource is not accessible to the user' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+ end
+
+ private
+
+ def mutation_for(project, user)
+ described_class.new(object: project, context: { current_user: user }, field: nil)
+ end
+end
diff --git a/spec/graphql/mutations/alert_management/update_alert_status_spec.rb b/spec/graphql/mutations/alert_management/update_alert_status_spec.rb
new file mode 100644
index 00000000000..8b9abd9497d
--- /dev/null
+++ b/spec/graphql/mutations/alert_management/update_alert_status_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Mutations::AlertManagement::UpdateAlertStatus do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:alert) { create(:alert_management_alert, :triggered) }
+ let_it_be(:project) { alert.project }
+ let(:new_status) { Types::AlertManagement::StatusEnum.values['ACKNOWLEDGED'].value }
+ let(:args) { { status: new_status, project_path: project.full_path, iid: alert.iid } }
+
+ specify { expect(described_class).to require_graphql_authorizations(:update_alert_management_alert) }
+
+ describe '#resolve' do
+ subject(:resolve) { mutation_for(project, current_user).resolve(args) }
+
+ context 'user has access to project' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ it 'changes the status' do
+ expect { resolve }.to change { alert.reload.acknowledged? }.to(true)
+ end
+
+ it 'returns the alert with no errors' do
+ expect(resolve).to eq(
+ alert: alert,
+ errors: []
+ )
+ end
+
+ context 'error occurs when updating' do
+ it 'returns the alert with errors' do
+ # Stub an error on the alert
+ allow_next_instance_of(Resolvers::AlertManagementAlertResolver) do |resolver|
+ allow(resolver).to receive(:resolve).and_return(alert)
+ end
+
+ allow(alert).to receive(:save).and_return(false)
+ allow(alert).to receive(:errors).and_return(
+ double(full_messages: %w(foo bar))
+ )
+ expect(resolve).to eq(
+ alert: alert,
+ errors: ['foo and bar']
+ )
+ end
+
+ context 'invalid status given' do
+ let(:new_status) { 'invalid_status' }
+
+ it 'returns the alert with errors' do
+ expect(resolve).to eq(
+ alert: alert,
+ errors: [_('Invalid status')]
+ )
+ end
+ end
+ end
+ end
+
+ it 'raises an error if the resource is not accessible to the user' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ private
+
+ def mutation_for(project, user)
+ described_class.new(object: project, context: { current_user: user }, field: nil)
+ end
+end
diff --git a/spec/graphql/mutations/branches/create_spec.rb b/spec/graphql/mutations/branches/create_spec.rb
new file mode 100644
index 00000000000..744f8f1f2bc
--- /dev/null
+++ b/spec/graphql/mutations/branches/create_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Mutations::Branches::Create do
+ subject(:mutation) { described_class.new(object: nil, context: context, field: nil) }
+
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:context) do
+ GraphQL::Query::Context.new(
+ query: OpenStruct.new(schema: nil),
+ values: { current_user: user },
+ object: nil
+ )
+ end
+
+ describe '#resolve' do
+ subject { mutation.resolve(project_path: project.full_path, name: branch, ref: ref) }
+
+ let(:branch) { 'new_branch' }
+ let(:ref) { 'master' }
+ let(:mutated_branch) { subject[:branch] }
+
+ it 'raises an error if the resource is not accessible to the user' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+
+ context 'when the user can create a branch' do
+ before do
+ project.add_developer(user)
+
+ allow_next_instance_of(::Branches::CreateService, project, user) do |create_service|
+ allow(create_service).to receive(:execute).with(branch, ref) { service_result }
+ end
+ end
+
+ context 'when service successfully creates a new branch' do
+ let(:service_result) { { status: :success, branch: double(name: branch) } }
+
+ it 'returns a new branch' do
+ expect(mutated_branch.name).to eq(branch)
+ expect(subject[:errors]).to be_empty
+ end
+ end
+
+ context 'when service fails to create a new branch' do
+ let(:service_result) { { status: :error, message: 'Branch already exists' } }
+
+ it { expect(mutated_branch).to be_nil }
+ it { expect(subject[:errors]).to eq(['Branch already exists']) }
+ end
+ end
+ end
+end
diff --git a/spec/graphql/mutations/design_management/delete_spec.rb b/spec/graphql/mutations/design_management/delete_spec.rb
new file mode 100644
index 00000000000..60be6dad62a
--- /dev/null
+++ b/spec/graphql/mutations/design_management/delete_spec.rb
@@ -0,0 +1,145 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Mutations::DesignManagement::Delete do
+ include DesignManagementTestHelpers
+
+ let(:issue) { create(:issue) }
+ let(:current_designs) { issue.designs.current }
+ let(:user) { issue.author }
+ let(:project) { issue.project }
+ let(:design_a) { create(:design, :with_file, issue: issue) }
+ let(:design_b) { create(:design, :with_file, issue: issue) }
+ let(:design_c) { create(:design, :with_file, issue: issue) }
+ let(:filenames) { [design_a, design_b, design_c].map(&:filename) }
+
+ let(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+
+ before do
+ stub_const('Errors', Gitlab::Graphql::Errors, transfer_nested_constants: true)
+ end
+
+ def run_mutation
+ mutation = described_class.new(object: nil, context: { current_user: user }, field: nil)
+ mutation.resolve(project_path: project.full_path, iid: issue.iid, filenames: filenames)
+ end
+
+ describe '#resolve' do
+ let(:expected_response) do
+ { errors: [], version: DesignManagement::Version.for_issue(issue).ordered.first }
+ end
+
+ shared_examples "failures" do |error: Gitlab::Graphql::Errors::ResourceNotAvailable|
+ it "raises #{error.name}" do
+ expect { run_mutation }.to raise_error(error)
+ end
+ end
+
+ shared_examples "resource not available" do
+ it_behaves_like "failures"
+ end
+
+ context "when the feature is not available" do
+ before do
+ enable_design_management(false)
+ end
+
+ it_behaves_like "resource not available"
+ end
+
+ context "when the feature is available" do
+ before do
+ enable_design_management(true)
+ end
+
+ context "when the user is not allowed to delete designs" do
+ let(:user) { create(:user) }
+
+ it_behaves_like "resource not available"
+ end
+
+ context 'deleting an already deleted file' do
+ before do
+ run_mutation
+ end
+
+ it 'fails with an argument error' do
+ expect { run_mutation }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ end
+ end
+
+ context "when deleting all the designs" do
+ let(:response) { run_mutation }
+
+ it "returns a new version, and no errors" do
+ expect(response).to include(expected_response)
+ end
+
+ describe 'the current designs' do
+ before do
+ run_mutation
+ end
+
+ it 'is empty' do
+ expect(current_designs).to be_empty
+ end
+ end
+
+ it 'runs no more than 28 queries' do
+ filenames.each(&:present?) # ignore setup
+ # Queries: as of 2019-08-28
+ # -------------
+ # 01. routing query
+ # 02. find project by id
+ # 03. project.project_features
+ # 04. find namespace by id and type
+ # 05,06. project.authorizations for user (same query twice)
+ # 07. find issue by iid
+ # 08. find project by id
+ # 09. find namespace by id
+ # 10. find group namespace by id
+ # 11. project.authorizations for user (same query as 5)
+ # 12. project.project_features (same query as 3)
+ # 13. project.authorizations for user (same query as 5)
+ # 14. current designs by filename and issue
+ # 15, 16 project.authorizations for user (same query as 5)
+ # 17. find route by id and source_type
+ # ------------- our queries are below:
+ # 18. start transaction 1
+ # 19. start transaction 2
+ # 20. find version by sha and issue
+ # 21. exists version with sha and issue?
+ # 22. leave transaction 2
+ # 23. create version with sha and issue
+ # 24. create design-version links
+ # 25. validate version.actions.present?
+ # 26. validate version.issue.present?
+ # 27. validate version.sha is unique
+ # 28. leave transaction 1
+ #
+ expect { run_mutation }.not_to exceed_query_limit(28)
+ end
+ end
+
+ context "when deleting a design" do
+ let(:filenames) { [design_a.filename] }
+ let(:response) { run_mutation }
+
+ it "returns the expected response" do
+ expect(response).to include(expected_response)
+ end
+
+ describe 'the current designs' do
+ before do
+ run_mutation
+ end
+
+ it 'does contain designs b and c' do
+ expect(current_designs).to contain_exactly(design_b, design_c)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/mutations/design_management/upload_spec.rb b/spec/graphql/mutations/design_management/upload_spec.rb
new file mode 100644
index 00000000000..783af70448c
--- /dev/null
+++ b/spec/graphql/mutations/design_management/upload_spec.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+describe Mutations::DesignManagement::Upload do
+ include DesignManagementTestHelpers
+ include ConcurrentHelpers
+
+ let(:issue) { create(:issue) }
+ let(:user) { issue.author }
+ let(:project) { issue.project }
+
+ subject(:mutation) do
+ described_class.new(object: nil, context: { current_user: user }, field: nil)
+ end
+
+ def run_mutation(files_to_upload = files, project_path = project.full_path, iid = issue.iid)
+ mutation = described_class.new(object: nil, context: { current_user: user }, field: nil)
+ mutation.resolve(project_path: project_path, iid: iid, files: files_to_upload)
+ end
+
+ describe "#resolve" do
+ let(:files) { [fixture_file_upload('spec/fixtures/dk.png')] }
+
+ subject(:resolve) do
+ mutation.resolve(project_path: project.full_path, iid: issue.iid, files: files)
+ end
+
+ shared_examples "resource not available" do
+ it "raises an error" do
+ expect { resolve }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context "when the feature is not available" do
+ it_behaves_like "resource not available"
+ end
+
+ context "when the feature is available" do
+ before do
+ enable_design_management
+ end
+
+ describe 'contention in the design repo' do
+ before do
+ issue.design_collection.repository.create_if_not_exists
+ end
+
+ let(:files) do
+ ['dk.png', 'rails_sample.jpg', 'banana_sample.gif']
+ .cycle
+ .take(Concurrent.processor_count * 2)
+ .map { |f| RenameableUpload.unique_file(f) }
+ end
+
+ def creates_designs
+ prior_count = DesignManagement::Design.count
+
+ expect { yield }.not_to raise_error
+
+ expect(DesignManagement::Design.count).to eq(prior_count + files.size)
+ end
+
+ describe 'running requests in parallel' do
+ it 'does not cause errors' do
+ creates_designs do
+ run_parallel(files.map { |f| -> { run_mutation([f]) } })
+ end
+ end
+ end
+
+ describe 'running requests in parallel on different issues' do
+ it 'does not cause errors' do
+ creates_designs do
+ issues = create_list(:issue, files.size, author: user)
+ issues.each { |i| i.project.add_developer(user) }
+ blocks = files.zip(issues).map do |(f, i)|
+ -> { run_mutation([f], i.project.full_path, i.iid) }
+ end
+
+ run_parallel(blocks)
+ end
+ end
+ end
+
+ describe 'running requests in serial' do
+ it 'does not cause errors' do
+ creates_designs do
+ files.each do |f|
+ run_mutation([f])
+ end
+ end
+ end
+ end
+ end
+
+ context "when the user is not allowed to upload designs" do
+ let(:user) { create(:user) }
+
+ it_behaves_like "resource not available"
+ end
+
+ context "a valid design" do
+ it "returns the updated designs" do
+ expect(resolve[:errors]).to eq []
+ expect(resolve[:designs].map(&:filename)).to contain_exactly("dk.png")
+ end
+ end
+
+ context "context when passing an invalid project" do
+ let(:project) { build(:project) }
+
+ it_behaves_like "resource not available"
+ end
+
+ context "context when passing an invalid issue" do
+ let(:issue) { build(:issue) }
+
+ it_behaves_like "resource not available"
+ end
+
+ context "when creating designs causes errors" do
+ before do
+ fake_service = double(::DesignManagement::SaveDesignsService)
+
+ allow(fake_service).to receive(:execute).and_return(status: :error, message: "Something failed")
+ allow(::DesignManagement::SaveDesignsService).to receive(:new).and_return(fake_service)
+ end
+
+ it "wraps the errors" do
+ expect(resolve[:errors]).to eq(["Something failed"])
+ expect(resolve[:designs]).to eq([])
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/mutations/issues/set_confidential_spec.rb b/spec/graphql/mutations/issues/set_confidential_spec.rb
index 6031953c869..c90ce2658d6 100644
--- a/spec/graphql/mutations/issues/set_confidential_spec.rb
+++ b/spec/graphql/mutations/issues/set_confidential_spec.rb
@@ -8,6 +8,8 @@ describe Mutations::Issues::SetConfidential do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_issue) }
+
describe '#resolve' do
let(:confidential) { true }
let(:mutated_issue) { subject[:issue] }
diff --git a/spec/graphql/mutations/issues/set_due_date_spec.rb b/spec/graphql/mutations/issues/set_due_date_spec.rb
index 73ba11fc551..84df6fce7c7 100644
--- a/spec/graphql/mutations/issues/set_due_date_spec.rb
+++ b/spec/graphql/mutations/issues/set_due_date_spec.rb
@@ -8,6 +8,8 @@ describe Mutations::Issues::SetDueDate do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_issue) }
+
describe '#resolve' do
let(:due_date) { 2.days.since }
let(:mutated_issue) { subject[:issue] }
diff --git a/spec/graphql/mutations/issues/update_spec.rb b/spec/graphql/mutations/issues/update_spec.rb
index da286bb4092..8c3d01918fd 100644
--- a/spec/graphql/mutations/issues/update_spec.rb
+++ b/spec/graphql/mutations/issues/update_spec.rb
@@ -16,6 +16,8 @@ describe Mutations::Issues::Update do
let(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
let(:mutated_issue) { subject[:issue] }
+ specify { expect(described_class).to require_graphql_authorizations(:update_issue) }
+
describe '#resolve' do
let(:mutation_params) do
{
diff --git a/spec/graphql/mutations/merge_requests/set_labels_spec.rb b/spec/graphql/mutations/merge_requests/set_labels_spec.rb
index f58f35eb6f3..0fd2c20a5c8 100644
--- a/spec/graphql/mutations/merge_requests/set_labels_spec.rb
+++ b/spec/graphql/mutations/merge_requests/set_labels_spec.rb
@@ -8,6 +8,8 @@ describe Mutations::MergeRequests::SetLabels do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_merge_request) }
+
describe '#resolve' do
let(:label) { create(:label, project: merge_request.project) }
let(:label2) { create(:label, project: merge_request.project) }
diff --git a/spec/graphql/mutations/merge_requests/set_locked_spec.rb b/spec/graphql/mutations/merge_requests/set_locked_spec.rb
index 12ae1314f22..d5219c781fd 100644
--- a/spec/graphql/mutations/merge_requests/set_locked_spec.rb
+++ b/spec/graphql/mutations/merge_requests/set_locked_spec.rb
@@ -8,6 +8,8 @@ describe Mutations::MergeRequests::SetLocked do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_merge_request) }
+
describe '#resolve' do
let(:locked) { true }
let(:mutated_merge_request) { subject[:merge_request] }
diff --git a/spec/graphql/mutations/merge_requests/set_milestone_spec.rb b/spec/graphql/mutations/merge_requests/set_milestone_spec.rb
index ad7f2df0842..d77ec4de4d0 100644
--- a/spec/graphql/mutations/merge_requests/set_milestone_spec.rb
+++ b/spec/graphql/mutations/merge_requests/set_milestone_spec.rb
@@ -8,6 +8,8 @@ describe Mutations::MergeRequests::SetMilestone do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_merge_request) }
+
describe '#resolve' do
let(:milestone) { create(:milestone, project: merge_request.project) }
let(:mutated_merge_request) { subject[:merge_request] }
diff --git a/spec/graphql/mutations/merge_requests/set_subscription_spec.rb b/spec/graphql/mutations/merge_requests/set_subscription_spec.rb
index a28bab363f3..cf569a74aa9 100644
--- a/spec/graphql/mutations/merge_requests/set_subscription_spec.rb
+++ b/spec/graphql/mutations/merge_requests/set_subscription_spec.rb
@@ -9,6 +9,8 @@ describe Mutations::MergeRequests::SetSubscription do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_merge_request) }
+
describe '#resolve' do
let(:subscribe) { true }
let(:mutated_merge_request) { subject[:merge_request] }
diff --git a/spec/graphql/mutations/merge_requests/set_wip_spec.rb b/spec/graphql/mutations/merge_requests/set_wip_spec.rb
index 9f0adcf117a..7255d0fe7d7 100644
--- a/spec/graphql/mutations/merge_requests/set_wip_spec.rb
+++ b/spec/graphql/mutations/merge_requests/set_wip_spec.rb
@@ -8,6 +8,8 @@ describe Mutations::MergeRequests::SetWip do
subject(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_merge_request) }
+
describe '#resolve' do
let(:wip) { true }
let(:mutated_merge_request) { subject[:merge_request] }
diff --git a/spec/graphql/mutations/todos/mark_all_done_spec.rb b/spec/graphql/mutations/todos/mark_all_done_spec.rb
index 98b22a3e761..4af00307969 100644
--- a/spec/graphql/mutations/todos/mark_all_done_spec.rb
+++ b/spec/graphql/mutations/todos/mark_all_done_spec.rb
@@ -17,6 +17,8 @@ describe Mutations::Todos::MarkAllDone do
let_it_be(:user3) { create(:user) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_user) }
+
describe '#resolve' do
it 'marks all pending todos as done' do
updated_todo_ids = mutation_for(current_user).resolve.dig(:updated_ids)
diff --git a/spec/graphql/mutations/todos/mark_done_spec.rb b/spec/graphql/mutations/todos/mark_done_spec.rb
index 059ef3c8eee..44065f83f74 100644
--- a/spec/graphql/mutations/todos/mark_done_spec.rb
+++ b/spec/graphql/mutations/todos/mark_done_spec.rb
@@ -16,6 +16,8 @@ describe Mutations::Todos::MarkDone do
let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_todo) }
+
describe '#resolve' do
it 'marks a single todo as done' do
result = mark_done_mutation(todo1)
diff --git a/spec/graphql/mutations/todos/restore_spec.rb b/spec/graphql/mutations/todos/restore_spec.rb
index 1637acc2fb5..949ab6a164b 100644
--- a/spec/graphql/mutations/todos/restore_spec.rb
+++ b/spec/graphql/mutations/todos/restore_spec.rb
@@ -14,6 +14,8 @@ describe Mutations::Todos::Restore do
let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
+ specify { expect(described_class).to require_graphql_authorizations(:update_todo) }
+
describe '#resolve' do
it 'restores a single todo' do
result = restore_mutation(todo1)
diff --git a/spec/graphql/resolvers/alert_management/alert_status_counts_resolver_spec.rb b/spec/graphql/resolvers/alert_management/alert_status_counts_resolver_spec.rb
new file mode 100644
index 00000000000..8eb28c8c945
--- /dev/null
+++ b/spec/graphql/resolvers/alert_management/alert_status_counts_resolver_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::AlertManagement::AlertStatusCountsResolver do
+ include GraphqlHelpers
+
+ describe '#resolve' do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let(:args) { {} }
+
+ subject { resolve_alert_status_counts(args) }
+
+ it { is_expected.to be_a(Gitlab::AlertManagement::AlertStatusCounts) }
+ specify { expect(subject.project).to eq(project) }
+
+ private
+
+ def resolve_alert_status_counts(args = {}, context = { current_user: current_user })
+ resolve(described_class, obj: project, args: args, ctx: context)
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/alert_management_alert_resolver_spec.rb b/spec/graphql/resolvers/alert_management_alert_resolver_spec.rb
new file mode 100644
index 00000000000..971a81a826d
--- /dev/null
+++ b/spec/graphql/resolvers/alert_management_alert_resolver_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::AlertManagementAlertResolver do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:alert_1) { create(:alert_management_alert, :resolved, project: project, ended_at: 1.year.ago, events: 2, severity: :high) }
+ let_it_be(:alert_2) { create(:alert_management_alert, :ignored, project: project, events: 1, severity: :critical) }
+ let_it_be(:alert_other_proj) { create(:alert_management_alert) }
+
+ let(:args) { {} }
+
+ subject { resolve_alerts(args) }
+
+ context 'user does not have permission' do
+ it { is_expected.to eq(AlertManagement::Alert.none) }
+ end
+
+ context 'user has permission' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ it { is_expected.to contain_exactly(alert_1, alert_2) }
+
+ context 'finding by iid' do
+ let(:args) { { iid: alert_1.iid } }
+
+ it { is_expected.to contain_exactly(alert_1) }
+ end
+
+ context 'finding by status' do
+ let(:args) { { status: [Types::AlertManagement::StatusEnum.values['IGNORED'].value] } }
+
+ it { is_expected.to contain_exactly(alert_2) }
+ end
+
+ describe 'sorting' do
+ # Other sorting examples in spec/finders/alert_management/alerts_finder_spec.rb
+ context 'when sorting by events count' do
+ let_it_be(:alert_count_6) { create(:alert_management_alert, project: project, events: 6) }
+ let_it_be(:alert_count_3) { create(:alert_management_alert, project: project, events: 3) }
+
+ it 'sorts alerts ascending' do
+ expect(resolve_alerts(sort: :events_count_asc)).to eq [alert_2, alert_1, alert_count_3, alert_count_6]
+ end
+
+ it 'sorts alerts descending' do
+ expect(resolve_alerts(sort: :events_count_desc)).to eq [alert_count_6, alert_count_3, alert_1, alert_2]
+ end
+ end
+ end
+ end
+
+ private
+
+ def resolve_alerts(args = {}, context = { current_user: current_user })
+ resolve(described_class, obj: project, args: args, ctx: context)
+ end
+end
diff --git a/spec/graphql/resolvers/board_lists_resolver_spec.rb b/spec/graphql/resolvers/board_lists_resolver_spec.rb
new file mode 100644
index 00000000000..5f6c440a8ed
--- /dev/null
+++ b/spec/graphql/resolvers/board_lists_resolver_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::BoardListsResolver do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:unauth_user) { create(:user) }
+ let_it_be(:project) { create(:project, creator_id: user.id, namespace: user.namespace ) }
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:project_label) { create(:label, project: project, name: 'Development') }
+ let_it_be(:group_label) { create(:group_label, group: group, name: 'Development') }
+
+ shared_examples_for 'group and project board lists resolver' do
+ let(:board) { create(:board, resource_parent: board_parent) }
+
+ before do
+ board_parent.add_developer(user)
+ end
+
+ it 'does not create the backlog list' do
+ lists = resolve_board_lists.items
+
+ expect(lists.count).to eq 1
+ expect(lists[0].list_type).to eq 'closed'
+ end
+
+ context 'with unauthorized user' do
+ it 'raises an error' do
+ expect do
+ resolve_board_lists(current_user: unauth_user)
+ end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when authorized' do
+ let!(:label_list) { create(:list, board: board, label: label) }
+ let!(:backlog_list) { create(:backlog_list, board: board) }
+
+ it 'returns a list of board lists' do
+ lists = resolve_board_lists.items
+
+ expect(lists.count).to eq 3
+ expect(lists.map(&:list_type)).to eq %w(backlog label closed)
+ end
+
+ context 'when another user has list preferences' do
+ before do
+ board.lists.first.update_preferences_for(guest, collapsed: true)
+ end
+
+ it 'returns the complete list of board lists for this user' do
+ lists = resolve_board_lists.items
+
+ expect(lists.count).to eq 3
+ end
+ end
+ end
+ end
+
+ describe '#resolve' do
+ context 'when project boards' do
+ let(:board_parent) { project }
+ let(:label) { project_label }
+
+ it_behaves_like 'group and project board lists resolver'
+ end
+
+ context 'when group boards' do
+ let(:board_parent) { group }
+ let(:label) { group_label }
+
+ it_behaves_like 'group and project board lists resolver'
+ end
+ end
+
+ def resolve_board_lists(args: {}, current_user: user)
+ resolve(described_class, obj: board, args: args, ctx: { current_user: current_user })
+ end
+end
diff --git a/spec/graphql/resolvers/branch_commit_resolver_spec.rb b/spec/graphql/resolvers/branch_commit_resolver_spec.rb
new file mode 100644
index 00000000000..22e1de8f375
--- /dev/null
+++ b/spec/graphql/resolvers/branch_commit_resolver_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::BranchCommitResolver do
+ include GraphqlHelpers
+
+ subject(:commit) { resolve(described_class, obj: branch) }
+
+ let_it_be(:repository) { create(:project, :repository).repository }
+ let(:branch) { repository.find_branch('master') }
+
+ describe '#resolve' do
+ it 'resolves commit' do
+ is_expected.to eq(repository.commits('master', limit: 1).last)
+ end
+
+ context 'when branch does not exist' do
+ let(:branch) { nil }
+
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb b/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
new file mode 100644
index 00000000000..a5054ae3ebf
--- /dev/null
+++ b/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::DesignManagement::DesignAtVersionResolver do
+ include GraphqlHelpers
+ include DesignManagementTestHelpers
+
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:project) { issue.project }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:design_a) { create(:design, issue: issue) }
+ let_it_be(:version_a) { create(:design_version, issue: issue, created_designs: [design_a]) }
+
+ let(:current_user) { user }
+ let(:object) { issue.design_collection }
+ let(:global_id) { GitlabSchema.id_from_object(design_at_version).to_s }
+
+ let(:design_at_version) { ::DesignManagement::DesignAtVersion.new(design: design_a, version: version_a) }
+
+ let(:resource_not_available) { ::Gitlab::Graphql::Errors::ResourceNotAvailable }
+
+ before do
+ enable_design_management
+ project.add_developer(user)
+ end
+
+ describe '#resolve' do
+ context 'when the user cannot see designs' do
+ let(:current_user) { create(:user) }
+
+ it 'raises ResourceNotAvailable' do
+ expect { resolve_design }.to raise_error(resource_not_available)
+ end
+ end
+
+ it 'returns the specified design' do
+ expect(resolve_design).to eq(design_at_version)
+ end
+
+ context 'the ID belongs to a design on another issue' do
+ let(:other_dav) do
+ create(:design_at_version, issue: create(:issue, project: project))
+ end
+
+ let(:global_id) { global_id_of(other_dav) }
+
+ it 'raises ResourceNotAvailable' do
+ expect { resolve_design }.to raise_error(resource_not_available)
+ end
+
+ context 'the current object does not constrain the issue' do
+ let(:object) { nil }
+
+ it 'returns the object' do
+ expect(resolve_design).to eq(other_dav)
+ end
+ end
+ end
+ end
+
+ private
+
+ def resolve_design
+ args = { id: global_id }
+ ctx = { current_user: current_user }
+ eager_resolve(described_class, obj: object, args: args, ctx: ctx)
+ end
+end
diff --git a/spec/graphql/resolvers/design_management/design_resolver_spec.rb b/spec/graphql/resolvers/design_management/design_resolver_spec.rb
new file mode 100644
index 00000000000..857acc3d371
--- /dev/null
+++ b/spec/graphql/resolvers/design_management/design_resolver_spec.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::DesignManagement::DesignResolver do
+ include GraphqlHelpers
+ include DesignManagementTestHelpers
+
+ before do
+ enable_design_management
+ end
+
+ describe '#resolve' do
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:project) { issue.project }
+ let_it_be(:first_version) { create(:design_version) }
+ let_it_be(:first_design) { create(:design, issue: issue, versions: [first_version]) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:design_on_other_issue) do
+ create(:design, issue: create(:issue, project: project), versions: [create(:design_version)])
+ end
+
+ let(:args) { { id: GitlabSchema.id_from_object(first_design).to_s } }
+ let(:gql_context) { { current_user: current_user } }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ context 'when the user cannot see designs' do
+ let(:gql_context) { { current_user: create(:user) } }
+
+ it 'returns nothing' do
+ expect(resolve_design).to be_nil
+ end
+ end
+
+ context 'when no argument has been passed' do
+ let(:args) { {} }
+
+ it 'raises an error' do
+ expect { resolve_design }.to raise_error(::Gitlab::Graphql::Errors::ArgumentError, /must/)
+ end
+ end
+
+ context 'when both arguments have been passed' do
+ let(:args) { { filename: first_design.filename, id: GitlabSchema.id_from_object(first_design).to_s } }
+
+ it 'raises an error' do
+ expect { resolve_design }.to raise_error(::Gitlab::Graphql::Errors::ArgumentError, /may/)
+ end
+ end
+
+ context 'by ID' do
+ it 'returns the specified design' do
+ expect(resolve_design).to eq(first_design)
+ end
+
+ context 'the ID belongs to a design on another issue' do
+ let(:args) { { id: GitlabSchema.id_from_object(design_on_other_issue).to_s } }
+
+ it 'returns nothing' do
+ expect(resolve_design).to be_nil
+ end
+ end
+ end
+
+ context 'by filename' do
+ let(:args) { { filename: first_design.filename } }
+
+ it 'returns the specified design' do
+ expect(resolve_design).to eq(first_design)
+ end
+
+ context 'the filename belongs to a design on another issue' do
+ let(:args) { { filename: design_on_other_issue.filename } }
+
+ it 'returns nothing' do
+ expect(resolve_design).to be_nil
+ end
+ end
+ end
+ end
+
+ def resolve_design
+ resolve(described_class, obj: issue.design_collection, args: args, ctx: gql_context)
+ end
+end
diff --git a/spec/graphql/resolvers/design_management/designs_resolver_spec.rb b/spec/graphql/resolvers/design_management/designs_resolver_spec.rb
new file mode 100644
index 00000000000..28fc9e2151d
--- /dev/null
+++ b/spec/graphql/resolvers/design_management/designs_resolver_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::DesignManagement::DesignsResolver do
+ include GraphqlHelpers
+ include DesignManagementTestHelpers
+
+ before do
+ enable_design_management
+ end
+
+ describe '#resolve' do
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:project) { issue.project }
+ let_it_be(:first_version) { create(:design_version) }
+ let_it_be(:first_design) { create(:design, issue: issue, versions: [first_version]) }
+ let_it_be(:current_user) { create(:user) }
+ let(:gql_context) { { current_user: current_user } }
+ let(:args) { {} }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ context 'when the user cannot see designs' do
+ let(:gql_context) { { current_user: create(:user) } }
+
+ it 'returns nothing' do
+ expect(resolve_designs).to be_empty
+ end
+ end
+
+ context 'for a design collection' do
+ context 'which contains just a single design' do
+ it 'returns just that design' do
+ expect(resolve_designs).to contain_exactly(first_design)
+ end
+ end
+
+ context 'which contains another design' do
+ it 'returns all designs' do
+ second_version = create(:design_version)
+ second_design = create(:design, issue: issue, versions: [second_version])
+
+ expect(resolve_designs).to contain_exactly(first_design, second_design)
+ end
+ end
+ end
+
+ describe 'filtering' do
+ describe 'by filename' do
+ let(:second_version) { create(:design_version) }
+ let(:second_design) { create(:design, issue: issue, versions: [second_version]) }
+ let(:args) { { filenames: [second_design.filename] } }
+
+ it 'resolves to just the relevant design, ignoring designs with the same filename on different issues' do
+ create(:design, issue: create(:issue, project: project), filename: second_design.filename)
+
+ expect(resolve_designs).to contain_exactly(second_design)
+ end
+ end
+
+ describe 'by id' do
+ let(:second_version) { create(:design_version) }
+ let(:second_design) { create(:design, issue: issue, versions: [second_version]) }
+
+ context 'the ID is on the current issue' do
+ let(:args) { { ids: [GitlabSchema.id_from_object(second_design).to_s] } }
+
+ it 'resolves to just the relevant design' do
+ expect(resolve_designs).to contain_exactly(second_design)
+ end
+ end
+
+ context 'the ID is on a different issue' do
+ let(:third_version) { create(:design_version) }
+ let(:third_design) { create(:design, issue: create(:issue, project: project), versions: [third_version]) }
+
+ let(:args) { { ids: [GitlabSchema.id_from_object(third_design).to_s] } }
+
+ it 'ignores it' do
+ expect(resolve_designs).to be_empty
+ end
+ end
+ end
+ end
+ end
+
+ def resolve_designs
+ resolve(described_class, obj: issue.design_collection, args: args, ctx: gql_context)
+ end
+end
diff --git a/spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb b/spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb
new file mode 100644
index 00000000000..cc9c0436885
--- /dev/null
+++ b/spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::DesignManagement::Version::DesignAtVersionResolver do
+ include GraphqlHelpers
+
+ include_context 'four designs in three versions'
+
+ let(:current_user) { authorized_user }
+ let(:gql_context) { { current_user: current_user } }
+
+ let(:version) { third_version }
+ let(:design) { design_a }
+
+ let(:all_singular_args) do
+ {
+ design_at_version_id: global_id_of(dav(design)),
+ design_id: global_id_of(design),
+ filename: design.filename
+ }
+ end
+
+ shared_examples 'a bad argument' do
+ let(:err_class) { ::Gitlab::Graphql::Errors::ArgumentError }
+
+ it 'raises an appropriate error' do
+ expect { resolve_objects }.to raise_error(err_class)
+ end
+ end
+
+ describe '#resolve' do
+ describe 'passing combinations of arguments' do
+ context 'passing no arguments' do
+ let(:args) { {} }
+
+ it_behaves_like 'a bad argument'
+ end
+
+ context 'passing all arguments' do
+ let(:args) { all_singular_args }
+
+ it_behaves_like 'a bad argument'
+ end
+
+ context 'passing any two arguments' do
+ let(:args) { all_singular_args.slice(*all_singular_args.keys.sample(2)) }
+
+ it_behaves_like 'a bad argument'
+ end
+ end
+
+ %i[design_at_version_id design_id filename].each do |arg|
+ describe "passing #{arg}" do
+ let(:args) { all_singular_args.slice(arg) }
+
+ it 'finds the design' do
+ expect(resolve_objects).to eq(dav(design))
+ end
+
+ context 'when the user cannot see designs' do
+ let(:current_user) { create(:user) }
+
+ it 'returns nothing' do
+ expect(resolve_objects).to be_nil
+ end
+ end
+ end
+ end
+
+ describe 'attempting to retrieve an object not visible at this version' do
+ let(:design) { design_d }
+
+ %i[design_at_version_id design_id filename].each do |arg|
+ describe "passing #{arg}" do
+ let(:args) { all_singular_args.slice(arg) }
+
+ it 'does not find the design' do
+ expect(resolve_objects).to be_nil
+ end
+ end
+ end
+ end
+ end
+
+ def resolve_objects
+ resolve(described_class, obj: version, args: args, ctx: gql_context)
+ end
+
+ def dav(design)
+ build(:design_at_version, design: design, version: version)
+ end
+end
diff --git a/spec/graphql/resolvers/design_management/version/designs_at_version_resolver_spec.rb b/spec/graphql/resolvers/design_management/version/designs_at_version_resolver_spec.rb
new file mode 100644
index 00000000000..123b26862d0
--- /dev/null
+++ b/spec/graphql/resolvers/design_management/version/designs_at_version_resolver_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::DesignManagement::Version::DesignsAtVersionResolver do
+ include GraphqlHelpers
+
+ include_context 'four designs in three versions'
+
+ let_it_be(:current_user) { authorized_user }
+ let(:gql_context) { { current_user: current_user } }
+
+ let(:version) { third_version }
+
+ describe '.single' do
+ let(:single) { ::Resolvers::DesignManagement::Version::DesignAtVersionResolver }
+
+ it 'returns the single context resolver' do
+ expect(described_class.single).to eq(single)
+ end
+ end
+
+ describe '#resolve' do
+ let(:args) { {} }
+
+ context 'when the user cannot see designs' do
+ let(:current_user) { create(:user) }
+
+ it 'returns nothing' do
+ expect(resolve_objects).to be_empty
+ end
+ end
+
+ context 'for the current version' do
+ it 'returns all designs visible at that version' do
+ expect(resolve_objects).to contain_exactly(dav(design_a), dav(design_b), dav(design_c))
+ end
+ end
+
+ context 'for a previous version with more objects' do
+ let(:version) { second_version }
+
+ it 'returns objects that were later deleted' do
+ expect(resolve_objects).to contain_exactly(dav(design_a), dav(design_b), dav(design_c), dav(design_d))
+ end
+ end
+
+ context 'for a previous version with fewer objects' do
+ let(:version) { first_version }
+
+ it 'does not return objects that were later created' do
+ expect(resolve_objects).to contain_exactly(dav(design_a))
+ end
+ end
+
+ describe 'filtering' do
+ describe 'by filename' do
+ let(:red_herring) { create(:design, issue: create(:issue, project: project)) }
+ let(:args) { { filenames: [design_b.filename, red_herring.filename] } }
+
+ it 'resolves to just the relevant design' do
+ create(:design, issue: create(:issue, project: project), filename: design_b.filename)
+
+ expect(resolve_objects).to contain_exactly(dav(design_b))
+ end
+ end
+
+ describe 'by id' do
+ let(:red_herring) { create(:design, issue: create(:issue, project: project)) }
+ let(:args) { { ids: [design_a, red_herring].map { |x| global_id_of(x) } } }
+
+ it 'resolves to just the relevant design, ignoring objects on other issues' do
+ expect(resolve_objects).to contain_exactly(dav(design_a))
+ end
+ end
+ end
+ end
+
+ def resolve_objects
+ resolve(described_class, obj: version, args: args, ctx: gql_context)
+ end
+
+ def dav(design)
+ build(:design_at_version, design: design, version: version)
+ end
+end
diff --git a/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb b/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb
new file mode 100644
index 00000000000..ef50598d241
--- /dev/null
+++ b/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::DesignManagement::VersionInCollectionResolver do
+ include GraphqlHelpers
+ include DesignManagementTestHelpers
+
+ let(:resolver) { described_class }
+
+ describe '#resolve' do
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:first_version) { create(:design_version, issue: issue) }
+
+ let(:project) { issue.project }
+ let(:params) { {} }
+
+ before do
+ enable_design_management
+ project.add_developer(current_user)
+ end
+
+ let(:appropriate_error) { ::Gitlab::Graphql::Errors::ArgumentError }
+
+ subject(:result) { resolve_version(issue.design_collection) }
+
+ context 'Neither id nor sha is passed as parameters' do
+ it 'raises an appropriate error' do
+ expect { result }.to raise_error(appropriate_error)
+ end
+ end
+
+ context 'we pass an id' do
+ let(:params) { { id: global_id_of(first_version) } }
+
+ it { is_expected.to eq(first_version) }
+ end
+
+ context 'we pass a sha' do
+ let(:params) { { sha: first_version.sha } }
+
+ it { is_expected.to eq(first_version) }
+ end
+
+ context 'we pass an inconsistent mixture of sha and version id' do
+ let(:params) { { sha: first_version.sha, id: global_id_of(create(:design_version)) } }
+
+ it { is_expected.to be_nil }
+ end
+
+ context 'we pass the id of something that is not a design_version' do
+ let(:params) { { id: global_id_of(project) } }
+
+ it 'raises an appropriate error' do
+ expect { result }.to raise_error(appropriate_error)
+ end
+ end
+ end
+
+ def resolve_version(obj, context = { current_user: current_user })
+ resolve(resolver, obj: obj, args: params, ctx: context)
+ end
+end
diff --git a/spec/graphql/resolvers/design_management/version_resolver_spec.rb b/spec/graphql/resolvers/design_management/version_resolver_spec.rb
new file mode 100644
index 00000000000..e7c09351204
--- /dev/null
+++ b/spec/graphql/resolvers/design_management/version_resolver_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::DesignManagement::VersionResolver do
+ include GraphqlHelpers
+ include DesignManagementTestHelpers
+
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:version) { create(:design_version, issue: issue) }
+ let_it_be(:developer) { create(:user) }
+
+ let(:project) { issue.project }
+ let(:params) { { id: global_id_of(version) } }
+
+ before do
+ enable_design_management
+ project.add_developer(developer)
+ end
+
+ context 'the current user is not authorized' do
+ let(:current_user) { create(:user) }
+
+ it 'raises an error on resolution' do
+ expect { resolve_version }.to raise_error(::Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'the current user is authorized' do
+ let(:current_user) { developer }
+
+ context 'the id parameter is provided' do
+ it 'returns the specified version' do
+ expect(resolve_version).to eq(version)
+ end
+ end
+ end
+
+ def resolve_version
+ resolve(described_class, obj: nil, args: params, ctx: { current_user: current_user })
+ end
+end
diff --git a/spec/graphql/resolvers/design_management/versions_resolver_spec.rb b/spec/graphql/resolvers/design_management/versions_resolver_spec.rb
new file mode 100644
index 00000000000..d5bab025e45
--- /dev/null
+++ b/spec/graphql/resolvers/design_management/versions_resolver_spec.rb
@@ -0,0 +1,117 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::DesignManagement::VersionsResolver do
+ include GraphqlHelpers
+ include DesignManagementTestHelpers
+
+ describe '#resolve' do
+ let(:resolver) { described_class }
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:authorized_user) { create(:user) }
+ let_it_be(:first_version) { create(:design_version, issue: issue) }
+ let_it_be(:other_version) { create(:design_version, issue: issue) }
+ let_it_be(:first_design) { create(:design, issue: issue, versions: [first_version, other_version]) }
+ let_it_be(:other_design) { create(:design, :with_versions, issue: issue) }
+
+ let(:project) { issue.project }
+ let(:params) { {} }
+ let(:current_user) { authorized_user }
+ let(:parent_args) { { irrelevant: 1.2 } }
+ let(:parent) { double('Parent', parent: nil, irep_node: double(arguments: parent_args)) }
+
+ before do
+ enable_design_management
+ project.add_developer(authorized_user)
+ end
+
+ shared_examples 'a source of versions' do
+ subject(:result) { resolve_versions(object) }
+
+ let_it_be(:all_versions) { object.versions.ordered }
+
+ context 'when the user is not authorized' do
+ let(:current_user) { create(:user) }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'without constraints' do
+ it 'returns the ordered versions' do
+ expect(result).to eq(all_versions)
+ end
+ end
+
+ context 'when constrained' do
+ let_it_be(:matching) { all_versions.earlier_or_equal_to(first_version) }
+
+ shared_examples 'a query for all_versions up to the first_version' do
+ it { is_expected.to eq(matching) }
+ end
+
+ context 'by earlier_or_equal_to_id' do
+ let(:params) { { id: global_id_of(first_version) } }
+
+ it_behaves_like 'a query for all_versions up to the first_version'
+ end
+
+ context 'by earlier_or_equal_to_sha' do
+ let(:params) { { sha: first_version.sha } }
+
+ it_behaves_like 'a query for all_versions up to the first_version'
+ end
+
+ context 'by earlier_or_equal_to_sha AND earlier_or_equal_to_id' do
+ context 'and they match' do
+ # This usage is rather dumb, but so long as they match, this will
+ # return successfully
+ let(:params) do
+ {
+ sha: first_version.sha,
+ id: global_id_of(first_version)
+ }
+ end
+
+ it_behaves_like 'a query for all_versions up to the first_version'
+ end
+
+ context 'and they do not match' do
+ let(:params) do
+ {
+ sha: first_version.sha,
+ id: global_id_of(other_version)
+ }
+ end
+
+ it 'raises a suitable error' do
+ expect { result }.to raise_error(GraphQL::ExecutionError)
+ end
+ end
+ end
+
+ context 'by at_version in parent' do
+ let(:parent_args) { { atVersion: global_id_of(first_version) } }
+
+ it_behaves_like 'a query for all_versions up to the first_version'
+ end
+ end
+ end
+
+ describe 'a design collection' do
+ let_it_be(:object) { DesignManagement::DesignCollection.new(issue) }
+
+ it_behaves_like 'a source of versions'
+ end
+
+ describe 'a design' do
+ let_it_be(:object) { first_design }
+
+ it_behaves_like 'a source of versions'
+ end
+
+ def resolve_versions(obj, context = { current_user: current_user })
+ eager_resolve(resolver, obj: obj, args: params.merge(parent: parent), ctx: context)
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb
index 53e0a9e3724..b7cc9bc6d71 100644
--- a/spec/graphql/resolvers/issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/issues_resolver_spec.rb
@@ -125,12 +125,11 @@ describe Resolvers::IssuesResolver do
end
context 'when sorting by due date' do
- let(:project) { create(:project) }
-
- let!(:due_issue1) { create(:issue, project: project, due_date: 3.days.from_now) }
- let!(:due_issue2) { create(:issue, project: project, due_date: nil) }
- let!(:due_issue3) { create(:issue, project: project, due_date: 2.days.ago) }
- let!(:due_issue4) { create(:issue, project: project, due_date: nil) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:due_issue1) { create(:issue, project: project, due_date: 3.days.from_now) }
+ let_it_be(:due_issue2) { create(:issue, project: project, due_date: nil) }
+ let_it_be(:due_issue3) { create(:issue, project: project, due_date: 2.days.ago) }
+ let_it_be(:due_issue4) { create(:issue, project: project, due_date: nil) }
it 'sorts issues ascending' do
expect(resolve_issues(sort: :due_date_asc)).to eq [due_issue3, due_issue1, due_issue4, due_issue2]
@@ -142,17 +141,72 @@ describe Resolvers::IssuesResolver do
end
context 'when sorting by relative position' do
- let(:project) { create(:project) }
-
- let!(:relative_issue1) { create(:issue, project: project, relative_position: 2000) }
- let!(:relative_issue2) { create(:issue, project: project, relative_position: nil) }
- let!(:relative_issue3) { create(:issue, project: project, relative_position: 1000) }
- let!(:relative_issue4) { create(:issue, project: project, relative_position: nil) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:relative_issue1) { create(:issue, project: project, relative_position: 2000) }
+ let_it_be(:relative_issue2) { create(:issue, project: project, relative_position: nil) }
+ let_it_be(:relative_issue3) { create(:issue, project: project, relative_position: 1000) }
+ let_it_be(:relative_issue4) { create(:issue, project: project, relative_position: nil) }
it 'sorts issues ascending' do
expect(resolve_issues(sort: :relative_position_asc)).to eq [relative_issue3, relative_issue1, relative_issue4, relative_issue2]
end
end
+
+ context 'when sorting by priority' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:early_milestone) { create(:milestone, project: project, due_date: 10.days.from_now) }
+ let_it_be(:late_milestone) { create(:milestone, project: project, due_date: 30.days.from_now) }
+ let_it_be(:priority_label1) { create(:label, project: project, priority: 1) }
+ let_it_be(:priority_label2) { create(:label, project: project, priority: 5) }
+ let_it_be(:priority_issue1) { create(:issue, project: project, labels: [priority_label1], milestone: late_milestone) }
+ let_it_be(:priority_issue2) { create(:issue, project: project, labels: [priority_label2]) }
+ let_it_be(:priority_issue3) { create(:issue, project: project, milestone: early_milestone) }
+ let_it_be(:priority_issue4) { create(:issue, project: project) }
+
+ it 'sorts issues ascending' do
+ expect(resolve_issues(sort: :priority_asc).items).to eq([priority_issue3, priority_issue1, priority_issue2, priority_issue4])
+ end
+
+ it 'sorts issues descending' do
+ expect(resolve_issues(sort: :priority_desc).items).to eq([priority_issue1, priority_issue3, priority_issue2, priority_issue4])
+ end
+ end
+
+ context 'when sorting by label priority' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:label1) { create(:label, project: project, priority: 1) }
+ let_it_be(:label2) { create(:label, project: project, priority: 5) }
+ let_it_be(:label3) { create(:label, project: project, priority: 10) }
+ let_it_be(:label_issue1) { create(:issue, project: project, labels: [label1]) }
+ let_it_be(:label_issue2) { create(:issue, project: project, labels: [label2]) }
+ let_it_be(:label_issue3) { create(:issue, project: project, labels: [label1, label3]) }
+ let_it_be(:label_issue4) { create(:issue, project: project) }
+
+ it 'sorts issues ascending' do
+ expect(resolve_issues(sort: :label_priority_asc).items).to eq([label_issue3, label_issue1, label_issue2, label_issue4])
+ end
+
+ it 'sorts issues descending' do
+ expect(resolve_issues(sort: :label_priority_desc).items).to eq([label_issue2, label_issue3, label_issue1, label_issue4])
+ end
+ end
+
+ context 'when sorting by milestone due date' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:early_milestone) { create(:milestone, project: project, due_date: 10.days.from_now) }
+ let_it_be(:late_milestone) { create(:milestone, project: project, due_date: 30.days.from_now) }
+ let_it_be(:milestone_issue1) { create(:issue, project: project) }
+ let_it_be(:milestone_issue2) { create(:issue, project: project, milestone: early_milestone) }
+ let_it_be(:milestone_issue3) { create(:issue, project: project, milestone: late_milestone) }
+
+ it 'sorts issues ascending' do
+ expect(resolve_issues(sort: :milestone_due_asc).items).to eq([milestone_issue2, milestone_issue3, milestone_issue1])
+ end
+
+ it 'sorts issues descending' do
+ expect(resolve_issues(sort: :milestone_due_desc).items).to eq([milestone_issue3, milestone_issue2, milestone_issue1])
+ end
+ end
end
it 'returns issues user can see' do
diff --git a/spec/graphql/resolvers/milestone_resolver_spec.rb b/spec/graphql/resolvers/milestone_resolver_spec.rb
index 297130c2027..8e2c67fdc03 100644
--- a/spec/graphql/resolvers/milestone_resolver_spec.rb
+++ b/spec/graphql/resolvers/milestone_resolver_spec.rb
@@ -8,14 +8,14 @@ describe Resolvers::MilestoneResolver do
describe '#resolve' do
let_it_be(:current_user) { create(:user) }
+ def resolve_group_milestones(args = {}, context = { current_user: current_user })
+ resolve(described_class, obj: group, args: args, ctx: context)
+ end
+
context 'for group milestones' do
let_it_be(:now) { Time.now }
let_it_be(:group) { create(:group, :private) }
- def resolve_group_milestones(args = {}, context = { current_user: current_user })
- resolve(described_class, obj: group, args: args, ctx: context)
- end
-
before do
group.add_developer(current_user)
end
@@ -89,5 +89,25 @@ describe Resolvers::MilestoneResolver do
end
end
end
+
+ context 'when including descendant milestones in a public group' do
+ let_it_be(:group) { create(:group, :public) }
+ let(:args) { { include_descendants: true } }
+
+ it 'finds milestones only in accessible projects and groups' do
+ accessible_group = create(:group, :private, parent: group)
+ accessible_project = create(:project, group: accessible_group)
+ accessible_group.add_developer(current_user)
+ inaccessible_group = create(:group, :private, parent: group)
+ inaccessible_project = create(:project, :private, group: group)
+ milestone1 = create(:milestone, group: group)
+ milestone2 = create(:milestone, group: accessible_group)
+ milestone3 = create(:milestone, project: accessible_project)
+ create(:milestone, group: inaccessible_group)
+ create(:milestone, project: inaccessible_project)
+
+ expect(resolve_group_milestones(args)).to match_array([milestone1, milestone2, milestone3])
+ end
+ end
end
end
diff --git a/spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb b/spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb
index 47889126531..7146bfb441b 100644
--- a/spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb
+++ b/spec/graphql/resolvers/projects/jira_imports_resolver_spec.rb
@@ -16,7 +16,7 @@ describe Resolvers::Projects::JiraImportsResolver do
context 'when anonymous user' do
let(:current_user) { nil }
- it_behaves_like 'no jira import access'
+ it_behaves_like 'no Jira import access'
end
end
@@ -25,7 +25,7 @@ describe Resolvers::Projects::JiraImportsResolver do
project.add_guest(user)
end
- it_behaves_like 'no jira import data present'
+ it_behaves_like 'no Jira import data present'
it 'does not raise access error' do
expect do
@@ -47,14 +47,14 @@ describe Resolvers::Projects::JiraImportsResolver do
stub_feature_flags(jira_issue_import: false)
end
- it_behaves_like 'no jira import access'
+ it_behaves_like 'no Jira import access'
end
context 'when user cannot read Jira imports' do
context 'when anonymous user' do
let(:current_user) { nil }
- it_behaves_like 'no jira import access'
+ it_behaves_like 'no Jira import access'
end
end
diff --git a/spec/graphql/resolvers/projects_resolver_spec.rb b/spec/graphql/resolvers/projects_resolver_spec.rb
new file mode 100644
index 00000000000..73ff99a2520
--- /dev/null
+++ b/spec/graphql/resolvers/projects_resolver_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::ProjectsResolver do
+ include GraphqlHelpers
+
+ describe '#resolve' do
+ subject { resolve(described_class, obj: nil, args: filters, ctx: { current_user: current_user }) }
+
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:other_project) { create(:project, :public) }
+ let_it_be(:private_project) { create(:project, :private) }
+ let_it_be(:other_private_project) { create(:project, :private) }
+
+ let_it_be(:user) { create(:user) }
+
+ let(:filters) { {} }
+
+ before_all do
+ project.add_developer(user)
+ private_project.add_developer(user)
+ end
+
+ context 'when user is not logged in' do
+ let(:current_user) { nil }
+
+ context 'when no filters are applied' do
+ it 'returns all public projects' do
+ is_expected.to contain_exactly(project, other_project)
+ end
+
+ context 'when search filter is provided' do
+ let(:filters) { { search: project.name } }
+
+ it 'returns matching project' do
+ is_expected.to contain_exactly(project)
+ end
+ end
+
+ context 'when membership filter is provided' do
+ let(:filters) { { membership: true } }
+
+ it 'returns empty list' do
+ is_expected.to be_empty
+ end
+ end
+ end
+ end
+
+ context 'when user is logged in' do
+ let(:current_user) { user }
+
+ context 'when no filters are applied' do
+ it 'returns all visible projects for the user' do
+ is_expected.to contain_exactly(project, other_project, private_project)
+ end
+
+ context 'when search filter is provided' do
+ let(:filters) { { search: project.name } }
+
+ it 'returns matching project' do
+ is_expected.to contain_exactly(project)
+ end
+ end
+
+ context 'when membership filter is provided' do
+ let(:filters) { { membership: true } }
+
+ it 'returns projects that user is member of' do
+ is_expected.to contain_exactly(project, private_project)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/release_resolver_spec.rb b/spec/graphql/resolvers/release_resolver_spec.rb
new file mode 100644
index 00000000000..71aa4bbb439
--- /dev/null
+++ b/spec/graphql/resolvers/release_resolver_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::ReleaseResolver do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :private) }
+ let_it_be(:release) { create(:release, project: project) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:public_user) { create(:user) }
+
+ let(:args) { { tag_name: release.tag } }
+
+ before do
+ project.add_developer(developer)
+ end
+
+ describe '#resolve' do
+ context 'when the user does not have access to the project' do
+ let(:current_user) { public_user }
+
+ it 'returns nil' do
+ expect(resolve_release).to be_nil
+ end
+ end
+
+ context "when the user has full access to the project's releases" do
+ let(:current_user) { developer }
+
+ it 'returns the release associated with the specified tag' do
+ expect(resolve_release).to eq(release)
+ end
+
+ context 'when no tag_name argument was passed' do
+ let(:args) { {} }
+
+ it 'raises an error' do
+ expect { resolve_release }.to raise_error(ArgumentError, "missing keyword: tag_name")
+ end
+ end
+ end
+ end
+
+ private
+
+ def resolve_release
+ context = { current_user: current_user }
+ resolve(described_class, obj: project, args: args, ctx: context)
+ end
+end
diff --git a/spec/graphql/resolvers/releases_resolver_spec.rb b/spec/graphql/resolvers/releases_resolver_spec.rb
new file mode 100644
index 00000000000..9de539b417a
--- /dev/null
+++ b/spec/graphql/resolvers/releases_resolver_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::ReleasesResolver do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project, :private) }
+ let_it_be(:release_v1) { create(:release, project: project, tag: 'v1.0.0') }
+ let_it_be(:release_v2) { create(:release, project: project, tag: 'v2.0.0') }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:public_user) { create(:user) }
+
+ before do
+ project.add_developer(developer)
+ end
+
+ describe '#resolve' do
+ context 'when the user does not have access to the project' do
+ let(:current_user) { public_user }
+
+ it 'returns an empty array' do
+ expect(resolve_releases).to eq([])
+ end
+ end
+
+ context "when the user has full access to the project's releases" do
+ let(:current_user) { developer }
+
+ it 'returns all releases associated to the project' do
+ expect(resolve_releases).to eq([release_v1, release_v2])
+ end
+ end
+ end
+
+ private
+
+ def resolve_releases
+ context = { current_user: current_user }
+ resolve(described_class, obj: project, args: {}, ctx: context)
+ end
+end
diff --git a/spec/graphql/types/alert_management/alert_status_count_type_spec.rb b/spec/graphql/types/alert_management/alert_status_count_type_spec.rb
new file mode 100644
index 00000000000..1c56028425e
--- /dev/null
+++ b/spec/graphql/types/alert_management/alert_status_count_type_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['AlertManagementAlertStatusCountsType'] do
+ specify { expect(described_class.graphql_name).to eq('AlertManagementAlertStatusCountsType') }
+
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ all
+ open
+ triggered
+ acknowledged
+ resolved
+ ignored
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/alert_management/alert_type_spec.rb b/spec/graphql/types/alert_management/alert_type_spec.rb
new file mode 100644
index 00000000000..9c326f30e3c
--- /dev/null
+++ b/spec/graphql/types/alert_management/alert_type_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['AlertManagementAlert'] do
+ specify { expect(described_class.graphql_name).to eq('AlertManagementAlert') }
+
+ specify { expect(described_class).to require_graphql_authorizations(:read_alert_management_alert) }
+
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ iid
+ issue_iid
+ title
+ description
+ severity
+ status
+ service
+ monitoring_tool
+ hosts
+ started_at
+ ended_at
+ event_count
+ details
+ created_at
+ updated_at
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/alert_management/severity_enum_spec.rb b/spec/graphql/types/alert_management/severity_enum_spec.rb
new file mode 100644
index 00000000000..ca5aa826fe5
--- /dev/null
+++ b/spec/graphql/types/alert_management/severity_enum_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['AlertManagementSeverity'] do
+ specify { expect(described_class.graphql_name).to eq('AlertManagementSeverity') }
+
+ it 'exposes all the severity values' do
+ expect(described_class.values.keys).to include(*%w[CRITICAL HIGH MEDIUM LOW INFO UNKNOWN])
+ end
+end
diff --git a/spec/graphql/types/alert_management/status_enum_spec.rb b/spec/graphql/types/alert_management/status_enum_spec.rb
new file mode 100644
index 00000000000..240d8863c97
--- /dev/null
+++ b/spec/graphql/types/alert_management/status_enum_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['AlertManagementStatus'] do
+ specify { expect(described_class.graphql_name).to eq('AlertManagementStatus') }
+
+ describe 'statuses' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:status_name, :status_value) do
+ 'TRIGGERED' | 0
+ 'ACKNOWLEDGED' | 1
+ 'RESOLVED' | 2
+ 'IGNORED' | 3
+ end
+
+ with_them do
+ it 'exposes a status with the correct value' do
+ expect(described_class.values[status_name].value).to eq(status_value)
+ end
+ end
+ end
+end
diff --git a/spec/graphql/types/award_emojis/award_emoji_type_spec.rb b/spec/graphql/types/award_emojis/award_emoji_type_spec.rb
index de5ece3b749..4e06329506d 100644
--- a/spec/graphql/types/award_emojis/award_emoji_type_spec.rb
+++ b/spec/graphql/types/award_emojis/award_emoji_type_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe GitlabSchema.types['AwardEmoji'] do
- it { expect(described_class.graphql_name).to eq('AwardEmoji') }
+ specify { expect(described_class.graphql_name).to eq('AwardEmoji') }
- it { expect(described_class).to require_graphql_authorizations(:read_emoji) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_emoji) }
- it { expect(described_class).to have_graphql_fields(:description, :unicode_version, :emoji, :name, :unicode, :user) }
+ specify { expect(described_class).to have_graphql_fields(:description, :unicode_version, :emoji, :name, :unicode, :user) }
end
diff --git a/spec/graphql/types/blob_viewers/type_enum_spec.rb b/spec/graphql/types/blob_viewers/type_enum_spec.rb
index 7bd4352f388..09664382af9 100644
--- a/spec/graphql/types/blob_viewers/type_enum_spec.rb
+++ b/spec/graphql/types/blob_viewers/type_enum_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Types::BlobViewers::TypeEnum do
- it { expect(described_class.graphql_name).to eq('BlobViewersType') }
+ specify { expect(described_class.graphql_name).to eq('BlobViewersType') }
it 'exposes all tree entry types' do
expect(described_class.values.keys).to include(*%w[rich simple auxiliary])
diff --git a/spec/graphql/types/board_list_type_spec.rb b/spec/graphql/types/board_list_type_spec.rb
new file mode 100644
index 00000000000..69597fc9617
--- /dev/null
+++ b/spec/graphql/types/board_list_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['BoardList'] do
+ specify { expect(described_class.graphql_name).to eq('BoardList') }
+
+ it 'has specific fields' do
+ expected_fields = %w[id list_type position label]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/board_type_spec.rb b/spec/graphql/types/board_type_spec.rb
index 1ca4bf18b57..5d87a1757b5 100644
--- a/spec/graphql/types/board_type_spec.rb
+++ b/spec/graphql/types/board_type_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe GitlabSchema.types['Board'] do
- it { expect(described_class.graphql_name).to eq('Board') }
+ specify { expect(described_class.graphql_name).to eq('Board') }
- it { expect(described_class).to require_graphql_authorizations(:read_board) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_board) }
it 'has specific fields' do
expected_fields = %w[id name]
diff --git a/spec/graphql/types/branch_type_spec.rb b/spec/graphql/types/branch_type_spec.rb
new file mode 100644
index 00000000000..f58b514116d
--- /dev/null
+++ b/spec/graphql/types/branch_type_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['Branch'] do
+ it { expect(described_class.graphql_name).to eq('Branch') }
+
+ it { expect(described_class).to have_graphql_fields(:name, :commit) }
+end
diff --git a/spec/graphql/types/ci/detailed_status_type_spec.rb b/spec/graphql/types/ci/detailed_status_type_spec.rb
index 169a03c770b..c62c8f23728 100644
--- a/spec/graphql/types/ci/detailed_status_type_spec.rb
+++ b/spec/graphql/types/ci/detailed_status_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Types::Ci::DetailedStatusType do
- it { expect(described_class.graphql_name).to eq('DetailedStatus') }
+ specify { expect(described_class.graphql_name).to eq('DetailedStatus') }
it "has all fields" do
expect(described_class).to have_graphql_fields(:group, :icon, :favicon,
diff --git a/spec/graphql/types/ci/pipeline_type_spec.rb b/spec/graphql/types/ci/pipeline_type_spec.rb
index 2fafc1bc13f..d56cff12105 100644
--- a/spec/graphql/types/ci/pipeline_type_spec.rb
+++ b/spec/graphql/types/ci/pipeline_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Types::Ci::PipelineType do
- it { expect(described_class.graphql_name).to eq('Pipeline') }
+ specify { expect(described_class.graphql_name).to eq('Pipeline') }
- it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Ci::Pipeline) }
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Ci::Pipeline) }
end
diff --git a/spec/graphql/types/commit_type_spec.rb b/spec/graphql/types/commit_type_spec.rb
index f5f99229f3a..88b450e3924 100644
--- a/spec/graphql/types/commit_type_spec.rb
+++ b/spec/graphql/types/commit_type_spec.rb
@@ -3,13 +3,13 @@
require 'spec_helper'
describe GitlabSchema.types['Commit'] do
- it { expect(described_class.graphql_name).to eq('Commit') }
+ specify { expect(described_class.graphql_name).to eq('Commit') }
- it { expect(described_class).to require_graphql_authorizations(:download_code) }
+ specify { expect(described_class).to require_graphql_authorizations(:download_code) }
it 'contains attributes related to commit' do
expect(described_class).to have_graphql_fields(
- :id, :sha, :title, :description, :message, :authored_date,
+ :id, :sha, :title, :description, :message, :title_html, :authored_date,
:author_name, :author_gravatar, :author, :web_url, :latest_pipeline,
:pipelines, :signature_html
)
diff --git a/spec/graphql/types/design_management/design_at_version_type_spec.rb b/spec/graphql/types/design_management/design_at_version_type_spec.rb
new file mode 100644
index 00000000000..1453d73d59c
--- /dev/null
+++ b/spec/graphql/types/design_management/design_at_version_type_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['DesignAtVersion'] do
+ it_behaves_like 'a GraphQL type with design fields' do
+ let(:extra_design_fields) { %i[version design] }
+ let_it_be(:design) { create(:design, :with_versions) }
+ let(:object_id) do
+ version = design.versions.first
+ GitlabSchema.id_from_object(create(:design_at_version, design: design, version: version))
+ end
+ let_it_be(:object_id_b) { GitlabSchema.id_from_object(create(:design_at_version)) }
+ let(:object_type) { ::Types::DesignManagement::DesignAtVersionType }
+ end
+end
diff --git a/spec/graphql/types/design_management/design_collection_type_spec.rb b/spec/graphql/types/design_management/design_collection_type_spec.rb
new file mode 100644
index 00000000000..65150f0971d
--- /dev/null
+++ b/spec/graphql/types/design_management/design_collection_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['DesignCollection'] do
+ it { expect(described_class).to require_graphql_authorizations(:read_design) }
+
+ it 'has the expected fields' do
+ expected_fields = %i[project issue designs versions version designAtVersion design]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/design_management/design_type_spec.rb b/spec/graphql/types/design_management/design_type_spec.rb
new file mode 100644
index 00000000000..75b4cd66d5e
--- /dev/null
+++ b/spec/graphql/types/design_management/design_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['Design'] do
+ it_behaves_like 'a GraphQL type with design fields' do
+ let(:extra_design_fields) { %i[notes discussions versions] }
+ let_it_be(:design) { create(:design, :with_versions) }
+ let(:object_id) { GitlabSchema.id_from_object(design) }
+ let_it_be(:object_id_b) { GitlabSchema.id_from_object(create(:design, :with_versions)) }
+ let(:object_type) { ::Types::DesignManagement::DesignType }
+ end
+end
diff --git a/spec/graphql/types/design_management/design_version_event_enum_spec.rb b/spec/graphql/types/design_management/design_version_event_enum_spec.rb
new file mode 100644
index 00000000000..a65f1bb5990
--- /dev/null
+++ b/spec/graphql/types/design_management/design_version_event_enum_spec.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['DesignVersionEvent'] do
+ it { expect(described_class.graphql_name).to eq('DesignVersionEvent') }
+
+ it 'exposes the correct event states' do
+ expect(described_class.values.keys).to include(*%w[CREATION MODIFICATION DELETION NONE])
+ end
+end
diff --git a/spec/graphql/types/design_management/version_type_spec.rb b/spec/graphql/types/design_management/version_type_spec.rb
new file mode 100644
index 00000000000..3317c4c6571
--- /dev/null
+++ b/spec/graphql/types/design_management/version_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['DesignVersion'] do
+ it { expect(described_class).to require_graphql_authorizations(:read_design) }
+
+ it 'has the expected fields' do
+ expected_fields = %i[id sha designs design_at_version designs_at_version]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/design_management_type_spec.rb b/spec/graphql/types/design_management_type_spec.rb
new file mode 100644
index 00000000000..a6204f20f23
--- /dev/null
+++ b/spec/graphql/types/design_management_type_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['DesignManagement'] do
+ it { expect(described_class).to have_graphql_fields(:version, :design_at_version) }
+end
diff --git a/spec/graphql/types/diff_refs_type_spec.rb b/spec/graphql/types/diff_refs_type_spec.rb
index a6ead27455f..3165e642452 100644
--- a/spec/graphql/types/diff_refs_type_spec.rb
+++ b/spec/graphql/types/diff_refs_type_spec.rb
@@ -3,11 +3,11 @@
require 'spec_helper'
describe GitlabSchema.types['DiffRefs'] do
- it { expect(described_class.graphql_name).to eq('DiffRefs') }
+ specify { expect(described_class.graphql_name).to eq('DiffRefs') }
- it { expect(described_class).to have_graphql_fields(:head_sha, :base_sha, :start_sha).only }
+ specify { expect(described_class).to have_graphql_fields(:head_sha, :base_sha, :start_sha).only }
- it { expect(described_class.fields['headSha'].type).to be_non_null }
- it { expect(described_class.fields['baseSha'].type).not_to be_non_null }
- it { expect(described_class.fields['startSha'].type).to be_non_null }
+ specify { expect(described_class.fields['headSha'].type).to be_non_null }
+ specify { expect(described_class.fields['baseSha'].type).not_to be_non_null }
+ specify { expect(described_class.fields['startSha'].type).to be_non_null }
end
diff --git a/spec/graphql/types/environment_type_spec.rb b/spec/graphql/types/environment_type_spec.rb
index 24a8bddfa6a..0e5cbac05df 100644
--- a/spec/graphql/types/environment_type_spec.rb
+++ b/spec/graphql/types/environment_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['Environment'] do
- it { expect(described_class.graphql_name).to eq('Environment') }
+ specify { expect(described_class.graphql_name).to eq('Environment') }
it 'has the expected fields' do
expected_fields = %w[
@@ -13,5 +13,5 @@ describe GitlabSchema.types['Environment'] do
expect(described_class).to have_graphql_fields(*expected_fields)
end
- it { expect(described_class).to require_graphql_authorizations(:read_environment) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_environment) }
end
diff --git a/spec/graphql/types/error_tracking/sentry_detailed_error_type_spec.rb b/spec/graphql/types/error_tracking/sentry_detailed_error_type_spec.rb
index 44652f831b5..0a094e9e188 100644
--- a/spec/graphql/types/error_tracking/sentry_detailed_error_type_spec.rb
+++ b/spec/graphql/types/error_tracking/sentry_detailed_error_type_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe GitlabSchema.types['SentryDetailedError'] do
- it { expect(described_class.graphql_name).to eq('SentryDetailedError') }
+ specify { expect(described_class.graphql_name).to eq('SentryDetailedError') }
- it { expect(described_class).to require_graphql_authorizations(:read_sentry_issue) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_sentry_issue) }
it 'exposes the expected fields' do
expected_fields = %i[
diff --git a/spec/graphql/types/error_tracking/sentry_error_collection_type_spec.rb b/spec/graphql/types/error_tracking/sentry_error_collection_type_spec.rb
index 20ec31391d8..793da2db960 100644
--- a/spec/graphql/types/error_tracking/sentry_error_collection_type_spec.rb
+++ b/spec/graphql/types/error_tracking/sentry_error_collection_type_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe GitlabSchema.types['SentryErrorCollection'] do
- it { expect(described_class.graphql_name).to eq('SentryErrorCollection') }
+ specify { expect(described_class.graphql_name).to eq('SentryErrorCollection') }
- it { expect(described_class).to require_graphql_authorizations(:read_sentry_issue) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_sentry_issue) }
it 'exposes the expected fields' do
expected_fields = %i[
diff --git a/spec/graphql/types/error_tracking/sentry_error_stack_trace_entry_type_spec.rb b/spec/graphql/types/error_tracking/sentry_error_stack_trace_entry_type_spec.rb
index 05cc2ca7612..b65398fccc9 100644
--- a/spec/graphql/types/error_tracking/sentry_error_stack_trace_entry_type_spec.rb
+++ b/spec/graphql/types/error_tracking/sentry_error_stack_trace_entry_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['SentryErrorStackTraceEntry'] do
- it { expect(described_class.graphql_name).to eq('SentryErrorStackTraceEntry') }
+ specify { expect(described_class.graphql_name).to eq('SentryErrorStackTraceEntry') }
it 'exposes the expected fields' do
expected_fields = %i[
diff --git a/spec/graphql/types/error_tracking/sentry_error_stack_trace_type_spec.rb b/spec/graphql/types/error_tracking/sentry_error_stack_trace_type_spec.rb
index 2a422228f72..2cec8865764 100644
--- a/spec/graphql/types/error_tracking/sentry_error_stack_trace_type_spec.rb
+++ b/spec/graphql/types/error_tracking/sentry_error_stack_trace_type_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe GitlabSchema.types['SentryErrorStackTrace'] do
- it { expect(described_class.graphql_name).to eq('SentryErrorStackTrace') }
+ specify { expect(described_class.graphql_name).to eq('SentryErrorStackTrace') }
- it { expect(described_class).to require_graphql_authorizations(:read_sentry_issue) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_sentry_issue) }
it 'exposes the expected fields' do
expected_fields = %i[
diff --git a/spec/graphql/types/error_tracking/sentry_error_type_spec.rb b/spec/graphql/types/error_tracking/sentry_error_type_spec.rb
index 4676d91ef9c..f8cc801e35e 100644
--- a/spec/graphql/types/error_tracking/sentry_error_type_spec.rb
+++ b/spec/graphql/types/error_tracking/sentry_error_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['SentryError'] do
- it { expect(described_class.graphql_name).to eq('SentryError') }
+ specify { expect(described_class.graphql_name).to eq('SentryError') }
it 'exposes the expected fields' do
expected_fields = %i[
diff --git a/spec/graphql/types/grafana_integration_type_spec.rb b/spec/graphql/types/grafana_integration_type_spec.rb
index ac26911acbf..429b5bdffe6 100644
--- a/spec/graphql/types/grafana_integration_type_spec.rb
+++ b/spec/graphql/types/grafana_integration_type_spec.rb
@@ -14,9 +14,9 @@ describe GitlabSchema.types['GrafanaIntegration'] do
]
end
- it { expect(described_class.graphql_name).to eq('GrafanaIntegration') }
+ specify { expect(described_class.graphql_name).to eq('GrafanaIntegration') }
- it { expect(described_class).to require_graphql_authorizations(:admin_operations) }
+ specify { expect(described_class).to require_graphql_authorizations(:admin_operations) }
- it { expect(described_class).to have_graphql_fields(*expected_fields) }
+ specify { expect(described_class).to have_graphql_fields(*expected_fields) }
end
diff --git a/spec/graphql/types/group_type_spec.rb b/spec/graphql/types/group_type_spec.rb
index 532f1a4b53d..a834a9038db 100644
--- a/spec/graphql/types/group_type_spec.rb
+++ b/spec/graphql/types/group_type_spec.rb
@@ -3,11 +3,11 @@
require 'spec_helper'
describe GitlabSchema.types['Group'] do
- it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Group) }
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Group) }
- it { expect(described_class.graphql_name).to eq('Group') }
+ specify { expect(described_class.graphql_name).to eq('Group') }
- it { expect(described_class).to require_graphql_authorizations(:read_group) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_group) }
it 'has the expected fields' do
expected_fields = %w[
diff --git a/spec/graphql/types/issuable_sort_enum_spec.rb b/spec/graphql/types/issuable_sort_enum_spec.rb
new file mode 100644
index 00000000000..35c42d8194c
--- /dev/null
+++ b/spec/graphql/types/issuable_sort_enum_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Types::IssuableSortEnum do
+ specify { expect(described_class.graphql_name).to eq('IssuableSort') }
+
+ it 'exposes all the existing issuable sort values' do
+ expect(described_class.values.keys).to include(
+ *%w[PRIORITY_ASC PRIORITY_DESC
+ LABEL_PRIORITY_ASC LABEL_PRIORITY_DESC
+ MILESTONE_DUE_ASC MILESTONE_DUE_DESC]
+ )
+ end
+end
diff --git a/spec/graphql/types/issuable_state_enum_spec.rb b/spec/graphql/types/issuable_state_enum_spec.rb
index 65a80fa4176..f974ed5f5fb 100644
--- a/spec/graphql/types/issuable_state_enum_spec.rb
+++ b/spec/graphql/types/issuable_state_enum_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['IssuableState'] do
- it { expect(described_class.graphql_name).to eq('IssuableState') }
+ specify { expect(described_class.graphql_name).to eq('IssuableState') }
it_behaves_like 'issuable state'
end
diff --git a/spec/graphql/types/issue_sort_enum_spec.rb b/spec/graphql/types/issue_sort_enum_spec.rb
index 1b6aa6d6069..c496b897cdb 100644
--- a/spec/graphql/types/issue_sort_enum_spec.rb
+++ b/spec/graphql/types/issue_sort_enum_spec.rb
@@ -3,11 +3,13 @@
require 'spec_helper'
describe GitlabSchema.types['IssueSort'] do
- it { expect(described_class.graphql_name).to eq('IssueSort') }
+ specify { expect(described_class.graphql_name).to eq('IssueSort') }
it_behaves_like 'common sort values'
it 'exposes all the existing issue sort values' do
- expect(described_class.values.keys).to include(*%w[DUE_DATE_ASC DUE_DATE_DESC RELATIVE_POSITION_ASC])
+ expect(described_class.values.keys).to include(
+ *%w[DUE_DATE_ASC DUE_DATE_DESC RELATIVE_POSITION_ASC]
+ )
end
end
diff --git a/spec/graphql/types/issue_state_enum_spec.rb b/spec/graphql/types/issue_state_enum_spec.rb
index de19e6fc505..a18c5f5d317 100644
--- a/spec/graphql/types/issue_state_enum_spec.rb
+++ b/spec/graphql/types/issue_state_enum_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['IssueState'] do
- it { expect(described_class.graphql_name).to eq('IssueState') }
+ specify { expect(described_class.graphql_name).to eq('IssueState') }
it_behaves_like 'issuable state'
end
diff --git a/spec/graphql/types/issue_type_spec.rb b/spec/graphql/types/issue_type_spec.rb
index ebe48c17c11..a8f7edcfe8e 100644
--- a/spec/graphql/types/issue_type_spec.rb
+++ b/spec/graphql/types/issue_type_spec.rb
@@ -3,18 +3,19 @@
require 'spec_helper'
describe GitlabSchema.types['Issue'] do
- it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Issue) }
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Issue) }
- it { expect(described_class.graphql_name).to eq('Issue') }
+ specify { expect(described_class.graphql_name).to eq('Issue') }
- it { expect(described_class).to require_graphql_authorizations(:read_issue) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_issue) }
- it { expect(described_class.interfaces).to include(Types::Notes::NoteableType) }
+ specify { expect(described_class.interfaces).to include(Types::Notes::NoteableType) }
it 'has specific fields' do
fields = %i[iid title description state reference author assignees participants labels milestone due_date
confidential discussion_locked upvotes downvotes user_notes_count web_path web_url relative_position
- subscribed time_estimate total_time_spent closed_at created_at updated_at task_completion_status]
+ subscribed time_estimate total_time_spent closed_at created_at updated_at task_completion_status
+ designs design_collection]
fields.each do |field_name|
expect(described_class).to have_graphql_field(field_name)
diff --git a/spec/graphql/types/jira_import_type_spec.rb b/spec/graphql/types/jira_import_type_spec.rb
index 8448a120682..ac1aa672e30 100644
--- a/spec/graphql/types/jira_import_type_spec.rb
+++ b/spec/graphql/types/jira_import_type_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe GitlabSchema.types['JiraImport'] do
- it { expect(described_class.graphql_name).to eq('JiraImport') }
+ specify { expect(described_class.graphql_name).to eq('JiraImport') }
it 'has the expected fields' do
- expect(described_class).to have_graphql_fields(:jira_project_key, :scheduled_at, :scheduled_by)
+ expect(described_class).to have_graphql_fields(:jira_project_key, :createdAt, :scheduled_at, :scheduled_by)
end
end
diff --git a/spec/graphql/types/label_type_spec.rb b/spec/graphql/types/label_type_spec.rb
index 71b86d9b528..026c63906ef 100644
--- a/spec/graphql/types/label_type_spec.rb
+++ b/spec/graphql/types/label_type_spec.rb
@@ -8,5 +8,5 @@ describe GitlabSchema.types['Label'] do
expect(described_class).to have_graphql_fields(*expected_fields)
end
- it { expect(described_class).to require_graphql_authorizations(:read_label) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_label) }
end
diff --git a/spec/graphql/types/merge_request_state_enum_spec.rb b/spec/graphql/types/merge_request_state_enum_spec.rb
index 626e33b18d3..2abc7b298b1 100644
--- a/spec/graphql/types/merge_request_state_enum_spec.rb
+++ b/spec/graphql/types/merge_request_state_enum_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['MergeRequestState'] do
- it { expect(described_class.graphql_name).to eq('MergeRequestState') }
+ specify { expect(described_class.graphql_name).to eq('MergeRequestState') }
it_behaves_like 'issuable state'
diff --git a/spec/graphql/types/merge_request_type_spec.rb b/spec/graphql/types/merge_request_type_spec.rb
index 0c83ebd3de9..e7ab2100084 100644
--- a/spec/graphql/types/merge_request_type_spec.rb
+++ b/spec/graphql/types/merge_request_type_spec.rb
@@ -3,11 +3,11 @@
require 'spec_helper'
describe GitlabSchema.types['MergeRequest'] do
- it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::MergeRequest) }
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::MergeRequest) }
- it { expect(described_class).to require_graphql_authorizations(:read_merge_request) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_merge_request) }
- it { expect(described_class.interfaces).to include(Types::Notes::NoteableType) }
+ specify { expect(described_class.interfaces).to include(Types::Notes::NoteableType) }
it 'has the expected fields' do
expected_fields = %w[
diff --git a/spec/graphql/types/metadata_type_spec.rb b/spec/graphql/types/metadata_type_spec.rb
index c8270a8c2f5..75369ec9c3c 100644
--- a/spec/graphql/types/metadata_type_spec.rb
+++ b/spec/graphql/types/metadata_type_spec.rb
@@ -3,6 +3,6 @@
require 'spec_helper'
describe GitlabSchema.types['Metadata'] do
- it { expect(described_class.graphql_name).to eq('Metadata') }
- it { expect(described_class).to require_graphql_authorizations(:read_instance_metadata) }
+ specify { expect(described_class.graphql_name).to eq('Metadata') }
+ specify { expect(described_class).to require_graphql_authorizations(:read_instance_metadata) }
end
diff --git a/spec/graphql/types/metrics/dashboard_type_spec.rb b/spec/graphql/types/metrics/dashboard_type_spec.rb
index 76f2b4b8935..81219c596a7 100644
--- a/spec/graphql/types/metrics/dashboard_type_spec.rb
+++ b/spec/graphql/types/metrics/dashboard_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['MetricsDashboard'] do
- it { expect(described_class.graphql_name).to eq('MetricsDashboard') }
+ specify { expect(described_class.graphql_name).to eq('MetricsDashboard') }
it 'has the expected fields' do
expected_fields = %w[
diff --git a/spec/graphql/types/metrics/dashboards/annotation_type_spec.rb b/spec/graphql/types/metrics/dashboards/annotation_type_spec.rb
index 2956a2512eb..dbb8b04dbd7 100644
--- a/spec/graphql/types/metrics/dashboards/annotation_type_spec.rb
+++ b/spec/graphql/types/metrics/dashboards/annotation_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['MetricsDashboardAnnotation'] do
- it { expect(described_class.graphql_name).to eq('MetricsDashboardAnnotation') }
+ specify { expect(described_class.graphql_name).to eq('MetricsDashboardAnnotation') }
it 'has the expected fields' do
expected_fields = %w[
@@ -13,5 +13,5 @@ describe GitlabSchema.types['MetricsDashboardAnnotation'] do
expect(described_class).to have_graphql_fields(*expected_fields)
end
- it { expect(described_class).to require_graphql_authorizations(:read_metrics_dashboard_annotation) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_metrics_dashboard_annotation) }
end
diff --git a/spec/graphql/types/milestone_type_spec.rb b/spec/graphql/types/milestone_type_spec.rb
index f7ee79eae9f..4c3d9f50a64 100644
--- a/spec/graphql/types/milestone_type_spec.rb
+++ b/spec/graphql/types/milestone_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['Milestone'] do
- it { expect(described_class.graphql_name).to eq('Milestone') }
+ specify { expect(described_class.graphql_name).to eq('Milestone') }
- it { expect(described_class).to require_graphql_authorizations(:read_milestone) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_milestone) }
end
diff --git a/spec/graphql/types/namespace_type_spec.rb b/spec/graphql/types/namespace_type_spec.rb
index 6c2ba70cf4c..741698021e7 100644
--- a/spec/graphql/types/namespace_type_spec.rb
+++ b/spec/graphql/types/namespace_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['Namespace'] do
- it { expect(described_class.graphql_name).to eq('Namespace') }
+ specify { expect(described_class.graphql_name).to eq('Namespace') }
it 'has the expected fields' do
expected_fields = %w[
@@ -14,5 +14,5 @@ describe GitlabSchema.types['Namespace'] do
expect(described_class).to have_graphql_fields(*expected_fields)
end
- it { expect(described_class).to require_graphql_authorizations(:read_namespace) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_namespace) }
end
diff --git a/spec/graphql/types/notes/discussion_type_spec.rb b/spec/graphql/types/notes/discussion_type_spec.rb
index 804785ba67d..44774594d17 100644
--- a/spec/graphql/types/notes/discussion_type_spec.rb
+++ b/spec/graphql/types/notes/discussion_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
describe GitlabSchema.types['Discussion'] do
- it { expect(described_class).to have_graphql_fields(:id, :created_at, :notes, :reply_id) }
+ specify { expect(described_class).to have_graphql_fields(:id, :created_at, :notes, :reply_id) }
- it { expect(described_class).to require_graphql_authorizations(:read_note) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_note) }
end
diff --git a/spec/graphql/types/notes/note_type_spec.rb b/spec/graphql/types/notes/note_type_spec.rb
index 8cf84cd8dfd..019f742ee77 100644
--- a/spec/graphql/types/notes/note_type_spec.rb
+++ b/spec/graphql/types/notes/note_type_spec.rb
@@ -10,6 +10,6 @@ describe GitlabSchema.types['Note'] do
expect(described_class).to have_graphql_fields(*expected_fields)
end
- it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Note) }
- it { expect(described_class).to require_graphql_authorizations(:read_note) }
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Note) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_note) }
end
diff --git a/spec/graphql/types/notes/noteable_type_spec.rb b/spec/graphql/types/notes/noteable_type_spec.rb
index a4259e160e0..4a81f45bd4e 100644
--- a/spec/graphql/types/notes/noteable_type_spec.rb
+++ b/spec/graphql/types/notes/noteable_type_spec.rb
@@ -2,12 +2,13 @@
require 'spec_helper'
describe Types::Notes::NoteableType do
- it { expect(described_class).to have_graphql_fields(:notes, :discussions) }
+ specify { expect(described_class).to have_graphql_fields(:notes, :discussions) }
describe ".resolve_type" do
it 'knows the correct type for objects' do
expect(described_class.resolve_type(build(:issue), {})).to eq(Types::IssueType)
expect(described_class.resolve_type(build(:merge_request), {})).to eq(Types::MergeRequestType)
+ expect(described_class.resolve_type(build(:design), {})).to eq(Types::DesignManagement::DesignType)
end
end
end
diff --git a/spec/graphql/types/permission_types/issue_spec.rb b/spec/graphql/types/permission_types/issue_spec.rb
index a94bc6b780e..a7a3dd00f11 100644
--- a/spec/graphql/types/permission_types/issue_spec.rb
+++ b/spec/graphql/types/permission_types/issue_spec.rb
@@ -5,8 +5,9 @@ require 'spec_helper'
describe Types::PermissionTypes::Issue do
it do
expected_permissions = [
- :read_issue, :admin_issue, :update_issue,
- :create_note, :reopen_issue
+ :read_issue, :admin_issue, :update_issue, :reopen_issue,
+ :read_design, :create_design, :destroy_design,
+ :create_note
]
expected_permissions.each do |permission|
diff --git a/spec/graphql/types/permission_types/merge_request_type_spec.rb b/spec/graphql/types/permission_types/merge_request_type_spec.rb
index 572b4ac42d0..7e9752cdc46 100644
--- a/spec/graphql/types/permission_types/merge_request_type_spec.rb
+++ b/spec/graphql/types/permission_types/merge_request_type_spec.rb
@@ -3,5 +3,5 @@
require 'spec_helper'
describe Types::MergeRequestType do
- it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::MergeRequest) }
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::MergeRequest) }
end
diff --git a/spec/graphql/types/permission_types/project_spec.rb b/spec/graphql/types/permission_types/project_spec.rb
index 56c4c2de4df..2789464d29c 100644
--- a/spec/graphql/types/permission_types/project_spec.rb
+++ b/spec/graphql/types/permission_types/project_spec.rb
@@ -13,7 +13,7 @@ describe Types::PermissionTypes::Project do
:create_merge_request_from, :create_wiki, :push_code, :create_deployment, :push_to_delete_protected_branch,
:admin_wiki, :admin_project, :update_pages, :admin_remote_mirror, :create_label,
:update_wiki, :destroy_wiki, :create_pages, :destroy_pages, :read_pages_content,
- :read_merge_request
+ :read_merge_request, :read_design, :create_design, :destroy_design
]
expected_permissions.each do |permission|
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index 6ea852190c9..6368f743720 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -3,11 +3,11 @@
require 'spec_helper'
describe GitlabSchema.types['Project'] do
- it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Project) }
+ specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Project) }
- it { expect(described_class.graphql_name).to eq('Project') }
+ specify { expect(described_class.graphql_name).to eq('Project') }
- it { expect(described_class).to require_graphql_authorizations(:read_project) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_project) }
it 'has the expected fields' do
expected_fields = %w[
@@ -24,7 +24,8 @@ describe GitlabSchema.types['Project'] do
namespace group statistics repository merge_requests merge_request issues
issue pipelines removeSourceBranchAfterMerge sentryDetailedError snippets
grafanaIntegration autocloseReferencedIssues suggestion_commit_message environments
- boards jira_import_status jira_imports services
+ boards jira_import_status jira_imports services releases release
+ alert_management_alerts alert_management_alert alert_management_alert_status_counts
]
expect(described_class).to include_graphql_fields(*expected_fields)
@@ -96,4 +97,18 @@ describe GitlabSchema.types['Project'] do
it { is_expected.to have_graphql_type(Types::Projects::ServiceType.connection_type) }
end
+
+ describe 'releases field' do
+ subject { described_class.fields['release'] }
+
+ it { is_expected.to have_graphql_type(Types::ReleaseType) }
+ it { is_expected.to have_graphql_resolver(Resolvers::ReleaseResolver) }
+ end
+
+ describe 'release field' do
+ subject { described_class.fields['releases'] }
+
+ it { is_expected.to have_graphql_type(Types::ReleaseType.connection_type) }
+ it { is_expected.to have_graphql_resolver(Resolvers::ReleasesResolver) }
+ end
end
diff --git a/spec/graphql/types/projects/base_service_type_spec.rb b/spec/graphql/types/projects/base_service_type_spec.rb
index bda6022bf79..4fcb9fe1a73 100644
--- a/spec/graphql/types/projects/base_service_type_spec.rb
+++ b/spec/graphql/types/projects/base_service_type_spec.rb
@@ -3,11 +3,11 @@
require 'spec_helper'
describe GitlabSchema.types['BaseService'] do
- it { expect(described_class.graphql_name).to eq('BaseService') }
+ specify { expect(described_class.graphql_name).to eq('BaseService') }
it 'has basic expected fields' do
expect(described_class).to have_graphql_fields(:type, :active)
end
- it { expect(described_class).to require_graphql_authorizations(:admin_project) }
+ specify { expect(described_class).to require_graphql_authorizations(:admin_project) }
end
diff --git a/spec/graphql/types/projects/jira_service_type_spec.rb b/spec/graphql/types/projects/jira_service_type_spec.rb
index 7f8fa6538e9..91d7e4586cb 100644
--- a/spec/graphql/types/projects/jira_service_type_spec.rb
+++ b/spec/graphql/types/projects/jira_service_type_spec.rb
@@ -3,11 +3,11 @@
require 'spec_helper'
describe GitlabSchema.types['JiraService'] do
- it { expect(described_class.graphql_name).to eq('JiraService') }
+ specify { expect(described_class.graphql_name).to eq('JiraService') }
it 'has basic expected fields' do
expect(described_class).to have_graphql_fields(:type, :active)
end
- it { expect(described_class).to require_graphql_authorizations(:admin_project) }
+ specify { expect(described_class).to require_graphql_authorizations(:admin_project) }
end
diff --git a/spec/graphql/types/projects/service_type_spec.rb b/spec/graphql/types/projects/service_type_spec.rb
index ad30a4008bc..f6758d17d18 100644
--- a/spec/graphql/types/projects/service_type_spec.rb
+++ b/spec/graphql/types/projects/service_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Types::Projects::ServiceType do
- it { expect(described_class).to have_graphql_fields(:type, :active) }
+ specify { expect(described_class).to have_graphql_fields(:type, :active) }
describe ".resolve_type" do
it 'resolves the corresponding type for objects' do
diff --git a/spec/graphql/types/projects/services_enum_spec.rb b/spec/graphql/types/projects/services_enum_spec.rb
index aac4aae4f69..91e398e8d81 100644
--- a/spec/graphql/types/projects/services_enum_spec.rb
+++ b/spec/graphql/types/projects/services_enum_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['ServiceType'] do
- it { expect(described_class.graphql_name).to eq('ServiceType') }
+ specify { expect(described_class.graphql_name).to eq('ServiceType') }
it 'exposes all the existing project services' do
expect(described_class.values.keys).to match_array(available_services_enum)
diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb
index ab210f2e918..1f269a80d00 100644
--- a/spec/graphql/types/query_type_spec.rb
+++ b/spec/graphql/types/query_type_spec.rb
@@ -8,7 +8,7 @@ describe GitlabSchema.types['Query'] do
end
it 'has the expected fields' do
- expected_fields = %i[project namespace group echo metadata current_user snippets]
+ expected_fields = %i[project namespace group echo metadata current_user snippets design_management]
expect(described_class).to have_graphql_fields(*expected_fields).at_least
end
diff --git a/spec/graphql/types/release_type_spec.rb b/spec/graphql/types/release_type_spec.rb
new file mode 100644
index 00000000000..d22a0b4f0fa
--- /dev/null
+++ b/spec/graphql/types/release_type_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['Release'] do
+ it { expect(described_class).to require_graphql_authorizations(:read_release) }
+
+ it 'has the expected fields' do
+ expected_fields = %w[
+ tag_name tag_path
+ description description_html
+ name milestones author commit
+ created_at released_at
+ ]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+
+ describe 'milestones field' do
+ subject { described_class.fields['milestones'] }
+
+ it { is_expected.to have_graphql_type(Types::MilestoneType.connection_type) }
+ end
+
+ describe 'author field' do
+ subject { described_class.fields['author'] }
+
+ it { is_expected.to have_graphql_type(Types::UserType) }
+ end
+
+ describe 'commit field' do
+ subject { described_class.fields['commit'] }
+
+ it { is_expected.to have_graphql_type(Types::CommitType) }
+ it { is_expected.to require_graphql_authorizations(:reporter_access) }
+ end
+end
diff --git a/spec/graphql/types/repository_type_spec.rb b/spec/graphql/types/repository_type_spec.rb
index f746e75b574..fb52839c712 100644
--- a/spec/graphql/types/repository_type_spec.rb
+++ b/spec/graphql/types/repository_type_spec.rb
@@ -3,11 +3,11 @@
require 'spec_helper'
describe GitlabSchema.types['Repository'] do
- it { expect(described_class.graphql_name).to eq('Repository') }
+ specify { expect(described_class.graphql_name).to eq('Repository') }
- it { expect(described_class).to require_graphql_authorizations(:download_code) }
+ specify { expect(described_class).to require_graphql_authorizations(:download_code) }
- it { expect(described_class).to have_graphql_field(:root_ref) }
+ specify { expect(described_class).to have_graphql_field(:root_ref) }
- it { expect(described_class).to have_graphql_field(:tree) }
+ specify { expect(described_class).to have_graphql_field(:tree) }
end
diff --git a/spec/graphql/types/root_storage_statistics_type_spec.rb b/spec/graphql/types/root_storage_statistics_type_spec.rb
index b796b974b82..ebaa5a18623 100644
--- a/spec/graphql/types/root_storage_statistics_type_spec.rb
+++ b/spec/graphql/types/root_storage_statistics_type_spec.rb
@@ -3,12 +3,12 @@
require 'spec_helper'
describe GitlabSchema.types['RootStorageStatistics'] do
- it { expect(described_class.graphql_name).to eq('RootStorageStatistics') }
+ specify { expect(described_class.graphql_name).to eq('RootStorageStatistics') }
it 'has all the required fields' do
expect(described_class).to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
:build_artifacts_size, :packages_size, :wiki_size)
end
- it { expect(described_class).to require_graphql_authorizations(:read_statistics) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_statistics) }
end
diff --git a/spec/graphql/types/snippet_type_spec.rb b/spec/graphql/types/snippet_type_spec.rb
index 6e580711fda..adc13d4d651 100644
--- a/spec/graphql/types/snippet_type_spec.rb
+++ b/spec/graphql/types/snippet_type_spec.rb
@@ -17,7 +17,7 @@ describe GitlabSchema.types['Snippet'] do
end
describe 'authorizations' do
- it { expect(described_class).to require_graphql_authorizations(:read_snippet) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_snippet) }
end
shared_examples 'response without repository URLs' do
@@ -35,14 +35,6 @@ describe GitlabSchema.types['Snippet'] do
expect(response['sshUrlToRepo']).to eq(snippet.ssh_url_to_repo)
expect(response['httpUrlToRepo']).to eq(snippet.http_url_to_repo)
end
-
- context 'when version_snippets feature is disabled' do
- before do
- stub_feature_flags(version_snippets: false)
- end
-
- it_behaves_like 'response without repository URLs'
- end
end
end
diff --git a/spec/graphql/types/snippets/blob_type_spec.rb b/spec/graphql/types/snippets/blob_type_spec.rb
index da36ab80f44..fb8c6896732 100644
--- a/spec/graphql/types/snippets/blob_type_spec.rb
+++ b/spec/graphql/types/snippets/blob_type_spec.rb
@@ -6,8 +6,22 @@ describe GitlabSchema.types['SnippetBlob'] do
it 'has the correct fields' do
expected_fields = [:rich_data, :plain_data,
:raw_path, :size, :binary, :name, :path,
- :simple_viewer, :rich_viewer, :mode]
+ :simple_viewer, :rich_viewer, :mode, :external_storage,
+ :rendered_as_text]
expect(described_class).to have_graphql_fields(*expected_fields)
end
+
+ specify { expect(described_class.fields['richData'].type).not_to be_non_null }
+ specify { expect(described_class.fields['plainData'].type).not_to be_non_null }
+ specify { expect(described_class.fields['rawPath'].type).to be_non_null }
+ specify { expect(described_class.fields['size'].type).to be_non_null }
+ specify { expect(described_class.fields['binary'].type).to be_non_null }
+ specify { expect(described_class.fields['name'].type).not_to be_non_null }
+ specify { expect(described_class.fields['path'].type).not_to be_non_null }
+ specify { expect(described_class.fields['simpleViewer'].type).to be_non_null }
+ specify { expect(described_class.fields['richViewer'].type).not_to be_non_null }
+ specify { expect(described_class.fields['mode'].type).not_to be_non_null }
+ specify { expect(described_class.fields['externalStorage'].type).not_to be_non_null }
+ specify { expect(described_class.fields['renderedAsText'].type).to be_non_null }
end
diff --git a/spec/graphql/types/snippets/blob_viewer_type_spec.rb b/spec/graphql/types/snippets/blob_viewer_type_spec.rb
index a51d09813ab..841e22451db 100644
--- a/spec/graphql/types/snippets/blob_viewer_type_spec.rb
+++ b/spec/graphql/types/snippets/blob_viewer_type_spec.rb
@@ -3,10 +3,91 @@
require 'spec_helper'
describe GitlabSchema.types['SnippetBlobViewer'] do
+ let_it_be(:snippet) { create(:personal_snippet, :repository) }
+ let_it_be(:blob) { snippet.repository.blob_at('HEAD', 'files/images/6049019_460s.jpg') }
+
it 'has the correct fields' do
expected_fields = [:type, :load_async, :too_large, :collapsed,
:render_error, :file_type, :loading_partial_name]
expect(described_class).to have_graphql_fields(*expected_fields)
end
+
+ it { expect(described_class.fields['type'].type).to be_non_null }
+ it { expect(described_class.fields['loadAsync'].type).to be_non_null }
+ it { expect(described_class.fields['collapsed'].type).to be_non_null }
+ it { expect(described_class.fields['tooLarge'].type).to be_non_null }
+ it { expect(described_class.fields['renderError'].type).not_to be_non_null }
+ it { expect(described_class.fields['fileType'].type).to be_non_null }
+ it { expect(described_class.fields['loadingPartialName'].type).to be_non_null }
+
+ shared_examples 'nil field converted to false' do
+ subject { GitlabSchema.execute(query, context: { current_user: snippet.author }).as_json }
+
+ before do
+ allow_next_instance_of(SnippetPresenter) do |instance|
+ allow(instance).to receive(:blob).and_return(blob)
+ end
+ end
+
+ it 'returns false' do
+ snippet_blob = subject.dig('data', 'snippets', 'edges')[0].dig('node', 'blob')
+
+ expect(snippet_blob['path']).to eq blob.path
+ expect(blob_attribute).to be_nil
+ expect(snippet_blob['simpleViewer'][attribute]).to eq false
+ end
+ end
+
+ describe 'collapsed' do
+ it_behaves_like 'nil field converted to false' do
+ let(:query) do
+ %(
+ query {
+ snippets(ids:"#{snippet.to_global_id}"){
+ edges {
+ node {
+ blob {
+ path
+ simpleViewer {
+ collapsed
+ }
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ let(:attribute) { 'collapsed' }
+ let(:blob_attribute) { blob.simple_viewer.collapsed? }
+ end
+ end
+
+ describe 'tooLarge' do
+ it_behaves_like 'nil field converted to false' do
+ let(:query) do
+ %(
+ query {
+ snippets(ids:"#{snippet.to_global_id}"){
+ edges {
+ node {
+ blob {
+ path
+ simpleViewer {
+ tooLarge
+ }
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ let(:attribute) { 'tooLarge' }
+ let(:blob_attribute) { blob.simple_viewer.too_large? }
+ end
+ end
end
diff --git a/spec/graphql/types/time_type_spec.rb b/spec/graphql/types/time_type_spec.rb
index 88a535ed3bb..3c6e191e2fb 100644
--- a/spec/graphql/types/time_type_spec.rb
+++ b/spec/graphql/types/time_type_spec.rb
@@ -6,7 +6,7 @@ describe GitlabSchema.types['Time'] do
let(:iso) { "2018-06-04T15:23:50+02:00" }
let(:time) { Time.parse(iso) }
- it { expect(described_class.graphql_name).to eq('Time') }
+ specify { expect(described_class.graphql_name).to eq('Time') }
it 'coerces Time object into ISO 8601' do
expect(described_class.coerce_isolated_result(time)).to eq(iso)
diff --git a/spec/graphql/types/todo_type_spec.rb b/spec/graphql/types/todo_type_spec.rb
index 59118259d09..87a5405f0e2 100644
--- a/spec/graphql/types/todo_type_spec.rb
+++ b/spec/graphql/types/todo_type_spec.rb
@@ -9,5 +9,5 @@ describe GitlabSchema.types['Todo'] do
expect(described_class).to have_graphql_fields(*expected_fields)
end
- it { expect(described_class).to require_graphql_authorizations(:read_todo) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_todo) }
end
diff --git a/spec/graphql/types/tree/blob_type_spec.rb b/spec/graphql/types/tree/blob_type_spec.rb
index 516c862b9c6..547a03b5edf 100644
--- a/spec/graphql/types/tree/blob_type_spec.rb
+++ b/spec/graphql/types/tree/blob_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Types::Tree::BlobType do
- it { expect(described_class.graphql_name).to eq('Blob') }
+ specify { expect(described_class.graphql_name).to eq('Blob') }
- it { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_url, :lfs_oid) }
+ specify { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_url, :lfs_oid) }
end
diff --git a/spec/graphql/types/tree/submodule_type_spec.rb b/spec/graphql/types/tree/submodule_type_spec.rb
index 81f7ad825a1..b5cfe8eb812 100644
--- a/spec/graphql/types/tree/submodule_type_spec.rb
+++ b/spec/graphql/types/tree/submodule_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Types::Tree::SubmoduleType do
- it { expect(described_class.graphql_name).to eq('Submodule') }
+ specify { expect(described_class.graphql_name).to eq('Submodule') }
- it { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_url, :tree_url) }
+ specify { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_url, :tree_url) }
end
diff --git a/spec/graphql/types/tree/tree_entry_type_spec.rb b/spec/graphql/types/tree/tree_entry_type_spec.rb
index 228a4be0949..14826d06645 100644
--- a/spec/graphql/types/tree/tree_entry_type_spec.rb
+++ b/spec/graphql/types/tree/tree_entry_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Types::Tree::TreeEntryType do
- it { expect(described_class.graphql_name).to eq('TreeEntry') }
+ specify { expect(described_class.graphql_name).to eq('TreeEntry') }
- it { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_url) }
+ specify { expect(described_class).to have_graphql_fields(:id, :sha, :name, :type, :path, :flat_path, :web_url) }
end
diff --git a/spec/graphql/types/tree/tree_type_spec.rb b/spec/graphql/types/tree/tree_type_spec.rb
index 23779d75600..93faebd3602 100644
--- a/spec/graphql/types/tree/tree_type_spec.rb
+++ b/spec/graphql/types/tree/tree_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Types::Tree::TreeType do
- it { expect(described_class.graphql_name).to eq('Tree') }
+ specify { expect(described_class.graphql_name).to eq('Tree') }
- it { expect(described_class).to have_graphql_fields(:trees, :submodules, :blobs, :last_commit) }
+ specify { expect(described_class).to have_graphql_fields(:trees, :submodules, :blobs, :last_commit) }
end
diff --git a/spec/graphql/types/tree/type_enum_spec.rb b/spec/graphql/types/tree/type_enum_spec.rb
index 4caf9e1c457..dcacd6073f9 100644
--- a/spec/graphql/types/tree/type_enum_spec.rb
+++ b/spec/graphql/types/tree/type_enum_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Types::Tree::TypeEnum do
- it { expect(described_class.graphql_name).to eq('EntryType') }
+ specify { expect(described_class.graphql_name).to eq('EntryType') }
it 'exposes all tree entry types' do
expect(described_class.values.keys).to include(*%w[tree blob commit])
diff --git a/spec/graphql/types/user_type_spec.rb b/spec/graphql/types/user_type_spec.rb
index 8c76ce43e95..cf1e91afb80 100644
--- a/spec/graphql/types/user_type_spec.rb
+++ b/spec/graphql/types/user_type_spec.rb
@@ -3,13 +3,13 @@
require 'spec_helper'
describe GitlabSchema.types['User'] do
- it { expect(described_class.graphql_name).to eq('User') }
+ specify { expect(described_class.graphql_name).to eq('User') }
- it { expect(described_class).to require_graphql_authorizations(:read_user) }
+ specify { expect(described_class).to require_graphql_authorizations(:read_user) }
it 'has the expected fields' do
expected_fields = %w[
- user_permissions snippets name username avatarUrl webUrl todos
+ id user_permissions snippets name username avatarUrl webUrl todos state
]
expect(described_class).to have_graphql_fields(*expected_fields)