Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/graphql/mutations')
-rw-r--r--spec/graphql/mutations/base_mutation_spec.rb2
-rw-r--r--spec/graphql/mutations/boards/update_spec.rb8
-rw-r--r--spec/graphql/mutations/ci/runner/delete_spec.rb8
-rw-r--r--spec/graphql/mutations/ci/runner/update_spec.rb8
-rw-r--r--spec/graphql/mutations/clusters/agent_tokens/create_spec.rb8
-rw-r--r--spec/graphql/mutations/clusters/agent_tokens/delete_spec.rb52
-rw-r--r--spec/graphql/mutations/clusters/agent_tokens/revoke_spec.rb10
-rw-r--r--spec/graphql/mutations/clusters/agents/delete_spec.rb9
-rw-r--r--spec/graphql/mutations/concerns/mutations/finds_by_gid_spec.rb2
-rw-r--r--spec/graphql/mutations/container_expiration_policies/update_spec.rb6
-rw-r--r--spec/graphql/mutations/container_repositories/destroy_spec.rb8
-rw-r--r--spec/graphql/mutations/container_repositories/destroy_tags_spec.rb8
-rw-r--r--spec/graphql/mutations/customer_relations/contacts/create_spec.rb6
-rw-r--r--spec/graphql/mutations/dependency_proxy/group_settings/update_spec.rb2
-rw-r--r--spec/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb4
-rw-r--r--spec/graphql/mutations/discussions/toggle_resolve_spec.rb17
-rw-r--r--spec/graphql/mutations/environments/canary_ingress/update_spec.rb10
-rw-r--r--spec/graphql/mutations/incident_management/timeline_event/create_spec.rb51
-rw-r--r--spec/graphql/mutations/incident_management/timeline_event/destroy_spec.rb66
-rw-r--r--spec/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb85
-rw-r--r--spec/graphql/mutations/incident_management/timeline_event/update_spec.rb100
-rw-r--r--spec/graphql/mutations/issues/set_due_date_spec.rb2
-rw-r--r--spec/graphql/mutations/merge_requests/accept_spec.rb3
-rw-r--r--spec/graphql/mutations/merge_requests/create_spec.rb4
-rw-r--r--spec/graphql/mutations/namespace/package_settings/update_spec.rb6
-rw-r--r--spec/graphql/mutations/release_asset_links/delete_spec.rb12
-rw-r--r--spec/graphql/mutations/release_asset_links/update_spec.rb12
-rw-r--r--spec/graphql/mutations/timelogs/delete_spec.rb93
-rw-r--r--spec/graphql/mutations/todos/create_spec.rb15
-rw-r--r--spec/graphql/mutations/todos/mark_done_spec.rb9
-rw-r--r--spec/graphql/mutations/todos/restore_many_spec.rb7
-rw-r--r--spec/graphql/mutations/todos/restore_spec.rb9
32 files changed, 445 insertions, 197 deletions
diff --git a/spec/graphql/mutations/base_mutation_spec.rb b/spec/graphql/mutations/base_mutation_spec.rb
index 7939fadb37b..6b366b0c234 100644
--- a/spec/graphql/mutations/base_mutation_spec.rb
+++ b/spec/graphql/mutations/base_mutation_spec.rb
@@ -15,6 +15,7 @@ RSpec.describe ::Mutations::BaseMutation do
context 'when argument is nullable and required' do
let(:mutation_class) do
Class.new(described_class) do
+ graphql_name 'BaseMutation'
argument :foo, GraphQL::Types::String, required: :nullable
end
end
@@ -35,6 +36,7 @@ RSpec.describe ::Mutations::BaseMutation do
context 'when argument is required and NOT nullable' do
let(:mutation_class) do
Class.new(described_class) do
+ graphql_name 'BaseMutation'
argument :foo, GraphQL::Types::String, required: true
end
end
diff --git a/spec/graphql/mutations/boards/update_spec.rb b/spec/graphql/mutations/boards/update_spec.rb
index da3dfeecd4d..4785bc94624 100644
--- a/spec/graphql/mutations/boards/update_spec.rb
+++ b/spec/graphql/mutations/boards/update_spec.rb
@@ -29,14 +29,6 @@ RSpec.describe Mutations::Boards::Update do
end
end
- context 'with invalid params' do
- it 'raises an error' do
- mutation_params[:id] = project.to_global_id
-
- expect { subject }.to raise_error(::GraphQL::CoercionError)
- end
- end
-
context 'when user can update board' do
before do
board.resource_parent.add_reporter(user)
diff --git a/spec/graphql/mutations/ci/runner/delete_spec.rb b/spec/graphql/mutations/ci/runner/delete_spec.rb
index ee640b21918..06d360430f8 100644
--- a/spec/graphql/mutations/ci/runner/delete_spec.rb
+++ b/spec/graphql/mutations/ci/runner/delete_spec.rb
@@ -44,14 +44,6 @@ RSpec.describe Mutations::Ci::Runner::Delete do
end
end
- context 'with invalid params' do
- let(:mutation_params) { { id: "invalid-id" } }
-
- it 'raises an error' do
- expect { subject }.to raise_error(::GraphQL::CoercionError)
- end
- end
-
context 'when required arguments are missing' do
let(:mutation_params) { {} }
diff --git a/spec/graphql/mutations/ci/runner/update_spec.rb b/spec/graphql/mutations/ci/runner/update_spec.rb
index 0b3489d37dc..75e9b57e60a 100644
--- a/spec/graphql/mutations/ci/runner/update_spec.rb
+++ b/spec/graphql/mutations/ci/runner/update_spec.rb
@@ -33,14 +33,6 @@ RSpec.describe Mutations::Ci::Runner::Update do
end
end
- context 'with invalid params' do
- it 'raises an error' do
- mutation_params[:id] = "invalid-id"
-
- expect { subject }.to raise_error(::GraphQL::CoercionError)
- end
- end
-
context 'when required arguments are missing' do
let(:mutation_params) { {} }
diff --git a/spec/graphql/mutations/clusters/agent_tokens/create_spec.rb b/spec/graphql/mutations/clusters/agent_tokens/create_spec.rb
index fc025c8e3d3..45d421509d0 100644
--- a/spec/graphql/mutations/clusters/agent_tokens/create_spec.rb
+++ b/spec/graphql/mutations/clusters/agent_tokens/create_spec.rb
@@ -48,14 +48,6 @@ RSpec.describe Mutations::Clusters::AgentTokens::Create do
expect(token.description).to eq(description)
expect(token.name).to eq(name)
end
-
- context 'invalid params' do
- subject { mutation.resolve(cluster_agent_id: cluster_agent.id) }
-
- it 'generates an error message when id invalid', :aggregate_failures do
- expect { subject }.to raise_error(::GraphQL::CoercionError)
- end
- end
end
end
end
diff --git a/spec/graphql/mutations/clusters/agent_tokens/delete_spec.rb b/spec/graphql/mutations/clusters/agent_tokens/delete_spec.rb
deleted file mode 100644
index 5cdbc0f6d72..00000000000
--- a/spec/graphql/mutations/clusters/agent_tokens/delete_spec.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Mutations::Clusters::AgentTokens::Delete do
- let(:token) { create(:cluster_agent_token) }
- let(:user) { create(:user) }
-
- let(:mutation) do
- described_class.new(
- object: double,
- context: { current_user: user },
- field: double
- )
- end
-
- it { expect(described_class.graphql_name).to eq('ClusterAgentTokenDelete') }
- it { expect(described_class).to require_graphql_authorizations(:admin_cluster) }
-
- describe '#resolve' do
- let(:global_id) { token.to_global_id }
-
- subject { mutation.resolve(id: global_id) }
-
- context 'without user permissions' do
- it 'fails to delete the cluster agent', :aggregate_failures do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
- expect { token.reload }.not_to raise_error
- end
- end
-
- context 'with user permissions' do
- before do
- token.agent.project.add_maintainer(user)
- end
-
- it 'deletes a cluster agent', :aggregate_failures do
- expect { subject }.to change { ::Clusters::AgentToken.count }.by(-1)
- expect { token.reload }.to raise_error(ActiveRecord::RecordNotFound)
- end
- end
-
- context 'with invalid params' do
- let(:global_id) { token.id }
-
- it 'raises an error if the cluster agent id is invalid', :aggregate_failures do
- expect { subject }.to raise_error(::GraphQL::CoercionError)
- expect { token.reload }.not_to raise_error
- end
- end
- end
-end
diff --git a/spec/graphql/mutations/clusters/agent_tokens/revoke_spec.rb b/spec/graphql/mutations/clusters/agent_tokens/revoke_spec.rb
index f5f4c0cefad..1dd4eece246 100644
--- a/spec/graphql/mutations/clusters/agent_tokens/revoke_spec.rb
+++ b/spec/graphql/mutations/clusters/agent_tokens/revoke_spec.rb
@@ -40,16 +40,6 @@ RSpec.describe Mutations::Clusters::AgentTokens::Revoke do
expect(token.reload).to be_revoked
end
-
- context 'supplied ID is invalid' do
- let(:global_id) { token.id }
-
- it 'raises a coercion error' do
- expect { subject }.to raise_error(::GraphQL::CoercionError)
-
- expect(token.reload).not_to be_revoked
- end
- end
end
end
end
diff --git a/spec/graphql/mutations/clusters/agents/delete_spec.rb b/spec/graphql/mutations/clusters/agents/delete_spec.rb
index 0aabf53391a..e0ecff5fe44 100644
--- a/spec/graphql/mutations/clusters/agents/delete_spec.rb
+++ b/spec/graphql/mutations/clusters/agents/delete_spec.rb
@@ -38,14 +38,5 @@ RSpec.describe Mutations::Clusters::Agents::Delete do
expect { cluster_agent.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
end
-
- context 'with invalid params' do
- subject { mutation.resolve(id: cluster_agent.id) }
-
- it 'raises an error if the cluster agent id is invalid', :aggregate_failures do
- expect { subject }.to raise_error(::GraphQL::CoercionError)
- expect { cluster_agent.reload }.not_to raise_error
- end
- end
end
end
diff --git a/spec/graphql/mutations/concerns/mutations/finds_by_gid_spec.rb b/spec/graphql/mutations/concerns/mutations/finds_by_gid_spec.rb
index 37e0fd611e4..451f6d1fe06 100644
--- a/spec/graphql/mutations/concerns/mutations/finds_by_gid_spec.rb
+++ b/spec/graphql/mutations/concerns/mutations/finds_by_gid_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Mutations::FindsByGid do
end
end
- let(:query) { double('Query', schema: GitlabSchema) }
+ let(:query) { query_double(schema: GitlabSchema) }
let(:context) { GraphQL::Query::Context.new(query: query, object: nil, values: { current_user: user }) }
let(:user) { create(:user) }
let(:gid) { user.to_global_id }
diff --git a/spec/graphql/mutations/container_expiration_policies/update_spec.rb b/spec/graphql/mutations/container_expiration_policies/update_spec.rb
index e22fb951172..e070336ef76 100644
--- a/spec/graphql/mutations/container_expiration_policies/update_spec.rb
+++ b/spec/graphql/mutations/container_expiration_policies/update_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
let(:container_expiration_policy) { project.container_expiration_policy }
let(:params) { { project_path: project.full_path, cadence: '3month', keep_n: 100, older_than: '14d' } }
- specify { expect(described_class).to require_graphql_authorizations(:destroy_container_image) }
+ specify { expect(described_class).to require_graphql_authorizations(:admin_container_image) }
describe '#resolve' do
subject { described_class.new(object: project, context: { current_user: user }, field: nil).resolve(**params) }
@@ -76,7 +76,7 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
context 'with existing container expiration policy' do
where(:user_role, :shared_examples_name) do
:maintainer | 'updating the container expiration policy'
- :developer | 'updating the container expiration policy'
+ :developer | 'denying access to container expiration policy'
:reporter | 'denying access to container expiration policy'
:guest | 'denying access to container expiration policy'
:anonymous | 'denying access to container expiration policy'
@@ -96,7 +96,7 @@ RSpec.describe Mutations::ContainerExpirationPolicies::Update do
where(:user_role, :shared_examples_name) do
:maintainer | 'creating the container expiration policy'
- :developer | 'creating the container expiration policy'
+ :developer | 'denying access to container expiration policy'
:reporter | 'denying access to container expiration policy'
:guest | 'denying access to container expiration policy'
:anonymous | 'denying access to container expiration policy'
diff --git a/spec/graphql/mutations/container_repositories/destroy_spec.rb b/spec/graphql/mutations/container_repositories/destroy_spec.rb
index 3903196a511..97da7846339 100644
--- a/spec/graphql/mutations/container_repositories/destroy_spec.rb
+++ b/spec/graphql/mutations/container_repositories/destroy_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Mutations::ContainerRepositories::Destroy do
let_it_be(:user) { create(:user) }
let(:project) { container_repository.project }
- let(:id) { container_repository.to_global_id.to_s }
+ let(:id) { container_repository.to_global_id }
specify { expect(described_class).to require_graphql_authorizations(:destroy_container_image) }
@@ -57,11 +57,5 @@ RSpec.describe Mutations::ContainerRepositories::Destroy do
it_behaves_like params[:shared_examples_name]
end
end
-
- context 'with invalid id' do
- let(:id) { 'gid://gitlab/ContainerRepository/5555' }
-
- it_behaves_like 'denying access to container respository'
- end
end
end
diff --git a/spec/graphql/mutations/container_repositories/destroy_tags_spec.rb b/spec/graphql/mutations/container_repositories/destroy_tags_spec.rb
index f22d9ffe753..3e5f28ee244 100644
--- a/spec/graphql/mutations/container_repositories/destroy_tags_spec.rb
+++ b/spec/graphql/mutations/container_repositories/destroy_tags_spec.rb
@@ -3,10 +3,12 @@
require 'spec_helper'
RSpec.describe Mutations::ContainerRepositories::DestroyTags do
+ include GraphqlHelpers
+
include_context 'container repository delete tags service shared context'
using RSpec::Parameterized::TableSyntax
- let(:id) { repository.to_global_id.to_s }
+ let(:id) { repository.to_global_id }
specify { expect(described_class).to require_graphql_authorizations(:destroy_container_image) }
@@ -67,8 +69,8 @@ RSpec.describe Mutations::ContainerRepositories::DestroyTags do
end
end
- context 'with invalid id' do
- let(:id) { 'gid://gitlab/ContainerRepository/5555' }
+ context 'with non-existing id' do
+ let(:id) { global_id_of(id: non_existing_record_id, model_name: 'ContainerRepository') }
it_behaves_like 'denying access to container respository'
end
diff --git a/spec/graphql/mutations/customer_relations/contacts/create_spec.rb b/spec/graphql/mutations/customer_relations/contacts/create_spec.rb
index d17d11305b1..dafc7b4c367 100644
--- a/spec/graphql/mutations/customer_relations/contacts/create_spec.rb
+++ b/spec/graphql/mutations/customer_relations/contacts/create_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Mutations::CustomerRelations::Contacts::Create do
+ include GraphqlHelpers
+
let_it_be(:user) { create(:user) }
let(:group) { create(:group, :crm_enabled) }
@@ -78,9 +80,9 @@ RSpec.describe Mutations::CustomerRelations::Contacts::Create do
end
end
- context 'when organization_id is invalid' do
+ context 'when organization does not exist' do
before do
- valid_params[:organization_id] = "gid://gitlab/CustomerRelations::Organization/#{non_existing_record_id}"
+ valid_params[:organization_id] = global_id_of(model_name: 'CustomerRelations::Organization', id: non_existing_record_id)
end
it 'returns the relevant error' do
diff --git a/spec/graphql/mutations/dependency_proxy/group_settings/update_spec.rb b/spec/graphql/mutations/dependency_proxy/group_settings/update_spec.rb
index 35d3224d5ba..ae368e4d37e 100644
--- a/spec/graphql/mutations/dependency_proxy/group_settings/update_spec.rb
+++ b/spec/graphql/mutations/dependency_proxy/group_settings/update_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Mutations::DependencyProxy::GroupSettings::Update do
where(:user_role, :shared_examples_name) do
:maintainer | 'updating the dependency proxy group settings'
- :developer | 'updating the dependency proxy group settings'
+ :developer | 'denying access to dependency proxy group settings'
:reporter | 'denying access to dependency proxy group settings'
:guest | 'denying access to dependency proxy group settings'
:anonymous | 'denying access to dependency proxy group settings'
diff --git a/spec/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb b/spec/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
index 792e87f0d25..1e5059d7ef7 100644
--- a/spec/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
+++ b/spec/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
@@ -72,7 +72,7 @@ RSpec.describe Mutations::DependencyProxy::ImageTtlGroupPolicy::Update do
where(:user_role, :shared_examples_name) do
:maintainer | 'updating the dependency proxy image ttl policy'
- :developer | 'updating the dependency proxy image ttl policy'
+ :developer | 'denying access to dependency proxy image ttl policy'
:reporter | 'denying access to dependency proxy image ttl policy'
:guest | 'denying access to dependency proxy image ttl policy'
:anonymous | 'denying access to dependency proxy image ttl policy'
@@ -92,7 +92,7 @@ RSpec.describe Mutations::DependencyProxy::ImageTtlGroupPolicy::Update do
where(:user_role, :shared_examples_name) do
:maintainer | 'creating the dependency proxy image ttl policy'
- :developer | 'creating the dependency proxy image ttl policy'
+ :developer | 'denying access to dependency proxy image ttl policy'
:reporter | 'denying access to dependency proxy image ttl policy'
:guest | 'denying access to dependency proxy image ttl policy'
:anonymous | 'denying access to dependency proxy image ttl policy'
diff --git a/spec/graphql/mutations/discussions/toggle_resolve_spec.rb b/spec/graphql/mutations/discussions/toggle_resolve_spec.rb
index 2041b86d6e7..3f7347798e5 100644
--- a/spec/graphql/mutations/discussions/toggle_resolve_spec.rb
+++ b/spec/graphql/mutations/discussions/toggle_resolve_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Mutations::Discussions::ToggleResolve do
+ include GraphqlHelpers
+
subject(:mutation) do
described_class.new(object: nil, context: { current_user: user }, field: nil)
end
@@ -15,7 +17,7 @@ RSpec.describe Mutations::Discussions::ToggleResolve do
mutation.resolve(id: id_arg, resolve: resolve_arg)
end
- let(:id_arg) { discussion.to_global_id.to_s }
+ let(:id_arg) { global_id_of(discussion) }
let(:resolve_arg) { true }
let(:mutated_discussion) { subject[:discussion] }
let(:errors) { subject[:errors] }
@@ -36,7 +38,7 @@ RSpec.describe Mutations::Discussions::ToggleResolve do
let_it_be(:user) { create(:user, developer_projects: [project]) }
context 'when discussion cannot be found' do
- let(:id_arg) { "#{discussion.to_global_id}foo" }
+ let(:id_arg) { global_id_of(id: non_existing_record_id, model_name: discussion.class.name) }
it 'raises an error' do
expect { subject }.to raise_error(
@@ -46,17 +48,6 @@ RSpec.describe Mutations::Discussions::ToggleResolve do
end
end
- context 'when discussion is not a Discussion' do
- let(:discussion) { create(:note, noteable: noteable, project: project) }
-
- it 'raises an error' do
- expect { subject }.to raise_error(
- GraphQL::CoercionError,
- "\"#{discussion.to_global_id}\" does not represent an instance of Discussion"
- )
- end
- end
-
shared_examples 'returns a resolved discussion without errors' do
it 'returns a resolved discussion' do
expect(mutated_discussion).to be_resolved
diff --git a/spec/graphql/mutations/environments/canary_ingress/update_spec.rb b/spec/graphql/mutations/environments/canary_ingress/update_spec.rb
index fdf9cbaf25b..b93fb36a8ff 100644
--- a/spec/graphql/mutations/environments/canary_ingress/update_spec.rb
+++ b/spec/graphql/mutations/environments/canary_ingress/update_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Mutations::Environments::CanaryIngress::Update do
describe '#resolve' do
subject { mutation.resolve(id: environment_id, weight: weight) }
- let(:environment_id) { environment.to_global_id.to_s }
+ let(:environment_id) { environment.to_global_id }
let(:weight) { 50 }
let(:update_service) { double('update_service') }
@@ -62,14 +62,6 @@ RSpec.describe Mutations::Environments::CanaryIngress::Update do
end
end
- context 'when environment is not found' do
- let(:environment_id) { non_existing_record_id.to_s }
-
- it 'raises an error' do
- expect { subject }.to raise_error(GraphQL::CoercionError)
- end
- end
-
context 'when user is reporter who does not have permission to access the environment' do
let(:user) { reporter }
diff --git a/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb b/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb
new file mode 100644
index 00000000000..63faecad5d5
--- /dev/null
+++ b/spec/graphql/mutations/incident_management/timeline_event/create_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::IncidentManagement::TimelineEvent::Create do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:incident) { create(:incident, project: project) }
+
+ let(:args) { { note: 'note', occurred_at: Time.current } }
+
+ specify { expect(described_class).to require_graphql_authorizations(:admin_incident_management_timeline_event) }
+
+ describe '#resolve' do
+ subject(:resolve) { mutation_for(project, current_user).resolve(incident_id: incident.to_global_id, **args) }
+
+ context 'when a user has permissions to create a timeline event' do
+ let(:expected_timeline_event) do
+ instance_double(
+ 'IncidentManagement::TimelineEvent',
+ note: args[:note],
+ occurred_at: args[:occurred_at].to_s,
+ incident: incident,
+ author: current_user,
+ promoted_from_note: nil
+ )
+ end
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ it_behaves_like 'creating an incident timeline event'
+
+ context 'when TimelineEvents::CreateService responds with an error' do
+ let(:args) { {} }
+
+ it_behaves_like 'responding with an incident timeline errors',
+ errors: ["Occurred at can't be blank, Note can't be blank, and Note html can't be blank"]
+ end
+ end
+
+ it_behaves_like 'failing to create an incident timeline event'
+ 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/incident_management/timeline_event/destroy_spec.rb b/spec/graphql/mutations/incident_management/timeline_event/destroy_spec.rb
new file mode 100644
index 00000000000..4dd7b2ccb14
--- /dev/null
+++ b/spec/graphql/mutations/incident_management/timeline_event/destroy_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::IncidentManagement::TimelineEvent::Destroy do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:incident) { create(:incident, project: project) }
+
+ let(:timeline_event) { create(:incident_management_timeline_event, incident: incident, project: project) }
+ let(:args) { { id: timeline_event.to_global_id } }
+
+ specify { expect(described_class).to require_graphql_authorizations(:admin_incident_management_timeline_event) }
+
+ describe '#resolve' do
+ subject(:resolve) { mutation_for(project, current_user).resolve(**args) }
+
+ context 'when a user has permissions to delete timeline event' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ context 'when TimelineEvents::DestroyService responds with success' do
+ it 'returns the timeline event with no errors' do
+ expect(resolve).to eq(
+ timeline_event: timeline_event,
+ errors: []
+ )
+ end
+ end
+
+ context 'when TimelineEvents::DestroyService responds with an error' do
+ before do
+ allow_next_instance_of(::IncidentManagement::TimelineEvents::DestroyService) do |service|
+ allow(service)
+ .to receive(:execute)
+ .and_return(ServiceResponse.error(payload: { timeline_event: nil }, message: 'An error has occurred'))
+ end
+ end
+
+ it 'returns errors' do
+ expect(resolve).to eq(
+ timeline_event: nil,
+ errors: ['An error has occurred']
+ )
+ end
+ end
+ end
+
+ context 'when a user has no permissions to delete timeline event' do
+ before do
+ project.add_guest(current_user)
+ end
+
+ it 'raises an error' do
+ expect { resolve }.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/incident_management/timeline_event/promote_from_note_spec.rb b/spec/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb
new file mode 100644
index 00000000000..598ee496cf1
--- /dev/null
+++ b/spec/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::IncidentManagement::TimelineEvent::PromoteFromNote do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:incident) { create(:incident, project: project) }
+ let_it_be(:comment) { create(:note, project: project, noteable: incident) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:issue_comment) { create(:note, project: project, noteable: issue) }
+ let_it_be(:alert) { create(:alert_management_alert, project: project) }
+ let_it_be(:alert_comment) { create(:note, project: project, noteable: alert) }
+
+ let(:args) { { note_id: comment.to_global_id.to_s } }
+
+ specify { expect(described_class).to require_graphql_authorizations(:admin_incident_management_timeline_event) }
+
+ describe '#resolve' do
+ subject(:resolve) { mutation_for(project, current_user).resolve(**args) }
+
+ context 'when a user has permissions to create timeline event' do
+ let(:expected_timeline_event) do
+ instance_double(
+ 'IncidentManagement::TimelineEvent',
+ note: comment.note,
+ occurred_at: comment.created_at.to_s,
+ incident: incident,
+ author: current_user,
+ promoted_from_note: comment
+ )
+ end
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ it_behaves_like 'creating an incident timeline event'
+
+ context 'when TimelineEvents::CreateService responds with an error' do
+ before do
+ allow_next_instance_of(::IncidentManagement::TimelineEvents::CreateService) do |service|
+ allow(service).to receive(:execute).and_return(
+ ServiceResponse.error(payload: { timeline_event: nil }, message: 'Some error')
+ )
+ end
+ end
+
+ it_behaves_like 'responding with an incident timeline errors', errors: ['Some error']
+ end
+ end
+
+ context 'when note does not exist' do
+ let(:args) { { note_id: 'gid://gitlab/Note/0' } }
+
+ it 'raises an error' do
+ expect { resolve }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when note does not belong to an incident' do
+ let(:args) { { note_id: issue_comment.to_global_id.to_s } }
+
+ it 'raises an error' do
+ expect { resolve }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when note belongs to anything else but issuable' do
+ let(:args) { { note_id: alert_comment.to_global_id.to_s } }
+
+ it 'raises an error' do
+ expect { resolve }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ it_behaves_like 'failing to create an incident timeline event'
+ 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/incident_management/timeline_event/update_spec.rb b/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb
new file mode 100644
index 00000000000..8296e5c6c15
--- /dev/null
+++ b/spec/graphql/mutations/incident_management/timeline_event/update_spec.rb
@@ -0,0 +1,100 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::IncidentManagement::TimelineEvent::Update do
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:incident) { create(:incident, project: project) }
+ let_it_be_with_reload(:timeline_event) do
+ create(:incident_management_timeline_event, project: project, incident: incident)
+ end
+
+ let(:args) do
+ {
+ id: timeline_event_id,
+ note: note,
+ occurred_at: occurred_at
+ }
+ end
+
+ let(:note) { 'Updated Note' }
+ let(:timeline_event_id) { GitlabSchema.id_from_object(timeline_event).to_s }
+ let(:occurred_at) { 1.minute.ago }
+
+ before do
+ project.add_developer(developer)
+ project.add_reporter(reporter)
+ end
+
+ describe '#resolve' do
+ let(:current_user) { developer }
+
+ subject(:resolve) { mutation_for(current_user).resolve(**args) }
+
+ shared_examples 'failed update with a top-level access error' do |error|
+ specify do
+ expect { resolve }.to raise_error(
+ Gitlab::Graphql::Errors::ResourceNotAvailable,
+ error || Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
+ )
+ end
+ end
+
+ context 'when user has permissions to update the timeline event' do
+ context 'when timeline event exists' do
+ it 'updates the timeline event' do
+ expect { resolve }.to change { timeline_event.reload.note }.to(note)
+ .and change { timeline_event.reload.occurred_at.to_s }.to(occurred_at.to_s)
+ end
+
+ it 'returns updated timeline event' do
+ expect(resolve).to eq(
+ timeline_event: timeline_event.reload,
+ errors: []
+ )
+ end
+
+ context 'when there is a validation error' do
+ let(:occurred_at) { 'invalid date' }
+
+ it 'does not update the timeline event' do
+ expect { resolve }.not_to change { timeline_event.reload.updated_at }
+ end
+
+ it 'responds with error' do
+ expect(resolve).to eq(
+ timeline_event: nil,
+ errors: ["Occurred at can't be blank"]
+ )
+ end
+ end
+ end
+
+ context 'when timeline event cannot be found' do
+ let(:timeline_event_id) do
+ Gitlab::GlobalId.build(
+ nil,
+ model_name: ::IncidentManagement::TimelineEvent.name,
+ id: non_existing_record_id
+ ).to_s
+ end
+
+ it_behaves_like 'failed update with a top-level access error'
+ end
+ end
+
+ context 'when user does not have permissions to update the timeline event' do
+ let(:current_user) { reporter }
+
+ it_behaves_like 'failed update with a top-level access error'
+ end
+ end
+
+ private
+
+ def mutation_for(user)
+ described_class.new(object: nil, context: { current_user: user }, field: nil)
+ end
+end
diff --git a/spec/graphql/mutations/issues/set_due_date_spec.rb b/spec/graphql/mutations/issues/set_due_date_spec.rb
index 263122e5d5f..83edd670695 100644
--- a/spec/graphql/mutations/issues/set_due_date_spec.rb
+++ b/spec/graphql/mutations/issues/set_due_date_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe Mutations::Issues::SetDueDate do
it 'returns the issue with updated due date', :aggregate_failures do
expect(mutated_issue).to eq(issue)
- expect(mutated_issue.due_date).to eq(Date.today + 2.days)
+ expect(mutated_issue.due_date).to eq(due_date.to_date)
expect(subject[:errors]).to be_empty
end
diff --git a/spec/graphql/mutations/merge_requests/accept_spec.rb b/spec/graphql/mutations/merge_requests/accept_spec.rb
index c97c78ec206..c99b1d988c5 100644
--- a/spec/graphql/mutations/merge_requests/accept_spec.rb
+++ b/spec/graphql/mutations/merge_requests/accept_spec.rb
@@ -3,6 +3,7 @@
require 'spec_helper'
RSpec.describe Mutations::MergeRequests::Accept do
+ include GraphqlHelpers
include AfterNextHelpers
subject(:mutation) { described_class.new(context: context, object: nil, field: nil) }
@@ -12,7 +13,7 @@ RSpec.describe Mutations::MergeRequests::Accept do
let(:project) { create(:project, :public, :repository) }
let(:context) do
GraphQL::Query::Context.new(
- query: double('query', schema: GitlabSchema),
+ query: query_double(schema: GitlabSchema),
values: { current_user: user },
object: nil
)
diff --git a/spec/graphql/mutations/merge_requests/create_spec.rb b/spec/graphql/mutations/merge_requests/create_spec.rb
index 83af1e3f1b3..e1edb60e4ff 100644
--- a/spec/graphql/mutations/merge_requests/create_spec.rb
+++ b/spec/graphql/mutations/merge_requests/create_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Mutations::MergeRequests::Create do
+ include GraphqlHelpers
+
subject(:mutation) { described_class.new(object: nil, context: context, field: nil) }
let_it_be(:project) { create(:project, :public, :repository) }
@@ -10,7 +12,7 @@ RSpec.describe Mutations::MergeRequests::Create do
let(:context) do
GraphQL::Query::Context.new(
- query: double('query', schema: nil),
+ query: query_double(schema: nil),
values: { current_user: user },
object: nil
)
diff --git a/spec/graphql/mutations/namespace/package_settings/update_spec.rb b/spec/graphql/mutations/namespace/package_settings/update_spec.rb
index 978c81fadfa..631e02ff3dc 100644
--- a/spec/graphql/mutations/namespace/package_settings/update_spec.rb
+++ b/spec/graphql/mutations/namespace/package_settings/update_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Mutations::Namespace::PackageSettings::Update do
let(:params) { { namespace_path: namespace.full_path } }
- specify { expect(described_class).to require_graphql_authorizations(:create_package_settings) }
+ specify { expect(described_class).to require_graphql_authorizations(:admin_package) }
describe '#resolve' do
subject { described_class.new(object: namespace, context: { current_user: user }, field: nil).resolve(**params) }
@@ -68,7 +68,7 @@ RSpec.describe Mutations::Namespace::PackageSettings::Update do
where(:user_role, :shared_examples_name) do
:maintainer | 'updating the namespace package setting'
- :developer | 'updating the namespace package setting'
+ :developer | 'denying access to namespace package setting'
:reporter | 'denying access to namespace package setting'
:guest | 'denying access to namespace package setting'
:anonymous | 'denying access to namespace package setting'
@@ -88,7 +88,7 @@ RSpec.describe Mutations::Namespace::PackageSettings::Update do
where(:user_role, :shared_examples_name) do
:maintainer | 'creating the namespace package setting'
- :developer | 'creating the namespace package setting'
+ :developer | 'denying access to namespace package setting'
:reporter | 'denying access to namespace package setting'
:guest | 'denying access to namespace package setting'
:anonymous | 'denying access to namespace package setting'
diff --git a/spec/graphql/mutations/release_asset_links/delete_spec.rb b/spec/graphql/mutations/release_asset_links/delete_spec.rb
index cda292f2ffa..cca7bd2ba38 100644
--- a/spec/graphql/mutations/release_asset_links/delete_spec.rb
+++ b/spec/graphql/mutations/release_asset_links/delete_spec.rb
@@ -52,18 +52,12 @@ RSpec.describe Mutations::ReleaseAssetLinks::Delete do
end
context "when the link doesn't exist" do
- let(:mutation_arguments) { super().merge(id: "gid://gitlab/Releases::Link/#{non_existing_record_id}") }
-
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ let(:mutation_arguments) do
+ super().merge(id: global_id_of(id: non_existing_record_id, model_name: release_link.class.name))
end
- end
-
- context "when the provided ID is invalid" do
- let(:mutation_arguments) { super().merge(id: 'not-a-valid-gid') }
it 'raises an error' do
- expect { subject }.to raise_error(::GraphQL::CoercionError)
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
diff --git a/spec/graphql/mutations/release_asset_links/update_spec.rb b/spec/graphql/mutations/release_asset_links/update_spec.rb
index 64648687336..e119cf9cc77 100644
--- a/spec/graphql/mutations/release_asset_links/update_spec.rb
+++ b/spec/graphql/mutations/release_asset_links/update_spec.rb
@@ -186,18 +186,12 @@ RSpec.describe Mutations::ReleaseAssetLinks::Update do
end
context "when the link doesn't exist" do
- let(:mutation_arguments) { super().merge(id: "gid://gitlab/Releases::Link/#{non_existing_record_id}") }
-
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ let(:mutation_arguments) do
+ super().merge(id: global_id_of(id: non_existing_record_id, model_name: "Releases::Link"))
end
- end
-
- context "when the provided ID is invalid" do
- let(:mutation_arguments) { super().merge(id: 'not-a-valid-gid') }
it 'raises an error' do
- expect { subject }.to raise_error(::GraphQL::CoercionError)
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
diff --git a/spec/graphql/mutations/timelogs/delete_spec.rb b/spec/graphql/mutations/timelogs/delete_spec.rb
new file mode 100644
index 00000000000..f4a258e0f78
--- /dev/null
+++ b/spec/graphql/mutations/timelogs/delete_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::Timelogs::Delete do
+ include GraphqlHelpers
+
+ let_it_be(:author) { create(:user) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:administrator) { create(:user, :admin) }
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be_with_reload(:timelog) { create(:timelog, user: author, issue: issue, time_spent: 1800) }
+
+ let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
+ let(:timelog_id) { global_id_of(timelog) }
+ let(:mutation_arguments) { { id: timelog_id } }
+
+ describe '#resolve' do
+ subject(:resolve) do
+ mutation.resolve(**mutation_arguments)
+ end
+
+ context 'when the timelog id is not valid' do
+ let(:current_user) { author }
+ let(:timelog_id) { global_id_of(model_name: 'Timelog', id: non_existing_record_id) }
+
+ it 'raises Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when the current user is not the timelog\'s author, not a maintainer and not an admin' do
+ let(:current_user) { create(:user) }
+
+ it 'raises Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when the current user is the timelog\'s author' do
+ let(:current_user) { author }
+
+ it 'deletes the timelog' do
+ expect { subject }.to change { Timelog.count }.by(-1)
+ end
+
+ it 'returns the deleted timelog' do
+ expect(subject[:timelog]).to eq(timelog)
+ end
+
+ it 'returns no errors' do
+ expect(subject[:errors]).to be_empty
+ end
+ end
+
+ context 'when the current user is not the timelog\'s author but a maintainer of the project' do
+ let(:current_user) { maintainer }
+
+ before do
+ project.add_maintainer(maintainer)
+ end
+
+ it 'deletes the timelog' do
+ expect { subject }.to change { Timelog.count }.by(-1)
+ end
+
+ it 'returns the deleted timelog' do
+ expect(subject[:timelog]).to eq(timelog)
+ end
+
+ it 'returns no errors' do
+ expect(subject[:errors]).to be_empty
+ end
+ end
+
+ context 'when the current user is not the timelog\'s author, not a maintainer but an admin', :enable_admin_mode do
+ let(:current_user) { administrator }
+
+ it 'deletes the timelog' do
+ expect { subject }.to change { Timelog.count }.by(-1)
+ end
+
+ it 'returns the deleted timelog' do
+ expect(subject[:timelog]).to eq(timelog)
+ end
+
+ it 'returns no errors' do
+ expect(subject[:errors]).to be_empty
+ end
+ end
+ end
+end
diff --git a/spec/graphql/mutations/todos/create_spec.rb b/spec/graphql/mutations/todos/create_spec.rb
index bbb033e2f33..8c6dca98bad 100644
--- a/spec/graphql/mutations/todos/create_spec.rb
+++ b/spec/graphql/mutations/todos/create_spec.rb
@@ -10,12 +10,19 @@ RSpec.describe Mutations::Todos::Create do
context 'when target does not support todos' do
it 'raises error' do
current_user = create(:user)
- mutation = described_class.new(object: nil, context: { current_user: current_user }, field: nil)
-
target = create(:milestone)
- expect { mutation.resolve(target_id: global_id_of(target)) }
- .to raise_error(GraphQL::CoercionError)
+ ctx = { current_user: current_user }
+ input = { target_id: global_id_of(target).to_s }
+ mutation = graphql_mutation(described_class, input)
+
+ response = GitlabSchema.execute(mutation.query, context: ctx, variables: mutation.variables).to_h
+
+ expect(response).to include(
+ 'errors' => contain_exactly(
+ include('message' => /invalid value for targetId/)
+ )
+ )
end
end
diff --git a/spec/graphql/mutations/todos/mark_done_spec.rb b/spec/graphql/mutations/todos/mark_done_spec.rb
index 9723ac8af42..51df2032cf1 100644
--- a/spec/graphql/mutations/todos/mark_done_spec.rb
+++ b/spec/graphql/mutations/todos/mark_done_spec.rb
@@ -56,15 +56,6 @@ RSpec.describe Mutations::Todos::MarkDone do
expect(todo2.reload.state).to eq('done')
expect(other_user_todo.reload.state).to eq('pending')
end
-
- it 'ignores invalid GIDs' do
- expect { mutation.resolve(id: author.to_global_id.to_s) }
- .to raise_error(::GraphQL::CoercionError)
-
- expect(todo1.reload.state).to eq('pending')
- expect(todo2.reload.state).to eq('done')
- expect(other_user_todo.reload.state).to eq('pending')
- end
end
def mark_done_mutation(todo)
diff --git a/spec/graphql/mutations/todos/restore_many_spec.rb b/spec/graphql/mutations/todos/restore_many_spec.rb
index dc10355ef22..d43f1c8a2e9 100644
--- a/spec/graphql/mutations/todos/restore_many_spec.rb
+++ b/spec/graphql/mutations/todos/restore_many_spec.rb
@@ -49,13 +49,6 @@ RSpec.describe Mutations::Todos::RestoreMany do
expect_states_were_not_changed
end
- it 'raises an error with invalid or non-Todo GIDs' do
- expect { mutation.resolve(ids: [author.to_global_id.to_s]) }
- .to raise_error(GraphQL::CoercionError)
-
- expect_states_were_not_changed
- end
-
it 'restores multiple todos' do
todo4 = create(:todo, user: current_user, author: author, state: :done)
diff --git a/spec/graphql/mutations/todos/restore_spec.rb b/spec/graphql/mutations/todos/restore_spec.rb
index 954bb3db668..fad9d6c08a6 100644
--- a/spec/graphql/mutations/todos/restore_spec.rb
+++ b/spec/graphql/mutations/todos/restore_spec.rb
@@ -56,15 +56,6 @@ RSpec.describe Mutations::Todos::Restore do
expect(todo2.reload.state).to eq('pending')
expect(other_user_todo.reload.state).to eq('done')
end
-
- it 'raises error for invalid GID' do
- expect { mutation.resolve(id: author.to_global_id.to_s) }
- .to raise_error(::GraphQL::CoercionError)
-
- expect(todo1.reload.state).to eq('done')
- expect(todo2.reload.state).to eq('pending')
- expect(other_user_todo.reload.state).to eq('done')
- end
end
def restore_mutation(todo)