chore: more passing int suites

This commit is contained in:
Jarrod Flesch
2024-02-16 15:09:51 -05:00
parent 504892ddb9
commit 28c4046300
9 changed files with 215 additions and 113 deletions

View File

@@ -7,6 +7,7 @@ import { APIError, Forbidden } from 'payload/errors'
import { RouteError } from '../../../RouteError'
import { createPayloadRequest } from '../../../../../utilities/createPayloadRequest'
import httpStatus from 'http-status'
import { endpointsAreDisabled } from '../../../checkEndpoints'
async function checkFileAccess({
req,
@@ -18,6 +19,9 @@ async function checkFileAccess({
collection: Collection
}) {
const { config } = collection
const disableEndpoints = endpointsAreDisabled({ request: req, endpoints: config.endpoints })
if (disableEndpoints) return disableEndpoints
const accessResult = await executeAccess({ isReadingStaticFile: true, req }, config.access.read)
if (typeof accessResult === 'object') {

View File

@@ -0,0 +1,21 @@
import httpStatus from 'http-status'
import { CollectionConfig, GlobalConfig } from 'payload/types'
export const endpointsAreDisabled = ({
request,
endpoints,
}: {
request: Partial<Request>
endpoints: unknown[] | false
}) => {
if (!endpoints) {
return Response.json(
{
message: `Cannot ${request.method.toUpperCase()} ${request.url}`,
},
{
status: httpStatus.NOT_IMPLEMENTED,
},
)
}
}

View File

@@ -11,6 +11,9 @@ import {
GlobalRouteHandlerWithID,
} from './types'
import { RouteError } from './RouteError'
import { endpointsAreDisabled } from './checkEndpoints'
import { me } from './auth/me'
import { init } from './auth/init'
import { login } from './auth/login'
@@ -41,7 +44,6 @@ import { docAccess as docAccessGlobal } from './globals/docAccess'
import { findVersions as findVersionsGlobal } from './globals/findVersions'
import { restoreVersion as restoreVersionGlobal } from './globals/restoreVersion'
import { findVersionByID as findVersionByIdGlobal } from './globals/findVersionByID'
import { RouteError } from './RouteError'
const endpoints = {
root: {
@@ -161,13 +163,25 @@ export const GET =
},
})
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: req.payload.config.endpoints,
})
if (disableEndpoints) return disableEndpoints
collection = req.payload.collections?.[slug1]
if (collection) {
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: collection.config.endpoints,
})
if (disableEndpoints) return disableEndpoints
const customEndpointResponse = await handleCustomEndpoints({
entitySlug: slug1,
payloadRequest: req,
endpoints: collection.config?.endpoints || [],
endpoints: collection.config.endpoints,
})
if (customEndpointResponse) return customEndpointResponse
@@ -202,10 +216,17 @@ export const GET =
}
} else if (slug1 === 'globals') {
const globalConfig = req.payload.config.globals.find((global) => global.slug === slug2)
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: globalConfig.endpoints,
})
if (disableEndpoints) return disableEndpoints
const customEndpointResponse = await handleCustomEndpoints({
entitySlug: `${slug1}/${slug2}`,
payloadRequest: req,
endpoints: globalConfig?.endpoints || [],
endpoints: globalConfig.endpoints,
})
if (customEndpointResponse) return customEndpointResponse
@@ -276,11 +297,23 @@ export const POST =
})
collection = req.payload.collections?.[slug1]
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: req.payload.config.endpoints,
})
if (disableEndpoints) return disableEndpoints
if (collection) {
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: collection.config.endpoints,
})
if (disableEndpoints) return disableEndpoints
const customEndpointResponse = await handleCustomEndpoints({
entitySlug: slug1,
payloadRequest: req,
endpoints: collection.config?.endpoints || [],
endpoints: collection.config.endpoints,
})
if (customEndpointResponse) return customEndpointResponse
@@ -318,6 +351,18 @@ export const POST =
}
} else if (slug1 === 'globals' && slug2) {
const globalConfig = req.payload.config.globals.find((global) => global.slug === slug2)
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: globalConfig.endpoints,
})
if (disableEndpoints) return disableEndpoints
const customEndpointResponse = await handleCustomEndpoints({
entitySlug: `${slug1}/${slug2}`,
payloadRequest: req,
endpoints: globalConfig.endpoints,
})
if (customEndpointResponse) return customEndpointResponse
switch (slug.length) {
case 2:
@@ -387,11 +432,23 @@ export const DELETE =
})
collection = req.payload.collections?.[slug1]
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: req.payload.config.endpoints,
})
if (disableEndpoints) return disableEndpoints
if (collection) {
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: collection.config.endpoints,
})
if (disableEndpoints) return disableEndpoints
const customEndpointResponse = await handleCustomEndpoints({
entitySlug: slug1,
payloadRequest: req,
endpoints: collection.config?.endpoints || [],
endpoints: collection.config.endpoints,
})
if (customEndpointResponse) return customEndpointResponse
@@ -444,11 +501,23 @@ export const PATCH =
})
collection = req.payload.collections?.[slug1]
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: req.payload.config.endpoints,
})
if (disableEndpoints) return disableEndpoints
if (collection) {
const disableEndpoints = endpointsAreDisabled({
request,
endpoints: collection.config.endpoints,
})
if (disableEndpoints) return disableEndpoints
const customEndpointResponse = await handleCustomEndpoints({
entitySlug: slug1,
payloadRequest: req,
endpoints: collection.config?.endpoints || [],
endpoints: collection.config.endpoints,
})
if (customEndpointResponse) return customEndpointResponse

View File

@@ -25,6 +25,7 @@ const databaseAdapters = {
export function buildConfigWithDefaults(testConfig?: Partial<Config>): Promise<SanitizedConfig> {
const config: Config = {
secret: 'TEST_SECRET',
// editor: slateEditor({}),
editor: undefined,
rateLimit: {
max: 9999999999,

View File

@@ -1,11 +1,15 @@
import payload from '../../packages/payload/src'
import { initPayloadTest } from '../helpers/configHelpers'
import type { Payload } from '../../packages/payload/src'
require('isomorphic-fetch')
import { getPayload } from '../../packages/payload/src'
import { startMemoryDB } from '../startMemoryDB'
import configPromise from './config'
let payload: Payload
describe('Config', () => {
beforeAll(async () => {
await initPayloadTest({ __dirname, init: { local: true } })
const config = await startMemoryDB(configPromise)
payload = await getPayload({ config })
})
describe('payload config', () => {

View File

@@ -1,16 +1,15 @@
import { GraphQLClient } from 'graphql-request'
import { initPayloadTest } from '../helpers/configHelpers'
import { getPayload } from '../../packages/payload/src'
import { NextRESTClient } from '../helpers/NextRESTClient'
import { startMemoryDB } from '../startMemoryDB'
import configPromise from './config'
let client: GraphQLClient
let restClient: NextRESTClient
describe('Custom 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)
const payload = await getPayload({ config })
restClient = new NextRESTClient(payload.config)
})
describe('Isolated Transaction ID', () => {
@@ -19,11 +18,15 @@ describe('Custom GraphQL', () => {
TransactionID1
TransactionID2
}`
const response = await client.request(query)
const { data } = await restClient
.GRAPHQL_POST({
body: JSON.stringify({ query }),
})
.then((res) => res.json())
// either no transactions at all or they are different
expect(
(response.TransactionID2 === null && response.TransactionID1 === null) ||
response.TransactionID2 !== response.TransactionID1,
(data.TransactionID2 === null && data.TransactionID1 === null) ||
data.TransactionID2 !== data.TransactionID1,
).toBe(true)
})
it('should isolate transaction IDs between mutations in the same request', async () => {
@@ -31,11 +34,15 @@ describe('Custom GraphQL', () => {
MutateTransactionID1
MutateTransactionID2
}`
const response = await client.request(query)
const { data } = await restClient
.GRAPHQL_POST({
body: JSON.stringify({ query }),
})
.then((res) => res.json())
// either no transactions at all or they are different
expect(
(response.MutateTransactionID2 === null && response.MutateTransactionID1 === null) ||
response.MutateTransactionID2 !== response.MutateTransactionID1,
(data.MutateTransactionID2 === null && data.MutateTransactionID1 === null) ||
data.MutateTransactionID2 !== data.MutateTransactionID1,
).toBe(true)
})
})

View File

@@ -1,28 +1,25 @@
import { GraphQLClient } from 'graphql-request'
import type { Payload } from '../../packages/payload/src'
import type { TypeWithID } from '../../packages/payload/src/collections/config/types'
import type { PayloadRequest } from '../../packages/payload/src/types'
import payload from '../../packages/payload/src'
import { getPayload } from '../../packages/payload/src'
import { commitTransaction } from '../../packages/payload/src/utilities/commitTransaction'
import { initTransaction } from '../../packages/payload/src/utilities/initTransaction'
import { devUser } from '../credentials'
import { initPayloadTest } from '../helpers/configHelpers'
import { startMemoryDB } from '../startMemoryDB'
import configPromise from './config'
let payload: Payload
let user: TypeWithID & Record<string, unknown>
let useTransactions = true
const collection = 'posts'
const title = 'title'
describe('database', () => {
let serverURL
let client: GraphQLClient
let token: string
const collection = 'posts'
const title = 'title'
let user: TypeWithID & Record<string, unknown>
let useTransactions = true
beforeAll(async () => {
const init = await initPayloadTest({ __dirname, init: { local: false } })
serverURL = init.serverURL
const url = `${serverURL}/api/graphql`
client = new GraphQLClient(url)
const config = await startMemoryDB(configPromise)
payload = await getPayload({ config })
if (payload.db.name === 'mongoose') {
useTransactions = false
}
@@ -35,7 +32,6 @@ describe('database', () => {
},
})
if (loginResult.token) token = loginResult.token
user = loginResult.user
})

View File

@@ -1,24 +1,21 @@
import { GraphQLClient } from 'graphql-request'
import type { Payload } from '../../packages/payload/src'
import payload from '../../packages/payload/src'
import { getPayload } from '../../packages/payload/src'
import { devUser } from '../credentials'
import { initPayloadTest } from '../helpers/configHelpers'
import { NextRESTClient } from '../helpers/NextRESTClient'
import { startMemoryDB } from '../startMemoryDB'
import configPromise from './config'
import { postDoc } from './config'
let restClient: NextRESTClient
let payload: Payload
let token: string
describe('dataloader', () => {
let serverURL
beforeAll(async () => {
const init = await initPayloadTest({ __dirname, init: { local: false } })
serverURL = init.serverURL
})
describe('graphql', () => {
let client: GraphQLClient
let token: string
beforeAll(async () => {
const url = `${serverURL}/api/graphql`
client = new GraphQLClient(url)
const config = await startMemoryDB(configPromise)
payload = await getPayload({ config })
restClient = new NextRESTClient(payload.config)
const loginResult = await payload.login({
collection: 'users',
@@ -31,6 +28,7 @@ describe('dataloader', () => {
if (loginResult.token) token = loginResult.token
})
describe('graphql', () => {
it('should allow querying via graphql', async () => {
const query = `query {
Posts {
@@ -43,11 +41,16 @@ describe('dataloader', () => {
}
}`
const response = await client.request(query, null, {
const { data } = await restClient
.GRAPHQL_POST({
body: JSON.stringify({ query }),
headers: {
Authorization: `JWT ${token}`,
},
})
.then((res) => res.json())
const { docs } = response.Posts
const { docs } = data.Posts
expect(docs[0].title).toStrictEqual(postDoc.title)
})

View File

@@ -1,5 +1,7 @@
import { initPayloadTest } from '../helpers/configHelpers'
import { RESTClient } from '../helpers/rest'
import { getPayload } from '../../packages/payload/src'
import { NextRESTClient } from '../helpers/NextRESTClient'
import { startMemoryDB } from '../startMemoryDB'
import configPromise from './config'
import {
applicationEndpoint,
collectionSlug,
@@ -10,90 +12,82 @@ import {
rootEndpoint,
} from './shared'
require('isomorphic-fetch')
let client: RESTClient
let restClient: NextRESTClient
describe('Endpoints', () => {
beforeAll(async () => {
const config = await initPayloadTest({ __dirname, init: { local: false } })
const { serverURL } = config
client = new RESTClient(config, { serverURL, defaultSlug: collectionSlug })
const config = await startMemoryDB(configPromise)
await getPayload({ config })
restClient = new NextRESTClient(config)
})
describe('Collections', () => {
it('should GET a static endpoint', async () => {
const { status, data } = await client.endpoint(`/api/${collectionSlug}/say-hello/joe-bloggs`)
expect(status).toBe(200)
const response = await restClient.GET(`/${collectionSlug}/say-hello/joe-bloggs`)
const data = await response.json()
expect(response.status).toBe(200)
expect(data.message).toStrictEqual('Hey Joey!')
})
it('should GET an endpoint with a parameter', async () => {
const name = 'George'
const { status, data } = await client.endpoint(`/api/${collectionSlug}/say-hello/${name}`)
expect(status).toBe(200)
const response = await restClient.GET(`/${collectionSlug}/say-hello/${name}`)
const data = await response.json()
expect(response.status).toBe(200)
expect(data.message).toStrictEqual(`Hello ${name}!`)
})
it('should POST an endpoint with data', async () => {
const params = { name: 'George', age: 29 }
const { status, data } = await client.endpoint(
`/api/${collectionSlug}/whoami`,
'post',
params,
)
expect(status).toBe(200)
const response = await restClient.POST(`/${collectionSlug}/whoami`, {
body: JSON.stringify(params),
})
const data = await response.json()
expect(response.status).toBe(200)
expect(data.name).toStrictEqual(params.name)
expect(data.age).toStrictEqual(params.age)
})
it('should disable built-in endpoints when false', async () => {
let result
try {
result = await client.endpoint(`/api/${noEndpointsCollectionSlug}`, 'get')
} catch (err: unknown) {
result = err
}
expect(result instanceof Error).toBe(true)
const response = await restClient.GET(`/${noEndpointsCollectionSlug}`)
expect(response.status).toBe(501)
})
})
describe('Globals', () => {
it('should call custom endpoint', async () => {
const params = { globals: 'response' }
const { status, data } = await client.endpoint(
`/api/globals/${globalSlug}/${globalEndpoint}`,
'post',
params,
)
const response = await restClient.POST(`/globals/${globalSlug}/${globalEndpoint}`, {
body: JSON.stringify(params),
})
const data = await response.json()
expect(status).toBe(200)
expect(response.status).toBe(200)
expect(params).toMatchObject(data)
})
it('should disable built-in endpoints when false', async () => {
let result
try {
result = await client.endpoint(`/api/globals/${noEndpointsGlobalSlug}`, 'get')
} catch (err: unknown) {
result = err
}
expect(result instanceof Error).toBe(true)
const response = await restClient.GET(`/globals/${noEndpointsGlobalSlug}`)
expect(response.status).toBe(501)
})
})
describe('API', () => {
it('should call custom endpoint', async () => {
const params = { app: 'response' }
const { status, data } = await client.endpoint(`/api/${applicationEndpoint}`, 'post', params)
const response = await restClient.POST(`/${applicationEndpoint}`, {
body: JSON.stringify(params),
})
const data = await response.json()
expect(status).toBe(200)
expect(response.status).toBe(200)
expect(params).toMatchObject(data)
})
it('should have i18n on req', async () => {
const { status, data } = await client.endpoint(`/api/${applicationEndpoint}/i18n`, 'get')
const response = await restClient.GET(`/${applicationEndpoint}/i18n`)
const data = await response.json()
expect(status).toBe(200)
expect(response.status).toBe(200)
expect(data.message).toStrictEqual('Back to Dashboard')
})
})
@@ -101,9 +95,12 @@ describe('Endpoints', () => {
describe('Root', () => {
it('should call custom root endpoint', async () => {
const params = { root: 'response' }
const { status, data } = await client.endpoint(`/${rootEndpoint}`, 'post', params)
const response = await restClient.POST(`/${rootEndpoint}`, {
body: JSON.stringify(params),
})
const data = await response.json()
expect(status).toBe(200)
expect(response.status).toBe(200)
expect(params).toMatchObject(data)
})
})