Skip to content

Input Value Validation #3813

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 18, 2024
Merged
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
6 changes: 3 additions & 3 deletions src/execution/__tests__/nonnull-test.ts
Original file line number Diff line number Diff line change
@@ -647,7 +647,7 @@ describe('Execute: handles non-nullable types', () => {
errors: [
{
message:
'Argument "cannotBeNull" of non-null type "String!" must not be null.',
'Argument "cannotBeNull" has invalid value: Expected value of non-null type "String!" not to be null.',
locations: [{ line: 3, column: 42 }],
path: ['withNonNullArg'],
},
@@ -677,7 +677,7 @@ describe('Execute: handles non-nullable types', () => {
errors: [
{
message:
'Argument "cannotBeNull" of required type "String!" was provided the variable "$testVar" which was not provided a runtime value.',
'Argument "cannotBeNull" has invalid value: Expected variable "$testVar" provided to type "String!" to provide a runtime value.',
locations: [{ line: 3, column: 42 }],
path: ['withNonNullArg'],
},
@@ -705,7 +705,7 @@ describe('Execute: handles non-nullable types', () => {
errors: [
{
message:
'Argument "cannotBeNull" of non-null type "String!" must not be null.',
'Argument "cannotBeNull" has invalid value: Expected variable "$testVar" provided to non-null type "String!" not to be null.',
locations: [{ line: 3, column: 43 }],
path: ['withNonNullArg'],
},
153 changes: 149 additions & 4 deletions src/execution/__tests__/oneof-test.ts
Original file line number Diff line number Diff line change
@@ -30,7 +30,12 @@ function executeQuery(
rootValue: unknown,
variableValues?: { [variable: string]: unknown },
): ExecutionResult | Promise<ExecutionResult> {
return execute({ schema, document: parse(query), rootValue, variableValues });
return execute({
schema,
document: parse(query, { experimentalFragmentArguments: true }),
rootValue,
variableValues,
});
}

describe('Execute: Handles OneOf Input Objects', () => {
@@ -83,7 +88,7 @@ describe('Execute: Handles OneOf Input Objects', () => {
message:
// This type of error would be caught at validation-time
// hence the vague error message here.
'Argument "input" of non-null type "TestInputObject!" must not be null.',
'Argument "input" has invalid value: Expected variable "$input" provided to type "TestInputObject!" to provide a runtime value.',
path: ['test'],
},
],
@@ -134,6 +139,28 @@ describe('Execute: Handles OneOf Input Objects', () => {
});
});

it('rejects a variable with a nulled key', () => {
const query = `
query ($input: TestInputObject!) {
test(input: $input) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, { input: { a: null } });

expectJSON(result).toDeepEqual({
errors: [
{
message:
'Variable "$input" has invalid value: Field "a" for OneOf type "TestInputObject" must be non-null.',
locations: [{ line: 2, column: 16 }],
},
],
});
});

it('rejects a variable with multiple non-null keys', () => {
const query = `
query ($input: TestInputObject!) {
@@ -152,7 +179,7 @@ describe('Execute: Handles OneOf Input Objects', () => {
{
locations: [{ column: 16, line: 2 }],
message:
'Variable "$input" got invalid value { a: "abc", b: 123 }; Exactly one key must be specified for OneOf type "TestInputObject".',
'Variable "$input" has invalid value: Exactly one key must be specified for OneOf type "TestInputObject".',
},
],
});
@@ -176,7 +203,125 @@ describe('Execute: Handles OneOf Input Objects', () => {
{
locations: [{ column: 16, line: 2 }],
message:
'Variable "$input" got invalid value { a: "abc", b: null }; Exactly one key must be specified for OneOf type "TestInputObject".',
'Variable "$input" has invalid value: Exactly one key must be specified for OneOf type "TestInputObject".',
},
],
});
});

it('errors with nulled variable for field', () => {
const query = `
query ($a: String) {
test(input: { a: $a }) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, { a: null });

expectJSON(result).toDeepEqual({
data: {
test: null,
},
errors: [
{
// A nullable variable in a oneOf field position would be caught at validation-time
// hence the vague error message here.
message:
'Argument "input" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" not to be null.',
locations: [{ line: 3, column: 23 }],
path: ['test'],
},
],
});
});

it('errors with missing variable for field', () => {
const query = `
query ($a: String) {
test(input: { a: $a }) {
a
b
}
}
`;
const result = executeQuery(query, rootValue);

expectJSON(result).toDeepEqual({
data: {
test: null,
},
errors: [
{
// A nullable variable in a oneOf field position would be caught at validation-time
// hence the vague error message here.
message:
'Argument "input" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" to provide a runtime value.',
locations: [{ line: 3, column: 23 }],
path: ['test'],
},
],
});
});

it('errors with nulled fragment variable for field', () => {
const query = `
query {
...TestFragment(a: null)
}
fragment TestFragment($a: String) on Query {
test(input: { a: $a }) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, { a: null });

expectJSON(result).toDeepEqual({
data: {
test: null,
},
errors: [
{
// A nullable variable in a oneOf field position would be caught at validation-time
// hence the vague error message here.
message:
'Argument "input" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" not to be null.',
locations: [{ line: 6, column: 23 }],
path: ['test'],
},
],
});
});

it('errors with missing fragment variable for field', () => {
const query = `
query {
...TestFragment
}
fragment TestFragment($a: String) on Query {
test(input: { a: $a }) {
a
b
}
}
`;
const result = executeQuery(query, rootValue);

expectJSON(result).toDeepEqual({
data: {
test: null,
},
errors: [
{
// A nullable variable in a oneOf field position would be caught at validation-time
// hence the vague error message here.
message:
'Argument "input" has invalid value: Expected variable "$a" provided to field "a" for OneOf Input Object type "TestInputObject" to provide a runtime value.',
locations: [{ line: 6, column: 23 }],
path: ['test'],
},
],
});
2 changes: 1 addition & 1 deletion src/execution/__tests__/subscribe-test.ts
Original file line number Diff line number Diff line change
@@ -567,7 +567,7 @@ describe('Subscription Initialization Phase', () => {
errors: [
{
message:
'Variable "$arg" got invalid value "meow"; Int cannot represent non-integer value: "meow"',
'Variable "$arg" has invalid value: Int cannot represent non-integer value: "meow"',
locations: [{ line: 2, column: 21 }],
},
],
Loading