From 5f2db3ce3da7be4758fc174afd606abab98c7c3a Mon Sep 17 00:00:00 2001 From: ValeriaVG Date: Thu, 1 Oct 2020 18:06:18 +0200 Subject: [PATCH 1/3] Validate static schema on load --- src/__tests__/usage-test.ts | 13 +++++++++++++ src/index.ts | 9 ++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/__tests__/usage-test.ts b/src/__tests__/usage-test.ts index d63ee572..d74244b8 100644 --- a/src/__tests__/usage-test.ts +++ b/src/__tests__/usage-test.ts @@ -117,4 +117,17 @@ describe('Useful errors when incorrectly used', () => { ], }); }); + + it('requires a valid schema if static scheme is defined in options', () => { + expect(() => { + // @ts-expect-error + graphqlHTTP({ schema: new GraphQLSchema({ directives: [null] }) }); + }).to.throw('GraphQL schema validation failed'); + expect(() => { + graphqlHTTP(() => ({ + // @ts-expect-error + schema: new GraphQLSchema({ directives: [null] }), + })); + }).not.to.throw(); + }); }); diff --git a/src/index.ts b/src/index.ts index 23b4d930..9814fce1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -190,6 +190,12 @@ export function graphqlHTTP(options: Options): Middleware { throw new Error('GraphQL middleware requires options.'); } + const staticSchemaValidationErrors = + 'schema' in options ? validateSchema(options.schema) : undefined; + + if (staticSchemaValidationErrors?.length) { + throw Error('GraphQL schema validation failed'); + } return async function graphqlMiddleware( request: Request, response: Response, @@ -272,7 +278,8 @@ export function graphqlHTTP(options: Options): Middleware { } // Validate Schema - const schemaValidationErrors = validateSchema(schema); + const schemaValidationErrors = + staticSchemaValidationErrors ?? validateSchema(schema); if (schemaValidationErrors.length > 0) { // Return 500: Internal Server Error if invalid schema. throw httpError(500, 'GraphQL schema validation error.', { From 080871683c3c5063a2010a1bb383497d236f06c0 Mon Sep 17 00:00:00 2001 From: ValeriaVG Date: Thu, 1 Oct 2020 18:07:27 +0200 Subject: [PATCH 2/3] Fix typo in tests --- src/__tests__/usage-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__tests__/usage-test.ts b/src/__tests__/usage-test.ts index d74244b8..2f889b32 100644 --- a/src/__tests__/usage-test.ts +++ b/src/__tests__/usage-test.ts @@ -118,7 +118,7 @@ describe('Useful errors when incorrectly used', () => { }); }); - it('requires a valid schema if static scheme is defined in options', () => { + it('requires a valid schema if static schema is defined in options', () => { expect(() => { // @ts-expect-error graphqlHTTP({ schema: new GraphQLSchema({ directives: [null] }) }); From 284d3ab71bbce1855d0b5f147b0a7ba6141f76d6 Mon Sep 17 00:00:00 2001 From: ValeriaVG Date: Thu, 1 Oct 2020 18:41:38 +0200 Subject: [PATCH 3/3] Fix test coverage --- src/__tests__/http-test.ts | 29 +++++++++++++++++++++++++++++ src/__tests__/usage-test.ts | 14 ++++++++------ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/__tests__/http-test.ts b/src/__tests__/http-test.ts index ffca7714..5098caee 100644 --- a/src/__tests__/http-test.ts +++ b/src/__tests__/http-test.ts @@ -248,6 +248,35 @@ function runTests(server: Server) { }); }); + it('Reports validation errors for dynamic schema', async () => { + const app = server(); + + app.get( + urlString(), + graphqlHTTP(() => Promise.resolve({ schema: TestSchema })), + ); + + const response = await app.request().get( + urlString({ + query: '{ test, unknownOne, unknownTwo }', + }), + ); + + expect(response.status).to.equal(400); + expect(JSON.parse(response.text)).to.deep.equal({ + errors: [ + { + message: 'Cannot query field "unknownOne" on type "QueryRoot".', + locations: [{ line: 1, column: 9 }], + }, + { + message: 'Cannot query field "unknownTwo" on type "QueryRoot".', + locations: [{ line: 1, column: 21 }], + }, + ], + }); + }); + it('Errors when missing operation name', async () => { const app = server(); diff --git a/src/__tests__/usage-test.ts b/src/__tests__/usage-test.ts index 2f889b32..866a8672 100644 --- a/src/__tests__/usage-test.ts +++ b/src/__tests__/usage-test.ts @@ -119,15 +119,17 @@ describe('Useful errors when incorrectly used', () => { }); it('requires a valid schema if static schema is defined in options', () => { - expect(() => { + const options = () => ({ // @ts-expect-error - graphqlHTTP({ schema: new GraphQLSchema({ directives: [null] }) }); + schema: new GraphQLSchema({ directives: [null] }), + }); + const { schema } = options(); + expect(() => { + graphqlHTTP({ schema }); }).to.throw('GraphQL schema validation failed'); + expect(() => { - graphqlHTTP(() => ({ - // @ts-expect-error - schema: new GraphQLSchema({ directives: [null] }), - })); + graphqlHTTP(options); }).not.to.throw(); }); });