Skip to content

Commit 5dab84a

Browse files
committed
First implementation
1 parent 25666da commit 5dab84a

9 files changed

Lines changed: 2399 additions & 0 deletions

File tree

.DS_Store

6 KB
Binary file not shown.

.editorconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[*]
2+
indent_style = space
3+
indent_size = 2
4+
end_of_line = lf
5+
charset = utf-8
6+
trim_trailing_whitespace = true
7+
insert_final_newline = true
8+
9+
[*.md]
10+
indent_size = 4
11+
trim_trailing_whitespace = false

.gitignore

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
# Runtime data
9+
pids
10+
*.pid
11+
*.seed
12+
*.pid.lock
13+
14+
# Directory for instrumented libs generated by jscoverage/JSCover
15+
lib-cov
16+
17+
# Coverage directory used by tools like istanbul
18+
coverage
19+
20+
# nyc test coverage
21+
.nyc_output
22+
23+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24+
.grunt
25+
26+
# Bower dependency directory (https://bower.io/)
27+
bower_components
28+
29+
# node-waf configuration
30+
.lock-wscript
31+
32+
# Compiled binary addons (https://nodejs.org/api/addons.html)
33+
build/Release
34+
35+
# Dependency directories
36+
node_modules/
37+
jspm_packages/
38+
39+
# TypeScript v1 declaration files
40+
typings/
41+
42+
# Optional npm cache directory
43+
.npm
44+
45+
# Optional eslint cache
46+
.eslintcache
47+
48+
# Optional REPL history
49+
.node_repl_history
50+
51+
# Output of 'npm pack'
52+
*.tgz
53+
54+
# Yarn Integrity file
55+
.yarn-integrity
56+
57+
# dotenv environment variables file
58+
.env
59+
60+
# next.js build output
61+
.next
62+
63+
# typescript compilation output
64+
dist/

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# CHANGELOG
2+
3+
## 1.0.0
4+
5+
First public release

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Zapier
4+
Copyright (c) 2020 Marco Reni
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.

package.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"name": "apollo-server-integration-testing-fastify",
3+
"version": "0.0.5",
4+
"description": "Test helper for writing apollo-server integration tests",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
7+
"repository": "https://github.com/marcoreni/apollo-server-integration-testing-fastify.git",
8+
"author": "Marco Reni <reni.marco@gmail.com>",
9+
"keywords": [
10+
"GraphQL",
11+
"Apollo",
12+
"Server",
13+
"Javascript",
14+
"Testing",
15+
"Integration Testing",
16+
"Fastify"
17+
],
18+
"license": "MIT",
19+
"private": false,
20+
"scripts": {
21+
"clean": "rm -rf dist/",
22+
"compile": "tsc",
23+
"prepublish": "yarn clean && yarn compile",
24+
"dev": "tsc --watch",
25+
"release": "smooth-release"
26+
},
27+
"dependencies": {
28+
"apollo-server-fastify": "^2.12.0",
29+
"fastify": "^2.13.1"
30+
},
31+
"devDependencies": {
32+
"smooth-release": "^8.0.9",
33+
"typescript": "^3.7.3"
34+
},
35+
"peerDependencies": {
36+
"graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
37+
},
38+
"files": [
39+
"dist"
40+
]
41+
}

src/index.ts

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { ApolloServer } from 'apollo-server-fastify';
2+
import fastify from 'fastify';
3+
import { DocumentNode, print } from 'graphql';
4+
5+
export type StringOrAst = string | DocumentNode;
6+
7+
export type TestClientConfig = {
8+
// The ApolloServer instance that will be used for handling the queries you run in your tests.
9+
// Must be an instance of the ApolloServer class from `apollo-server-fastify` (or a compatible subclass).
10+
apolloServer: ApolloServer;
11+
// Extends the mocked Request object with additional data.
12+
// Useful when your apolloServer `context` option is a callback that operates on the passed in `req` key,
13+
// and you want to inject data into that `req` object.
14+
requestOptions?: fastify.HTTPInjectOptions;
15+
};
16+
17+
export type SetOptionsFn = (options: {
18+
requestOptions?: fastify.HTTPInjectOptions;
19+
}) => void;
20+
21+
type Query = {
22+
query: StringOrAst;
23+
mutation?: undefined;
24+
variables?: {
25+
[name: string]: any;
26+
};
27+
operationName?: string;
28+
};
29+
type Mutation = {
30+
mutation: StringOrAst;
31+
query?: undefined;
32+
variables?: {
33+
[name: string]: any;
34+
};
35+
operationName?: string;
36+
};
37+
38+
export interface ApolloServerTestClient {
39+
query: (query: Query) => Promise<fastify.HTTPInjectResponse>;
40+
mutate: (mutation: Mutation) => Promise<fastify.HTTPInjectResponse>;
41+
setOptions: SetOptionsFn,
42+
}
43+
44+
/**
45+
* This function takes in an apollo server instance and returns a function that you can use to run operations
46+
* against your schema, and assert on the results.
47+
* @example
48+
* const apolloServer = await createApolloServer({ schema })
49+
* const query = createTestClient({
50+
* apolloServer,
51+
* });
52+
* @param {TestClientConfig} options
53+
* @returns {ApolloServerTestClient}
54+
*/
55+
export function createTestClient({
56+
apolloServer,
57+
requestOptions = {},
58+
}: TestClientConfig): ApolloServerTestClient {
59+
const app = fastify();
60+
app.register(apolloServer.createHandler());
61+
62+
let mockRequestOptions = requestOptions;
63+
64+
/**
65+
* Set the options after TestClient creation
66+
* Useful when you don't want to create a new instance just for a specific change in the request.
67+
*/
68+
const setOptions: SetOptionsFn = ({
69+
requestOptions,
70+
}) => {
71+
if (requestOptions) {
72+
mockRequestOptions = requestOptions;
73+
}
74+
};
75+
76+
/**
77+
* Run an operation against the server
78+
* @example
79+
* const result = await query({
80+
* query: `{ currentUser { id } }`
81+
* })
82+
*
83+
* expect(result.json()).toEqual({
84+
* data: {
85+
* currentUser: {
86+
* id: '1'
87+
* }
88+
* }
89+
* });
90+
* @param {Query | Mutation} params
91+
* @returns {fastify.HTTPInjectResponse} fastify response
92+
*/
93+
const test = ({ query, mutation, ...args }: Query | Mutation): Promise<fastify.HTTPInjectResponse> => {
94+
const operation = query || mutation;
95+
96+
if (!operation || (query && mutation)) {
97+
throw new Error(
98+
'Either `query` or `mutation` must be passed, but not both.',
99+
);
100+
}
101+
102+
const opts: fastify.HTTPInjectOptions = {
103+
url: apolloServer.graphqlPath,
104+
method: 'POST',
105+
payload: {
106+
query: typeof operation === 'string' ? operation : print(operation),
107+
...args,
108+
},
109+
...mockRequestOptions,
110+
};
111+
112+
return app.inject(opts);
113+
};
114+
115+
return {
116+
query: test,
117+
mutate: test,
118+
setOptions
119+
};
120+
}

tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"outDir": "./dist",
4+
"target": "es2016",
5+
"module": "commonjs",
6+
"esModuleInterop": true,
7+
"moduleResolution": "node",
8+
"removeComments": true,
9+
"strict": true,
10+
"declaration": true
11+
},
12+
"include": ["./src/**/*"]
13+
}

0 commit comments

Comments
 (0)