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/lib/gitlab/graphql')
-rw-r--r--spec/lib/gitlab/graphql/authorize/authorize_resource_spec.rb32
-rw-r--r--spec/lib/gitlab/graphql/markdown_field_spec.rb40
-rw-r--r--spec/lib/gitlab/graphql/negatable_arguments_spec.rb4
-rw-r--r--spec/lib/gitlab/graphql/pagination/keyset/connection_generic_keyset_spec.rb4
-rw-r--r--spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb4
-rw-r--r--spec/lib/gitlab/graphql/present/field_extension_spec.rb17
-rw-r--r--spec/lib/gitlab/graphql/query_analyzers/ast/logger_analyzer_spec.rb51
-rw-r--r--spec/lib/gitlab/graphql/query_analyzers/ast/recursion_analyzer_spec.rb72
-rw-r--r--spec/lib/gitlab/graphql/query_analyzers/logger_analyzer_spec.rb49
-rw-r--r--spec/lib/gitlab/graphql/tracers/logger_tracer_spec.rb6
10 files changed, 191 insertions, 88 deletions
diff --git a/spec/lib/gitlab/graphql/authorize/authorize_resource_spec.rb b/spec/lib/gitlab/graphql/authorize/authorize_resource_spec.rb
index 0c548e1ce32..ac512e28e7b 100644
--- a/spec/lib/gitlab/graphql/authorize/authorize_resource_spec.rb
+++ b/spec/lib/gitlab/graphql/authorize/authorize_resource_spec.rb
@@ -103,4 +103,36 @@ RSpec.describe Gitlab::Graphql::Authorize::AuthorizeResource do
.to contain_exactly(:base_authorization, :sub_authorization)
end
end
+
+ describe 'authorizes_object?' do
+ it 'is false by default' do
+ a_class = Class.new do
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+ end
+
+ expect(a_class).not_to be_authorizes_object
+ end
+
+ it 'is true after calling authorizes_object!' do
+ a_class = Class.new do
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ authorizes_object!
+ end
+
+ expect(a_class).to be_authorizes_object
+ end
+
+ it 'is true if a parent authorizes_object' do
+ parent = Class.new do
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ authorizes_object!
+ end
+
+ child = Class.new(parent)
+
+ expect(child).to be_authorizes_object
+ end
+ end
end
diff --git a/spec/lib/gitlab/graphql/markdown_field_spec.rb b/spec/lib/gitlab/graphql/markdown_field_spec.rb
index ed3f19d8cf2..974951ab30c 100644
--- a/spec/lib/gitlab/graphql/markdown_field_spec.rb
+++ b/spec/lib/gitlab/graphql/markdown_field_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Graphql::MarkdownField do
include Gitlab::Routing
+ include GraphqlHelpers
describe '.markdown_field' do
it 'creates the field with some default attributes' do
@@ -21,21 +22,12 @@ RSpec.describe Gitlab::Graphql::MarkdownField do
expect { class_with_markdown_field(:test_html, null: true, resolver: 'not really') }
.to raise_error(expected_error)
end
-
- # TODO: remove as part of https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27536
- # so that until that time, the developer check is there
- it 'raises when passing a resolve block' do
- expect { class_with_markdown_field(:test_html, null: true, resolve: -> (_, _, _) { 'not really' } ) }
- .to raise_error(expected_error)
- end
end
context 'resolving markdown' do
let_it_be(:note) { build(:note, note: '# Markdown!') }
let_it_be(:expected_markdown) { '<h1 data-sourcepos="1:1-1:11" dir="auto">Markdown!</h1>' }
- let_it_be(:query_type) { GraphQL::ObjectType.new }
- let_it_be(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
- let_it_be(:query) { GraphQL::Query.new(schema, document: nil, context: {}, variables: {}) }
+ let_it_be(:query) { GraphQL::Query.new(empty_schema, document: nil, context: {}, variables: {}) }
let_it_be(:context) { GraphQL::Query::Context.new(query: query, values: {}, object: nil) }
let(:type_class) { class_with_markdown_field(:note_html, null: false) }
@@ -55,6 +47,20 @@ RSpec.describe Gitlab::Graphql::MarkdownField do
end
end
+ context 'when a block is passed for the resolved object' do
+ let(:type_class) do
+ class_with_markdown_field(:note_html, null: false) do |resolved_object|
+ resolved_object.object
+ end
+ end
+
+ let(:type_instance) { type_class.authorized_new(class_wrapped_object(note), context) }
+
+ it 'renders markdown from the same property as the field name without the `_html` suffix' do
+ expect(field.resolve(type_instance, {}, context)).to eq(expected_markdown)
+ end
+ end
+
describe 'basic verification that references work' do
let_it_be(:project) { create(:project, :public) }
@@ -83,12 +89,22 @@ RSpec.describe Gitlab::Graphql::MarkdownField do
end
end
- def class_with_markdown_field(name, **args)
+ def class_with_markdown_field(name, **args, &blk)
Class.new(Types::BaseObject) do
prepend Gitlab::Graphql::MarkdownField
graphql_name 'MarkdownFieldTest'
- markdown_field name, **args
+ markdown_field name, **args, &blk
end
end
+
+ def class_wrapped_object(object)
+ Class.new do
+ def initialize(object)
+ @object = object
+ end
+
+ attr_accessor :object
+ end.new(object)
+ end
end
diff --git a/spec/lib/gitlab/graphql/negatable_arguments_spec.rb b/spec/lib/gitlab/graphql/negatable_arguments_spec.rb
index 71ef75836c0..04ee1c1b820 100644
--- a/spec/lib/gitlab/graphql/negatable_arguments_spec.rb
+++ b/spec/lib/gitlab/graphql/negatable_arguments_spec.rb
@@ -25,7 +25,9 @@ RSpec.describe Gitlab::Graphql::NegatableArguments do
expect(test_resolver.arguments['not'].type.arguments.keys).to match_array(['foo'])
end
- it 'defines all arguments passed as block even if called multiple times' do
+ # TODO: suffers from the `DuplicateNamesError` error. skip until we upgrade
+ # to the graphql 2.0 gem https://gitlab.com/gitlab-org/gitlab/-/issues/363131
+ xit 'defines all arguments passed as block even if called multiple times' do
test_resolver.negated do
argument :foo, GraphQL::Types::String, required: false
end
diff --git a/spec/lib/gitlab/graphql/pagination/keyset/connection_generic_keyset_spec.rb b/spec/lib/gitlab/graphql/pagination/keyset/connection_generic_keyset_spec.rb
index b6c3cb4e04a..97613edee5e 100644
--- a/spec/lib/gitlab/graphql/pagination/keyset/connection_generic_keyset_spec.rb
+++ b/spec/lib/gitlab/graphql/pagination/keyset/connection_generic_keyset_spec.rb
@@ -9,9 +9,7 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do
# The spec will be merged with connection_spec.rb in the future.
let(:nodes) { Project.all.order(id: :asc) }
let(:arguments) { {} }
- let(:query_type) { GraphQL::ObjectType.new }
- let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
- let(:context) { GraphQL::Query::Context.new(query: query_double(schema: schema), values: nil, object: nil) }
+ let(:context) { GraphQL::Query::Context.new(query: query_double, values: nil, object: nil) }
let_it_be(:column_order_id) { Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(attribute_name: 'id', order_expression: Project.arel_table[:id].asc) }
let_it_be(:column_order_id_desc) { Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(attribute_name: 'id', order_expression: Project.arel_table[:id].desc) }
diff --git a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
index a4ba288b7f1..61a79d90546 100644
--- a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
+++ b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
@@ -7,9 +7,7 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do
let(:nodes) { Project.all.order(id: :asc) }
let(:arguments) { {} }
- let(:query_type) { GraphQL::ObjectType.new }
- let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
- let(:context) { GraphQL::Query::Context.new(query: query_double(schema: schema), values: nil, object: nil) }
+ let(:context) { GraphQL::Query::Context.new(query: query_double, values: nil, object: nil) }
subject(:connection) do
described_class.new(nodes, **{ context: context, max_page_size: 3 }.merge(arguments))
diff --git a/spec/lib/gitlab/graphql/present/field_extension_spec.rb b/spec/lib/gitlab/graphql/present/field_extension_spec.rb
index 5f0f444e0bb..49992d7b71f 100644
--- a/spec/lib/gitlab/graphql/present/field_extension_spec.rb
+++ b/spec/lib/gitlab/graphql/present/field_extension_spec.rb
@@ -143,23 +143,6 @@ RSpec.describe Gitlab::Graphql::Present::FieldExtension do
it_behaves_like 'calling the presenter method'
end
- # This is exercised here using an explicit `resolve:` proc, but
- # @resolver_proc values are used in field instrumentation as well.
- context 'when the field uses a resolve proc' do
- let(:presenter) { base_presenter }
- let(:field) do
- ::Types::BaseField.new(
- name: field_name,
- type: GraphQL::Types::String,
- null: true,
- owner: owner,
- resolve: ->(obj, args, ctx) { 'Hello from a proc' }
- )
- end
-
- specify { expect(resolve_value).to eq 'Hello from a proc' }
- end
-
context 'when the presenter provides a new method' do
def presenter
Class.new(base_presenter) do
diff --git a/spec/lib/gitlab/graphql/query_analyzers/ast/logger_analyzer_spec.rb b/spec/lib/gitlab/graphql/query_analyzers/ast/logger_analyzer_spec.rb
new file mode 100644
index 00000000000..a5274d49fdb
--- /dev/null
+++ b/spec/lib/gitlab/graphql/query_analyzers/ast/logger_analyzer_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Graphql::QueryAnalyzers::AST::LoggerAnalyzer do
+ let(:query) { GraphQL::Query.new(GitlabSchema, document: document, context: {}, variables: { body: 'some note' }) }
+ let(:document) do
+ GraphQL.parse <<-GRAPHQL
+ mutation createNote($body: String!) {
+ createNote(input: {noteableId: "gid://gitlab/Noteable/1", body: $body}) {
+ note {
+ id
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ describe '#result' do
+ let(:monotonic_time_before) { 42 }
+ let(:monotonic_time_after) { 500 }
+ let(:monotonic_time_duration) { monotonic_time_after - monotonic_time_before }
+
+ before do
+ RequestStore.store[:graphql_logs] = nil
+
+ allow(Gitlab::Metrics::System).to receive(:monotonic_time)
+ .and_return(monotonic_time_before, monotonic_time_before,
+ monotonic_time_before, monotonic_time_before,
+ monotonic_time_after)
+ end
+
+ it 'returns the complexity, depth, duration, etc' do
+ results = GraphQL::Analysis::AST.analyze_query(query, [described_class], multiplex_analyzers: [])
+ result = results.first
+
+ expect(result[:duration_s]).to eq monotonic_time_duration
+ expect(result[:depth]).to eq 3
+ expect(result[:complexity]).to eq 3
+ expect(result[:used_fields]).to eq ['Note.id', 'CreateNotePayload.note', 'Mutation.createNote']
+ expect(result[:used_deprecated_fields]).to eq []
+
+ request = result.except(:duration_s).merge({
+ operation_name: 'createNote',
+ variables: { body: "[FILTERED]" }.to_s
+ })
+
+ expect(RequestStore.store[:graphql_logs]).to match([request])
+ end
+ end
+end
diff --git a/spec/lib/gitlab/graphql/query_analyzers/ast/recursion_analyzer_spec.rb b/spec/lib/gitlab/graphql/query_analyzers/ast/recursion_analyzer_spec.rb
new file mode 100644
index 00000000000..997fb129f42
--- /dev/null
+++ b/spec/lib/gitlab/graphql/query_analyzers/ast/recursion_analyzer_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Graphql::QueryAnalyzers::AST::RecursionAnalyzer do
+ let(:query) { GraphQL::Query.new(GitlabSchema, document: document, context: {}, variables: { body: 'some note' }) }
+
+ context 'when recursion threshold not exceeded' do
+ let(:document) do
+ GraphQL.parse <<-GRAPHQL
+ query recurse {
+ group(fullPath: "h5bp") {
+ projects {
+ nodes {
+ name
+ group {
+ projects {
+ nodes {
+ name
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ it 'returns the complexity, depth, duration, etc' do
+ result = GraphQL::Analysis::AST.analyze_query(query, [described_class], multiplex_analyzers: [])
+
+ expect(result.first).to be_nil
+ end
+ end
+
+ context 'when recursion threshold exceeded' do
+ let(:document) do
+ GraphQL.parse <<-GRAPHQL
+ query recurse {
+ group(fullPath: "h5bp") {
+ projects {
+ nodes {
+ name
+ group {
+ projects {
+ nodes {
+ name
+ group {
+ projects {
+ nodes {
+ name
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ it 'returns error' do
+ result = GraphQL::Analysis::AST.analyze_query(query, [described_class], multiplex_analyzers: [])
+
+ expect(result.first.is_a?(GraphQL::AnalysisError)).to be_truthy
+ end
+ end
+end
diff --git a/spec/lib/gitlab/graphql/query_analyzers/logger_analyzer_spec.rb b/spec/lib/gitlab/graphql/query_analyzers/logger_analyzer_spec.rb
deleted file mode 100644
index dee8f9e3c64..00000000000
--- a/spec/lib/gitlab/graphql/query_analyzers/logger_analyzer_spec.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Graphql::QueryAnalyzers::LoggerAnalyzer do
- let(:initial_value) { analyzer.initial_value(query) }
- let(:analyzer) { described_class.new }
- let(:query) { GraphQL::Query.new(GitlabSchema, document: document, context: {}, variables: { body: "some note" }) }
- let(:document) do
- GraphQL.parse <<-GRAPHQL
- mutation createNote($body: String!) {
- createNote(input: {noteableId: "1", body: $body}) {
- note {
- id
- }
- }
- }
- GRAPHQL
- end
-
- describe '#final_value' do
- let(:monotonic_time_before) { 42 }
- let(:monotonic_time_after) { 500 }
- let(:monotonic_time_duration) { monotonic_time_after - monotonic_time_before }
- let(:memo) { initial_value }
-
- subject(:final_value) { analyzer.final_value(memo) }
-
- before do
- RequestStore.store[:graphql_logs] = nil
-
- allow(GraphQL::Analysis).to receive(:analyze_query).and_return([4, 2, [[], []]])
- allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(monotonic_time_before, monotonic_time_after)
- allow(Gitlab::GraphqlLogger).to receive(:info)
- end
-
- it 'inserts duration in seconds to memo and sets request store' do
- expect { final_value }.to change { memo[:duration_s] }.to(monotonic_time_duration)
- .and change { RequestStore.store[:graphql_logs] }.to([{
- complexity: 4,
- depth: 2,
- operation_name: query.operation_name,
- used_deprecated_fields: [],
- used_fields: [],
- variables: { body: "[FILTERED]" }.to_s
- }])
- end
- end
-end
diff --git a/spec/lib/gitlab/graphql/tracers/logger_tracer_spec.rb b/spec/lib/gitlab/graphql/tracers/logger_tracer_spec.rb
index 5bc077a963e..20792fb4554 100644
--- a/spec/lib/gitlab/graphql/tracers/logger_tracer_spec.rb
+++ b/spec/lib/gitlab/graphql/tracers/logger_tracer_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Gitlab::Graphql::Tracers::LoggerTracer do
use Gitlab::Graphql::Tracers::LoggerTracer
use Gitlab::Graphql::Tracers::TimerTracer
- query_analyzer Gitlab::Graphql::QueryAnalyzers::LoggerAnalyzer.new
+ query_analyzer Gitlab::Graphql::QueryAnalyzers::AST::LoggerAnalyzer
query Graphql::FakeQueryType
end
@@ -20,11 +20,11 @@ RSpec.describe Gitlab::Graphql::Tracers::LoggerTracer do
end
end
- it "logs every query", :aggregate_failures do
+ it "logs every query", :aggregate_failures, :unlimited_max_formatted_output_length do
variables = { name: "Ada Lovelace" }
query_string = 'query fooOperation($name: String) { helloWorld(message: $name) }'
- # Build an actual query so we don't have to hardocde the "fingerprint" calculations
+ # Build an actual query so we don't have to hardcode the "fingerprint" calculations
query = GraphQL::Query.new(dummy_schema, query_string, variables: variables)
expect(::Gitlab::GraphqlLogger).to receive(:info).with({