Skip to content
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

add additional runtime errors for pre-coercion OneOf errors #4195

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
342 changes: 340 additions & 2 deletions src/execution/__tests__/oneof-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -158,7 +163,7 @@ describe('Execute: Handles OneOf Input Objects', () => {
});
});

it('rejects a variable with multiple nullable keys', () => {
it('rejects a variable with multiple keys, some set to null', () => {
const query = `
query ($input: TestInputObject!) {
test(input: $input) {
Expand All @@ -181,5 +186,338 @@ describe('Execute: Handles OneOf Input Objects', () => {
],
});
});

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

expectJSON(result).toDeepEqual({
errors: [
{
locations: [{ column: 16, line: 2 }],
message:
'Variable "$input" got invalid value { a: null, b: null }; Exactly one key must be specified for OneOf type "TestInputObject".',
},
],
});
});

it('accepts a valid variable for field', () => {
const query = `
query ($a: String!) {
test(input: { a: $a }) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, { a: 'abc' });

expectJSON(result).toDeepEqual({
data: {
test: {
a: 'abc',
b: null,
},
},
});
});

it('rejects multiple variables for fields', () => {
const query = `
query ($a: String!, $b: Int!) {
test(input: { a: $a, b: $b }) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, { a: 'abc', b: 123 });

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" of type "TestInputObject!" has invalid value { a: $a, b: $b }.',
yaacovCR marked this conversation as resolved.
Show resolved Hide resolved
locations: [{ line: 3, column: 23 }],
path: ['test'],
},
],
});
});

it('rejects variable for field explicitly set to undefined', () => {
const query = `
query ($a: String) {
test(input: { a: $a }) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, { a: undefined });

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" of type "TestInputObject!" has invalid value { a: $a }.',
locations: [{ line: 3, column: 23 }],
path: ['test'],
},
],
});
});

it('rejects 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" of type "TestInputObject!" has invalid value { a: $a }.',
locations: [{ line: 3, column: 23 }],
path: ['test'],
},
],
});
});

it('rejects 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" of type "TestInputObject!" has invalid value { a: $a }.',
locations: [{ line: 3, column: 23 }],
path: ['test'],
},
],
});
});

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

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" of type "TestInputObject!" has invalid value { a: $a, b: $b }.',
locations: [{ line: 3, column: 23 }],
path: ['test'],
},
],
yaacovCR marked this conversation as resolved.
Show resolved Hide resolved
});
});

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

expectJSON(result).toDeepEqual({
data: {
test: {
a: 'abc',
b: null,
},
},
});
});

it('rejects multiple fragment variables for fields', () => {
const query = `
query {
...TestFragment(a: "abc", b: 123)
}
fragment TestFragment($a: String, $b: Int) on Query {
test(input: { a: $a, b: $b }) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, { a: 'abc', b: 123 });

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" of type "TestInputObject!" has invalid value { a: $a, b: $b }.',
locations: [{ line: 6, column: 23 }],
path: ['test'],
},
],
});
});

it('rejects 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" of type "TestInputObject!" has invalid value { a: $a }.',
locations: [{ line: 6, column: 23 }],
path: ['test'],
},
],
});
});

it('rejects 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" of type "TestInputObject!" has invalid value { a: $a }.',
locations: [{ line: 6, column: 23 }],
path: ['test'],
},
],
});
});

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

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" of type "TestInputObject!" has invalid value { a: $a, b: $b }.',
locations: [{ line: 6, column: 23 }],
path: ['test'],
},
],
});
});
});
});
Loading
Loading