Skip to content

Commit

Permalink
Expose the express app to test runners (#6193)
Browse files Browse the repository at this point in the history
  • Loading branch information
timleslie authored Jul 27, 2021
1 parent ef14e31 commit 14cb7c5
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-deers-perform.md
Original file line number Diff line number Diff line change
@@ -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.
22 changes: 20 additions & 2 deletions docs/pages/docs/guides/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions packages/testing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
4 changes: 3 additions & 1 deletion packages/testing/src/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -22,6 +23,7 @@ export type GraphQLRequest = (arg: {
export type TestArgs = {
context: KeystoneContext;
graphQLRequest: GraphQLRequest;
app: express.Express;
};

export type TestEnv = {
Expand Down Expand Up @@ -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 }) {
Expand Down

1 comment on commit 14cb7c5

@vercel
Copy link

@vercel vercel bot commented on 14cb7c5 Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.