debian-mirror-gitlab/spec/requests/api/graphql/gitlab_schema_spec.rb

220 lines
6.6 KiB
Ruby
Raw Normal View History

2019-12-26 22:10:19 +05:30
# frozen_string_literal: true
2019-07-07 11:18:12 +05:30
require 'spec_helper'
2020-07-28 23:09:34 +05:30
RSpec.describe 'GitlabSchema configurations' do
2019-07-07 11:18:12 +05:30
include GraphqlHelpers
2020-03-09 13:42:32 +05:30
let_it_be(:project) { create(:project) }
2019-07-07 11:18:12 +05:30
2019-09-04 21:01:54 +05:30
shared_examples 'imposing query limits' do
2020-01-03 18:37:03 +05:30
describe 'timeouts' do
context 'when timeout is reached' do
it 'shows an error' do
2020-04-08 14:13:33 +05:30
allow_any_instance_of(Gitlab::Graphql::Timeout).to receive(:max_seconds).and_return(0)
2020-01-03 18:37:03 +05:30
2020-04-08 14:13:33 +05:30
subject
expect_graphql_errors_to_include /Timeout/
2020-01-03 18:37:03 +05:30
end
end
end
2019-09-04 21:01:54 +05:30
describe '#max_complexity' do
context 'when complexity is too high' do
it 'shows an error' do
allow(GitlabSchema).to receive(:max_query_complexity).and_return 1
2019-07-07 11:18:12 +05:30
2019-09-04 21:01:54 +05:30
subject
2019-07-07 11:18:12 +05:30
2019-10-31 01:37:42 +05:30
expect_graphql_errors_to_include /which exceeds max complexity of 1/
2019-09-04 21:01:54 +05:30
end
end
end
describe '#max_depth' do
context 'when query depth is too high' do
it 'shows error' do
allow(GitlabSchema).to receive(:max_query_depth).and_return 1
subject
2019-10-31 01:37:42 +05:30
expect_graphql_errors_to_include /exceeds max depth/
2019-09-04 21:01:54 +05:30
end
end
context 'when query depth is within range' do
it 'has no error' do
allow(GitlabSchema).to receive(:max_query_depth).and_return 5
subject
2019-10-31 01:37:42 +05:30
expect_graphql_errors_to_be_empty
end
end
end
end
context 'depth, complexity and recursion checking' do
context 'unauthenticated recursive queries' do
context 'a not-quite-recursive-enough introspective query' do
it 'succeeds' do
query = File.read(Rails.root.join('spec/fixtures/api/graphql/small-recursive-introspection.graphql'))
post_graphql(query, current_user: nil)
expect_graphql_errors_to_be_empty
end
end
2020-03-09 13:42:32 +05:30
context 'failing queries' do
before do
allow(GitlabSchema).to receive(:max_query_recursion).and_return 1
end
2019-10-31 01:37:42 +05:30
2020-03-09 13:42:32 +05:30
context 'a recursive introspective query' do
it 'fails due to recursion' do
query = File.read(Rails.root.join('spec/fixtures/api/graphql/recursive-introspection.graphql'))
2019-10-31 01:37:42 +05:30
2020-03-09 13:42:32 +05:30
post_graphql(query, current_user: nil)
expect_graphql_errors_to_include [/Recursive query/]
end
2019-10-31 01:37:42 +05:30
end
2020-03-09 13:42:32 +05:30
context 'a recursive non-introspective query' do
before do
allow(GitlabSchema).to receive(:max_query_complexity).and_return 1
allow(GitlabSchema).to receive(:max_query_depth).and_return 1
allow(GitlabSchema).to receive(:max_query_complexity).and_return 1
end
2019-10-31 01:37:42 +05:30
2020-03-09 13:42:32 +05:30
shared_examples 'fails due to recursion, complexity and depth' do |fixture_file|
it 'fails due to recursion, complexity and depth' do
query = File.read(Rails.root.join(fixture_file))
post_graphql(query, current_user: nil)
expect_graphql_errors_to_include [/Recursive query/, /exceeds max complexity/, /exceeds max depth/]
end
end
2019-10-31 01:37:42 +05:30
2020-03-09 13:42:32 +05:30
context 'using `nodes` notation' do
it_behaves_like 'fails due to recursion, complexity and depth', 'spec/fixtures/api/graphql/recursive-query-nodes.graphql'
end
context 'using `edges -> node` notation' do
it_behaves_like 'fails due to recursion, complexity and depth', 'spec/fixtures/api/graphql/recursive-query-edges-node.graphql'
end
2019-09-04 21:01:54 +05:30
end
end
end
end
context 'regular queries' do
subject do
query = graphql_query_for('project', { 'fullPath' => project.full_path }, %w(id name description))
post_graphql(query)
end
it_behaves_like 'imposing query limits'
end
context 'multiplexed queries' do
let(:current_user) { nil }
subject do
queries = [
{ query: graphql_query_for('project', { 'fullPath' => '$fullPath' }, %w(id name description)) },
{ query: graphql_query_for('echo', { 'text' => "$test" }, []), variables: { "test" => "Hello world" } },
{ query: graphql_query_for('project', { 'fullPath' => project.full_path }, "userPermissions { createIssue }") }
]
post_multiplex(queries, current_user: current_user)
end
it 'does not authenticate all queries' do
subject
expect(json_response.last['data']['project']).to be_nil
end
it_behaves_like 'imposing query limits' do
2020-04-08 14:13:33 +05:30
it 'fails all queries when only one of the queries is too complex' do
2019-09-04 21:01:54 +05:30
# The `project` query above has a complexity of 5
allow(GitlabSchema).to receive(:max_query_complexity).and_return 4
subject
# Expect a response for each query, even though it will be empty
expect(json_response.size).to eq(3)
json_response.each do |single_query_response|
expect(single_query_response).not_to have_key('data')
end
# Expect errors for each query
expect(graphql_errors.size).to eq(3)
graphql_errors.each do |single_query_errors|
2019-10-31 01:37:42 +05:30
expect_graphql_errors_to_include(/which exceeds max complexity of 4/)
2019-09-04 21:01:54 +05:30
end
end
end
context 'authentication' do
let(:current_user) { project.owner }
it 'authenticates all queries' do
subject
expect(json_response.last['data']['project']['userPermissions']['createIssue']).to be(true)
end
end
2019-07-07 11:18:12 +05:30
end
context 'when IntrospectionQuery' do
2019-10-31 01:37:42 +05:30
it 'is not too complex nor recursive' do
2019-07-07 11:18:12 +05:30
query = File.read(Rails.root.join('spec/fixtures/api/graphql/introspection.graphql'))
post_graphql(query, current_user: nil)
2019-10-31 01:37:42 +05:30
expect_graphql_errors_to_be_empty
2019-07-07 11:18:12 +05:30
end
end
2019-09-04 21:01:54 +05:30
context 'logging' do
let(:query) { File.read(Rails.root.join('spec/fixtures/api/graphql/introspection.graphql')) }
it 'logs the query complexity and depth' do
analyzer_memo = {
query_string: query,
variables: {}.to_s,
complexity: 181,
2019-12-04 20:38:33 +05:30
depth: 13,
2020-05-24 23:13:21 +05:30
duration_s: 7
2019-09-04 21:01:54 +05:30
}
expect_any_instance_of(Gitlab::Graphql::QueryAnalyzers::LoggerAnalyzer).to receive(:duration).and_return(7)
expect(Gitlab::GraphqlLogger).to receive(:info).with(analyzer_memo)
post_graphql(query, current_user: nil)
end
it 'logs using `format_message`' do
expect_any_instance_of(Gitlab::GraphqlLogger).to receive(:format_message)
post_graphql(query, current_user: nil)
end
end
context "global id's" do
it 'uses GlobalID to expose ids' do
post_graphql(graphql_query_for('project', { 'fullPath' => project.full_path }, %w(id)),
current_user: project.owner)
parsed_id = GlobalID.parse(graphql_data['project']['id'])
expect(parsed_id).to eq(project.to_global_id)
end
end
2019-07-07 11:18:12 +05:30
end