From 14cb7c5c40456cd0d2c8408ed46823d2695614cc Mon Sep 17 00:00:00 2001 From: Tim Leslie Date: Tue, 27 Jul 2021 12:30:06 +1000 Subject: [PATCH] Expose the express app to test runners (#6193) --- .changeset/red-deers-perform.md | 5 +++++ docs/pages/docs/guides/testing.mdx | 22 ++++++++++++++++++++-- packages/testing/package.json | 1 + packages/testing/src/index.ts | 4 +++- 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 .changeset/red-deers-perform.md diff --git a/.changeset/red-deers-perform.md b/.changeset/red-deers-perform.md new file mode 100644 index 00000000000..0d7b6ed450f --- /dev/null +++ b/.changeset/red-deers-perform.md @@ -0,0 +1,5 @@ +--- +'@keystone-next/testing': minor +--- + +Added an `app` value to the `TestArgs` type to provide direct access to the Express application from test runners. diff --git a/docs/pages/docs/guides/testing.mdx b/docs/pages/docs/guides/testing.mdx index 47434f2ba83..4b983acfdda 100644 --- a/docs/pages/docs/guides/testing.mdx +++ b/docs/pages/docs/guides/testing.mdx @@ -50,8 +50,9 @@ This ensures that all tests are run in a known state. The test runner then sets up a partial Keystone system for you, including an Apollo server to handle GraphQL requests. The system does not include an Admin UI, and does not open a network port to listen for requests. -Finally, the runner sets up two APIs for you to use in your test. The first is a `KeystoneContext` object, which lets you use any of the functions in the [context API](../apis/context). -The second is a `graphQLRequest` function, which lets you run GraphQL requests over HTTP using the [`supertest`](https://github.com/visionmedia/supertest) library +Finally, the runner sets up three APIs for you to use in your test. The first is a `KeystoneContext` object, which lets you use any of the functions in the [context API](../apis/context). +The second is a `graphQLRequest` function, which lets you run GraphQL requests over HTTP using the [`supertest`](https://github.com/visionmedia/supertest) library. +The third is an [`express.Express`](https://expressjs.com/) value named `app` which lets you access any of the endpoints of the Express server using `supertest`. x> The test runner will drop all data in your database on each run. Make sure you do not run your tests against a system with live data. @@ -166,6 +167,23 @@ runner(async ({ graphQLRequest }) => { See the [`supertest`](https://github.com/visionmedia/supertest) docs for full details on the methods available with `graphQLRequest`. +### Express `app` + +There are some situations where you might want to directly interact with specific endpoints of the Express server. +The underlying Express application is exposed as `app`, and you can use `supertest` to interact with it. +For example, if you wanted to check the `/_healthcheck` endpoint, you could do the following: + +``` +runner(async ({ app }) => { + const { text } = await supertest(app) + .get('/_healthcheck') + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200); + expect(JSON.parse(text)).toMatchObject({ status: 'pass' }); +}) +``` + ## Test environment The test runner function resets the database to a clean state for every test. diff --git a/packages/testing/package.json b/packages/testing/package.json index 086b6e1d525..260250e21c6 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -12,6 +12,7 @@ "dependencies": { "@keystone-next/keystone": "^22.0.0", "@types/supertest": "^2.0.11", + "express": "^4.17.1", "memoize-one": "^5.2.1", "supertest": "^6.1.4" }, diff --git a/packages/testing/src/index.ts b/packages/testing/src/index.ts index e50700ae3f3..36f060e55f4 100644 --- a/packages/testing/src/index.ts +++ b/packages/testing/src/index.ts @@ -1,6 +1,7 @@ import path from 'path'; import crypto from 'crypto'; import fs from 'fs'; +import express from 'express'; import supertest, { Test } from 'supertest'; import memoizeOne from 'memoize-one'; import { initConfig, createSystem, createExpressServer } from '@keystone-next/keystone'; @@ -22,6 +23,7 @@ export type GraphQLRequest = (arg: { export type TestArgs = { context: KeystoneContext; graphQLRequest: GraphQLRequest; + app: express.Express; }; export type TestEnv = { @@ -72,7 +74,7 @@ export async function setupTestEnv({ .send({ query, variables, operationName }) .set('Accept', 'application/json'); - return { connect, disconnect, testArgs: { context: createContext(), graphQLRequest } }; + return { connect, disconnect, testArgs: { context: createContext(), graphQLRequest, app } }; } export function setupTestRunner({ config }: { config: KeystoneConfig }) {