mercurius-integration-testing
Version:
[](https://badge.fury.io/js/mercurius-integration-testing) [](https://codecov.i
210 lines (209 loc) • 7.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMercuriusTestClient = createMercuriusTestClient;
const cookie_1 = require("cookie");
const graphql_1 = require("graphql");
const client_1 = require("./subscription/client");
function createMercuriusTestClient(
/**
* Fastify instance, in which it should have been already registered `mercurius`.
*/
app,
/**
* Global Options for the client, including:
* - headers
* - url
* - cookies
*/
opts = {}) {
const readyPromise = new Promise(async (resolve, reject) => {
try {
await app.ready();
if (typeof app.graphql === 'function') {
resolve();
}
else {
reject(Error('Mercurius is not registered in Fastify Instance!'));
}
}
catch (err) {
if (err instanceof Error &&
err.message === 'app.ready is not a function') {
return reject(Error('Invalid Fastify Instance'));
}
reject(err);
}
});
let headers = opts.headers || {};
let cookies = opts.cookies || {};
const url = opts.url || '/graphql';
const query = async (query, queryOptions = {
variables: {},
}) => {
await readyPromise;
const { variables = {}, operationName = null, headers: querySpecificHeaders = {}, cookies: querySpecificCookies = {}, } = queryOptions;
return (await app.inject({
method: 'POST',
url,
cookies: {
...cookies,
...querySpecificCookies,
},
headers: {
'content-type': 'application/json; charset=utf-8',
...headers,
...querySpecificHeaders,
},
payload: JSON.stringify({
query: typeof query === 'string' ? query : (0, graphql_1.print)(query),
variables,
operationName,
}),
})).json();
};
const setHeaders = (newHeaders) => {
headers = newHeaders;
};
const setCookies = (newCookies) => {
cookies = newCookies;
};
const batchQueries = async (queries, queryOptions) => {
await readyPromise;
const { headers: querySpecificHeaders = {}, cookies: querySpecificCookies = {}, } = queryOptions || {};
const responses = (await app.inject({
method: 'POST',
url,
cookies: {
...cookies,
...querySpecificCookies,
},
headers: {
'content-type': 'application/json; charset=utf-8',
...headers,
...querySpecificHeaders,
},
payload: JSON.stringify(queries.map(({ query, variables, operationName }) => {
return {
query: typeof query === 'string' ? query : (0, graphql_1.print)(query),
variables: variables || {},
operationName: operationName || null,
};
})),
})).json();
return responses;
};
const subscribe = ({ query, variables = {}, operationName, initPayload = {}, onData, headers: newHeaders = {}, cookies: newCookies = {}, }) => {
return new Promise(async (resolve, reject) => {
try {
await readyPromise;
let port;
const address = app.server.address();
if (typeof address === 'object' && address) {
port = address.port;
}
else {
app.log.warn('Remember to close the app instance manually');
await app.listen({
port: 0,
});
const address = app.server.address();
/* istanbul ignore else */
if (typeof address === 'object' && address) {
port = address.port;
}
else {
throw Error('Error while trying to automatically start the test server');
}
}
const combinedCookies = Object.entries({ ...cookies, ...newCookies });
const combinedHeaders = {
...headers,
...newHeaders,
};
const subscriptionClient = new client_1.SubscriptionClient(`ws://localhost:${port}${url}`, {
headers: combinedCookies.length
? {
...combinedHeaders,
cookie: combinedCookies.reduce((acum, [key, value]) => {
if (acum) {
acum += '; ';
}
acum += (0, cookie_1.serialize)(key, value);
return acum;
}, ''),
}
: combinedHeaders,
connectionInitPayload: initPayload,
connectionCallback: () => {
try {
subscriptionClient
.createSubscription(typeof query === 'string' ? query : (0, graphql_1.print)(query), variables, ({ payload }) => {
onData(payload);
}, operationName)
.then(() => {
setImmediate(() => {
resolve({
unsubscribe() {
subscriptionClient.close();
},
});
});
})
.catch(
/* istanbul ignore next */
(err) => {
reject(err);
subscriptionClient.close();
});
}
catch (err) {
reject(err);
subscriptionClient.close();
}
},
failedConnectionCallback: reject,
});
}
catch (err) {
reject(err);
}
});
};
const getFederatedEntity = async ({ typename, keys, typeQuery, }) => {
try {
const result = await query(`
query Entities($representations: [_Any!]!) {
_entities(representations: $representations) {
__typename
... on ${typename} {
${typeQuery}
}
}
}
`, {
variables: {
representations: [{ __typename: typename, ...keys }],
},
});
return result.data._entities[0];
}
catch (err) {
if (err instanceof Error &&
err.message.includes('Unknown directive "@key"')) {
throw new Error('Service is not federated');
}
throw err;
}
};
return {
query,
mutate: query,
setHeaders,
headers,
cookies,
setCookies,
batchQueries,
subscribe,
getFederatedEntity,
};
}