Skip to content

Commit ea9d1ea

Browse files
authored
Merge pull request #5396 from rmosolgo/filter-types-for-required-validator
RequiredValidator: remove non-visible definitions from the error message
2 parents 5069859 + 000eacb commit ea9d1ea

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

lib/graphql/schema/validator/required_validator.rb

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,26 @@ def validate(_object, context, value)
9696
end
9797

9898
def build_message(context)
99-
argument_definitions = @validated.arguments(context).values
99+
argument_definitions = context.types.arguments(@validated)
100+
100101
required_names = @one_of.map do |arg_keyword|
101102
if arg_keyword.is_a?(Array)
102103
names = arg_keyword.map { |arg| arg_keyword_to_graphql_name(argument_definitions, arg) }
104+
names.compact! # hidden arguments are `nil`
103105
"(" + names.join(" and ") + ")"
104106
else
105107
arg_keyword_to_graphql_name(argument_definitions, arg_keyword)
106108
end
107109
end
110+
required_names.compact! # remove entries for hidden arguments
111+
108112

109-
if required_names.size == 1
113+
case required_names.size
114+
when 0
115+
# The required definitions were hidden from the client.
116+
# Another option here would be to raise an error in the application....
117+
"%{validated} is missing a required argument."
118+
when 1
110119
"%{validated} must include the following argument: #{required_names.first}."
111120
else
112121
"%{validated} must include exactly one of the following arguments: #{required_names.join(", ")}."
@@ -115,7 +124,7 @@ def build_message(context)
115124

116125
def arg_keyword_to_graphql_name(argument_definitions, arg_keyword)
117126
argument_definition = argument_definitions.find { |defn| defn.keyword == arg_keyword }
118-
argument_definition.graphql_name
127+
argument_definition&.graphql_name
119128
end
120129
end
121130
end

spec/graphql/schema/validator/required_validator_spec.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
expectations = [
99
{
10-
config: { one_of: [:a, :b] },
10+
config: { one_of: [:a, :b, :secret] },
1111
cases: [
1212
{ query: "{ validated: multiValidated(a: 1, b: 2) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, b."] },
1313
{ query: "{ validated: multiValidated(a: 1, b: 2, c: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, b."] },
@@ -32,6 +32,13 @@
3232
{ query: "{ validated: multiValidated(b: 2) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, (b and c)."] },
3333
]
3434
},
35+
{
36+
name: "All options hidden",
37+
config: { one_of: [:secret, :secret2] },
38+
cases: [
39+
{ query: "{ validated: multiValidated(a: 1, b: 2) }", result: nil, error_messages: ["multiValidated is missing a required argument."] },
40+
],
41+
},
3542
{
3643
name: "Definition order independence",
3744
config: { one_of: [[:a, :b], :c] },

spec/graphql/schema/validator/validator_helpers.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ class NonBlankString < String
2020
def build_schema(arg_type, validates_config)
2121
schema = Class.new(GraphQL::Schema)
2222

23+
base_argument = Class.new(GraphQL::Schema::Argument) do
24+
def initialize(*args, secret: false, **kwargs, &block)
25+
super(*args, **kwargs, &block)
26+
@secret = secret
27+
end
28+
29+
def visible?(_ctx)
30+
!@secret
31+
end
32+
end
33+
34+
base_field = Class.new(GraphQL::Schema::Field) do
35+
argument_class(base_argument)
36+
end
37+
2338
validated_input = Class.new(GraphQL::Schema::InputObject) do
2439
graphql_name "ValidatedInput"
2540
argument :a, arg_type, required: false
@@ -55,6 +70,7 @@ def resolve(input: :NO_INPUT)
5570

5671
query_type = Class.new(GraphQL::Schema::Object) do
5772
graphql_name "Query"
73+
field_class(base_field)
5874
field :validated, arg_type do
5975
argument :value, arg_type, required: false, validates: validates_config
6076
end
@@ -67,6 +83,8 @@ def validated(value: nil)
6783
argument :a, arg_type, required: false
6884
argument :b, arg_type, required: false
6985
argument :c, arg_type, required: false
86+
argument :secret, arg_type, required: false, secret: true
87+
argument :secret2, arg_type, required: false, secret: true
7088
end
7189

7290
def multi_validated(a: 0, b: 0, c: 0)
@@ -91,6 +109,11 @@ def list
91109
end
92110

93111
schema.query(query_type)
112+
if ADD_WARDEN
113+
schema.use(GraphQL::Schema::Warden)
114+
else
115+
schema.use(GraphQL::Schema::Visibility)
116+
end
94117
schema
95118
end
96119

0 commit comments

Comments
 (0)