UNPKG

mercurius-integration-testing

Version:

[![npm version](https://badge.fury.io/js/mercurius-integration-testing.svg)](https://badge.fury.io/js/mercurius-integration-testing) [![codecov](https://codecov.io/gh/PabloSzx/mercurius-integration-testing/branch/master/graph/badge.svg)](https://codecov.i

210 lines (209 loc) 7.63 kB
"use strict"; 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, }; }