diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/graphql_controller_spec.rb | 38 | ||||
-rw-r--r-- | spec/graphql/gitlab_schema_spec.rb | 34 | ||||
-rw-r--r-- | spec/support/helpers/graphql_helpers.rb | 5 |
3 files changed, 77 insertions, 0 deletions
diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb index 6e7bcfdaa08..f9b15c9a48e 100644 --- a/spec/controllers/graphql_controller_spec.rb +++ b/spec/controllers/graphql_controller_spec.rb @@ -52,6 +52,44 @@ RSpec.describe GraphqlController do expect(response).to have_gitlab_http_status(:ok) end + it 'executes a simple query with no errors' do + post :execute, params: { query: '{ __typename }' } + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq({ 'data' => { '__typename' => 'Query' } }) + end + + it 'executes a simple multiplexed query with no errors' do + multiplex = [{ query: '{ __typename }' }] * 2 + + post :execute, params: { _json: multiplex } + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq([ + { 'data' => { '__typename' => 'Query' } }, + { 'data' => { '__typename' => 'Query' } } + ]) + end + + it 'sets a limit on the total query size' do + graphql_query = "{#{(['__typename'] * 1000).join(' ')}}" + + post :execute, params: { query: graphql_query } + + expect(response).to have_gitlab_http_status(:unprocessable_entity) + expect(json_response).to eq({ 'errors' => [{ 'message' => 'Query too large' }] }) + end + + it 'sets a limit on the total query size for multiplex queries' do + graphql_query = "{#{(['__typename'] * 200).join(' ')}}" + multiplex = [{ query: graphql_query }] * 5 + + post :execute, params: { _json: multiplex } + + expect(response).to have_gitlab_http_status(:unprocessable_entity) + expect(json_response).to eq({ 'errors' => [{ 'message' => 'Query too large' }] }) + end + it 'returns forbidden when user cannot access API' do # User cannot access API in a couple of cases # * When user is internal(like ghost users) diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb index 3fa0dc95126..02c686af688 100644 --- a/spec/graphql/gitlab_schema_spec.rb +++ b/spec/graphql/gitlab_schema_spec.rb @@ -35,6 +35,10 @@ RSpec.describe GitlabSchema do expect(connection).to eq(Gitlab::Graphql::Pagination::ExternallyPaginatedArrayConnection) end + it 'sets an appropriate validation timeout' do + expect(described_class.validate_timeout).to be <= 0.2.seconds + end + describe '.execute' do describe 'setting query `max_complexity` and `max_depth`' do subject(:result) { described_class.execute('query', **kwargs).query } @@ -195,6 +199,36 @@ RSpec.describe GitlabSchema do end end + describe 'validate_max_errors' do + it 'reports at most 5 errors' do + query = <<~GQL + query { + currentUser { + x: id + x: bot + x: username + x: state + x: name + + x: id + x: bot + x: username + x: state + x: name + + badField + veryBadField + alsoNotAGoodField + } + } + GQL + + result = described_class.execute(query) + + expect(result.to_h['errors'].count).to eq 5 + end + end + describe '.parse_gid' do let_it_be(:global_id) { 'gid://gitlab/TestOne/2147483647' } diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb index ee4621deb2d..1f0c9b658dc 100644 --- a/spec/support/helpers/graphql_helpers.rb +++ b/spec/support/helpers/graphql_helpers.rb @@ -374,6 +374,7 @@ module GraphqlHelpers allow_unlimited_graphql_depth if max_depth > 1 allow_high_graphql_recursion allow_high_graphql_transaction_threshold + allow_high_graphql_query_size type = class_name.respond_to?(:kind) ? class_name : GitlabSchema.types[class_name.to_s] raise "#{class_name} is not a known type in the GitlabSchema" unless type @@ -624,6 +625,10 @@ module GraphqlHelpers stub_const("Gitlab::QueryLimiting::Transaction::THRESHOLD", 1000) end + def allow_high_graphql_query_size + stub_const('GraphqlController::MAX_QUERY_SIZE', 10_000_000) + end + def node_array(data, extract_attribute = nil) data.map do |item| extract_attribute ? item['node'][extract_attribute] : item['node'] |