From f5ad7a163a2bb682de40289822f7712c887d5d5e Mon Sep 17 00:00:00 2001 From: Elliot DeNolf Date: Sun, 17 Jul 2022 16:07:59 -0700 Subject: [PATCH] test: remove all old tests --- jest.config.js | 1 + .../graphql/resolvers/resolvers.spec.ts | 417 -------- .../operations/local/local.spec.ts | 246 ----- src/collections/tests/collections.spec.ts | 892 ------------------ src/collections/tests/defaultValue.spec.ts | 109 --- src/collections/tests/endpoints.spec.ts | 73 -- src/collections/tests/hooks.spec.ts | 170 ---- src/collections/tests/pointField.spec.ts | 250 ----- src/collections/tests/relationships.spec.ts | 227 ----- src/collections/tests/validations.spec.js | 81 -- src/express/middleware/errorHandler.spec.ts | 112 --- src/globals/requestHandlers/globals.spec.ts | 192 ---- src/preferences/graphql/resolvers.spec.ts | 135 --- test/access-control/int.todo-spec.ts | 3 + test/collections-rest/int.spec.ts | 1 + test/helpers/rest.ts | 36 +- 16 files changed, 33 insertions(+), 2912 deletions(-) delete mode 100644 src/collections/graphql/resolvers/resolvers.spec.ts delete mode 100644 src/collections/operations/local/local.spec.ts delete mode 100644 src/collections/tests/collections.spec.ts delete mode 100644 src/collections/tests/defaultValue.spec.ts delete mode 100644 src/collections/tests/endpoints.spec.ts delete mode 100644 src/collections/tests/hooks.spec.ts delete mode 100644 src/collections/tests/pointField.spec.ts delete mode 100644 src/collections/tests/relationships.spec.ts delete mode 100644 src/collections/tests/validations.spec.js delete mode 100644 src/express/middleware/errorHandler.spec.ts delete mode 100644 src/globals/requestHandlers/globals.spec.ts delete mode 100644 src/preferences/graphql/resolvers.spec.ts create mode 100644 test/access-control/int.todo-spec.ts diff --git a/jest.config.js b/jest.config.js index c2b217ac7f..4d2dbd0d0d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,6 +2,7 @@ module.exports = { verbose: true, testEnvironment: 'node', testMatch: [ + '**/src/**/*.spec.ts', '**/test/**/*int.spec.ts', ], globalSetup: './test/jest.setup.ts', diff --git a/src/collections/graphql/resolvers/resolvers.spec.ts b/src/collections/graphql/resolvers/resolvers.spec.ts deleted file mode 100644 index 6ae36448f6..0000000000 --- a/src/collections/graphql/resolvers/resolvers.spec.ts +++ /dev/null @@ -1,417 +0,0 @@ -/** - * @jest-environment node - */ -import { request, GraphQLClient } from 'graphql-request'; -import getConfig from '../../../config/load'; -import { email, password } from '../../../mongoose/testCredentials'; - -require('isomorphic-fetch'); - -const config = getConfig(); - -const url = `${config.serverURL}${config.routes.api}${config.routes.graphQL}`; - -let client = null; -let token = null; - -describe('GrahpQL Resolvers', () => { - beforeAll(async (done) => { - const query = ` - mutation { - loginAdmin( - email: "${email}", - password: "${password}" - ) { - token - } - }`; - - const response = await request(url, query); - - token = response.loginAdmin.token; - - client = new GraphQLClient(url, { headers: { Authorization: `JWT ${token}` } }); - - done(); - }); - - describe('Create', () => { - it('should allow a localized post to be created', async () => { - const title = 'gql create'; - const description = 'description'; - - // language=graphQL - const query = `mutation { - createLocalizedPost(data: {title: "${title}", description: "${description}", priority: 10}) { - id - title - description - priority - createdAt - updatedAt - } - }`; - - const response = await client.request(query); - - const data = response.createLocalizedPost; - - expect(data.title).toBe(title); - expect(data.id).toStrictEqual(expect.any(String)); - // const timestampRegex = /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/; - // expect(data.createdAt).toStrictEqual(expect.stringMatching(timestampRegex)); - // expect(data.updatedAt).toStrictEqual(expect.stringMatching(timestampRegex)); - expect(data.createdAt).toStrictEqual(expect.any(String)); - expect(data.updatedAt).toStrictEqual(expect.any(String)); - }); - }); - - describe('Read', () => { - it('should be able to read localized post', async () => { - const title = 'gql read 1'; - const description = 'description'; - - // language=graphQL - const query = `mutation { - createLocalizedPost(data: {title: "${title}", description: "${description}", priority: 10}) { - id - title - description - priority - createdAt - updatedAt - } - }`; - - const response = await client.request(query); - - const { id } = response.createLocalizedPost; - // language=graphQL - const readQuery = `query { - LocalizedPost(id: "${id}") { - id - } - }`; - const readResponse = await client.request(readQuery); - const retrievedId = readResponse.LocalizedPost.id; - - expect(retrievedId).toStrictEqual(id); - }); - - it('should query exists - true', async () => { - const title = 'gql read 2'; - const description = 'description'; - const summary = 'summary'; - - // language=graphQL - const query = `mutation { - createLocalizedPost(data: {title: "${title}", description: "${description}", summary: "${summary}", priority: 10}) { - id - title - description - priority - createdAt - updatedAt - } - }`; - - const response = await client.request(query); - - const { id } = response.createLocalizedPost; - // language=graphQL - const readQuery = `query { - LocalizedPosts(where: { summary: { exists: true }}) { - docs { - id - description - summary - } - } -}`; - const readResponse = await client.request(readQuery); - const retrievedId = readResponse.LocalizedPosts.docs[0].id; - - expect(readResponse.LocalizedPosts.docs).toHaveLength(1); - expect(retrievedId).toStrictEqual(id); - }); - - it('should query exists - false', async () => { - const title = 'gql read 3'; - const description = 'description'; - - // language=graphQL - const query = `mutation { - createLocalizedPost(data: {title: "${title}", description: "${description}", priority: 10}) { - id - title - description - priority - createdAt - updatedAt - } - }`; - - const response = await client.request(query); - - const { id } = response.createLocalizedPost; - // language=graphQL - const readQuery = `query { - LocalizedPosts(where: { summary: { exists: false }}) { - docs { - id - summary - } - } -}`; - const readResponse = await client.request(readQuery); - const retrievedDoc = readResponse.LocalizedPosts.docs[0]; - - expect(readResponse.LocalizedPosts.docs.length).toBeGreaterThan(0); - expect(retrievedDoc.id).toStrictEqual(id); - expect(retrievedDoc.summary).toBeNull(); - }); - }); - - describe('Update', () => { - it('should allow updating an existing post', async () => { - const title = 'gql update'; - const description = 'description'; - - // language=graphQL - const query = `mutation { - createLocalizedPost(data: { title: "${title}", description: "${description}", priority: 10}) { - id - title - description - priority - } - }`; - - const createResponse = await client.request(query); - - const createData = createResponse.createLocalizedPost; - const { id } = createData; - const updatedDesc = 'updated description'; - - // language=graphQL - const update = ` - mutation { - updateLocalizedPost(id: "${id}" data: {description: "${updatedDesc}"}) { - description - } - }`; - - const response = await client.request(update); - const data = response.updateLocalizedPost; - - expect(data.description).toBe(updatedDesc); - }); - }); - - describe('Delete', () => { - it('should be able to delete a localized post', async () => { - const title = 'gql delete'; - const description = 'description'; - - // language=graphQL - const query = `mutation { - createLocalizedPost(data: {title: "${title}", description: "${description}", priority: 10}) { - id - title - description - priority - createdAt - updatedAt - } - }`; - - const response = await client.request(query); - - const { id } = response.createLocalizedPost; - // language=graphQL - const deleteMutation = `mutation { - deleteLocalizedPost(id: "${id}") { - id - } - }`; - const deleteResponse = await client.request(deleteMutation); - const deletedId = deleteResponse.deleteLocalizedPost.id; - - expect(deletedId).toStrictEqual(id); - }); - }); - - describe('Error Handler', () => { - it('should return have an array of errors when making a bad request', async () => { - let error; - - // language=graphQL - const query = `query { - LocalizedPosts(where: { summary: { exists: true }}) { - docs { - badFieldName - } - } - }`; - 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'); - }); - - it('should return have an array of errors when failing to pass validation', async () => { - let error; - // language=graphQL - const query = `mutation { - createLocalizedPost(data: {priority: 10}) { - id - priority - createdAt - updatedAt - } - }`; - - 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'); - }); - }); - - describe('Custom ID', () => { - it('should create', async () => { - const id = 10; - const query = `mutation { - createCustomID(data: { - id: ${id}, - name: "custom" - }) { - id, - name - } - }`; - const response = await client.request(query); - const data = response.createCustomID; - expect(data.id).toStrictEqual(id); - }); - - it('should update', async () => { - const id = 11; - const name = 'custom name'; - - const query = ` - mutation { - createCustomID(data: { - id: ${id}, - name: "${name}" - }) { - id - name - } - }`; - - await client.request(query); - const updatedName = 'updated name'; - - const update = ` - mutation { - updateCustomID(id: ${id} data: {name: "${updatedName}"}) { - name - } - }`; - - const response = await client.request(update); - const data = response.updateCustomID; - - expect(data.name).toStrictEqual(updatedName); - expect(data.name).not.toStrictEqual(name); - }); - - it('should query on id', async () => { - const id = 15; - const name = 'custom name'; - - const create = `mutation { - createCustomID(data: { - id: ${id}, - name: "${name}" - }) { - id - name - } - }`; - - await client.request(create); - - const query = ` - query { - CustomIDs(where: { id: { equals: ${id} } }) { - docs { - id - name - } - } - }`; - const response = await client.request(query); - const [doc] = response.CustomIDs.docs; - expect(doc.id).toStrictEqual(id); - expect(doc.name).toStrictEqual(name); - }); - - it('should delete', async () => { - const id = 12; - const query = `mutation { - createCustomID(data: { - id: ${id}, - name: "delete me" - }) { - id - name - } - }`; - - await client.request(query); - - const deleteMutation = `mutation { - deleteCustomID(id: ${id}) { - id - } - }`; - const deleteResponse = await client.request(deleteMutation); - const deletedId = deleteResponse.deleteCustomID.id; - - expect(deletedId).toStrictEqual(id); - }); - - it('should allow relationships', async () => { - const id = 13; - const query = `mutation { - createCustomID(data: { - id: ${id}, - name: "relate me" - }) { - id - name - } - }`; - - await client.request(query); - const relation = `mutation { - createRelationshipA(data: { - customID: [ ${id} ] - }) { - customID { - id - } - } - }`; - const relationResponse = await client.request(relation); - const { customID } = relationResponse.createRelationshipA; - - expect(customID).toHaveLength(1); - expect(customID).toHaveLength(1); - }); - }); -}); diff --git a/src/collections/operations/local/local.spec.ts b/src/collections/operations/local/local.spec.ts deleted file mode 100644 index 7e05410895..0000000000 --- a/src/collections/operations/local/local.spec.ts +++ /dev/null @@ -1,246 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import { UploadedFile } from 'express-fileupload'; -import payload from '../../..'; -import getFileByPath from '../../../uploads/getFileByPath'; - -let createdMediaID; - -payload.init({ - secret: 'SECRET_KEY', - mongoURL: 'mongodb://localhost/payload', - local: true, -}); - -describe('Collections - Local', () => { - describe('Create', () => { - it('should allow an upload-enabled file to be created and uploaded', async () => { - const alt = 'Alt Text Here'; - const filePath = path.resolve( - __dirname, - '../../../admin/assets/images/generic-block-image.svg', - ); - const { size } = fs.statSync(filePath); - - const result: Media = await payload.create({ - collection: 'media', - data: { - alt, - }, - filePath, - }); - - expect(result.id).toBeDefined(); - expect(result.alt).toStrictEqual(alt); - expect(result.filename).toStrictEqual('generic-block-image.svg'); - expect(result.filesize).toStrictEqual(size); - createdMediaID = result.id; - }); - - it('should allow an upload-enabled file to be created from file instead of filepath', async () => { - const name = 'upload-local.svg'; - const alt = 'Alt Text Here'; - const filePath = path.resolve( - __dirname, - '../../../admin/assets/images/generic-block-image.svg', - ); - const { size } = fs.statSync(filePath); - const file = getFileByPath(filePath); - file.name = name; - - const result: Media = await payload.create({ - collection: 'media', - data: { - alt, - }, - file, - }); - - expect(result.id).toBeDefined(); - expect(result.alt).toStrictEqual(alt); - expect(result.filename).toStrictEqual(name); - expect(result.filesize).toStrictEqual(size); - createdMediaID = result.id; - }); - }); - - describe('Update', () => { - it('should allow an upload-enabled file to be re-uploaded and alt-text to be changed.', async () => { - const newAltText = 'New Alt Text Here'; - - const result: Media = await payload.update({ - collection: 'media', - id: createdMediaID, - data: { - alt: newAltText, - }, - filePath: path.resolve(__dirname, '../../../admin/assets/images/og-image.png'), - }); - - expect(result.alt).toStrictEqual(newAltText); - expect(result.sizes.mobile.width).toStrictEqual(320); - expect(result.width).toStrictEqual(640); - }); - }); - - describe('Read with Hidden Fields', () => { - it('should allow a document with nested hidden fields to be retrieved with hidden fields shown.', async () => { - const demoHiddenField = 'this is going to be hidden'; - - const result = await payload.create({ - collection: 'localized-posts', - data: { - title: 'this post has a hidden field present', - description: 'desc', - priority: 1, - nonLocalizedGroup: { - text: '40w5g534gw34j', - }, - localizedGroup: { - text: '34lijgw45ligjw4li5j', - demoHiddenField, - }, - }, - }); - - expect(result.id).toBeDefined(); - expect(result.localizedGroup).toBeDefined(); - expect(result.localizedGroup.demoHiddenField).toBeUndefined(); - - const withHiddenFields = await payload.findByID({ - collection: 'localized-posts', - id: result.id, - showHiddenFields: true, - }); - - expect(withHiddenFields.localizedGroup.demoHiddenField).toStrictEqual(demoHiddenField); - expect(withHiddenFields.id).toStrictEqual(result.id); - }); - - it('should allow a document with a relationship to a document with hidden fields to read the related document hidden fields', async () => { - const demoHiddenField = 'this is going to be hidden'; - - const relationshipA = await payload.create({ - collection: 'relationship-a', - data: { - demoHiddenField, - }, - }); - - expect(relationshipA.id).toBeDefined(); - expect(relationshipA.demoHiddenField).toBeUndefined(); - - const relationshipB = await payload.create({ - collection: 'relationship-b', - data: { - title: 'pretty clever name here', - post: [relationshipA.id], - }, - }); - - expect(relationshipB.id).toBeDefined(); - - const relationshipBWithHiddenNestedField = await payload.findByID({ - collection: 'relationship-b', - id: relationshipB.id, - showHiddenFields: true, - }); - - expect(relationshipBWithHiddenNestedField.post[0].demoHiddenField).toStrictEqual( - demoHiddenField, - ); - }); - describe('Find', () => { - const title = 'local-find'; - beforeAll(async (done) => { - const data = { - title, - description: 'a description', - priority: 1, - nonLocalizedGroup: { - text: 'english', - }, - localizedGroup: { - text: 'english', - }, - nonLocalizedArray: [ - { - localizedEmbeddedText: 'english', - }, - ], - richTextBlocks: [ - { - blockType: 'richTextBlock', - blockName: 'Test Block Name', - content: [ - { - children: [{ text: 'english' }], - }, - ], - }, - ], - }; - await payload.create({ - collection: 'localized-posts', - data, - }); - Array.from(Array(10).keys()).map(async (i) => { - const uniqueTitle = `${title}-${i}`; - await payload.create({ - collection: 'localized-posts', - data: { - ...data, - title: uniqueTitle, - }, - }); - }); - done(); - }); - it('should find collection with query', async () => { - const result = await payload.find({ - collection: 'localized-posts', - where: { - title: { - equals: title, - }, - }, - }); - const doc = result.docs[0]; - expect(doc.id).toBeDefined(); - expect(doc.title).toStrictEqual(title); - }); - it('should allow disable pagination to return all docs', async () => { - const result = await payload.find({ - collection: 'localized-posts', - pagination: false, - limit: 5, // limit will not be used - }); - expect(result.docs.length).toBeGreaterThan(10); - }); - }); - }); -}); - -interface ImageSize { - url?: string; - width?: number; - height?: number; - mimeType?: string; - filesize?: number; - filename?: string; -} - -interface Media { - id?: string; - filename?: string; - filesize?: number; - width?: number; - height?: number; - sizes?: { - maintainedAspectRatio?: ImageSize; - tablet?: ImageSize; - mobile?: ImageSize; - icon?: ImageSize; - }; - alt: string; -} diff --git a/src/collections/tests/collections.spec.ts b/src/collections/tests/collections.spec.ts deleted file mode 100644 index db2fd4622e..0000000000 --- a/src/collections/tests/collections.spec.ts +++ /dev/null @@ -1,892 +0,0 @@ -import { v4 as uuid } from 'uuid'; -import getConfig from '../../config/load'; -import { email, password } from '../../mongoose/testCredentials'; - -require('isomorphic-fetch'); - -const { serverURL: url } = getConfig(); - -let token = null; -let headers = {}; - -let localizedPost; -let relationshipBID; -const localizedPostTitle = 'title'; -const englishPostDesc = 'english description'; -const spanishPostDesc = 'spanish description'; - -describe('Collections - REST', () => { - beforeAll(async (done) => { - const response = await fetch(`${url}/api/admins/login`, { - body: JSON.stringify({ - email, - password, - }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - const data = await response.json(); - - ({ token } = data); - headers = { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }; - - done(); - }); - - describe('Create', () => { - let response; - let data; - - beforeAll(async () => { - response = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: localizedPostTitle, - description: englishPostDesc, - priority: 1, - nonLocalizedGroup: { - text: 'english', - }, - localizedGroup: { - text: 'english', - }, - nonLocalizedArray: [ - { - localizedEmbeddedText: 'english', - }, - ], - richTextBlocks: [ - { - blockType: 'richTextBlock', - blockName: 'Test Block Name', - content: [ - { - children: [{ text: 'english' }], - }, - ], - }, - ], - }), - headers, - method: 'post', - }); - data = await response.json(); - }); - - it('should allow a localized post to be created', async () => { - expect(response.status).toBe(201); - expect(data.doc.title).toBeDefined(); - expect(data.doc.id).toBeDefined(); - expect(data.doc.nonLocalizedGroup.text).toStrictEqual('english'); - expect(data.doc.localizedGroup.text).toStrictEqual('english'); - expect(data.doc.nonLocalizedArray[0].localizedEmbeddedText).toStrictEqual('english'); - expect(data.doc.richTextBlocks[0].content[0].children[0].text).toStrictEqual('english'); - - const timestampRegex = /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/; - expect(data.doc.createdAt).toStrictEqual(expect.stringMatching(timestampRegex)); - expect(data.doc.updatedAt).toStrictEqual(expect.stringMatching(timestampRegex)); - - localizedPost = data.doc; - }); - - it('should add id to array items', async () => { - expect(data.doc.nonLocalizedArray[0].id).toBeDefined(); - }); - - it('should add id to block items', async () => { - expect(data.doc.richTextBlocks[0].id).toBeDefined(); - }); - }); - - describe('Update', () => { - it('should allow updating an existing post', async () => { - const createResponse = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: 'newTitle', - description: 'original description', - richText: [ - { - children: [{ text: 'english' }], - }, - ], - priority: 1, - }), - headers, - method: 'post', - }); - - expect(createResponse.status).toBe(201); - const createData = await createResponse.json(); - const { id } = createData.doc; - - const updatedDesc = 'updated description'; - const updatedRichText = [ - { - children: [{ text: 'english update' }], - }, - ]; - const updatedNonLocalizedArray = [ - { - localizedEmbeddedText: 'english', - }, - { - localizedEmbeddedText: 'english update', - }, - ]; - const response = await fetch(`${url}/api/localized-posts/${id}`, { - body: JSON.stringify({ - title: 'newTitle', - description: updatedDesc, - richText: updatedRichText, - nonLocalizedArray: updatedNonLocalizedArray, - priority: '', - }), - headers, - method: 'put', - }); - - const data = await response.json(); - - expect(response.status).toBe(200); - expect(data.doc.description).toBe(updatedDesc); - expect(data.doc.priority).not.toStrictEqual(1); - expect(data.doc.nonLocalizedArray).toHaveLength(2); - expect(data.doc.richText[0].children[0].text).toBe('english update'); - - // make certain the stored object is exactly the same as the returned object - const stored = await ( - await fetch(`${url}/api/localized-posts/${id}`, { - method: 'get', - headers, - }) - ).json(); - - expect(data.doc).toMatchObject(stored); - }); - - it('should allow a Spanish locale to be added to an existing post', async () => { - const response = await fetch(`${url}/api/localized-posts/${localizedPost.id}?locale=es`, { - body: JSON.stringify({ - title: 'title in spanish', - description: spanishPostDesc, - priority: 1, - nonLocalizedGroup: { - text: 'spanish', - }, - localizedGroup: { - text: 'spanish', - }, - nonLocalizedArray: [ - { - id: localizedPost.nonLocalizedArray[0].id, - localizedEmbeddedText: 'spanish', - }, - ], - richTextBlocks: [ - { - id: localizedPost.richTextBlocks[0].id, - blockType: 'richTextBlock', - blockName: 'Test Block Name', - content: [ - { - children: [{ text: 'spanish' }], - }, - ], - }, - ], - }), - headers, - method: 'put', - }); - - const data = await response.json(); - - expect(response.status).toBe(200); - expect(data.doc.description).toBe(spanishPostDesc); - expect(data.doc.nonLocalizedGroup.text).toStrictEqual('spanish'); - expect(data.doc.localizedGroup.text).toStrictEqual('spanish'); - expect(data.doc.nonLocalizedArray[0].localizedEmbeddedText).toStrictEqual('spanish'); - expect(data.doc.richTextBlocks[0].content[0].children[0].text).toStrictEqual('spanish'); - }); - }); - - describe('Read', () => { - describe('Localized', () => { - it('should allow a localized post to be retrieved in unspecified locale, defaulting to English', async () => { - const response = await fetch(`${url}/api/localized-posts/${localizedPost.id}`); - const data = await response.json(); - - expect(response.status).toBe(200); - expect(data.description).toBe(englishPostDesc); - expect(data.nonLocalizedGroup.text).toStrictEqual('english'); - expect(data.localizedGroup.text).toStrictEqual('english'); - expect(data.nonLocalizedArray[0].localizedEmbeddedText).toStrictEqual('english'); - expect(data.richTextBlocks[0].content[0].children[0].text).toStrictEqual('english'); - }); - - it('should allow a localized post to be retrieved in specified English locale', async () => { - const response = await fetch(`${url}/api/localized-posts/${localizedPost.id}?locale=en`); - const data = await response.json(); - - expect(response.status).toBe(200); - expect(data.description).toBe(englishPostDesc); - expect(data.nonLocalizedGroup.text).toStrictEqual('english'); - expect(data.localizedGroup.text).toStrictEqual('english'); - expect(data.nonLocalizedArray[0].localizedEmbeddedText).toStrictEqual('english'); - expect(data.richTextBlocks[0].content[0].children[0].text).toStrictEqual('english'); - }); - - it('should allow a localized post to be retrieved in Spanish', async () => { - const response = await fetch(`${url}/api/localized-posts/${localizedPost.id}?locale=es`); - const data = await response.json(); - - expect(response.status).toBe(200); - expect(data.description).toBe(spanishPostDesc); - expect(data.nonLocalizedGroup.text).toStrictEqual('spanish'); - expect(data.localizedGroup.text).toStrictEqual('spanish'); - expect(data.nonLocalizedArray[0].localizedEmbeddedText).toStrictEqual('spanish'); - expect(data.richTextBlocks[0].content[0].children[0].text).toStrictEqual('spanish'); - }); - - it('should allow a localized post to be retrieved in all locales', async () => { - const response = await fetch(`${url}/api/localized-posts/${localizedPost.id}?locale=all`); - const data = await response.json(); - - expect(response.status).toBe(200); - expect(data.description.es).toBe(spanishPostDesc); - expect(data.description.en).toBe(englishPostDesc); - }); - }); - - it('should allow querying by id', async () => { - const response = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: 'another title', - description: 'description', - priority: 1, - }), - headers, - method: 'post', - }); - - expect(response.status).toBe(201); - - const data = await response.json(); - const getResponse = await fetch(`${url}/api/localized-posts/${data.doc.id}`); - - expect(getResponse.status).toBe(200); - - const getData = await getResponse.json(); - - expect(getData.id).toBeDefined(); - }); - - it('should allow querying on a field', async () => { - const desc = 'query test'; - const response = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: 'unique title here', - description: desc, - priority: 1, - nonLocalizedGroup: { - text: 'sample content', - }, - }), - headers, - method: 'post', - }); - - expect(response.status).toBe(201); - const getResponse = await fetch( - `${url}/api/localized-posts?where[description][equals]=${desc}`, - ); - const data = await getResponse.json(); - - expect(getResponse.status).toBe(200); - expect(data.docs[0].description).toBe(desc); - expect(data.docs).toHaveLength(1); - - const getResponse2 = await fetch( - `${url}/api/localized-posts?where[nonLocalizedGroup.text][equals]=sample content`, - ); - const data2 = await getResponse2.json(); - - expect(getResponse2.status).toBe(200); - expect(data2.docs[0].description).toBe(desc); - expect(data2.docs).toHaveLength(1); - }); - - it('should allow querying with OR', async () => { - const title1 = 'Or1'; - const title2 = 'Or2'; - const response = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: title1, - description: 'desc', - priority: 1, - }), - headers, - method: 'post', - }); - - const response2 = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: title2, - description: 'desc', - priority: 1, - }), - headers, - method: 'post', - }); - - expect(response.status).toBe(201); - expect(response2.status).toBe(201); - - const queryResponse = await fetch( - `${url}/api/localized-posts?where[or][0][title][equals]=${title1}&where[or][1][title][equals]=${title2}`, - ); - const data = await queryResponse.json(); - - expect(queryResponse.status).toBe(200); - expect(data.docs).toHaveLength(2); - expect(data.docs).toContainEqual(expect.objectContaining({ title: title1 })); - expect(data.docs).toContainEqual(expect.objectContaining({ title: title2 })); - }); - - it('should allow querying with OR, 1 result', async () => { - const title1 = 'OrNegative1'; - const title2 = 'OrNegative2'; - const response = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: title1, - description: 'desc', - priority: 1, - }), - headers, - method: 'post', - }); - - const response2 = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: title2, - description: 'desc', - priority: 1, - }), - headers, - method: 'post', - }); - - expect(response.status).toBe(201); - expect(response2.status).toBe(201); - - const queryResponse = await fetch( - `${url}/api/localized-posts?where[or][0][title][equals]=${title1}&where[or][1][title][equals]=nonexistent`, - ); - const data = await queryResponse.json(); - - expect(queryResponse.status).toBe(200); - expect(data.docs).toHaveLength(1); - expect(data.docs[0].title).toBe(title1); - }); - - it('should allow querying by a non-localized nested relationship property', async () => { - const relationshipBTitle = 'test'; - const relationshipBRes = await fetch(`${url}/api/relationship-b?depth=0`, { - body: JSON.stringify({ - title: relationshipBTitle, - }), - headers, - method: 'post', - }); - - const relationshipBData = await relationshipBRes.json(); - - const res = await fetch(`${url}/api/relationship-a?depth=0`, { - body: JSON.stringify({ - post: relationshipBData.doc.id, - }), - headers, - method: 'post', - }); - - const additionalRelationshipARes = await fetch(`${url}/api/relationship-a?depth=0`, { - body: JSON.stringify({ - postLocalizedMultiple: [ - { - relationTo: 'localized-posts', - value: localizedPost.id, - }, - ], - }), - headers, - method: 'post', - }); - - const relationshipAData = await res.json(); - - expect(res.status).toBe(201); - expect(additionalRelationshipARes.status).toBe(201); - expect(relationshipAData.doc.post).toBe(relationshipBData.doc.id); - - const queryRes = await fetch( - `${url}/api/relationship-a?where[post.title][equals]=${relationshipBTitle}`, - ); - const data = await queryRes.json(); - - expect(data.docs).toHaveLength(1); - }); - - it('should allow querying by a localized nested relationship property', async () => { - const res = await fetch(`${url}/api/relationship-a`, { - body: JSON.stringify({ - LocalizedPost: [localizedPost.id], - }), - headers, - method: 'post', - }); - - expect(res.status).toBe(201); - - const queryRes1 = await fetch( - `${url}/api/relationship-a?where[LocalizedPost.title][in]=${localizedPostTitle}`, - ); - const data1 = await queryRes1.json(); - - expect(data1.docs).toHaveLength(1); - }); - - it('should allow querying by a localized nested relationship with many relationTos', async () => { - const relationshipBTitle = 'lawleifjawelifjew'; - const relationshipB = await fetch(`${url}/api/relationship-b?depth=0`, { - body: JSON.stringify({ - title: relationshipBTitle, - }), - headers, - method: 'post', - }).then((res) => res.json()); - - expect(relationshipB.doc.id).toBeDefined(); - - const res = await fetch(`${url}/api/relationship-a`, { - body: JSON.stringify({ - postManyRelationships: { - value: relationshipB.doc.id, - relationTo: 'relationship-b', - }, - }), - headers, - method: 'post', - }); - - expect(res.status).toBe(201); - - const queryRes = await fetch( - `${url}/api/relationship-a?where[postManyRelationships.value][equals]=${relationshipB.doc.id}`, - ); - const data = await queryRes.json(); - expect(data.docs).toHaveLength(1); - }); - - it('should allow querying by a non-localized relationship with many relationTos', async () => { - const relationshipB = await fetch(`${url}/api/relationship-b?depth=0`, { - body: JSON.stringify({ - title: 'awefjlaiwejfalweiijfaew', - nonLocalizedRelationToMany: { - relationTo: 'localized-posts', - value: localizedPost.id, - }, - }), - headers, - method: 'post', - }).then((res) => res.json()); - - expect(relationshipB.doc.id).toBeDefined(); - relationshipBID = relationshipB.doc.id; - - const queryRes = await fetch( - `${url}/api/relationship-b?where[nonLocalizedRelationToMany.value][equals]=${localizedPost.id}`, - ); - const data = await queryRes.json(); - expect(data.docs).toHaveLength(1); - }); - - it('should propagate locale through populated documents', async () => { - const relationshipB = await fetch(`${url}/api/relationship-b/${relationshipBID}?locale=es`, { - headers, - }); - - const data = await relationshipB.json(); - expect(data.nonLocalizedRelationToMany.value.description).toBe(spanishPostDesc); - }); - - it('should allow querying by a numeric custom ID', async () => { - const customID = 1988; - - const customIDResult = await fetch(`${url}/api/custom-id?depth=0`, { - body: JSON.stringify({ - id: customID, - name: 'woohoo', - }), - headers, - method: 'post', - }).then((res) => res.json()); - - expect(customIDResult.doc.id).toStrictEqual(customID); - - await fetch(`${url}/api/custom-id?depth=0`, { - body: JSON.stringify({ - id: 2343452, - name: 'another post', - }), - headers, - method: 'post', - }).then((res) => res.json()); - - const queryRes1 = await fetch(`${url}/api/custom-id?where[id][equals]=${customID}`, { - headers, - }); - - const data1 = await queryRes1.json(); - - expect(data1.docs).toHaveLength(1); - - const queryByIDRes = await fetch(`${url}/api/custom-id/${customID}`, { - headers, - }); - const queryByIDData = await queryByIDRes.json(); - expect(queryByIDData.id).toStrictEqual(customID); - }); - - it('should allow querying by a field within a group', async () => { - const text = 'laiwjefliajwe'; - - await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: 'super great title', - description: 'desc', - priority: 1, - nonLocalizedGroup: { - text, - }, - localizedGroup: { - text, - }, - }), - headers, - method: 'post', - }); - - const queryRes1 = await fetch( - `${url}/api/localized-posts?where[nonLocalizedGroup.text][equals]=${text}`, - ); - const data1 = await queryRes1.json(); - - expect(data1.docs).toHaveLength(1); - - const queryRes2 = await fetch( - `${url}/api/localized-posts?where[localizedGroup.text][equals]=${text}`, - ); - const data2 = await queryRes2.json(); - - expect(queryRes2.status).toBe(200); - expect(data2.docs).toHaveLength(1); - }); - }); - - describe('Delete', () => { - it('should allow a post to be deleted', async () => { - const response = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: 'title to be deleted', - description: englishPostDesc, - priority: 1, - }), - headers, - method: 'post', - }); - - const data = await response.json(); - const docId = data.doc.id; - expect(response.status).toBe(201); - expect(docId).toBeDefined(); - - const deleteResponse = await fetch(`${url}/api/localized-posts/${docId}`, { - headers, - method: 'delete', - }); - const deleteData = await deleteResponse.json(); - expect(deleteResponse.status).toBe(200); - expect(deleteData.id).toBe(docId); - }); - }); - - describe('Metadata', () => { - async function createPost(title, description) { - await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: title || uuid(), - description, - priority: 1, - }), - headers, - method: 'post', - }); - } - - it('should include metadata', async () => { - const desc = 'metadataDesc'; - for (let i = 0; i < 12; i += 1) { - // eslint-disable-next-line no-await-in-loop - await createPost(null, desc); - } - - const getResponse = await fetch( - `${url}/api/localized-posts?where[description][equals]=${desc}`, - ); - const data = await getResponse.json(); - - expect(getResponse.status).toBe(200); - - // TODO: Assert exact length once query bug is fixed - expect(data.docs.length).toBeGreaterThan(0); - expect(data.totalDocs).toBeGreaterThan(0); - expect(data.limit).toBe(10); - expect(data.page).toBe(1); - expect(data.pagingCounter).toBe(1); - expect(data.hasPrevPage).toBe(false); - expect(data.hasNextPage).toBe(true); - expect(data.prevPage).toBeNull(); - expect(data.nextPage).toBe(2); - }); - - it('should sort the results', async () => { - const desc = 'sort'; - - // Create 2 posts with different titles, same desc - const req1 = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: 'aaa', - description: desc, - priority: 1, - }), - headers, - method: 'post', - }); - - const req2 = await fetch(`${url}/api/localized-posts`, { - body: JSON.stringify({ - title: 'zzz', - description: desc, - priority: 1, - }), - headers, - method: 'post', - }); - - const req1data = await req1.json(); - const req2data = await req2.json(); - const id1 = req1data.doc.id; - const id2 = req2data.doc.id; - - // Query on shared desc and sort ascending - const getResponse = await fetch( - `${url}/api/localized-posts?where[description][equals]=${desc}&sort=title`, - ); - const data = await getResponse.json(); - - expect(getResponse.status).toBe(200); - expect(data.docs).toHaveLength(2); - expect(data.docs[0].id).toStrictEqual(id1); - expect(data.docs[1].id).toStrictEqual(id2); - - // Query on shared desc and sort descending - const getResponseSorted = await fetch( - `${url}/api/localized-posts?where[description][equals]=${desc}&sort=-title`, - ); - const sortedData = await getResponseSorted.json(); - - expect(getResponse.status).toBe(200); - expect(sortedData.docs).toHaveLength(2); - // Opposite order from first request - expect(sortedData.docs[0].id).toStrictEqual(id2); - expect(sortedData.docs[1].id).toStrictEqual(id1); - }); - }); - - describe('Field Access', () => { - it('should properly prevent / allow public users from reading a restricted field', async () => { - const firstArrayText1 = 'test 1'; - const firstArrayText2 = 'test 2'; - - const response = await fetch(`${url}/api/localized-arrays`, { - body: JSON.stringify({ - array: [ - { - arrayText1: firstArrayText1, - arrayText2: 'test 2', - arrayText3: 'test 3', - allowPublicReadability: true, - }, - { - arrayText1: firstArrayText2, - arrayText2: 'test 2', - arrayText3: 'test 3', - allowPublicReadability: false, - }, - ], - }), - headers, - method: 'post', - }); - - const data = await response.json(); - const docId = data.doc.id; - expect(response.status).toBe(201); - expect(data.doc.array[1].arrayText1).toStrictEqual(firstArrayText2); - - const unauthenticatedResponse = await fetch(`${url}/api/localized-arrays/${docId}`, { - headers: { - 'Content-Type': 'application/json', - }, - }); - expect(unauthenticatedResponse.status).toBe(200); - const unauthenticatedData = await unauthenticatedResponse.json(); - - // This string should be allowed to come back - expect(unauthenticatedData.array[0].arrayText1).toBe(firstArrayText1); - - // This string should be prevented from coming back - expect(unauthenticatedData.array[1].arrayText1).toBeUndefined(); - - const authenticatedResponse = await fetch(`${url}/api/localized-arrays/${docId}`, { - headers, - }); - - const authenticatedData = await authenticatedResponse.json(); - - // If logged in, we should get this field back - expect(authenticatedData.array[1].arrayText1).toStrictEqual(firstArrayText2); - }); - }); - - describe('Unique', () => { - it('should prevent unique fields from duplicating data', async () => { - const nonUniqueTitle = 'title'; - - const response = await fetch(`${url}/api/uniques`, { - body: JSON.stringify({ - title: nonUniqueTitle, - }), - headers, - method: 'post', - }); - - const data = await response.json(); - - expect(response.status).toBe(201); - expect(data.doc.title).toStrictEqual(nonUniqueTitle); - - const failedResponse = await fetch(`${url}/api/uniques`, { - body: JSON.stringify({ - title: nonUniqueTitle, - }), - headers, - method: 'post', - }); - - expect(failedResponse.status).toStrictEqual(500); - }); - }); - - describe('Custom ID', () => { - const document = { - id: 1, - name: 'name', - }; - let data; - beforeAll(async (done) => { - // create document - const create = await fetch(`${url}/api/custom-id`, { - body: JSON.stringify(document), - headers, - method: 'post', - }); - data = await create.json(); - done(); - }); - - it('should create collections with custom ID', async () => { - expect(data.doc.id).toBe(document.id); - }); - - it('should read collections by custom ID', async () => { - const response = await fetch(`${url}/api/custom-id/${document.id}`, { - headers, - method: 'get', - }); - - const result = await response.json(); - - expect(result.id).toStrictEqual(document.id); - expect(result.name).toStrictEqual(document.name); - }); - - it('should update collection by custom ID', async () => { - const updatedDoc = { id: 'cannot-update-id', name: 'updated' }; - const response = await fetch(`${url}/api/custom-id/${document.id}`, { - headers, - body: JSON.stringify(updatedDoc), - method: 'put', - }); - - const result = await response.json(); - - expect(result.doc.id).not.toStrictEqual(updatedDoc.id); - expect(result.doc.name).not.toStrictEqual(document.name); - expect(result.doc.name).toStrictEqual(updatedDoc.name); - }); - - it('should delete collection by custom ID', async () => { - const doc = { - id: 2, - name: 'delete me', - }; - const createResponse = await fetch(`${url}/api/custom-id`, { - body: JSON.stringify(doc), - headers, - method: 'post', - }); - const result = await createResponse.json(); - const response = await fetch(`${url}/api/custom-id/${result.doc.id}`, { - headers, - method: 'delete', - }); - - expect(response.status).toBe(200); - const deleteData = await response.json(); - expect(deleteData.id).toBe(doc.id); - }); - - it('should allow querying by custom ID', async () => { - const response = await fetch(`${url}/api/custom-id?where[id][equals]=${document.id}`, { - headers, - method: 'get', - }); - const emptyResponse = await fetch(`${url}/api/custom-id?where[id][equals]=900`, { - headers, - method: 'get', - }); - - const result = await response.json(); - const emptyResult = await emptyResponse.json(); - - expect(result.docs).toHaveLength(1); - expect(emptyResult.docs).toHaveLength(0); - }); - }); -}); diff --git a/src/collections/tests/defaultValue.spec.ts b/src/collections/tests/defaultValue.spec.ts deleted file mode 100644 index 08b2bb2b53..0000000000 --- a/src/collections/tests/defaultValue.spec.ts +++ /dev/null @@ -1,109 +0,0 @@ -import getConfig from '../../config/load'; -import { email, password } from '../../mongoose/testCredentials'; - -require('isomorphic-fetch'); - -const { serverURL: url } = getConfig(); - -let token = null; -let headers = null; - -describe('DefaultValue - REST', () => { - beforeAll(async (done) => { - const response = await fetch(`${url}/api/admins/login`, { - body: JSON.stringify({ - email, - password, - }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - const data = await response.json(); - - ({ token } = data); - headers = { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }; - - done(); - }); - - describe('DefaultValues', () => { - let document; - beforeAll(async (done) => { - const result = await fetch(`${url}/api/default-values`, { - body: JSON.stringify({}), - headers, - method: 'post', - }); - - const data = await result.json(); - document = data.doc; - done(); - }); - - it('should create with defaultValues saved', async () => { - expect(document.id).toBeDefined(); - expect(document.function).toStrictEqual('function'); - expect(document.asyncText).toStrictEqual('asyncFunction'); - expect(document.array[0].arrayText1).toStrictEqual('Get out'); - expect(document.group.nestedText1).toStrictEqual('this should take priority'); - expect(document.group.nestedText2).toStrictEqual('nested default text 2'); - expect(document.group.nestedText3).toStrictEqual('neat'); - }); - - it('should not overwrite other locales when updating', async () => { - const slug = 'updated'; - const esSlug = 'spanish'; - const createResult = await fetch(`${url}/api/default-values`, { - body: JSON.stringify({ - text: 'unique', - slug: 'unique', - }), - headers, - method: 'post', - }); - - const createData = await createResult.json(); - - const { id } = createData.doc; - - const enResult = await fetch(`${url}/api/default-values/${id}?locale=en`, { - body: JSON.stringify({ - slug, - }), - headers, - method: 'put', - }); - - const enData = await enResult.json(); - - const esResult = await fetch(`${url}/api/default-values/${id}?locale=es`, { - body: JSON.stringify({ - slug: esSlug, - }), - headers, - method: 'put', - }); - - const esData = await esResult.json(); - - const allResult = await fetch(`${url}/api/default-values/${id}?locale=all`, { - headers, - method: 'get', - }); - - const allData = await allResult.json(); - - expect(createData.doc.slug).toStrictEqual('unique'); - expect(enData.doc.slug).toStrictEqual(slug); - expect(esData.doc.slug).toStrictEqual(esSlug); - expect(allData.slug.en).toStrictEqual(slug); - expect(allData.slug.es).toStrictEqual(esSlug); - }); - }); -}); diff --git a/src/collections/tests/endpoints.spec.ts b/src/collections/tests/endpoints.spec.ts deleted file mode 100644 index de46d4bf86..0000000000 --- a/src/collections/tests/endpoints.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import getConfig from '../../config/load'; -import { email, password } from '../../mongoose/testCredentials'; - -require('isomorphic-fetch'); - -const { serverURL: url } = getConfig(); - -let token = null; -let headers = null; - -describe('Collections - REST', () => { - beforeAll(async (done) => { - const response = await fetch(`${url}/api/admins/login`, { - body: JSON.stringify({ - email, - password, - }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - const data = await response.json(); - - ({ token } = data); - headers = { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }; - - done(); - }); - - describe('Endpoints', () => { - it('should GET a static endpoint', async () => { - const response = await fetch(`${url}/api/endpoints/say-hello/joe-bloggs`, { - headers: { - ...headers, - }, - method: 'get', - }); - const data = await response.json(); - expect(response.status).toBe(200); - expect(data.message).toStrictEqual(`Hey Joey! Welcome to ${url}/api`); - }); - it('should GET an endpoint with a parameter', async () => { - const response = await fetch(`${url}/api/endpoints/say-hello/George`, { - headers: { - ...headers, - }, - method: 'get', - }); - const data = await response.json(); - expect(response.status).toBe(200); - expect(data.message).toStrictEqual('Hello George!'); - }); - it('should POST an endpoint with data', async () => { - const params = { name: 'George', age: 29 }; - const response = await fetch(`${url}/api/endpoints/whoami`, { - body: JSON.stringify(params), - headers: { - ...headers, - }, - method: 'post', - }); - const data = await response.json(); - expect(response.status).toBe(200); - expect(data.name).toStrictEqual(params.name); - expect(data.age).toStrictEqual(params.age); - }); - }); -}); diff --git a/src/collections/tests/hooks.spec.ts b/src/collections/tests/hooks.spec.ts deleted file mode 100644 index 28aa947080..0000000000 --- a/src/collections/tests/hooks.spec.ts +++ /dev/null @@ -1,170 +0,0 @@ -import getConfig from '../../config/load'; -import { email, password } from '../../mongoose/testCredentials'; - -require('isomorphic-fetch'); - -const { serverURL: url } = getConfig(); - -let token = null; -let headers = null; - -describe('Collections - REST', () => { - beforeAll(async (done) => { - const response = await fetch(`${url}/api/admins/login`, { - body: JSON.stringify({ - email, - password, - }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - const data = await response.json(); - - ({ token } = data); - headers = { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }; - - done(); - }); - - describe('Hooks', () => { - describe('Before', () => { - it('beforeChange', async () => { - const response = await fetch(`${url}/api/hooks`, { - body: JSON.stringify({ - title: 'title 1', - description: 'Original', - priority: 1, - }), - headers: { - ...headers, - hook: 'beforeChange', // Used by hook - }, - method: 'post', - }); - const data = await response.json(); - expect(response.status).toBe(201); - expect(data.doc.description).toStrictEqual('Original-beforeChangeSuffix'); - }); - - it('beforeDelete', async () => { - const createResponse = await fetch(`${url}/api/hooks`, { - body: JSON.stringify({ - title: 'title 2', - description: 'Original', - priority: 1, - }), - headers, - method: 'post', - }); - const createData = await createResponse.json(); - const { id } = createData.doc; - - const response = await fetch(`${url}/api/hooks/${id}`, { - headers: { - ...headers, - hook: 'beforeDelete', // Used by hook - }, - method: 'delete', - }); - - const data = await response.json(); - expect(response.status).toBe(200); - // Intentionally afterDeleteHook - beforeDelete hook is setting header in order to trigger afterDelete hook - expect(data.afterDeleteHook).toStrictEqual(true); - }); - }); - - describe('After', () => { - it('afterRead', async () => { - const response = await fetch(`${url}/api/hooks`, { - body: JSON.stringify({ - title: 'title 3', - description: 'afterRead', - priority: 1, - }), - headers: { - ...headers, - hook: 'afterRead', // Used by hook - }, - method: 'post', - }); - const data = await response.json(); - const getResponse = await fetch(`${url}/api/hooks/${data.doc.id}`); - const getResponseData = await getResponse.json(); - expect(getResponse.status).toBe(200); - expect(getResponseData.afterReadHook).toStrictEqual(true); - expect(getResponseData.findMany).toBeUndefined(); - - const getManyResponse = await fetch(`${url}/api/hooks`); - const getManyResponseData = await getManyResponse.json(); - - expect(getManyResponseData.docs[0].findMany).toStrictEqual(true); - }); - - it('afterChange', async () => { - const createResponse = await fetch(`${url}/api/hooks`, { - body: JSON.stringify({ - title: 'title 4', - description: 'Original', - priority: 1, - }), - headers, - method: 'post', - }); - const createData = await createResponse.json(); - const { id } = createData.doc; - - const response = await fetch(`${url}/api/hooks/${id}`, { - body: JSON.stringify({ - description: 'afterChange', - }), - headers: { - ...headers, - hook: 'afterChange', // Used by hook - }, - method: 'put', - }); - - const data = await response.json(); - expect(response.status).toBe(200); - expect(data.doc.afterChangeHook).toStrictEqual(true); - }); - - it('afterDelete', async () => { - const createResponse = await fetch(`${url}/api/hooks`, { - body: JSON.stringify({ - title: 'title 5', - description: 'Original', - priority: 1, - }), - headers: { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }, - method: 'post', - }); - const createData = await createResponse.json(); - const { id } = createData.doc; - - const response = await fetch(`${url}/api/hooks/${id}`, { - headers: { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - hook: 'afterDelete', // Used by hook - }, - method: 'delete', - }); - - const data = await response.json(); - expect(response.status).toBe(200); - expect(data.afterDeleteHook).toStrictEqual(true); - }); - }); - }); -}); diff --git a/src/collections/tests/pointField.spec.ts b/src/collections/tests/pointField.spec.ts deleted file mode 100644 index 46310f4402..0000000000 --- a/src/collections/tests/pointField.spec.ts +++ /dev/null @@ -1,250 +0,0 @@ -import { GraphQLClient } from 'graphql-request'; -import getConfig from '../../config/load'; -import { email, password } from '../../mongoose/testCredentials'; - -require('isomorphic-fetch'); - -const { serverURL, routes } = getConfig(); - -let token = null; -let headers = null; - -describe('GeoJSON', () => { - beforeAll(async (done) => { - const response = await fetch(`${serverURL}/api/admins/login`, { - body: JSON.stringify({ - email, - password, - }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - const data = await response.json(); - - ({ token } = data); - headers = { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }; - - done(); - }); - - describe('Point Field - REST', () => { - let location = [10, 20]; - const localizedPoint = [30, 40]; - const group = { point: [15, 25] }; - let doc; - - beforeAll(async (done) => { - const create = await fetch(`${serverURL}/api/geolocation`, { - body: JSON.stringify({ location, localizedPoint, group }), - headers, - method: 'post', - }); - ({ doc } = await create.json()); - - done(); - }); - - it('should create and read collections with points', async () => { - expect(doc.id).toBeDefined(); - expect(doc.location).toStrictEqual(location); - expect(doc.localizedPoint).toStrictEqual(localizedPoint); - }); - - it('should query where near point', async () => { - const [lng, lat] = location; - const hitResponse = await fetch(`${serverURL}/api/geolocation?where[location][near]=${lng + 0.01},${lat + 0.01},10000`, { - headers, - method: 'get', - }); - const hitData = await hitResponse.json(); - const hitDocs = hitData.docs; - - const missResponse = await fetch(`${serverURL}/api/geolocation?where[location][near]=-${lng},-${lat},5000`, { - headers, - method: 'get', - }); - const missData = await missResponse.json(); - const missDocs = missData.docs; - - expect(hitDocs).toHaveLength(1); - expect(missDocs).toHaveLength(0); - }); - - it('should query where near localized point', async () => { - const [lng, lat] = localizedPoint; - const hitResponse = await fetch(`${serverURL}/api/geolocation?where[localizedPoint][near]=${lng + 0.01},${lat + 0.01},10000`, { - headers, - method: 'get', - }); - const hitData = await hitResponse.json(); - const hitDocs = hitData.docs; - - const missResponse = await fetch(`${serverURL}/api/geolocation?where[localizedPoint][near]=-${lng},-${lat},5000`, { - headers, - method: 'get', - }); - const missData = await missResponse.json(); - const missDocs = missData.docs; - - expect(hitDocs).toHaveLength(1); - expect(missDocs).toHaveLength(0); - }); - - it('should query near a nested point', async () => { - const [x, y] = group.point; - const hitResponse = await fetch(`${serverURL}/api/geolocation?where[group.point][near]=${x + 0.01},${y + 0.01},10000`, { - headers, - method: 'get', - }); - const hitData = await hitResponse.json(); - const hitDocs = hitData.docs; - - const missResponse = await fetch(`${serverURL}/api/geolocation?where[group.point][near]=-${x},-${y},5000`, { - headers, - method: 'get', - }); - const missData = await missResponse.json(); - const missDocs = missData.docs; - - expect(hitDocs).toHaveLength(1); - expect(missDocs).toHaveLength(0); - }); - - it('should save with non-required point', async () => { - location = undefined; - - const create = await fetch(`${serverURL}/api/geolocation`, { - body: JSON.stringify({ location }), - headers, - method: 'post', - }); - - const { doc } = await create.json(); - - expect(doc.id).toBeDefined(); - expect(doc.location).toStrictEqual(location); - }); - }); - - - describe('Point Field - GraphQL', () => { - const url = `${serverURL}${routes.api}${routes.graphQL}`; - let client = null; - const location = [50, 60]; - const localizedPoint = [70, 80]; - const group = { point: [50.5, 60.5] }; - let doc; - - beforeAll(async (done) => { - client = new GraphQLClient(url, { headers: { Authorization: `JWT ${token}` } }); - - // language=graphQL - const query = `mutation { - createGeolocation ( - data: { - location: [${location[0]}, ${location[1]}], - localizedPoint: [${localizedPoint[0]}, ${localizedPoint[1]}], - group: { - point: [${group.point[0]}, ${group.point[1]}] - } - } - ) { - id - location - localizedPoint - } - }`; - - const response = await client.request(query); - - const { id } = response.createGeolocation; - // language=graphQL - const readQuery = `query { - Geolocation(id: "${id}") { - id - location - localizedPoint - } - }`; - const readResponse = await client.request(readQuery); - doc = readResponse.Geolocation; - done(); - }); - - it('should create and read collections with points', async () => { - expect(doc.id).toBeDefined(); - expect(doc.location).toStrictEqual(location); - expect(doc.localizedPoint).toStrictEqual(localizedPoint); - }); - - it('should query where near point', async () => { - const [lng, lat] = location; - // language=graphQL - const hitQuery = `query getGeos { - Geolocations(where: { location: { near: [${lng + 0.01},${lat + 0.01},10000]}}) { - docs { - id - location - localizedPoint - } - } - }`; - const hitResponse = await client.request(hitQuery); - const hitDocs = hitResponse.Geolocations.docs; - - const missQuery = `query getGeos { - Geolocations(where: { location: { near: [${-lng},${-lat},10000]}}) { - docs { - id - location - localizedPoint - } - } - }`; - const missResponse = await client.request(missQuery); - const missDocs = missResponse.Geolocations.docs; - - expect(hitDocs).toHaveLength(1); - expect(missDocs).toHaveLength(0); - }); - - it('should query where near a point in a group', async () => { - const [x, y] = group.point; - // language=graphQL - const hitQuery = `query getGeos { - Geolocations(where: { group__point: { near: [${x + 0.01},${y + 0.01},10000]}}) { - docs { - id - group { - point - } - } - } - }`; - const hitResponse = await client.request(hitQuery); - const hitDocs = hitResponse.Geolocations.docs; - - const missQuery = `query getGeos { - Geolocations(where: { group__point: { near: [${-x},${-y},10000]}}) { - docs { - id - group { - point - } - } - } - }`; - const missResponse = await client.request(missQuery); - const missDocs = missResponse.Geolocations.docs; - - expect(hitDocs).toHaveLength(1); - expect(missDocs).toHaveLength(0); - }); - }); -}); diff --git a/src/collections/tests/relationships.spec.ts b/src/collections/tests/relationships.spec.ts deleted file mode 100644 index c5721d586d..0000000000 --- a/src/collections/tests/relationships.spec.ts +++ /dev/null @@ -1,227 +0,0 @@ -import getConfig from '../../config/load'; -import { email, password } from '../../mongoose/testCredentials'; -import { PaginatedDocs } from '../../mongoose/types'; - -require('isomorphic-fetch'); - -const { serverURL: url } = getConfig(); - -let token = null; -let headers = null; - -type RelationshipA = { - id: string - post?: string | RelationshipB -} -type RelationshipB = { - id: string - post?: (string | RelationshipA)[] -} - -describe('Collections - REST', () => { - beforeAll(async (done) => { - const response = await fetch(`${url}/api/admins/login`, { - body: JSON.stringify({ - email, - password, - }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - const data = await response.json(); - - ({ token } = data); - headers = { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }; - - done(); - }); - - describe('Relationships', () => { - let documentA; - let documentB; - let strictAccessDoc; - - beforeAll(async (done) => { - const strictAccessRes = await fetch(`${url}/api/strict-access`, { - body: JSON.stringify({ - address: '123 Test Lane', - city: 'Grand Rapids', - state: 'MI', - zip: 49504, - }), - headers, - method: 'post', - }); - - const strictAccessJSON = await strictAccessRes.json(); - strictAccessDoc = strictAccessJSON.doc; - - // create document a - const createA = await fetch(`${url}/api/relationship-a`, { - body: JSON.stringify({}), - headers, - method: 'post', - }); - const createAData = await createA.json(); - // create document b, related to a - const createB = await fetch(`${url}/api/relationship-b`, { - body: JSON.stringify({ - post: [createAData.doc.id], - strictAccess: strictAccessDoc.id, - }), - headers, - method: 'post', - }); - // update a to relate to b - const createBData = await createB.json(); - documentB = createBData.doc; - const updateA = await fetch(`${url}/api/relationship-a/${createAData.doc.id}`, { - body: JSON.stringify({ - post: documentB.id, - postMaxDepth: documentB.id, - }), - headers, - method: 'put', - }); - const updateAData = await updateA.json(); - documentA = updateAData.doc; - done(); - }); - - it('should create and read collections with relationships', async () => { - expect(documentA.post).toBeDefined(); - expect(documentB.post).toHaveLength(1); - }); - - it('should prevent an unauthorized population of strict access', async () => { - const response = await fetch(`${url}/api/relationship-b/${documentB.id}`); - const data = await response.json(); - - expect(typeof data.strictAccess).not.toBe('object'); - }); - - it('should populate strict access when authorized', async () => { - const response = await fetch(`${url}/api/relationship-b/${documentB.id}`, { - headers, - }); - - const data = await response.json(); - expect(typeof data.strictAccess).toBe('object'); - }); - - it('should use depth to limit the number of relationships returned', async () => { - const response = await fetch(`${url}/api/relationship-a?depth=3`, { - headers, - method: 'get', - }); - const data: PaginatedDocs = await response.json(); - const [depth0] = data.docs; - expect(depth0.id).toBe(documentA.id); - const depth1 = depth0.post as RelationshipB; - expect(depth1.id).toBe(documentB.id); - const [depth2] = depth1.post as RelationshipA[]; - expect(depth2.id).toBe(documentA.id); - const depth3 = depth2.post as RelationshipB; - expect(depth3.id).toBe(documentB.id); - const [depth4] = depth3.post as RelationshipA[]; - expect(depth4).not.toHaveProperty('post'); - expect(depth4).toBe(documentA.id); - }); - - it('should respect max depth at the field level', async () => { - const response = await fetch(`${url}/api/relationship-a?depth=1`, { - headers, - method: 'get', - }); - const data = await response.json(); - const [doc] = data.docs; - // asserts postMaxDepth is not populated - expect(doc.postMaxDepth).toBe(documentB.id); - expect(doc.postMaxDepth).not.toHaveProperty('post'); - }); - - it('should allow a custom id relation', async () => { - const customID = { - id: 30, - name: 'custom', - }; - - const newCustomID = await fetch(`${url}/api/custom-id`, { - headers, - body: JSON.stringify(customID), - method: 'post', - }); - - const custom = await newCustomID.json(); - const response = await fetch(`${url}/api/relationship-a/${documentA.id}`, { - headers, - body: JSON.stringify({ - ...documentA, - post: documentB.id, - customID: [custom.doc.id], - }), - method: 'put', - }); - const { doc } = await response.json(); - expect(doc.customID[0].id).toBe(customID.id); - }); - - it('should allow a custom id relation and parse the id type', async () => { - const customID = { - id: '40', - name: 'custom', - }; - - const newCustomID = await fetch(`${url}/api/custom-id`, { - headers, - body: JSON.stringify(customID), - method: 'post', - }); - - const custom = await newCustomID.json(); - const response = await fetch(`${url}/api/relationship-a/${documentA.id}`, { - headers, - body: JSON.stringify({ - ...documentA, - post: documentB.id, - customID: [custom.doc.id], - }), - method: 'put', - }); - const { doc } = await response.json(); - - expect(custom.doc.id).toBe(parseFloat(customID.id)); - expect(doc.customID[0].id).toBe(parseFloat(customID.id)); - }); - - it('should use filterOptions to limit relationship options', async () => { - // update documentB to disable relations - await fetch(`${url}/api/relationship-b/${documentB.id}`, { - headers, - body: JSON.stringify({ - disableRelation: true, - }), - method: 'put', - }); - - // attempt to save relationship to documentB - const response = await fetch(`${url}/api/relationship-a/${documentA.id}`, { - headers, - body: JSON.stringify({ - filterRelationship: documentB.id, - }), - method: 'put', - }); - - const result = await response.json(); - - expect(result.errors).toBeDefined(); - }); - }); -}); diff --git a/src/collections/tests/validations.spec.js b/src/collections/tests/validations.spec.js deleted file mode 100644 index 1367e75d0c..0000000000 --- a/src/collections/tests/validations.spec.js +++ /dev/null @@ -1,81 +0,0 @@ -import getConfig from '../../config/load'; -import { email, password } from '../../mongoose/testCredentials'; - -require('isomorphic-fetch'); - -const { serverURL: url } = getConfig(); - -let token = null; -let headers = null; - -describe('Validations - REST', () => { - beforeAll(async (done) => { - const response = await fetch(`${url}/api/admins/login`, { - body: JSON.stringify({ - email, - password, - }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - const data = await response.json(); - - ({ token } = data); - headers = { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }; - - done(); - }); - - describe('Validations', () => { - let validation; - - beforeAll(async (done) => { - const result = await fetch(`${url}/api/validations`, { - body: JSON.stringify({ - validationOptions: 'ok', - text: 'test', - lessThan10: 9, - greaterThan10LessThan50: 20, - atLeast3Rows: [ - { greaterThan30: 40 }, - { greaterThan30: 50 }, - { greaterThan30: 60 }, - ], - array: [ - { lessThan20: 10 }, - ], - }), - headers, - method: 'post', - }); - - const data = await result.json(); - validation = data.doc; - done(); - }); - - it('should create with custom validation', async () => { - expect(validation.id).toBeDefined(); - }); - it('should update with custom validation', async () => { - const result = await fetch(`${url}/api/validations/${validation.id}`, { - body: JSON.stringify({ - validationOptions: 'update', - }), - headers, - method: 'put', - }); - - const data = await result.json(); - validation = data.doc; - - expect(validation.validationOptions).toStrictEqual('update'); - }); - }); -}); diff --git a/src/express/middleware/errorHandler.spec.ts b/src/express/middleware/errorHandler.spec.ts deleted file mode 100644 index e561abc5c9..0000000000 --- a/src/express/middleware/errorHandler.spec.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Response } from 'express'; -import Logger from '../../utilities/logger'; -import errorHandler from './errorHandler'; -import { APIError } from '../../errors'; -import { PayloadRequest } from '../types'; -import { SanitizedConfig } from '../../config/types'; - -const logger = Logger('payload'); - -const testError = new APIError('test error', 503); - -describe('errorHandler', () => { - const res = generateResponse(); - const next = jest.fn(); - const req = generateRequest() as PayloadRequest; - - it('should send the response with the error', async () => { - const handler = errorHandler(generateConfig({ debug: true }), logger); - await handler(testError, req, res, next); - expect(res.send).toHaveBeenCalledWith( - expect.objectContaining({ errors: [{ message: 'test error' }] }), - ); - }); - - it('should include stack trace when config debug is on', async () => { - const handler = errorHandler(generateConfig({ debug: true }), logger); - await handler(testError, req, res, next); - expect(res.send).toHaveBeenCalledWith(expect.objectContaining({ stack: expect.any(String) })); - }); - - it('should not include stack trace when config debug is not set', async () => { - const handler = errorHandler(generateConfig({ debug: undefined }), logger); - await handler(testError, req, res, next); - expect(res.send).toHaveBeenCalledWith( - expect.not.objectContaining({ stack: expect.any(String) }), - ); - }); - - it('should not include stack trace when config debug is false', async () => { - const handler = errorHandler(generateConfig({ debug: false }), logger); - await handler(testError, req, res, next); - expect(res.send).toHaveBeenCalledWith( - expect.not.objectContaining({ stack: expect.any(String) }), - ); - }); - - it('should show the status code when given an error with a code', async () => { - const handler = errorHandler(generateConfig(), logger); - await handler(testError, req, res, next); - expect(res.status).toHaveBeenCalledWith(503); - }); - - it('should default to 500 when an error does not have a status code', async () => { - const handler = errorHandler(generateConfig(), logger); - testError.status = undefined; - await handler(testError, req, res, next); - expect(res.status).toHaveBeenCalledWith(500); - }); - - it('should call payload config afterError hook', async () => { - const afterError = jest.fn(); - const handler = errorHandler( - generateConfig({ - hooks: { afterError }, - }), - logger, - ); - await handler(testError, req, res, next); - expect(afterError) - // eslint-disable-next-line jest/prefer-called-with - .toHaveBeenCalled(); - }); - - it('should call collection config afterError hook', async () => { - const handler = errorHandler(generateConfig(), logger); - await handler(testError, req, res, next); - expect(req.collection.config.hooks.afterError) - // eslint-disable-next-line jest/prefer-called-with - .toHaveBeenCalled(); - }); -}); - -function generateResponse() { - const res = { - status: jest.fn(), - send: jest.fn(), - }; - - jest.spyOn(res, 'status').mockImplementation().mockReturnValue(res); - jest.spyOn(res, 'send').mockImplementation().mockReturnValue(res); - return res as unknown as Response; -} - -function generateRequest(): PayloadRequest { - return { - collection: { - config: { - hooks: { - afterError: jest.fn(), - }, - }, - }, - } as unknown as PayloadRequest; -} - -function generateConfig(overrides?: Partial): SanitizedConfig { - return { - debug: false, - hooks: { afterError: jest.fn() }, - ...overrides, - } as unknown as SanitizedConfig; -} diff --git a/src/globals/requestHandlers/globals.spec.ts b/src/globals/requestHandlers/globals.spec.ts deleted file mode 100644 index fbd642bfc4..0000000000 --- a/src/globals/requestHandlers/globals.spec.ts +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @jest-environment node - */ - -import getConfig from '../../config/load'; -import { email, password } from '../../mongoose/testCredentials'; - -require('isomorphic-fetch'); - -const { serverURL: url } = getConfig(); - -let token = null; - -const navData = { - en: { - nav1: { - text: 'Navigation 1', - textarea: 'Some navigation text', - }, - nav2: { - text: 'Navigation 2', - textarea: 'Some more navigation text', - }, - }, - es: { - nav1: { - text: 'Navegación 1', - textarea: 'algún texto de navegación', - }, - nav2: { - text: 'Navegación 2', - textarea: 'un poco más de texto de navegación', - }, - }, -}; - -describe('Globals - REST', () => { - beforeAll(async (done) => { - const response = await fetch(`${url}/api/admins/login`, { - body: JSON.stringify({ - email, - password, - }), - headers: { - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - const data = await response.json(); - - ({ token } = data); - - done(); - }); - - describe('Create', () => { - it('should create one', async () => { - const response = await fetch(`${url}/api/globals/navigation-array`, { - - body: JSON.stringify({ - array: [ - { - text: navData.en.nav1.text, - textarea: navData.en.nav1.textarea, - }, - ], - }), - headers: { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - expect(response.status).toBe(200); - const data = await response.json(); - const { text, textarea } = data.result.array[0]; - expect(text).toStrictEqual(navData.en.nav1.text); - expect(textarea).toStrictEqual(navData.en.nav1.textarea); - }); - }); - - describe('Update', () => { - it('should update one', async () => { - const response = await fetch(`${url}/api/globals/navigation-array`, { - - body: JSON.stringify({ - array: [ - { - text: navData.en.nav1.text, - textarea: navData.en.nav1.textarea, - }, - { - text: navData.en.nav2.text, - textarea: navData.en.nav2.textarea, - }, - ], - }), - headers: { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - expect(response.status).toBe(200); - const data = await response.json(); - expect(data.result.array).toHaveLength(2); - const { text, textarea } = data.result.array[1]; - expect(text).toStrictEqual(navData.en.nav2.text); - expect(textarea).toStrictEqual(navData.en.nav2.textarea); - }); - - it('should allow Spanish update', async () => { - const response = await fetch(`${url}/api/globals/navigation-array?locale=es`, { - - body: JSON.stringify({ - array: [ - { - text: navData.es.nav1.text, - textarea: navData.es.nav1.textarea, - }, - { - text: navData.es.nav2.text, - textarea: navData.es.nav2.textarea, - }, - ], - }), - headers: { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }, - method: 'post', - }); - - expect(response.status).toBe(200); - const data = await response.json(); - expect(data.result.array).toHaveLength(2); - const { text, textarea } = data.result.array[0]; - expect(text).toStrictEqual(navData.es.nav1.text); - expect(textarea).toStrictEqual(navData.es.nav1.textarea); - }); - }); - - describe('Read', () => { - it('should read one', async () => { - const response = await fetch(`${url}/api/globals/navigation-array`, { - headers: { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }, - }); - - expect(response.status).toBe(200); - const data = await response.json(); - const { text, textarea } = data.array[0]; - expect(text).toStrictEqual(navData.en.nav1.text); - expect(textarea).toStrictEqual(navData.en.nav1.textarea); - }); - - it('should read Spanish', async () => { - const response = await fetch(`${url}/api/globals/navigation-array?locale=es`, { - headers: { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }, - }); - - expect(response.status).toBe(200); - const data = await response.json(); - const { text, textarea } = data.array[0]; - expect(text).toStrictEqual(navData.es.nav1.text); - expect(textarea).toStrictEqual(navData.es.nav1.textarea); - }); - }); - - describe('Endpoints', () => { - it('should respond with number of navigation items', async () => { - const response = await fetch(`${url}/api/globals/navigation-array/count`, { - headers: { - Authorization: `JWT ${token}`, - 'Content-Type': 'application/json', - }, - }); - - expect(response.status).toBe(200); - const data = await response.json(); - expect(data.count).toStrictEqual(2); - }); - }); -}); diff --git a/src/preferences/graphql/resolvers.spec.ts b/src/preferences/graphql/resolvers.spec.ts deleted file mode 100644 index 65ef70ef4a..0000000000 --- a/src/preferences/graphql/resolvers.spec.ts +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @jest-environment node - */ -import { request, GraphQLClient } from 'graphql-request'; -import getConfig from '../../config/load'; -import { email, password } from '../../mongoose/testCredentials'; - -require('isomorphic-fetch'); - -const config = getConfig(); - -const url = `${config.serverURL}${config.routes.api}${config.routes.graphQL}`; - -let client = null; -let token = null; - -describe('GrahpQL Preferences', () => { - beforeAll(async (done) => { - const query = ` - mutation { - loginAdmin( - email: "${email}", - password: "${password}" - ) { - token - } - }`; - - const response = await request(url, query); - - token = response.loginAdmin.token; - - client = new GraphQLClient(url, { headers: { Authorization: `JWT ${token}` } }); - - done(); - }); - - describe('Update', () => { - it('should allow a preference to be saved', async () => { - const key = 'preference-key'; - const value = 'preference-value'; - - // language=graphQL - const query = `mutation { - updatePreference(key: "${key}", value: "${value}") { - key - value - } - }`; - - const response = await client.request(query); - - const data = response.updatePreference; - - expect(data.key).toBe(key); - expect(data.value).toBe(value); - }); - }); - - describe('Read', () => { - it('should be able to read user preference', async () => { - const key = 'preference-key'; - const value = 'preference-value'; - - // language=graphQL - const query = `mutation { - updatePreference(key: "${key}", value: "${value}") { - key - value - } - }`; - - const response = await client.request(query); - - const { key: responseKey, value: responseValue } = response.updatePreference; - // language=graphQL - const readQuery = `query { - Preference(key: "${responseKey}") { - key - value - } - }`; - const readResponse = await client.request(readQuery); - - expect(responseKey).toStrictEqual(key); - expect(readResponse.Preference.key).toStrictEqual(key); - expect(responseValue).toStrictEqual(value); - expect(readResponse.Preference.value).toStrictEqual(value); - }); - }); - - describe('Delete', () => { - it('should be able to delete a preference', async () => { - const key = 'gql-delete'; - const value = 'description'; - - // language=graphQL - const query = `mutation { - updatePreference(key: "${key}" value: "${value}") { - key - value - } - }`; - - const response = await client.request(query); - - const { key: responseKey } = response.updatePreference; - // language=graphQL - const deleteMutation = `mutation { - deletePreference(key: "${key}") { - key - value - } - }`; - const deleteResponse = await client.request(deleteMutation); - const deleteKey = deleteResponse.deletePreference.key; - - expect(responseKey).toStrictEqual(key); - expect(deleteKey).toStrictEqual(key); - }); - }); - - it('should return null when query key is not found', async () => { - const key = 'bad-key'; - const readQuery = `query { - Preference(key: "${key}") { - key - value - } - }`; - const response = await client.request(readQuery); - - expect(response.Preference).toBeNull(); - }); -}); diff --git a/test/access-control/int.todo-spec.ts b/test/access-control/int.todo-spec.ts new file mode 100644 index 0000000000..4dbe5a3268 --- /dev/null +++ b/test/access-control/int.todo-spec.ts @@ -0,0 +1,3 @@ +describe('array stuff', () => { + it.todo('should properly prevent / allow public users from reading a restricted field'); +}); diff --git a/test/collections-rest/int.spec.ts b/test/collections-rest/int.spec.ts index 613a47bc3c..f1272ec26e 100644 --- a/test/collections-rest/int.spec.ts +++ b/test/collections-rest/int.spec.ts @@ -87,6 +87,7 @@ describe('collections-rest', () => { }); describe('Querying', () => { + it.todo('should allow querying by a field within a group'); describe('Relationships', () => { let post: Post; let relation: Relation; diff --git a/test/helpers/rest.ts b/test/helpers/rest.ts index e54c89a63a..1657cddb68 100644 --- a/test/helpers/rest.ts +++ b/test/helpers/rest.ts @@ -29,6 +29,21 @@ type FindArgs = { slug?: string; query?: Where; auth?: boolean; + depth?: number + page?: number + limit?: number +}; + +type FindByIDArgs = { + id: string; + slug?: string; + query?: Where; + auth?: boolean; + options?: { + depth?: number + page?: number + limit?: number + }, }; type UpdateArgs = { @@ -133,14 +148,10 @@ export class RESTClient { const options = { headers: { ...headers, - Authorization: '', + Authorization: args?.auth !== false && this.token ? `JWT ${this.token}` : '', }, }; - if (args?.auth) { - options.headers.Authorization = `JWT ${this.token}`; - } - const slug = args?.slug || this.defaultSlug; const whereQuery = qs.stringify(args?.query ? { where: args.query } : {}, { addQueryPrefix: true, @@ -169,9 +180,18 @@ export class RESTClient { return { status, doc: json.doc }; } - async findByID(id: string, args?: { slug?: string }): Promise> { - const response = await fetch(`${this.serverURL}/api/${args?.slug || this.defaultSlug}/${id}`, { - headers, + async findByID(args: FindByIDArgs): Promise> { + const options = { + headers: { + ...headers, + Authorization: args?.auth !== false && this.token ? `JWT ${this.token}` : '', + }, + }; + + const formattedOpts = qs.stringify(args?.options || {}, { addQueryPrefix: true }); + const fetchURL = `${this.serverURL}/api/${args?.slug || this.defaultSlug}/${args.id}${formattedOpts}`; + const response = await fetch(fetchURL, { + headers: options.headers, method: 'get', }); const { status } = response;