msw
Version:
139 lines (121 loc) • 4.28 kB
text/typescript
import { encodeBuffer } from '@mswjs/interceptors'
import { OperationTypeNode, parse } from 'graphql'
import {
parseDocumentNode,
parseGraphQLRequest,
type ParsedGraphQLQuery,
type ParsedGraphQLRequest,
} from './parse-graphql-request'
test('returns true given a GraphQL-compatible request', async () => {
const getRequest = new Request(
new URL(
'http://localhost:8080/graphql?query=mutation Login { user { id } }',
),
)
expect(await parseGraphQLRequest(getRequest)).toEqual<
ParsedGraphQLRequest<any>
>({
operationType: OperationTypeNode.MUTATION,
operationName: 'Login',
query: `mutation Login { user { id } }`,
variables: undefined,
})
const postRequest = new Request(new URL('http://localhost:8080/graphql'), {
method: 'POST',
headers: new Headers({ 'Content-Type': 'application/json' }),
body: encodeBuffer(
JSON.stringify({
query: `query GetUser { user { firstName } }`,
}),
),
})
expect(await parseGraphQLRequest(postRequest)).toEqual<
ParsedGraphQLRequest<any>
>({
operationType: OperationTypeNode.QUERY,
operationName: 'GetUser',
query: `query GetUser { user { firstName } }`,
variables: undefined,
})
})
test('throws an exception given an invalid GraphQL request', async () => {
const getRequest = new Request(
new URL('http://localhost:8080/graphql?query=mutation Login() { user { {}'),
)
await expect(parseGraphQLRequest(getRequest)).rejects.toThrowError(
'[MSW] Failed to intercept a GraphQL request to "GET http://localhost:8080/graphql": cannot parse query. See the error message from the parser below.',
)
const postRequest = new Request(new URL('http://localhost:8080/graphql'), {
method: 'POST',
headers: new Headers({ 'Content-Type': 'application/json' }),
body: encodeBuffer(
JSON.stringify({
query: `query GetUser() { user {{}`,
}),
),
})
await expect(parseGraphQLRequest(postRequest)).rejects.toThrowError(
'[MSW] Failed to intercept a GraphQL request to "POST http://localhost:8080/graphql": cannot parse query. See the error message from the parser below.\n\nSyntax Error: Expected "$", found ")".',
)
})
test('returns false given a GraphQL-incompatible request', async () => {
const getRequest = new Request(new URL('http://localhost:8080/graphql'), {
headers: new Headers({ 'Content-Type': 'application/json' }),
})
expect(await parseGraphQLRequest(getRequest)).toBeUndefined()
const postRequest = new Request(new URL('http://localhost:8080/graphql'), {
method: 'POST',
headers: new Headers({ 'Content-Type': 'application/json' }),
body: encodeBuffer(
JSON.stringify({
queryUser: true,
}),
),
})
expect(await parseGraphQLRequest(postRequest)).toBeUndefined()
})
test('does not read the original request body', async () => {
const request = new Request(new URL('http://localhost/api'), {
method: 'POST',
body: JSON.stringify({ payload: 'value' }),
})
await parseGraphQLRequest(request)
// Must not read the original request body because GraphQL parsing
// is an internal operation that must not lock the body stream.
expect(request.bodyUsed).toBe(false)
})
describe('parseDocumentNode', () => {
const document = parse(`
query GetComments {
comments {
text
}
}
subscription OnCommentAdded {
commentAdded {
text
}
}
`)
test('returns the first operation given no operation name', () => {
expect(parseDocumentNode(document)).toEqual<ParsedGraphQLQuery>({
operationType: OperationTypeNode.QUERY,
operationName: 'GetComments',
})
})
test('returns the operation matching the given operation name', () => {
expect(
parseDocumentNode(document, 'OnCommentAdded'),
).toEqual<ParsedGraphQLQuery>({
operationType: OperationTypeNode.SUBSCRIPTION,
operationName: 'OnCommentAdded',
})
})
test('resolves no operation given an unknown operation name', () => {
expect(parseDocumentNode(document, 'Unknown')).toEqual<ParsedGraphQLQuery>({
operationType: undefined,
// The requested name is echoed back for diagnostics.
operationName: 'Unknown',
})
})
})