-
Notifications
You must be signed in to change notification settings - Fork 308
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: spec compliant accept type (#1064)
- Loading branch information
1 parent
bb48aee
commit f5a6476
Showing
15 changed files
with
731 additions
and
877 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { describe, expect, expectTypeOf } from 'vitest' | ||
import { createResponse, test } from '../../../tests/_/helpers.js' | ||
import { Graffle } from '../../entrypoints/main.js' | ||
import { ACCEPT_REC, CONTENT_TYPE_REC } from '../../lib/graphqlHTTP.js' | ||
import { Transport } from '../5_core/types.js' | ||
import type { RequestInput } from './Settings/inputIncrementable/request.js' | ||
|
||
const endpoint = new URL(`https://foo.io/api/graphql`) | ||
|
||
test(`anyware hooks are typed to http transport`, () => { | ||
Graffle.create({ schema: endpoint }).use(async ({ encode }) => { | ||
expectTypeOf(encode.input.transport).toEqualTypeOf(Transport.http) | ||
const { pack } = await encode() | ||
expectTypeOf(pack.input.transport).toEqualTypeOf(Transport.http) | ||
const { exchange } = await pack() | ||
expectTypeOf(exchange.input.transport).toEqualTypeOf(Transport.http) | ||
expectTypeOf(exchange.input.request).toEqualTypeOf<RequestInput>() | ||
const { unpack } = await exchange() | ||
expectTypeOf(unpack.input.transport).toEqualTypeOf(Transport.http) | ||
expectTypeOf(unpack.input.response).toEqualTypeOf<Response>() | ||
const { decode } = await unpack() | ||
expectTypeOf(decode.input.transport).toEqualTypeOf(Transport.http) | ||
expectTypeOf(decode.input.response).toEqualTypeOf<Response>() | ||
const result = await decode() | ||
if (!(result instanceof Error)) { | ||
expectTypeOf(result.response).toEqualTypeOf<Response>() | ||
} | ||
return result | ||
}) | ||
}) | ||
|
||
test(`can set headers in constructor`, async ({ fetch }) => { | ||
fetch.mockImplementationOnce(() => Promise.resolve(createResponse({ data: { id: `abc` } }))) | ||
const graffle = Graffle.create({ schema: endpoint, request: { headers: { 'x-foo': `bar` } } }) | ||
await graffle.rawString({ document: `query { id }` }) | ||
const request = fetch.mock.calls[0]?.[0] | ||
expect(request?.headers.get(`x-foo`)).toEqual(`bar`) | ||
}) | ||
|
||
test(`sends spec compliant request`, async ({ fetch, graffle }) => { | ||
fetch.mockImplementationOnce(() => Promise.resolve(createResponse({ data: { greetings: `Hello World` } }))) | ||
await graffle.rawString({ document: `query { greetings }` }) | ||
const request = fetch.mock.calls[0]?.[0] | ||
expect(request?.headers.get(`content-type`)).toEqual(CONTENT_TYPE_REC) | ||
expect(request?.headers.get(`accept`)).toEqual(ACCEPT_REC) | ||
}) | ||
|
||
describe(`signal`, () => { | ||
// JSDom and Node result in different errors. JSDom is a plain Error type. Presumably an artifact of JSDom and now in actual browsers. | ||
const abortErrorMessagePattern = /This operation was aborted|AbortError: The operation was aborted/ | ||
test(`AbortController at instance level works`, async () => { | ||
const abortController = new AbortController() | ||
const graffle = Graffle.create({ | ||
schema: endpoint, | ||
request: { signal: abortController.signal }, | ||
}) | ||
const resultPromise = graffle.rawString({ document: `query { id }` }) | ||
abortController.abort() | ||
const { caughtError } = await resultPromise.catch((caughtError: unknown) => ({ caughtError })) as any as { | ||
caughtError: Error | ||
} | ||
expect(caughtError.message).toMatch(abortErrorMessagePattern) | ||
}) | ||
test(`AbortController at method level works`, async () => { | ||
const abortController = new AbortController() | ||
const graffle = Graffle.create({ | ||
schema: endpoint, | ||
}).with({ request: { signal: abortController.signal } }) | ||
const resultPromise = graffle.rawString({ document: `query { id }` }) | ||
abortController.abort() | ||
const { caughtError } = await resultPromise.catch((caughtError: unknown) => ({ caughtError })) as any as { | ||
caughtError: Error | ||
} | ||
expect(caughtError.message).toMatch(abortErrorMessagePattern) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { expectTypeOf } from 'vitest' | ||
import { test } from '../../../tests/_/helpers.js' | ||
import { schema } from '../../../tests/_/schema/schema.js' | ||
import { Graffle } from '../../entrypoints/main.js' | ||
import { Transport } from '../5_core/types.js' | ||
|
||
test(`anyware hooks are typed to memory transport`, () => { | ||
Graffle.create({ schema }).use(async ({ encode }) => { | ||
expectTypeOf(encode.input.transport).toEqualTypeOf(Transport.memory) | ||
const { pack } = await encode() | ||
expectTypeOf(pack.input.transport).toEqualTypeOf(Transport.memory) | ||
const { exchange } = await pack() | ||
expectTypeOf(exchange.input.transport).toEqualTypeOf(Transport.memory) | ||
// @ts-expect-error any | ||
exchange.input.request | ||
const { unpack } = await exchange() | ||
expectTypeOf(unpack.input.transport).toEqualTypeOf(Transport.memory) | ||
// @ts-expect-error any | ||
unpack.input.response | ||
const { decode } = await unpack() | ||
expectTypeOf(decode.input.transport).toEqualTypeOf(Transport.memory) | ||
// @ts-expect-error any | ||
decode.input.response | ||
const result = await decode() | ||
if (!(result instanceof Error)) { | ||
// @ts-expect-error any | ||
result.response | ||
} | ||
return result | ||
}) | ||
}) | ||
|
||
test(`cannot set headers in constructor`, () => { | ||
// todo: This error is poor for the user. It refers to schema not being a URL. The better message would be that headers is not allowed with memory transport. | ||
// @ts-expect-error headers not allowed with GraphQL schema | ||
Graffle.create({ schema, request: { headers: { 'x-foo': `bar` } } }) | ||
}) |
Oops, something went wrong.