Repository URL to install this package:
|
Version:
0.0.1 ▾
|
import { ApolloServerBase } from 'apollo-server-core'
import { GraphQLRequest } from 'apollo-server-core/src/requestpipelineapi'
import { print, DocumentNode } from 'graphql'
import { validateGraphQLResponse } from './validateGraphQLResponse'
import {
Headers as ApolloHeaders,
Request as ApolloRequest,
} from 'apollo-server-env/dist/fetch'
type StringOrAst = string | DocumentNode
// A query must not come with a mutation (and vice versa).
type Query = { query: StringOrAst; mutation?: undefined } & TestArgsType
type Mutation = { mutation: StringOrAst; query?: undefined } & TestArgsType
export type TestArgsApolloHeaderType<
RequestType extends Request | ApolloRequest = Request
> = Pick<RequestType, 'url' | 'method' | 'headers'>
export interface TestArgsNormalHeaderType<
HeadersType extends Headers | ApolloHeaders = Headers | ApolloHeaders
> {
headers: HeadersType
}
export type TestArgsHeadersUnionType =
| TestArgsApolloHeaderType
| TestArgsNormalHeaderType
export interface TestArgsType {
variables?: {
[key: string]: any
}
extensions?: Record<string, any>
http?: TestArgsHeadersUnionType
}
// diff is explicit on request
export interface ApolloTestArgsType {
variables?: {
[key: string]: any
}
extensions?: Record<string, any>
http?: ApolloRequest
}
export interface MockRequestInternals {
headers: Headers
}
export interface ApolloServerBaseWithMockedHeaderInternals {
server: ApolloServerBase
mockRequestInternals: MockRequestInternals
}
export const createTestClient = (
serverOrServerWithMock:
| ApolloServerBase
| ApolloServerBaseWithMockedHeaderInternals
) => {
const server =
serverOrServerWithMock instanceof ApolloServerBase
? serverOrServerWithMock
: serverOrServerWithMock.server
const mockRequestInternals = (serverOrServerWithMock as ApolloServerBaseWithMockedHeaderInternals)
.mockRequestInternals
const executeOperationReference = server.executeOperation.bind(server)
const executeOperation = async (request: GraphQLRequest) => {
try {
const response = await executeOperationReference(request)
validateGraphQLResponse(response)
return response
} catch (validationException) {
console.error('!!! validation')
throw validationException
}
}
const test = async ({ query, mutation, ...args }: Query | Mutation) => {
const operation = query || mutation
if ((!query && !mutation) || (query && mutation)) {
throw new Error(
'Either `query` or `mutation` must be passed, but not both.'
)
}
if (args.http) {
const headers = args.http.headers as Headers
headers.forEach((value, key) => {
// @todo: logger.debug
console.debug(`setting header ${key}=${value}`)
mockRequestInternals.headers.set(key, value)
})
}
const queryOperation =
typeof operation === 'string' ? operation : print(operation)
return executeOperation({
// Convert ASTs, which are produced by `graphql-tag` but not currently
// used by `executeOperation`, to a String using `graphql/language/print`.
query: queryOperation,
...(args as ApolloTestArgsType),
})
}
return { query: test, mutate: test }
}