Skip to content

Commit

Permalink
Cherry-pick definition tests for @OneOf
Browse files Browse the repository at this point in the history
Co-authored-by: erikkessler1 <[email protected]>
  • Loading branch information
rmosolgo and erikkessler1 committed Sep 7, 2022
1 parent bf6cb8f commit 8955413
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 8 deletions.
16 changes: 10 additions & 6 deletions lib/graphql/schema/input_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,10 @@ def self.authorized?(obj, value, ctx)
end

def self.one_of
if !@one_of
if (required_arg = all_argument_definitions.find { |arg| arg.type.non_null? })
raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to `argument #{required_arg.keyword.inspect}` to use `one_of`"
if !one_of?
if all_argument_definitions.any? { |arg| arg.type.non_null? }
raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`"
end
@one_of = true
directive(GraphQL::Schema::Directive::OneOf)
end
end
Expand Down Expand Up @@ -123,8 +122,13 @@ def to_kwargs
class << self
def argument(*args, **kwargs, &block)
argument_defn = super(*args, **kwargs, &block)
if one_of? && argument_defn.type.non_null?
raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to `argument #{argument_defn.keyword.inspect}` to use `one_of`"
if one_of?
if argument_defn.type.non_null?
raise ArgumentError, "Argument '#{argument_defn.path}' must be nullable because it is part of a OneOf type, add `required: false`."
end
if argument_defn.default_value?
raise ArgumentError, "Argument '#{argument_defn.path}' cannot have a default value because it is part of a OneOf type, remove `default_value: ...`."
end
end
# Add a method access
method_name = argument_defn.keyword
Expand Down
78 changes: 78 additions & 0 deletions spec/graphql/schema/directive/one_of_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# frozen_string_literal: true
require "spec_helper"

describe GraphQL::Schema::Directive::OneOf do
let(:schema) do
this = self
output_type = Class.new(GraphQL::Schema::Object) do
graphql_name "OneOfOutput"

field :string, GraphQL::Types::String
field :int, GraphQL::Types::Int
end

query_type = Class.new(GraphQL::Schema::Object) do
graphql_name "Query"

field :one_of_field, output_type, null: false do
argument :one_of_arg, this.one_of_input_object
end

def one_of_field(one_of_arg:)
one_of_arg
end
end

Class.new(GraphQL::Schema) do
query(query_type)
end
end

let(:one_of_input_object) do
Class.new(GraphQL::Schema::InputObject) do
graphql_name "OneOfInputObject"
directive GraphQL::Schema::Directive::OneOf

argument :int, GraphQL::Types::Int
argument :string, GraphQL::Types::String
end
end

describe "defining oneOf input objects" do
describe "with a non-null argument" do
let(:one_of_input_object) do
Class.new(GraphQL::Schema::InputObject) do
graphql_name "OneOfInputObject"
directive GraphQL::Schema::Directive::OneOf

argument :int, GraphQL::Types::Int, required: true # rubocop:disable GraphQL/DefaultRequiredTrue
argument :string, GraphQL::Types::String
end
end

it "raises an error" do
error = assert_raises(ArgumentError) { schema }
expected_message = "Argument 'OneOfInputObject.int' must be nullable because it is part of a OneOf type, add `required: false`."
assert_equal(expected_message, error.message)
end
end

describe "when an argument has a default" do
let(:one_of_input_object) do
Class.new(GraphQL::Schema::InputObject) do
graphql_name "OneOfInputObject"
directive GraphQL::Schema::Directive::OneOf

argument :int, GraphQL::Types::Int, default_value: 1, required: false
argument :string, GraphQL::Types::String, required: false
end
end

it "raises an error" do
error = assert_raises(ArgumentError) { schema }
expected_message = "Argument 'OneOfInputObject.int' cannot have a default value because it is part of a OneOf type, remove `default_value: ...`."
assert_equal(expected_message, error.message)
end
end
end
end
6 changes: 4 additions & 2 deletions spec/graphql/schema/input_object_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1183,21 +1183,23 @@ def f(a:)
it "doesn't work without required: false" do
err1 = assert_raises ArgumentError do
Class.new(GraphQL::Schema::InputObject) do
graphql_name "OneOfThing"
argument :arg_1, GraphQL::Types::Int
one_of
end
end

assert_equal "`one_of` may not be used with required arguments -- add `required: false` to `argument :arg_1` to use `one_of`", err1.message
assert_equal "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`", err1.message

err2 = assert_raises ArgumentError do
Class.new(GraphQL::Schema::InputObject) do
graphql_name "OneOfThing"
one_of
argument :arg_2, GraphQL::Types::Int
end
end

assert_equal "`one_of` may not be used with required arguments -- add `required: false` to `argument :arg_2` to use `one_of`", err2.message
assert_equal "Argument 'OneOfThing.arg2' must be nullable because it is part of a OneOf type, add `required: false`.", err2.message
end

it "allows queries with only one value" do
Expand Down

0 comments on commit 8955413

Please sign in to comment.