summaryrefslogtreecommitdiff
path: root/spec/support/shared_examples/graphql
diff options
context:
space:
mode:
Diffstat (limited to 'spec/support/shared_examples/graphql')
-rw-r--r--spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb6
-rw-r--r--spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb28
-rw-r--r--spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/graphql/spam_protection_shared_examples.rb85
-rw-r--r--spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb24
5 files changed, 143 insertions, 12 deletions
diff --git a/spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb b/spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb
index bb4270d7db6..fc795012ce7 100644
--- a/spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb
+++ b/spec/support/shared_examples/graphql/mutations/can_mutate_spammable_examples.rb
@@ -21,13 +21,13 @@ RSpec.shared_examples 'a mutation which can mutate a spammable' do
end
end
- describe "#with_spam_action_response_fields" do
+ describe "#spam_action_response_fields" do
it 'resolves with spam action fields' do
subject
# NOTE: We do not need to assert on the specific values of spam action fields here, we only need
- # to verify that #with_spam_action_response_fields was invoked and that the fields are present in the
- # response. The specific behavior of #with_spam_action_response_fields is covered in the
+ # to verify that #spam_action_response_fields was invoked and that the fields are present in the
+ # response. The specific behavior of #spam_action_response_fields is covered in the
# HasSpamActionResponseFields unit tests.
expect(mutation_response.keys)
.to include('spam', 'spamLogId', 'needsCaptchaResponse', 'captchaSiteKey')
diff --git a/spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb b/spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb
index cfa12171b7e..022e2308517 100644
--- a/spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/mutations/set_assignees_shared_examples.rb
@@ -10,22 +10,40 @@ RSpec.shared_examples 'an assignable resource' do
describe '#resolve' do
let_it_be(:assignee) { create(:user) }
let_it_be(:assignee2) { create(:user) }
+
let(:assignee_usernames) { [assignee.username] }
let(:mutated_resource) { subject[resource.class.name.underscore.to_sym] }
+ let(:mode) { described_class.arguments['operationMode'].default_value }
- subject { mutation.resolve(project_path: resource.project.full_path, iid: resource.iid, assignee_usernames: assignee_usernames) }
-
- before do
- resource.project.add_developer(assignee)
- resource.project.add_developer(assignee2)
+ subject do
+ mutation.resolve(project_path: resource.project.full_path,
+ iid: resource.iid,
+ operation_mode: mode,
+ assignee_usernames: assignee_usernames)
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
+ it 'does not change assignees if the resource is not accessible to the assignees' do
+ resource.project.add_developer(user)
+
+ expect { subject }.not_to change { resource.reload.assignee_ids }
+ end
+
+ it 'returns an operational error if the resource is not accessible to the assignees' do
+ resource.project.add_developer(user)
+
+ result = subject
+
+ expect(result[:errors]).to include a_string_matching(/Cannot assign/)
+ end
+
context 'when the user can update the resource' do
before do
+ resource.project.add_developer(assignee)
+ resource.project.add_developer(assignee2)
resource.project.add_developer(user)
end
diff --git a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
index f78ea364147..eaeb5faee3b 100644
--- a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
@@ -44,7 +44,7 @@
# end
# end
#
-RSpec.shared_examples 'sorted paginated query' do
+RSpec.shared_examples 'sorted paginated query' do |conditions = {}|
# Provided as a convenience when constructing queries using string concatenation
let(:page_info) { 'pageInfo { startCursor endCursor }' }
# Convenience for using default implementation of pagination_results_data
@@ -123,6 +123,16 @@ RSpec.shared_examples 'sorted paginated query' do
expect(results).to eq first_page
end
end
+
+ context 'when last and sort params are present', if: conditions[:is_reversible] do
+ let(:params) { sort_argument.merge(last: 1) }
+
+ it 'fetches last elements without error' do
+ post_graphql(pagination_query(params), current_user: current_user)
+
+ expect(results.first).to eq(expected_results.last)
+ end
+ end
end
end
end
diff --git a/spec/support/shared_examples/graphql/spam_protection_shared_examples.rb b/spec/support/shared_examples/graphql/spam_protection_shared_examples.rb
new file mode 100644
index 00000000000..8fb89a4f80e
--- /dev/null
+++ b/spec/support/shared_examples/graphql/spam_protection_shared_examples.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples 'has spam protection' do
+ include AfterNextHelpers
+
+ describe '#check_spam_action_response!' do
+ let(:variables) { nil }
+ let(:headers) { {} }
+ let(:spam_log_id) { 123 }
+ let(:captcha_site_key) { 'abc123' }
+
+ def send_request
+ post_graphql_mutation(mutation, current_user: current_user)
+ end
+
+ before do
+ allow_next(mutation_class).to receive(:spam_action_response_fields).and_return(
+ spam: spam,
+ needs_captcha_response: render_captcha,
+ spam_log_id: spam_log_id,
+ captcha_site_key: captcha_site_key
+ )
+ end
+
+ context 'when the object is spam (DISALLOW)' do
+ shared_examples 'disallow response' do
+ it 'informs the client that the request was denied as spam' do
+ send_request
+
+ expect(graphql_errors)
+ .to contain_exactly a_hash_including('message' => ::Mutations::SpamProtection::SPAM_DISALLOWED_MESSAGE)
+ expect(graphql_errors)
+ .to contain_exactly a_hash_including('extensions' => { "spam" => true })
+ end
+ end
+
+ let(:spam) { true }
+
+ context 'and no CAPTCHA is available' do
+ let(:render_captcha) { false }
+
+ it_behaves_like 'disallow response'
+ end
+
+ context 'and a CAPTCHA is required' do
+ let(:render_captcha) { true }
+
+ it_behaves_like 'disallow response'
+ end
+ end
+
+ context 'when the object is not spam (CONDITIONAL ALLOW)' do
+ let(:spam) { false }
+
+ context 'and no CAPTCHA is required' do
+ let(:render_captcha) { false }
+
+ it 'does not return a to-level error' do
+ send_request
+
+ expect(graphql_errors).to be_blank
+ end
+ end
+
+ context 'and a CAPTCHA is required' do
+ let(:render_captcha) { true }
+
+ it 'informs the client that the request may be retried after solving the CAPTCHA' do
+ send_request
+
+ expect(graphql_errors)
+ .to contain_exactly a_hash_including('message' => ::Mutations::SpamProtection::NEEDS_CAPTCHA_RESPONSE_MESSAGE)
+ expect(graphql_errors)
+ .to contain_exactly a_hash_including('extensions' => {
+ "captcha_site_key" => captcha_site_key,
+ "needs_captcha_response" => true,
+ "spam_log_id" => spam_log_id
+ })
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb b/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
index bc091a678e2..efb2c466f70 100644
--- a/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
@@ -13,18 +13,18 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
it 'raises an error if a required property is missing', :aggregate_failures do
expect { subject(deprecated: { milestone: '1.10' }) }.to raise_error(
ArgumentError,
- 'Please provide a `reason` within `deprecated`'
+ include("Reason can't be blank")
)
expect { subject(deprecated: { reason: 'Deprecation reason' }) }.to raise_error(
ArgumentError,
- 'Please provide a `milestone` within `deprecated`'
+ include("Milestone can't be blank")
)
end
it 'raises an error if milestone is not a String', :aggregate_failures do
expect { subject(deprecated: { milestone: 1.10, reason: 'Deprecation reason' }) }.to raise_error(
ArgumentError,
- '`milestone` must be a `String`'
+ include("Milestone must be a string")
)
end
end
@@ -49,4 +49,22 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
expect(deprecable.description).to be_nil
end
+
+ it 'adds information about the replacement if provided' do
+ deprecable = subject(deprecated: { milestone: '1.10', reason: :renamed, replacement: 'Foo.bar' })
+
+ expect(deprecable.deprecation_reason).to include 'Please use `Foo.bar`'
+ end
+
+ it 'supports named reasons: renamed' do
+ deprecable = subject(deprecated: { milestone: '1.10', reason: :renamed })
+
+ expect(deprecable.deprecation_reason).to include 'This was renamed.'
+ end
+
+ it 'supports named reasons: discouraged' do
+ deprecable = subject(deprecated: { milestone: '1.10', reason: :discouraged })
+
+ expect(deprecable.deprecation_reason).to include 'Use of this is not recommended.'
+ end
end