Commit 529ed05e authored by Alex Kalderimis's avatar Alex Kalderimis

GraphqlHelpers: Helper changes

parent a9cdcc34
...@@ -17,7 +17,10 @@ module GraphqlHelpers ...@@ -17,7 +17,10 @@ module GraphqlHelpers
# ready, then the early return is returned instead. # ready, then the early return is returned instead.
# #
# Then the resolve method is called. # Then the resolve method is called.
def resolve(resolver_class, args: {}, **resolver_args) def resolve(resolver_class, args: {}, lookahead: :not_given, parent: :not_given, **resolver_args)
args = aliased_args(resolver_class, args)
args[:parent] = parent unless parent == :not_given
args[:lookahead] = lookahead unless lookahead == :not_given
resolver = resolver_instance(resolver_class, **resolver_args) resolver = resolver_instance(resolver_class, **resolver_args)
ready, early_return = sync_all { resolver.ready?(**args) } ready, early_return = sync_all { resolver.ready?(**args) }
...@@ -26,6 +29,15 @@ module GraphqlHelpers ...@@ -26,6 +29,15 @@ module GraphqlHelpers
resolver.resolve(**args) resolver.resolve(**args)
end end
# TODO: Remove this method entirely when GraphqlHelpers uses real resolve_field
def aliased_args(resolver, args)
definitions = resolver.arguments
args.transform_keys do |k|
definitions[GraphqlHelpers.fieldnamerize(k)]&.keyword || k
end
end
def resolver_instance(resolver_class, obj: nil, ctx: {}, field: nil, schema: GitlabSchema) def resolver_instance(resolver_class, obj: nil, ctx: {}, field: nil, schema: GitlabSchema)
if ctx.is_a?(Hash) if ctx.is_a?(Hash)
q = double('Query', schema: schema) q = double('Query', schema: schema)
...@@ -121,14 +133,17 @@ module GraphqlHelpers ...@@ -121,14 +133,17 @@ module GraphqlHelpers
end end
end end
def resolve_field(name, object, args = {}) UnauthorizedObject = Class.new(StandardError)
context = double("Context",
schema: GitlabSchema, def resolve_field(name, object, args = {}, current_user: nil)
query: GraphQL::Query.new(GitlabSchema), q = GraphQL::Query.new(GitlabSchema)
parent: nil) context = GraphQL::Query::Context.new(query: q, object: object, values: { current_user: current_user })
field = described_class.fields[::GraphqlHelpers.fieldnamerize(name)] allow(context).to receive(:parent).and_return(nil)
field = described_class.fields.fetch(GraphqlHelpers.fieldnamerize(name))
instance = described_class.authorized_new(object, context) instance = described_class.authorized_new(object, context)
field.resolve_field(instance, {}, context) raise UnauthorizedObject unless instance
field.resolve_field(instance, args, context)
end end
# Recursively convert a Hash with Ruby-style keys to GraphQL fieldname-style keys # Recursively convert a Hash with Ruby-style keys to GraphQL fieldname-style keys
...@@ -165,10 +180,27 @@ module GraphqlHelpers ...@@ -165,10 +180,27 @@ module GraphqlHelpers
end end
def query_graphql_field(name, attributes = {}, fields = nil) def query_graphql_field(name, attributes = {}, fields = nil)
<<~QUERY attributes, fields = [nil, attributes] if fields.nil?
#{field_with_params(name, attributes)}
#{wrap_fields(fields || all_graphql_fields_for(name.to_s.classify))} field = field_with_params(name, attributes)
QUERY
field + wrap_fields(fields || all_graphql_fields_for(name.to_s.classify)).to_s
end
def query_nodes(name, args = nil, fields = nil)
fields ||= all_graphql_fields_for(name.to_s.classify, max_depth: 1)
query_graphql_path([[name, args], :nodes], fields)
end
# e.g:
# query_graphql_path(%i[foo bar baz], all_graphql_fields_for('Baz'))
# => foo { bar { baz { x y z } } }
def query_graphql_path(segments, fields = nil)
# we really want foldr here...
segments.reverse.reduce(fields) do |tail, segment|
name, args = Array.wrap(segment)
query_graphql_field(name, args, tail)
end
end end
def wrap_fields(fields) def wrap_fields(fields)
...@@ -498,6 +530,20 @@ module GraphqlHelpers ...@@ -498,6 +530,20 @@ module GraphqlHelpers
variables: {} variables: {}
) )
end end
# A lookahead that selects everything
def positive_lookahead
double(selects?: true).tap do |selection|
allow(selection).to receive(:selection).and_return(selection)
end
end
# A lookahead that selects nothing
def negative_lookahead
double(selects?: false).tap do |selection|
allow(selection).to receive(:selection).and_return(selection)
end
end
end end
# This warms our schema, doing this as part of loading the helpers to avoid # This warms our schema, doing this as part of loading the helpers to avoid
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment