From 366db1623b8a905d93b3dd53a4ba980f2c960435 Mon Sep 17 00:00:00 2001 From: Jarrod Flesch Date: Fri, 16 Feb 2024 09:08:37 -0500 Subject: [PATCH] chore: passing graphql test suite --- .../src/utilities/createPayloadRequest.ts | 5 +- packages/payload/src/exports/utilities.ts | 10 +- packages/payload/src/types/index.ts | 5 +- test/access-control/int.spec.ts | 11 +- test/array-update/config.ts | 3 +- test/array-update/int.spec.ts | 24 +- test/array-update/shared.ts | 1 + test/auth/int.spec.ts | 9 - test/collections-graphql/config.ts | 8 +- test/collections-graphql/int.spec.ts | 545 ++++++++++-------- test/helpers/NextRESTClient.ts | 19 +- 11 files changed, 362 insertions(+), 278 deletions(-) create mode 100644 test/array-update/shared.ts diff --git a/packages/next/src/utilities/createPayloadRequest.ts b/packages/next/src/utilities/createPayloadRequest.ts index d2cb3306c9..eed34d52a1 100644 --- a/packages/next/src/utilities/createPayloadRequest.ts +++ b/packages/next/src/utilities/createPayloadRequest.ts @@ -12,6 +12,7 @@ import { initI18n } from '@payloadcms/translations' import { getRequestLanguage } from './getRequestLanguage' import { getRequestLocales } from './getRequestLocales' import { getDataAndFile } from './getDataAndFile' +import { getDataLoader } from 'payload/utilities' type Args = { request: Request @@ -38,7 +39,8 @@ export const createPayloadRequest = async ({ const urlProperties = new URL(request.url) const { searchParams, pathname } = urlProperties - const isGraphQL = !config.graphQL.disable && pathname === `/api${config.routes.graphQL}` + const isGraphQL = + !config.graphQL.disable && pathname === `${config.routes.api}${config.routes.graphQL}` const { data, file } = await getDataAndFile({ request, @@ -96,6 +98,7 @@ export const createPayloadRequest = async ({ } const req: PayloadRequest = Object.assign(request, customRequest) + req.payloadDataLoader = getDataLoader(req) req.user = await getAuthenticatedUser({ payload, diff --git a/packages/payload/src/exports/utilities.ts b/packages/payload/src/exports/utilities.ts index 2aad1fb61d..7c8c8ebbd9 100644 --- a/packages/payload/src/exports/utilities.ts +++ b/packages/payload/src/exports/utilities.ts @@ -1,34 +1,36 @@ +export { getDataLoader } from '../collections/dataloader' export { default as getDefaultValue } from '../fields/getDefaultValue' export { promise as afterReadPromise } from '../fields/hooks/afterRead/promise' export { traverseFields as afterReadTraverseFields } from '../fields/hooks/afterRead/traverseFields' export { extractTranslations } from '../translations/extractTranslations' + export { default as isImage } from '../uploads/isImage' export { combineMerge } from '../utilities/combineMerge' - export { configToJSONSchema, entityToJSONSchema, withNullableJSONSchemaType, } from '../utilities/configToJSONSchema' -export { createArrayFromCommaDelineated } from '../utilities/createArrayFromCommaDelineated' +export { createArrayFromCommaDelineated } from '../utilities/createArrayFromCommaDelineated' export { deepCopyObject } from '../utilities/deepCopyObject' export { deepMerge } from '../utilities/deepMerge' export { fieldSchemaToJSON } from '../utilities/fieldSchemaToJSON' export { default as flattenTopLevelFields } from '../utilities/flattenTopLevelFields' export { formatLabels, formatNames, toWords } from '../utilities/formatLabels' -export { getIDType } from '../utilities/getIDType' +export { getIDType } from '../utilities/getIDType' export { getObjectDotNotation } from '../utilities/getObjectDotNotation' + export { default as getUniqueListBy } from '../utilities/getUniqueListBy' export { isNumber } from '../utilities/isNumber' - export { isValidID } from '../utilities/isValidID' export { setsAreEqual } from '../utilities/setsAreEqual' export { splitPathByArrayFields } from '../utilities/splitPathByArrayFields' export { default as toKebabCase } from '../utilities/toKebabCase' + export { default as wait } from '../utilities/wait' export { default as wordBoundariesRegex } from '../utilities/wordBoundariesRegex' diff --git a/packages/payload/src/types/index.ts b/packages/payload/src/types/index.ts index 5bc58ff060..94e76234ea 100644 --- a/packages/payload/src/types/index.ts +++ b/packages/payload/src/types/index.ts @@ -66,7 +66,10 @@ export type CustomPayloadRequest = { transactionIDPromise?: Promise /** The signed in user */ user: (U & User) | null -} & Pick +} & Pick< + URL, + 'hash' | 'host' | 'href' | 'origin' | 'pathname' | 'port' | 'protocol' | 'search' | 'searchParams' +> export type PayloadRequest = Partial & Required> & CustomPayloadRequest diff --git a/test/access-control/int.spec.ts b/test/access-control/int.spec.ts index c9b7c58a32..cda354f69e 100644 --- a/test/access-control/int.spec.ts +++ b/test/access-control/int.spec.ts @@ -1,9 +1,11 @@ +import type { Payload } from '../../packages/payload/src' import type { PayloadRequest } from '../../packages/payload/src/types' import type { Post, RelyOnRequestHeader, Restricted } from './payload-types' -import payload from '../../packages/payload/src' +import { getPayload } from '../../packages/payload/src' import { Forbidden } from '../../packages/payload/src/errors' -import { initPayloadTest } from '../helpers/configHelpers' +import { startMemoryDB } from '../startMemoryDB' +import configPromise from './config' import { requestHeaders } from './config' import { firstArrayText, @@ -17,12 +19,15 @@ import { slug, } from './shared' +let payload: Payload + describe('Access Control', () => { let post1: Post let restricted: Restricted beforeAll(async () => { - await initPayloadTest({ __dirname }) + const config = await startMemoryDB(configPromise) + payload = await getPayload({ config }) }) beforeEach(async () => { diff --git a/test/array-update/config.ts b/test/array-update/config.ts index 47ad4de80c..4300c4885e 100644 --- a/test/array-update/config.ts +++ b/test/array-update/config.ts @@ -1,10 +1,11 @@ import { buildConfigWithDefaults } from '../buildConfigWithDefaults' import { devUser } from '../credentials' +import { arraySlug } from './shared' export default buildConfigWithDefaults({ collections: [ { - slug: 'arrays', + slug: arraySlug, fields: [ { name: 'arrayOfFields', diff --git a/test/array-update/int.spec.ts b/test/array-update/int.spec.ts index e7548da19e..59d2ea7ecc 100644 --- a/test/array-update/int.spec.ts +++ b/test/array-update/int.spec.ts @@ -1,14 +1,16 @@ -import payload from '../../packages/payload/src' -import { initPayloadTest } from '../helpers/configHelpers' -import configPromise from './config' +import type { Payload } from '../../packages/payload/src' -let collection: string +import { getPayload } from '../../packages/payload/src' +import { startMemoryDB } from '../startMemoryDB' +import configPromise from './config' +import { arraySlug } from './shared' + +let payload: Payload describe('array-update', () => { beforeAll(async () => { - const config = await configPromise - collection = config.collections[0]?.slug - await initPayloadTest({ __dirname }) + const config = await startMemoryDB(configPromise) + payload = await getPayload({ config }) }) afterAll(async () => { @@ -21,7 +23,7 @@ describe('array-update', () => { const originalText = 'some optional text' const doc = await payload.create({ - collection, + collection: arraySlug, data: { arrayOfFields: [ { @@ -47,7 +49,7 @@ describe('array-update', () => { const updatedDoc = await payload.update({ id: doc.id, - collection, + collection: arraySlug, data: { arrayOfFields: arrayWithExistingValues, }, @@ -68,7 +70,7 @@ describe('array-update', () => { } const doc = await payload.create({ - collection, + collection: arraySlug, data: { arrayOfFields: [ { @@ -82,7 +84,7 @@ describe('array-update', () => { const updatedDoc = await payload.update({ id: doc.id, - collection, + collection: arraySlug, data: { arrayOfFields: [ { diff --git a/test/array-update/shared.ts b/test/array-update/shared.ts new file mode 100644 index 0000000000..a4341dada0 --- /dev/null +++ b/test/array-update/shared.ts @@ -0,0 +1 @@ +export const arraySlug = 'arrays' diff --git a/test/auth/int.spec.ts b/test/auth/int.spec.ts index d929e21748..debd4c8c46 100644 --- a/test/auth/int.spec.ts +++ b/test/auth/int.spec.ts @@ -71,15 +71,6 @@ describe('Auth', () => { }) describe('REST - admin user', () => { - beforeAll(async () => { - await restClient.POST(`/${slug}/first-register`, { - body: JSON.stringify({ - email, - password, - }), - }) - }) - it('should prevent registering a new first user', async () => { const response = await restClient.POST(`/${slug}/first-register`, { body: JSON.stringify({ diff --git a/test/collections-graphql/config.ts b/test/collections-graphql/config.ts index f667576ba5..cace7429be 100644 --- a/test/collections-graphql/config.ts +++ b/test/collections-graphql/config.ts @@ -286,6 +286,7 @@ export default buildConfigWithDefaults({ }, }, { + slug: 'payload-api-test-ones', access: { read: () => true, }, @@ -298,9 +299,9 @@ export default buildConfigWithDefaults({ type: 'text', }, ], - slug: 'payload-api-test-ones', }, { + slug: 'payload-api-test-twos', access: { read: () => true, }, @@ -318,7 +319,6 @@ export default buildConfigWithDefaults({ type: 'relationship', }, ], - slug: 'payload-api-test-twos', }, { access: { @@ -328,7 +328,7 @@ export default buildConfigWithDefaults({ { name: 'contentType', hooks: { - afterRead: [({ req }) => req.headers?.['content-type']], + afterRead: [({ req }) => req.headers?.get('content-type')], }, type: 'text', }, @@ -483,7 +483,7 @@ export default buildConfigWithDefaults({ data: {}, }) - await payload.create({ + const t = await payload.create({ collection: 'payload-api-test-twos', data: { relation: payloadAPITest1.id, diff --git a/test/collections-graphql/int.spec.ts b/test/collections-graphql/int.spec.ts index d5f1f4ff04..710dee8abc 100644 --- a/test/collections-graphql/int.spec.ts +++ b/test/collections-graphql/int.spec.ts @@ -1,34 +1,35 @@ -import { GraphQLClient } from 'graphql-request' - +import type { Payload } from '../../packages/payload/src' import type { Post } from './payload-types' -import payload from '../../packages/payload/src' +import { getPayload } from '../../packages/payload/src' import { mapAsync } from '../../packages/payload/src/utilities/mapAsync' -import { initPayloadTest } from '../helpers/configHelpers' +import { NextRESTClient } from '../helpers/NextRESTClient' import { idToString } from '../helpers/idToString' +import { startMemoryDB } from '../startMemoryDB' import configPromise, { errorOnHookSlug, pointSlug, relationSlug, slug } from './config' const title = 'title' -let client: GraphQLClient +let restClient: NextRESTClient +let payload: Payload describe('collections-graphql', () => { beforeAll(async () => { - const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } }) - const config = await configPromise - const url = `${serverURL}${config.routes.api}${config.routes.graphQL}` - client = new GraphQLClient(url) + const config = await startMemoryDB(configPromise) + payload = await getPayload({ config }) + restClient = new NextRESTClient(payload.config) + // TODO: reenable when we migrate back to mongoose v6 // Wait for indexes to be created, // as we need them to query by point - if (payload.db.name === 'mongoose') { - await new Promise((resolve, reject) => { - payload.db?.collections?.point?.ensureIndexes(function (err) { - if (err) reject(err) - resolve(true) - }) - }) - } + // if (payload.db.name === 'mongoose') { + // await new Promise((resolve, reject) => { + // payload.db?.collections?.point?.ensureIndexes(function (err) { + // if (err) reject(err) + // resolve(true) + // }) + // }) + // } }) afterAll(async () => { @@ -53,8 +54,11 @@ describe('collections-graphql', () => { title } }` - const response = await client.request(query) - const doc: Post = response.createPost + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + + const doc: Post = data.createPost expect(doc).toMatchObject({ title }) expect(doc.id).toBeDefined() @@ -67,8 +71,16 @@ describe('collections-graphql', () => { title } }` - const response = (await client.request(query, { title })) as any - const doc: Post = response.createPost + const { data } = await restClient + .GRAPHQL_POST({ + body: JSON.stringify({ + query, + variables: { title }, + }), + }) + .then((res) => res.json()) + + const doc: Post = data.createPost expect(doc).toMatchObject({ title }) expect(doc.id).toBeDefined() @@ -81,8 +93,10 @@ describe('collections-graphql', () => { title } }` - const response = await client.request(query) - const doc: Post = response.Post + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const doc: Post = data.Post expect(doc).toMatchObject({ id: existingDoc.id, title }) }) @@ -96,8 +110,10 @@ describe('collections-graphql', () => { } } }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual(expect.objectContaining({ id: existingDoc.id })) }) @@ -120,8 +136,10 @@ describe('collections-graphql', () => { title } }` - const response = await client.request(query) - const { postIDs, posts, singlePost } = response + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { postIDs, posts, singlePost } = data expect(postIDs.docs).toBeDefined() expect(posts.docs).toBeDefined() expect(singlePost.id).toBeDefined() @@ -167,12 +185,12 @@ describe('collections-graphql', () => { } }` - client.requestConfig.errorPolicy = 'all' - const response = await client.request(query) - client.requestConfig.errorPolicy = 'none' + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) const createdResult = await payload.findByID({ - id: response.createPost.id, + id: data.createPost.id, collection: slug, }) const updateFirstResult = await payload.findByID({ @@ -184,11 +202,11 @@ describe('collections-graphql', () => { collection: errorOnHookSlug, }) - expect(response?.createPost.id).toBeDefined() - expect(response?.updateFirst).toBeNull() - expect(response?.updateSecond).toBeNull() + expect(data?.createPost.id).toBeDefined() + expect(data?.updateFirst).toBeNull() + expect(data?.updateSecond).toBeNull() - expect(createdResult).toMatchObject(response.createPost) + expect(createdResult).toMatchObject(data.createPost) expect(updateFirstResult).toMatchObject(first) expect(updateSecondResult).toStrictEqual(second) }) @@ -198,6 +216,7 @@ describe('collections-graphql', () => { query { PayloadApiTestTwos { docs { + id payloadAPI relation { payloadAPI @@ -206,9 +225,10 @@ describe('collections-graphql', () => { } } ` - - const response = await client.request(query) - const res = response.PayloadApiTestTwos + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const res = data.PayloadApiTestTwos expect(res.docs[0].relation.payloadAPI).toStrictEqual('GraphQL') }) @@ -221,8 +241,10 @@ describe('collections-graphql', () => { } } }` - const response = await client.request(query) - expect(response.ContentTypes?.docs[0]?.contentType).toEqual('application/json') + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + expect(data.ContentTypes?.docs[0]?.contentType).toEqual('application/json') }) it('should update existing', async () => { @@ -234,8 +256,10 @@ describe('collections-graphql', () => { title } }` - const response = await client.request(query) - const doc: Post = response.updatePost + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const doc: Post = data.updatePost expect(doc).toMatchObject({ id: existingDoc.id, title: updatedTitle }) }) @@ -247,8 +271,14 @@ describe('collections-graphql', () => { title } }` - const response = await client.request(query) - const doc: Post = response.deletePost + const { data } = await restClient + .GRAPHQL_POST({ + body: JSON.stringify({ + query, + }), + }) + .then((res) => res.json()) + const doc: Post = data.deletePost expect(doc).toMatchObject({ id: existingDoc.id }) }) @@ -266,32 +296,35 @@ describe('collections-graphql', () => { it('equals', async () => { const query = `query { - Posts(where:{title: {equals:"${post1.title}"}}) { - docs { - id - title + Posts(where:{title: {equals:"${post1.title}"}}) { + docs { + id + title + } } - } - }` - - const response = await client.request(query) - const { docs } = response.Posts + }` + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual(expect.objectContaining({ id: post1.id, title: post1.title })) }) it('not_equals', async () => { const query = `query { - Posts(where:{title: {not_equals:"${post1.title}"}}) { - docs { - id - title + Posts(where:{title: {not_equals:"${post1.title}"}}) { + docs { + id + title + } } - } - }` + }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts const docsWithWhereTitleNotEqualPostTitle = docs.filter( (post) => post.title === post1.title, ) @@ -302,32 +335,36 @@ describe('collections-graphql', () => { it('like', async () => { const postWithWords = await createPost({ title: 'the quick brown fox' }) const query = `query { - Posts(where:{title: {like:"${postWithWords.title?.split(' ')[1]}"}}) { - docs { - id - title + Posts(where:{title: {like:"${postWithWords.title?.split(' ')[1]}"}}) { + docs { + id + title + } } - } - }` + }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs[0]).toMatchObject({ id: postWithWords.id, title: postWithWords.title }) }) it('contains', async () => { const query = `query { - Posts(where:{title: {contains:"${post1.title?.slice(0, 4)}"}}) { - docs { - id - title + Posts(where:{title: {contains:"${post1.title?.slice(0, 4)}"}}) { + docs { + id + title + } } - } - }` + }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual(expect.objectContaining({ id: post1.id, title: post1.title })) expect(docs).toContainEqual(expect.objectContaining({ id: post2.id, title: post2.title })) @@ -336,16 +373,18 @@ describe('collections-graphql', () => { it('exists - true', async () => { const withDescription = await createPost({ description: 'description' }) const query = `query { - Posts(where:{description: {exists:true}}) { - docs { - id - title + Posts(where:{description: {exists:true}}) { + docs { + id + title + } } - } - }` + }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual( expect.objectContaining({ id: withDescription.id, title: withDescription.title }), @@ -355,16 +394,17 @@ describe('collections-graphql', () => { it('exists - false', async () => { const withDescription = await createPost({ description: 'description' }) const query = `query { - Posts(where:{description: {exists:false}}) { - docs { - id - title + Posts(where:{description: {exists:false}}) { + docs { + id + title + } } - } - }` - - const response = await client.request(query) - const { docs } = response.Posts + }` + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).not.toContainEqual(expect.objectContaining({ id: withDescription.id })) expect(docs).toContainEqual(expect.objectContaining({ id: post1.id })) @@ -381,32 +421,34 @@ describe('collections-graphql', () => { it('greater_than', async () => { const query = `query { - Posts(where:{number: {greater_than:1}}) { - docs { - id - title - number + Posts(where:{number: {greater_than:1}}) { + docs { + id + title + number + } } - } - }` - - const response = await client.request(query) - const { docs } = response.Posts + }` + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs.map(({ id }) => id)).toContain(numPost2.id) }) it('greater_than_equal', async () => { const query = `query { - Posts(where:{number: {greater_than_equal:1}}) { - docs { - id - title + Posts(where:{number: {greater_than_equal:1}}) { + docs { + id + title + } } - } - }` - - const response = await client.request(query) - const { docs } = response.Posts + }` + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual(expect.objectContaining({ id: numPost1.id })) expect(docs).toContainEqual(expect.objectContaining({ id: numPost2.id })) @@ -414,32 +456,36 @@ describe('collections-graphql', () => { it('less_than', async () => { const query = `query { - Posts(where:{number: {less_than:2}}) { - docs { - id - title + Posts(where:{number: {less_than:2}}) { + docs { + id + title + } } - } - }` + }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual(expect.objectContaining({ id: numPost1.id })) }) it('less_than_equal', async () => { const query = `query { - Posts(where:{number: {less_than_equal:2}}) { - docs { - id - title + Posts(where:{number: {less_than_equal:2}}) { + docs { + id + title + } } - } - }` + }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual(expect.objectContaining({ id: numPost1.id })) expect(docs).toContainEqual(expect.objectContaining({ id: numPost2.id })) @@ -448,18 +494,20 @@ describe('collections-graphql', () => { it('or', async () => { const query = `query { - Posts( - where: {OR: [{ title: { equals: "${post1.title}" } }, { title: { equals: "${post2.title}" } }] - }) { - docs { - id - title + Posts( + where: {OR: [{ title: { equals: "${post1.title}" } }, { title: { equals: "${post2.title}" } }] + }) { + docs { + id + title + } } - } - }` + }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual(expect.objectContaining({ id: post1.id })) expect(docs).toContainEqual(expect.objectContaining({ id: post2.id })) @@ -467,18 +515,20 @@ describe('collections-graphql', () => { it('or - 1 result', async () => { const query = `query { - Posts( - where: {OR: [{ title: { equals: "${post1.title}" } }, { title: { equals: "nope" } }] - }) { - docs { - id - title + Posts( + where: {OR: [{ title: { equals: "${post1.title}" } }, { title: { equals: "nope" } }] + }) { + docs { + id + title + } } - } - }` + }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual(expect.objectContaining({ id: post1.id })) expect(docs).not.toContainEqual(expect.objectContaining({ id: post2.id })) @@ -488,22 +538,24 @@ describe('collections-graphql', () => { const specialPost = await createPost({ description: 'special-123123' }) const query = `query { - Posts( - where: { - AND: [ - { title: { equals: "${specialPost.title}" } } - { description: { equals: "${specialPost.description}" } } - ] - }) { - docs { - id - title + Posts( + where: { + AND: [ + { title: { equals: "${specialPost.title}" } } + { description: { equals: "${specialPost.description}" } } + ] + }) { + docs { + id + title + } } - } - }` + }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual(expect.objectContaining({ id: specialPost.id })) }) @@ -530,8 +582,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(nearQuery) - const { docs } = response.Points + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query: nearQuery }) }) + .then((res) => res.json()) + const { docs } = data.Points expect(docs).toHaveLength(1) }) @@ -553,8 +607,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(nearQuery) - const { docs } = response.Points + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query: nearQuery }) }) + .then((res) => res.json()) + const { docs } = data.Points expect(docs).toHaveLength(0) }) @@ -591,8 +647,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(nearQuery) - const { docs } = response.Points + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query: nearQuery }) }) + .then((res) => res.json()) + const { docs } = data.Points let previous = 0 docs.forEach(({ point: coordinates }) => { @@ -632,8 +690,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(query) - const { docs } = response.Points + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Points expect(docs).toHaveLength(1) expect(docs[0].point).toEqual([10, 20]) @@ -659,8 +719,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(query) - const { docs } = response.Points + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Points expect(docs).toHaveLength(0) }) @@ -695,8 +757,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(query) - const { docs } = response.Points + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Points expect(docs).toHaveLength(1) expect(docs[0].point).toEqual([10, 20]) @@ -722,8 +786,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(query) - const { docs } = response.Points + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Points expect(docs).toHaveLength(0) }) @@ -746,8 +812,10 @@ describe('collections-graphql', () => { } } }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs).toContainEqual( expect.objectContaining({ @@ -773,8 +841,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(query) - const { docs, totalDocs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs, totalDocs } = data.Posts expect(totalDocs).toStrictEqual(1) expect(docs[0].relationToCustomID.id).toStrictEqual(1) @@ -814,8 +884,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs[0].relationField).toBeFalsy() }) @@ -854,8 +926,10 @@ describe('collections-graphql', () => { } }` - const response = await client.request(query) - const { docs } = response.Posts + const { data } = await restClient + .GRAPHQL_POST({ body: JSON.stringify({ query }) }) + .then((res) => res.json()) + const { docs } = data.Posts expect(docs[0].relationHasManyField).toHaveLength(0) }) @@ -864,9 +938,6 @@ describe('collections-graphql', () => { describe('Error Handler', () => { it('should return have an array of errors when making a bad request', async () => { - let error - - // language=graphQL const query = `query { Posts(where: { title: { exists: true }}) { docs { @@ -874,16 +945,16 @@ describe('collections-graphql', () => { } } }` - await client.request(query).catch((err) => { - error = err - }) - expect(Array.isArray(error.response.errors)).toBe(true) - expect(typeof error.response.errors[0].message).toBe('string') + const { errors } = await restClient + .GRAPHQL_POST({ + body: JSON.stringify({ query }), + }) + .then((res) => res.json()) + expect(Array.isArray(errors)).toBe(true) + expect(typeof errors[0].message).toBe('string') }) it('should return have an array of errors when failing to pass validation', async () => { - let error - // language=graphQL const query = `mutation { createPost(data: {min: 1}) { id @@ -893,17 +964,17 @@ describe('collections-graphql', () => { } }` - await client.request(query).catch((err) => { - error = err - }) - expect(Array.isArray(error.response.errors)).toBe(true) - expect(error.response.errors[0].message).toEqual('The following field is invalid: min') - expect(typeof error.response.errors[0].locations).toBeDefined() + const { errors } = await restClient + .GRAPHQL_POST({ + body: JSON.stringify({ query }), + }) + .then((res) => res.json()) + expect(Array.isArray(errors)).toBe(true) + expect(errors[0].message).toEqual('The following field is invalid: min') + expect(typeof errors[0].locations).toBeDefined() }) it('should return have an array of errors when failing multiple mutations', async () => { - let error - // language=graphQL const query = `mutation createTest { test1:createUser(data: { email: "test@test.com", password: "test" }) { email @@ -922,36 +993,36 @@ describe('collections-graphql', () => { } }` - await client.request(query).catch((err) => { - error = err - }) + const { errors } = await restClient + .GRAPHQL_POST({ + body: JSON.stringify({ query }), + }) + .then((res) => res.json()) - expect(Array.isArray(error.response.errors)).toBe(true) + expect(Array.isArray(errors)).toBe(true) - expect(Array.isArray(error.response.errors[0].locations)).toEqual(true) - expect(error.response.errors[0].message).toEqual('The following field is invalid: password') - expect(error.response.errors[0].path[0]).toEqual('test2') - expect(error.response.errors[0].extensions.name).toEqual('ValidationError') - expect(error.response.errors[0].extensions.data[0].message).toEqual('No password was given') - expect(error.response.errors[0].extensions.data[0].field).toEqual('password') + expect(Array.isArray(errors[0].locations)).toEqual(true) + expect(errors[0].message).toEqual('The following field is invalid: password') + expect(errors[0].path[0]).toEqual('test2') + expect(errors[0].extensions.name).toEqual('ValidationError') + expect(errors[0].extensions.data[0].message).toEqual('No password was given') + expect(errors[0].extensions.data[0].field).toEqual('password') - expect(Array.isArray(error.response.errors[1].locations)).toEqual(true) - expect(error.response.errors[1].message).toEqual('The following field is invalid: email') - expect(error.response.errors[1].path[0]).toEqual('test3') - expect(error.response.errors[1].extensions.name).toEqual('ValidationError') - expect(error.response.errors[1].extensions.data[0].message).toEqual( + expect(Array.isArray(errors[1].locations)).toEqual(true) + expect(errors[1].message).toEqual('The following field is invalid: email') + expect(errors[1].path[0]).toEqual('test3') + expect(errors[1].extensions.name).toEqual('ValidationError') + expect(errors[1].extensions.data[0].message).toEqual( 'A user with the given email is already registered', ) - expect(error.response.errors[1].extensions.data[0].field).toEqual('email') + expect(errors[1].extensions.data[0].field).toEqual('email') - expect(Array.isArray(error.response.errors[2].locations)).toEqual(true) - expect(error.response.errors[2].message).toEqual('The following field is invalid: email') - expect(error.response.errors[2].path[0]).toEqual('test4') - expect(error.response.errors[2].extensions.name).toEqual('ValidationError') - expect(error.response.errors[2].extensions.data[0].message).toEqual( - 'Please enter a valid email address.', - ) - expect(error.response.errors[2].extensions.data[0].field).toEqual('email') + expect(Array.isArray(errors[2].locations)).toEqual(true) + expect(errors[2].message).toEqual('The following field is invalid: email') + expect(errors[2].path[0]).toEqual('test4') + expect(errors[2].extensions.name).toEqual('ValidationError') + expect(errors[2].extensions.data[0].message).toEqual('Please enter a valid email address.') + expect(errors[2].extensions.data[0].field).toEqual('email') }) it('should return the minimum allowed information about internal errors', async () => { @@ -963,16 +1034,18 @@ describe('collections-graphql', () => { } }` - await client.request(query).catch((err) => { - error = err - }) + const { errors } = await restClient + .GRAPHQL_POST({ + body: JSON.stringify({ query }), + }) + .then((res) => res.json()) - expect(Array.isArray(error.response.errors)).toBe(true) - expect(Array.isArray(error.response.errors[0].locations)).toEqual(true) - expect(error.response.errors[0].message).toEqual('Something went wrong.') - expect(error.response.errors[0].path[0]).toEqual('QueryWithInternalError') - expect(error.response.errors[0].extensions.statusCode).toEqual(500) - expect(error.response.errors[0].extensions.name).toEqual('Error') + expect(Array.isArray(errors)).toBe(true) + expect(Array.isArray(errors[0].locations)).toEqual(true) + expect(errors[0].message).toEqual('Something went wrong.') + expect(errors[0].path[0]).toEqual('QueryWithInternalError') + expect(errors[0].extensions.statusCode).toEqual(500) + expect(errors[0].extensions.name).toEqual('Error') }) }) }) diff --git a/test/helpers/NextRESTClient.ts b/test/helpers/NextRESTClient.ts index 9597c4df01..07689e91de 100644 --- a/test/helpers/NextRESTClient.ts +++ b/test/helpers/NextRESTClient.ts @@ -61,14 +61,17 @@ export class NextRESTClient { } async GRAPHQL_POST(options: RequestInit): Promise { - const request = new Request(`${this.serverURL}${this.config.routes.graphQL}`, { - ...options, - method: 'POST', - headers: new Headers({ - 'Content-Type': 'application/json', - ...(options?.headers || {}), - }), - }) + const request = new Request( + `${this.serverURL}${this.config.routes.api}${this.config.routes.graphQL}`, + { + ...options, + method: 'POST', + headers: new Headers({ + 'Content-Type': 'application/json', + ...(options?.headers || {}), + }), + }, + ) return this._GRAPHQL_POST(request) }