1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
# frozen_string_literal: true
require "spec_helper"
require_relative "./validator_helpers"
describe GraphQL::Schema::Validator::RequiredValidator do
include ValidatorHelpers
expectations = [
{
config: { one_of: [:a, :b, :secret] },
cases: [
{ query: "{ validated: multiValidated(a: 1, b: 2) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, b."] },
{ query: "{ validated: multiValidated(a: 1, b: 2, c: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, b."] },
{ query: "{ validated: multiValidated }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, b."] },
{ query: "{ validated: multiValidated(c: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, b."] },
{ query: "{ validated: multiValidated(a: 1) }", result: 1, error_messages: [] },
{ query: "{ validated: multiValidated(a: 1, c: 3) }", result: 4, error_messages: [] },
{ query: "{ validated: multiValidated(b: 2) }", result: 2, error_messages: [] },
{ query: "{ validated: multiValidated(b: 2, c: 3) }", result: 5, error_messages: [] },
]
},
{
config: { one_of: [:a, [:b, :c]] },
cases: [
{ query: "{ validated: multiValidated(a: 1) }", result: 1, error_messages: [] },
{ query: "{ validated: multiValidated(b: 2, c: 3) }", result: 5, error_messages: [] },
{ query: "{ validated: multiValidated }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: multiValidated(a: 1, b: 2, c: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: multiValidated(a: 1, b: 2) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: multiValidated(a: 1, c: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: multiValidated(c: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: multiValidated(b: 2) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: a, (b and c)."] },
]
},
{
name: "All options hidden, allow_all_hidden: true",
config: { one_of: [:secret, :secret2], allow_all_hidden: true },
cases: [
{ query: "{ validated: multiValidated(a: 1, b: 2) }", result: 3, error_messages: [] },
],
},
{
name: "Definition order independence",
config: { one_of: [[:a, :b], :c] },
cases: [
{ query: "{ validated: multiValidated(c: 1) }", result: 1, error_messages: [] },
{ query: "{ validated: multiValidated(a: 2, b: 3) }", result: 5, error_messages: [] },
{ query: "{ validated: multiValidated }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: (a and b), c."] },
{ query: "{ validated: multiValidated(a: 1, b: 2, c: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: (a and b), c."] },
{ query: "{ validated: multiValidated(a: 1, c: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: (a and b), c."] },
{ query: "{ validated: multiValidated(b: 2, c: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: (a and b), c."] },
{ query: "{ validated: multiValidated(a: 3) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: (a and b), c."] },
{ query: "{ validated: multiValidated(b: 2) }", result: nil, error_messages: ["multiValidated must include exactly one of the following arguments: (a and b), c."] },
]
},
{
name: "Input object validation",
config: { one_of: [:a, [:b, :c]] },
cases: [
{ query: "{ validated: validatedInput(input: { a: 1 }) }", result: 1, error_messages: [] },
{ query: "{ validated: validatedInput(input: { b: 2, c: 3 }) }", result: 5, error_messages: [] },
{ query: "{ validated: validatedInput(input: { a: 1, b: 2, c: 3 }) }", result: nil, error_messages: ["ValidatedInput must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: validatedInput(input: { a: 1, b: 2 }) }", result: nil, error_messages: ["ValidatedInput must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: validatedInput(input: { a: 1, c: 3 }) }", result: nil, error_messages: ["ValidatedInput must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: validatedInput(input: { c: 3 }) }", result: nil, error_messages: ["ValidatedInput must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: validatedInput(input: { b: 2 }) }", result: nil, error_messages: ["ValidatedInput must include exactly one of the following arguments: a, (b and c)."] },
]
},
{
name: "Resolver validation",
config: { one_of: [:a, [:b, :c]] },
cases: [
{ query: "{ validated: validatedResolver(a: 1) }", result: 1, error_messages: [] },
{ query: "{ validated: validatedResolver(b: 2, c: 3) }", result: 5, error_messages: [] },
{ query: "{ validated: validatedResolver(a: 1, b: 2, c: 3) }", result: nil, error_messages: ["validatedResolver must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: validatedResolver(a: 1, b: 2) }", result: nil, error_messages: ["validatedResolver must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: validatedResolver(a: 1, c: 3) }", result: nil, error_messages: ["validatedResolver must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: validatedResolver(c: 3) }", result: nil, error_messages: ["validatedResolver must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: validatedResolver(b: 2) }", result: nil, error_messages: ["validatedResolver must include exactly one of the following arguments: a, (b and c)."] },
{ query: "{ validated: validatedResolver }", result: nil, error_messages: ["validatedResolver must include exactly one of the following arguments: a, (b and c)."] },
]
},
{
name: "Single arg validation",
config: { argument: :a, message: "A value must be given, even if it's `null` (not %{value})" },
cases: [
{ query: "{ validated: validatedInput(input: { a: 1 }) }", result: 1, error_messages: [] },
{ query: "{ validated: validatedInput(input: {}) }", result: nil, error_messages: ["A value must be given, even if it's `null` (not {})"] },
{ query: "{ validated: validatedInput(input: { a: null }) }", result: 0, error_messages: [] },
]
}
]
build_tests(:required, Integer, expectations)
describe "when all arguments are hidden" do
class RequiredHiddenSchema < GraphQL::Schema
class BaseArgument < GraphQL::Schema::Argument
def initialize(*args, always_hidden: false, **kwargs, &block)
super(*args, **kwargs, &block)
@always_hidden = always_hidden
end
def visible?(ctx)
!@always_hidden
end
end
class BaseField < GraphQL::Schema::Field
argument_class(BaseArgument)
end
class Query < GraphQL::Schema::Object
field_class(BaseField)
field :one_argument, Int, fallback_value: 1 do
argument :a, Int, required: :nullable, always_hidden: true
end
field :two_arguments, Int, fallback_value: 2 do
validates required: { one_of: [:a, :b], allow_all_hidden: true }
argument :a, Int, required: false, always_hidden: true
argument :b, Int, required: false, always_hidden: true
end
field :two_arguments_error, Int, fallback_value: 2 do
validates required: { one_of: [:a, :b] }
argument :a, Int, required: false, always_hidden: true
argument :b, Int, required: false, always_hidden: true
end
field :three_arguments, Int, fallback_value: 3 do
validates required: { one_of: [:a, :b], allow_all_hidden: true }
argument :a, Int, required: false, always_hidden: true
argument :b, Int, required: false, always_hidden: true
argument :c, Int
end
field :four_arguments, Int, fallback_value: 4 do
validates required: { one_of: [[:a, :b], :c, :d], allow_all_hidden: true}
argument :a, Int, required: false, always_hidden: true
argument :b, Int, required: false, always_hidden: true
argument :c, Int, required: false, always_hidden: true
argument :d, Int, required: false, always_hidden: true
end
end
query(Query)
use GraphQL::Schema::Visibility
end
it "Doesn't require any of one_of to be present" do
result = RequiredHiddenSchema.execute("{ threeArguments(c: 5) }")
assert_equal 3, result["data"]["threeArguments"]
result = RequiredHiddenSchema.execute("{ twoArguments }")
assert_equal 2, result["data"]["twoArguments"]
err = assert_raises GraphQL::Error do
RequiredHiddenSchema.execute("{ twoArgumentsError }")
end
expected_message = "Query.twoArgumentsError validates `required: ...` but all required arguments were hidden.\n\nUpdate your schema definition to allow the client to see some fields or skip validation by adding `required: { ..., allow_all_hidden: true }`\n"
assert_equal expected_message, err.message
end
it "doesn't require hidden arguments when required as a group" do
result = RequiredHiddenSchema.execute("{ fourArguments }")
assert_equal 4, result["data"]["fourArguments"]
end
it "Doesn't require hidden argument to be present" do
result = RequiredHiddenSchema.execute("{ oneArgument }")
assert_equal 1, result["data"]["oneArgument"]
end
end
end
|