Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions lib/graphql/execution/input_values.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ def argument_values(owner_defn, argument_nodes, field_resolve_step)
arg_node = argument_nodes.find { |a| a.name == arg_graphql_key }
if arg_node.nil? || (arg_node.value.is_a?(Language::Nodes::VariableIdentifier) && !variable_values.key?(arg_node.value.name))
if argument_definition.default_value?
argument_value(argument_values, arg_ruby_key, argument_definition, argument_definition.default_value, nil, field_resolve_step)
arg_value = value_from_ast(argument_definition.default_value, argument_definition.type)
argument_value(argument_values, arg_ruby_key, argument_definition, arg_value, nil, field_resolve_step)
end
else
argument_value(argument_values, arg_ruby_key, argument_definition, arg_node.value, nil, field_resolve_step)
arg_value = value_from_ast(arg_node.value, argument_definition.type)
argument_value(argument_values, arg_ruby_key, argument_definition, arg_value, nil, field_resolve_step)
end
end

Expand Down Expand Up @@ -110,8 +112,6 @@ def argument_value(argument_values, argument_key, argument_definition, arg_value
treat_as_type = treat_as_type.of_type
end

arg_value = value_from_ast(arg_value, treat_as_type)

if treat_as_type.kind.list? && !arg_value.nil?
inner_t = treat_as_type.unwrap
arg_value = if arg_value.is_a?(Array)
Expand All @@ -125,14 +125,6 @@ def argument_value(argument_values, argument_key, argument_definition, arg_value
end
end

if override_type.nil? # only on root arguments, not list elements
arg_value = begin
argument_definition.prepare_value(nil, arg_value, context: @query.context)
rescue StandardError => err
@runner.schema.handle_or_reraise(@query.context, err)
end
end

if arg_value && treat_as_type.kind.input_object?
arg_defns = @query.types.arguments(treat_as_type)
new_arg_value = {}
Expand All @@ -151,7 +143,15 @@ def argument_value(argument_values, argument_key, argument_definition, arg_value
end
end
end
arg_value = new_arg_value
arg_value = treat_as_type.new(nil, ruby_kwargs: new_arg_value, context: @query.context, defaults_used: nil)
end

if override_type.nil? # only on root arguments, not list elements
arg_value = begin
argument_definition.prepare_value(nil, arg_value, context: @query.context)
rescue StandardError => err
@runner.schema.handle_or_reraise(@query.context, err)
end
end

if field_resolve_step && arg_value && override_type.nil? && argument_definition.loads
Expand Down
3 changes: 0 additions & 3 deletions lib/graphql/schema/argument.rb
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,6 @@ def recursively_prepare_input_object(value, type, context)
elsif value.is_a?(GraphQL::Schema::InputObject)
value.validate_for(context)
value.prepare
elsif value.is_a?(Hash)
type.validate_for(value, context)
value
else
value
end
Expand Down
6 changes: 0 additions & 6 deletions lib/graphql/schema/input_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,6 @@ def validate_for(context)
nil
end

# @api private
def self.validate_for(ruby_style_hash, context)
# Pass this object's class with `as` so that messages are rendered correctly from inherited validators
Schema::Validator.validate!(validators, nil, context, ruby_style_hash, as: self)
nil
end
class << self
def authorized?(obj, value, ctx)
# Authorize each argument (but this doesn't apply if `prepare` is implemented):
Expand Down
82 changes: 59 additions & 23 deletions spec/graphql/execution/input_values_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,41 @@
require "spec_helper"

class ExecutionInputValuesTest < Minitest::Test
TEST_SCHEMA = GraphQL::Schema.from_definition(%|
enum TestStatus {
ACTIVE
INACTIVE
}
class TestSchema < GraphQL::Schema
class TestStatus < GraphQL::Schema::Enum
value :ACTIVE
value :INACTIVE
end

input TestInput {
string: String
float: Float
int: Int
enum: TestStatus
}
class TestInput < GraphQL::Schema::InputObject
argument :string, String, required: false
argument :float, Float, required: false
argument :int, Int, required: false
argument :enum, TestStatus, required: false
end

type Mutation {
testInput(input: TestInput): Boolean
}
class Mutation < GraphQL::Schema::Object
field :test_input, Boolean do
argument :input, TestInput, required: false
end

type Query {
ping: Boolean
}
|)
field :test_list_input, Boolean do
argument :input, [TestInput, null: true], required: false
end
end

mutation(Mutation)
query(Mutation) # Just to have something
end

class DummyRunner
def add_step(s); end
def schema; TEST_SCHEMA; end
def schema; TestSchema; end
end

def get_input_values(variables_string: nil, variables: nil)
query_str = "query#{variables_string ? "(#{variables_string})" : ""} { __typename }"
query = GraphQL::Query.new(TEST_SCHEMA, query_str, validate: false, variables: variables)
def get_input_values(query_string: nil, variables_string: nil, variables: nil)
query_string ||= "query#{variables_string ? "(#{variables_string})" : ""} { __typename }"
query = GraphQL::Query.new(TestSchema, query_string, validate: false, variables: variables)
GraphQL::Execution::InputValues.new(query, DummyRunner.new)
end

Expand Down Expand Up @@ -67,6 +71,38 @@ def test_it_produces_argument_values_for_simple_scalars

def test_it_produces_argument_values_for_input_objects
input = get_input_values
assert_equal({input: { string: "a", enum: "ACTIVE" } }, input.argument_values(TEST_SCHEMA.find("Mutation.testInput"), get_argument_nodes("input: { string: \"a\", enum: ACTIVE }"), nil))
assert_equal_input( {input: { string: "a", enum: "ACTIVE" } }, input.argument_values(TestSchema.find("Mutation.testInput"), get_argument_nodes("input: { string: \"a\", enum: ACTIVE }"), nil))
end

def assert_equal_input(expected_ruby_hash, graphql_input, path = [])
case expected_ruby_hash
when Array
assert_instance_of Array, graphql_input, "Matches at `#{path.join(".")}`"
expected_ruby_hash.each_with_index do |next_expected, idx|
assert_equal_input(next_expected, graphql_input[idx], path + [idx])
end
when Hash
if path.empty?
assert_instance_of Hash, graphql_input, "Matches at `#{path.join(".")}`"
else
assert_kind_of GraphQL::Schema::InputObject, graphql_input, "Matches at `#{path.join(".")}`"
graphql_input = graphql_input.to_h
end
expected_ruby_hash.each do |k, v|
assert_equal_input(v, graphql_input[k], path + [k])
end
else
assert_equal expected_ruby_hash, graphql_input, "Matches at `#{path.join(".")}`"
end
end

def test_it_works_with_arrays_of_input_objects
input = get_input_values(variables_string: "$string: String = \"abc\", $string2: String, $input: TestInput!", variables: { string2: "xyz", input: { string: "nested" }})
assert_equal_input({input: [{}]}, input.argument_values(TestSchema.find("Mutation.testListInput"), get_argument_nodes("input: { string: $s }"), nil))
assert_equal_input({input: [{ string: "Str" }]}, input.argument_values(TestSchema.find("Mutation.testListInput"), get_argument_nodes("input: { string: \"Str\" }"), nil))
assert_equal_input({input: [{ string: "abc" }]}, input.argument_values(TestSchema.find("Mutation.testListInput"), get_argument_nodes("input: { string: $string }"), nil))
assert_equal_input({input: [{ string: "xyz" }]}, input.argument_values(TestSchema.find("Mutation.testListInput"), get_argument_nodes("input: { string: $string2 }"), nil))
assert_equal_input({input: [{ string: "nested" }]}, input.argument_values(TestSchema.find("Mutation.testListInput"), get_argument_nodes("input: $input"), nil))
assert_equal_input({input: [{}, {string: "Str"}, {string: "abc"}, {string: "xyz"}, {string: "nested"}]}, input.argument_values(TestSchema.find("Mutation.testListInput"), get_argument_nodes("input: [{string: $s}, {string: \"Str\"}, {string: $string }, { string: $string2 }, $input]"), nil))
end
end
Loading