Skip to content

Commit

Permalink
test: add test coverage for headers
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt committed Sep 4, 2020
1 parent e666f69 commit b17fd71
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 17 deletions.
42 changes: 28 additions & 14 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
import fetch from 'cross-fetch'
import { print } from 'graphql/language/printer'

import createRequestBody from './createRequestBody'
import { ClientError, GraphQLError, RequestDocument, Variables } from './types'
import { Headers, RequestInit, Response } from './types.dom'

export { ClientError } from './types'

const transformHeaders = (headers: RequestInit["headers"]): Record<string, string> => {
let oHeaders: Record<string, string> = {};
const resolveHeaders = (headers: RequestInit['headers']): Record<string, string> => {
let oHeaders: Record<string, string> = {}
if (headers) {
if (headers instanceof Headers) {
headers.forEach((v, k) => { oHeaders[k] = v })
oHeaders = HeadersInstanceToPlainObject(headers)
} else if (headers instanceof Array) {
headers.forEach(([k, v]) => { oHeaders[k] = v })
headers.forEach(([name, value]) => {
oHeaders[name] = value
})
} else {
oHeaders = headers as Record<string, string>
}
}

return oHeaders
};
}

/**
* todo
Expand All @@ -38,15 +39,15 @@ export class GraphQLClient {
query: string,
variables?: V
): Promise<{ data?: T; extensions?: any; headers: Headers; status: number; errors?: GraphQLError[] }> {
const { headers, ...others } = this.options
const oHeaders = transformHeaders(headers)
let { headers, ...others } = this.options
const body = createRequestBody(query, variables)
headers = resolveHeaders(headers)

const response = await fetch(this.url, {
method: 'POST',
headers: {
...(typeof body === 'string' ? { 'Content-Type': 'application/json' } : {}),
...oHeaders,
...headers,
},
body,
...others,
Expand All @@ -67,20 +68,19 @@ export class GraphQLClient {
}

/**
* todo
* Send a GraphQL document to the server.
*/
async request<T = any, V = Variables>(document: RequestDocument, variables?: V): Promise<T> {
const { headers, ...others } = this.options
const oHeaders = transformHeaders(headers)
let { headers, ...others } = this.options
headers = resolveHeaders(headers)
const resolvedDoc = resolveRequestDocument(document)

const body = createRequestBody(resolvedDoc, variables)

const response = await fetch(this.url, {
method: 'POST',
headers: {
...(typeof body === 'string' ? { 'Content-Type': 'application/json' } : {}),
...oHeaders,
...headers,
},
body,
...others,
Expand All @@ -101,6 +101,9 @@ export class GraphQLClient {
return this
}

/**
* Attach a header to the client. All subsequent requests will have this header.
*/
setHeader(key: string, value: string): GraphQLClient {
const { headers } = this.options

Expand Down Expand Up @@ -214,3 +217,14 @@ export function gql(chunks: TemplateStringsArray, ...variables: any[]): string {
''
)
}

/**
* Convert Headers instance into regular object
*/
function HeadersInstanceToPlainObject(headers: Response['headers']): Record<string, string> {
const o: any = {}
headers.forEach((v, k) => {
o[k] = v
})
return o
}
9 changes: 6 additions & 3 deletions tests/__helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ type Context = {
server: Application
nodeServer: Server
url: string
res: <S extends MockSpec>(spec: S) => MockResult<S>
/**
* Setup a response that will be sent to requests
*/
res: <S extends MockSpec>(spec?: S) => MockResult<S>
}

type MockSpec = {
Expand Down Expand Up @@ -53,12 +56,12 @@ export function setupTestServer() {
headers: req.headers,
body: req.body,
})
if (spec.headers) {
if (spec?.headers) {
Object.entries(spec.headers).forEach(([name, value]) => {
res.setHeader(name, value)
})
}
res.send(spec.body ?? {})
res.send(spec?.body ?? { data: {} })
})
return { spec, requests: requests as any } as any
}
Expand Down
38 changes: 38 additions & 0 deletions tests/headers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { GraphQLClient } from '../src'
import { setupTestServer } from './__helpers'

const ctx = setupTestServer()

describe('using class', () => {
test('.setHeader() sets a header that get sent to server', async () => {
const client = new GraphQLClient(ctx.url)
client.setHeader('x-foo', 'bar')
const mock = ctx.res()
await client.request(`{ me { id } }`)
expect(mock.requests[0].headers['x-foo']).toEqual('bar')
})

describe('.setHeaders() sets headers that get sent to the server', () => {
test('with headers instance', async () => {
const client = new GraphQLClient(ctx.url)
client.setHeaders(new Headers({ 'x-foo': 'bar' }))
const mock = ctx.res()
await client.request(`{ me { id } }`)
expect(mock.requests[0].headers['x-foo']).toEqual('bar')
})
test('with headers object', async () => {
const client = new GraphQLClient(ctx.url)
client.setHeaders({ 'x-foo': 'bar' })
const mock = ctx.res()
await client.request(`{ me { id } }`)
expect(mock.requests[0].headers['x-foo']).toEqual('bar')
})
test('with header tuples', async () => {
const client = new GraphQLClient(ctx.url)
client.setHeaders([['x-foo', 'bar']])
const mock = ctx.res()
await client.request(`{ me { id } }`)
expect(mock.requests[0].headers['x-foo']).toEqual('bar')
})
})
})

0 comments on commit b17fd71

Please sign in to comment.