chore: more passing int suites
This commit is contained in:
@@ -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') {
|
||||
|
||||
21
packages/next/src/routes/rest/checkEndpoints.ts
Normal file
21
packages/next/src/routes/rest/checkEndpoints.ts
Normal 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,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user