Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/graphql-toolset / src / createTestClient.ts
Size: Mime:
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 }
}