import { describe, it } from 'node:test';
import { expectJSON } from '../../__testUtils__/expectJSON.ts';
import { parse } from '../../language/parser.ts';
import { buildSchema } from '../../utilities/buildASTSchema.ts';
import { execute } from '../execute.ts';
import type { ExecutionResult } from '../Executor.ts';
const schema = buildSchema(`
type Query {
test(input: TestInputObject!): TestObject
}
input TestInputObject @oneOf {
a: String
b: Int
}
type TestObject {
a: String
b: Int
}
`);
function executeQuery(
query: string,
rootValue: unknown,
variableValues?: { [variable: string]: unknown },
): ExecutionResult | Promise<ExecutionResult> {
return execute({
schema,
document: parse(query, { experimentalFragmentArguments: true }),
rootValue,
variableValues,
});
}
describe('Execute: Handles OneOf Input Objects', () => {
describe('OneOf Input Objects', () => {
const rootValue = {
test({ input }: { input: { a?: string; b?: number } }) {
return input;
},
};
it('accepts a good default value', () => {
const query = `
query ($input: TestInputObject! = {a: "abc"}) {
test(input: $input) {
a
b
}
}
`;
const result = executeQuery(query, rootValue);
expectJSON(result).toDeepEqual({
data: {
test: {
a: 'abc',
b: null,
},
},
});
});
it('rejects a bad default value', () => {
const query = `
query ($input: TestInputObject! = {a: "abc", b: 123}) {
test(input: $input) {
a
b
}
}
`;
const result = executeQuery(query, rootValue);
expectJSON(result).toDeepEqual({
errors: [
{
locations: [{ column: 16, line: 2 }],
message:
'Variable "$input" has invalid default value: Within OneOf Input Object type "TestInputObject", exactly one field must be specified, and the value for that field must be non-null.',
},
],
});
});
it('accepts a good variable', () => {
const query = `
query ($input: TestInputObject!) {
test(input: $input) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, { input: { a: 'abc' } });
expectJSON(result).toDeepEqual({
data: {
test: {
a: 'abc',
b: null,
},
},
});
});
it('accepts a good variable with an undefined key', () => {
const query = `
query ($input: TestInputObject!) {
test(input: $input) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, {
input: { a: 'abc', b: undefined },
});
expectJSON(result).toDeepEqual({
data: {
test: {
a: 'abc',
b: null,
},
},
});
});
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 at .a: Within OneOf Input Object type "TestInputObject", exactly one field must be specified, and the value for that field must be non-null.',
locations: [{ line: 2, column: 16 }],
},
],
});
});
it('rejects a variable with multiple non-null keys', () => {
const query = `
query ($input: TestInputObject!) {
test(input: $input) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, {
input: { a: 'abc', b: 123 },
});
expectJSON(result).toDeepEqual({
errors: [
{
locations: [{ column: 16, line: 2 }],
message:
'Variable "$input" has invalid value: Within OneOf Input Object type "TestInputObject", exactly one field must be specified, and the value for that field must be non-null.',
},
],
});
});
it('rejects a variable with multiple nullable keys', () => {
const query = `
query ($input: TestInputObject!) {
test(input: $input) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, {
input: { a: 'abc', b: null },
});
expectJSON(result).toDeepEqual({
errors: [
{
locations: [{ column: 16, line: 2 }],
message:
'Variable "$input" has invalid value: Within OneOf Input Object type "TestInputObject", exactly one field must be specified, and the value for that field must be non-null.',
},
],
});
});
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: [
{
message:
'Argument "Query.test(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: [
{
message:
'Argument "Query.test(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 missing variable as an additional field', () => {
const query = `
query ($a: String, $b: Int) {
test(input: { a: $a, b: $b }) {
a
b
}
}
`;
const result = executeQuery(query, rootValue, { a: 'abc' });
expectJSON(result).toDeepEqual({
data: {
test: null,
},
errors: [
{
message:
'Argument "Query.test(input:)" has invalid value: Expected variable "$b" provided to field "b" 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: [
{
message:
'Argument "Query.test(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: [
{
message:
'Argument "Query.test(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'],
},
],
});
});
});
});