Skip to content

Commit

Permalink
Merge pull request #28 from kenneth-gray/update-context-improvement
Browse files Browse the repository at this point in the history
feat: extended updateContext so that it can also accept a function
  • Loading branch information
kenneth-gray authored Oct 24, 2020
2 parents c035803 + 78398bd commit 1647b49
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 9 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ See [HttpMock](#httpmock) and [GraphQlMock](#graphqlmock) for more details.
### HttpResponseFunction

> `function({ query, body, params, context, updateContext, getContext }): response | Promise<response>`
> `function({ query, body, params, context, updateContext }): response | Promise<response>`
<!-- https://www.tablesgenerator.com/markdown_tables -->

Expand All @@ -142,8 +142,7 @@ See [HttpMock](#httpmock) and [GraphQlMock](#graphqlmock) for more details.
| body | `object` | `{}` | body object as defined by `express`. |
| params | `object` | `{}` | params object as defined by `express`. |
| context | `object` | `{}` | Data stored across API calls. |
| updateContext | `Function` | `partialContext => updatedContext` | Used to update context. |
| getContext | `Function` | `() => context` | Used to get the latest context. |
| updateContext | `Function` | `partialContext => updatedContext` | Used to update context. `partialContext` can either be an `object` or a function (`context` => `partialContext`). |
| response | `undefined` / `Response` / `Override` | _required_ | [Response](#response), [Override](#override). |

### GraphQlMock
Expand Down Expand Up @@ -179,16 +178,15 @@ See [HttpMock](#httpmock) and [GraphQlMock](#graphqlmock) for more details.
### GraphQlResponseFunction

> `function({ variables, context, updateContext, getContext }): response | Promise<response>`
> `function({ variables, context, updateContext }): response | Promise<response>`
<!-- https://www.tablesgenerator.com/markdown_tables -->

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| variables | `object` | `{}` | variables sent by client. |
| context | `object` | `{}` | Data stored across API calls. |
| updateContext | `Function` | `partialContext => updatedContext` | Used to update context. |
| getContext | `Function` | `() => context` | Used to get the latest context. |
| updateContext | `Function` | `partialContext => updatedContext` | Used to update context. `partialContext` can either be an `object` or a function (`context` => `partialContext`). |
| response | `undefined` / `Response` / `GraphQlResponse` / `Override` | _required_ | [Response](#response), [GraphQlResponse](#graphqlresponse), [Override](#override). |

### Override
Expand Down
55 changes: 55 additions & 0 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,61 @@ describe('run', () => {
});
});

it('partial context can be set using a function', async () => {
const name = 'Betty';
const initialAge = 40;
const intervalDelayMs = 200;
const intervalTickCount = 5;
const timeoutDelayMs = intervalDelayMs * intervalTickCount + 100;

const server = run({
default: {
context: { age: initialAge, name },
mocks: [
{
url: '/info',
method: 'GET',
response: ({ context }) => context,
},
{
url: '/user',
method: 'POST',
response: ({ updateContext }) => {
const interval = setInterval(() => {
updateContext(({ age }: any) => ({ age: age + 1 }));
}, intervalDelayMs);
setTimeout(() => {
clearInterval(interval);
}, timeoutDelayMs);

return null;
},
},
],
},
});

await serverTest(server, async () => {
const info1 = await rp.get('http://localhost:3000/info', {
json: true,
});
expect(info1).toEqual({ name, age: initialAge });

await rp.post('http://localhost:3000/user');

await new Promise(resolve => {
setTimeout(() => {
resolve();
}, timeoutDelayMs + 100);
});

const info2 = await rp.get('http://localhost:3000/info', {
json: true,
});
expect(info2).toEqual({ name, age: initialAge + intervalTickCount });
});
});

it('context works for GraphQL requests', async () => {
const initialName = 'Alice';
const updatedName = 'Bob';
Expand Down
11 changes: 9 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,15 @@ function createRouter({

return router;

function updateContext(partialContext: Context) {
context = { ...context, ...partialContext };
function updateContext(
partialContext: Context | ((context: Context) => Context),
) {
context = {
...context,
...(typeof partialContext === 'function'
? partialContext(context)
: partialContext),
};

return context;
}
Expand Down
4 changes: 3 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,6 @@ export type Options = {

export type Context = Record<string, any>;

export type UpdateContext = (partialContext: Context) => Context;
export type UpdateContext = (
partialContext: Context | ((context: Context) => Context),
) => Context;

0 comments on commit 1647b49

Please sign in to comment.