/* eslint-disable @typescript-eslint/no-explicit-any */ import { ApolloServer } from 'apollo-server-express' import { GraphQLResponse } from 'apollo-server-types' import { DocumentNode } from 'graphql' import { GraphQLContext, Nullable } from '@/modules/shared/helpers/typeHelper' import { TypedDocumentNode } from '@graphql-typed-document-node/core' import { buildApolloServer } from '@/app' import { addLoadersToCtx } from '@/modules/shared/middleware' import { buildUnauthenticatedApolloServer } from '@/test/serverHelper' type TypedGraphqlResponse> = GraphQLResponse & { data: Nullable } /** * Use this to execute GQL operations from tests against an Apollo instance and get * a properly typed response */ export async function executeOperation< R extends Record = Record, V extends Record = Record >( apollo: ApolloServer, query: DocumentNode, variables?: V ): Promise> { return (await apollo.executeOperation({ query, variables })) as TypedGraphqlResponse } /** * Create a test context for a GraphQL request. Optionally override any of the default values. * By default the context will be unauthenticated */ export const createTestContext = ( ctx?: Partial[0]> ): GraphQLContext => addLoadersToCtx({ auth: false, userId: undefined, role: undefined, token: undefined, scopes: [], stream: undefined, err: undefined, ...(ctx || {}) }) /** * Utilities that make it easier to test against an Apollo Server instance */ export const testApolloServer = async (params?: { context?: GraphQLContext }) => { const instance = params?.context ? await buildApolloServer({ context: params.context }) : await buildUnauthenticatedApolloServer() /** * Execute an operation against Apollo and get a properly typed response */ const execute = async < R extends Record = Record, V extends Record = Record >( query: TypedDocumentNode, variables: V, options?: Partial<{ /** * Optionally override the instance's context */ context: Parameters[0] }> ): Promise> => { const realInstance = options?.context ? await buildApolloServer({ context: createTestContext({ ...(params?.context || {}), ...options.context }) }) : instance return (await realInstance.executeOperation({ query, variables })) as TypedGraphqlResponse } return { execute, server: instance } } export type TestApolloServer = Awaited>