chore: adds schema path to useFieldPath provider, more passing tests
This commit is contained in:
@@ -42,7 +42,7 @@ const nextConfig = {
|
||||
alias: {
|
||||
...config.resolve.alias,
|
||||
'@payloadcms/ui/scss': path.resolve(__dirname, './packages/ui/src/scss/styles.scss'),
|
||||
'payload-config': process.env.PAYLOAD_CONFIG_PATH,
|
||||
// 'payload-config': process.env.PAYLOAD_CONFIG_PATH,
|
||||
},
|
||||
fallback: {
|
||||
...config.resolve.fallback,
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
"get-port": "5.1.1",
|
||||
"get-stream": "6.0.1",
|
||||
"glob": "8.1.0",
|
||||
"graphql-request": "6.1.0",
|
||||
"husky": "^8.0.3",
|
||||
"isomorphic-fetch": "3.0.0",
|
||||
"jest": "29.7.0",
|
||||
@@ -123,7 +122,8 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@sentry/react": "^7.77.0"
|
||||
"@sentry/react": "^7.77.0",
|
||||
"passport-strategy": "1.0.0"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
|
||||
@@ -5,8 +5,27 @@ import type { PopulationsByCollection, UpdatedDocument } from './types'
|
||||
|
||||
import { traverseFields } from './traverseFields'
|
||||
|
||||
const defaultRequestHandler = ({ apiPath, endpoint, serverURL }) => {
|
||||
const url = `${serverURL}${apiPath}/${endpoint}`
|
||||
return fetch(url, {
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const mergeData = async <T>(args: {
|
||||
apiRoute?: string
|
||||
collectionPopulationRequestHandler?: ({
|
||||
apiPath,
|
||||
endpoint,
|
||||
serverURL,
|
||||
}: {
|
||||
apiPath: string
|
||||
endpoint: string
|
||||
serverURL: string
|
||||
}) => Promise<Response>
|
||||
depth?: number
|
||||
externallyUpdatedRelationship?: UpdatedDocument
|
||||
fieldSchema: ReturnType<typeof fieldSchemaToJSON>
|
||||
@@ -44,19 +63,16 @@ export const mergeData = async <T>(args: {
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(populationsByCollection).map(async ([collection, populations]) => {
|
||||
const ids = new Set(populations.map(({ id }) => id))
|
||||
const url = `${serverURL}${
|
||||
apiRoute || '/api'
|
||||
}/${collection}?depth=${depth}&where[id][in]=${Array.from(ids).join(',')}`
|
||||
|
||||
let res: PaginatedDocs
|
||||
|
||||
const ids = new Set(populations.map(({ id }) => id))
|
||||
const requestHandler = args.collectionPopulationRequestHandler || defaultRequestHandler
|
||||
|
||||
try {
|
||||
res = await fetch(url, {
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
res = await requestHandler({
|
||||
apiPath: apiRoute || '/api',
|
||||
endpoint: `${collection}?depth=${depth}&where[id][in]=${Array.from(ids).join(',')}`,
|
||||
serverURL,
|
||||
}).then((res) => res.json())
|
||||
|
||||
if (res?.docs?.length > 0) {
|
||||
|
||||
@@ -164,6 +164,7 @@ export const updateOperation = async <TSlug extends keyof GeneratedTypes['collec
|
||||
const promises = docs.map(async (doc) => {
|
||||
const { id } = doc
|
||||
let data = {
|
||||
...newFileData,
|
||||
...bulkUpdateData,
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ export const updateByIDOperation = async <TSlug extends keyof GeneratedTypes['co
|
||||
}
|
||||
|
||||
let { data } = args
|
||||
const { password } = data
|
||||
const password = data?.password
|
||||
const shouldSaveDraft = Boolean(draftArg && collectionConfig.versions.drafts)
|
||||
const shouldSavePassword = Boolean(password && collectionConfig.auth && !shouldSaveDraft)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import type { SanitizedCollectionConfig } from '../collections/config/types'
|
||||
import type { SanitizedConfig } from '../config/types'
|
||||
@@ -20,7 +19,6 @@ type Args = {
|
||||
|
||||
export const deleteAssociatedFiles: (args: Args) => Promise<void> = async ({
|
||||
collectionConfig,
|
||||
config,
|
||||
doc,
|
||||
files = [],
|
||||
overrideDelete,
|
||||
@@ -28,9 +26,9 @@ export const deleteAssociatedFiles: (args: Args) => Promise<void> = async ({
|
||||
}) => {
|
||||
if (!collectionConfig.upload) return
|
||||
if (overrideDelete || files.length > 0) {
|
||||
const staticPath = path.resolve(config.paths.configDir, collectionConfig.upload.staticDir)
|
||||
const { staticDir: staticPath } = collectionConfig.upload
|
||||
|
||||
const fileToDelete = `${staticPath}/${doc.filename}`
|
||||
const fileToDelete = `${staticPath}/${doc.filename as string}`
|
||||
|
||||
try {
|
||||
if (await fileExists(fileToDelete)) {
|
||||
|
||||
@@ -3,7 +3,6 @@ import type { OutputInfo, Sharp, SharpOptions } from 'sharp'
|
||||
import { fromBuffer } from 'file-type'
|
||||
import fs from 'fs'
|
||||
import mkdirp from 'mkdirp'
|
||||
import path from 'path'
|
||||
import sanitize from 'sanitize-filename'
|
||||
import sharp from 'sharp'
|
||||
|
||||
@@ -38,7 +37,6 @@ type Result<T> = Promise<{
|
||||
|
||||
export const generateFileData = async <T>({
|
||||
collection: { config: collectionConfig },
|
||||
config,
|
||||
data,
|
||||
overwriteExistingFiles,
|
||||
req,
|
||||
@@ -59,10 +57,7 @@ export const generateFileData = async <T>({
|
||||
const { disableLocalStorage, formatOptions, imageSizes, resizeOptions, staticDir, trimOptions } =
|
||||
collectionConfig.upload
|
||||
|
||||
let staticPath = staticDir
|
||||
if (staticDir.indexOf('/') !== 0) {
|
||||
staticPath = path.resolve(config.paths.configDir, staticDir)
|
||||
}
|
||||
const staticPath = staticDir
|
||||
|
||||
if (!file && uploadEdits && data) {
|
||||
const { filename, url } = data as FileData
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../ui/src/scss/styles.scss';
|
||||
|
||||
.rich-text__button {
|
||||
position: relative;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import type { User } from 'payload/auth'
|
||||
import type { SanitizedCollectionConfig } from 'payload/types'
|
||||
|
||||
import { useAuth, useConfig } from 'payload/components/utilities'
|
||||
import { useAuth, useConfig } from '@payloadcms/ui/providers'
|
||||
import * as React from 'react'
|
||||
|
||||
type options = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.rich-text-blockquote {
|
||||
&[data-slate-node='element'] {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.rich-text-link {
|
||||
position: relative;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.rich-text-link-edit-modal {
|
||||
&__template {
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
useEditDepth,
|
||||
useTranslation,
|
||||
} from '@payloadcms/ui'
|
||||
import { useHotkey } from 'payload/components/hooks'
|
||||
import { useHotkey } from '@payloadcms/ui/hooks'
|
||||
import React, { useRef } from 'react'
|
||||
|
||||
import type { Props } from './types'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.rich-text-ol {
|
||||
&[data-slate-node='element'] {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.relationship-rich-text-button {
|
||||
display: flex;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.rich-text-relationship {
|
||||
@extend %body;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.rich-text-ul {
|
||||
&[data-slate-node='element'] {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.upload-rich-text-button {
|
||||
display: flex;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.rich-text-upload {
|
||||
@extend %body;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.icon--indent-left {
|
||||
height: $baseline;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.icon--indent-right {
|
||||
height: $baseline;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.icon--link {
|
||||
width: $baseline;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.icon--relationship {
|
||||
height: $baseline;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../../../ui/src/scss/styles.scss';
|
||||
|
||||
.icon--upload {
|
||||
height: $baseline;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'payload/scss';
|
||||
@import '../../../ui/src/scss/styles.scss';
|
||||
|
||||
.rich-text {
|
||||
margin-bottom: base(2);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export { useIntersect } from '../hooks/useIntersect'
|
||||
export { default as usePayloadAPI } from '../hooks/usePayloadAPI'
|
||||
export { default as useThumbnail } from '../hooks/useThumbnail'
|
||||
export { default as useHotkey } from '../hooks/useHotkey'
|
||||
|
||||
@@ -18,7 +18,7 @@ const Error: React.FC<ErrorProps> = (props) => {
|
||||
path: pathFromProps,
|
||||
} = props
|
||||
|
||||
const pathFromContext = useFieldPath()
|
||||
const { path: pathFromContext } = useFieldPath()
|
||||
const path = pathFromProps || pathFromContext
|
||||
|
||||
const hasSubmitted = useFormSubmitted()
|
||||
|
||||
@@ -1,15 +1,32 @@
|
||||
'use client'
|
||||
import React from 'react'
|
||||
|
||||
const FieldPathContext = React.createContext<string>('')
|
||||
type FieldPathContextType = {
|
||||
path: string
|
||||
schemaPath: string
|
||||
}
|
||||
const FieldPathContext = React.createContext<FieldPathContextType>({
|
||||
path: '',
|
||||
schemaPath: '',
|
||||
})
|
||||
|
||||
export const FieldPathProvider: React.FC<{
|
||||
path: string
|
||||
schemaPath: string
|
||||
children: React.ReactNode
|
||||
}> = (props) => {
|
||||
const { children, path } = props
|
||||
const { children, path, schemaPath } = props
|
||||
|
||||
return <FieldPathContext.Provider value={path}>{children}</FieldPathContext.Provider>
|
||||
return (
|
||||
<FieldPathContext.Provider
|
||||
value={{
|
||||
path,
|
||||
schemaPath,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</FieldPathContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useFieldPath = () => {
|
||||
|
||||
@@ -7,7 +7,12 @@ export const RenderField: React.FC<{
|
||||
Field: React.ReactNode
|
||||
}> = (props) => {
|
||||
const { name, Field } = props
|
||||
const pathFromContext = useFieldPath()
|
||||
const { path: pathFromContext, schemaPath: schemaPathFromContext } = useFieldPath()
|
||||
const path = `${pathFromContext ? `${pathFromContext}.` : ''}${name || ''}`
|
||||
return <FieldPathProvider path={path}>{Field}</FieldPathProvider>
|
||||
const schemaPath = `${schemaPathFromContext ? `${schemaPathFromContext}.` : ''}${name || ''}`
|
||||
return (
|
||||
<FieldPathProvider path={path} schemaPath={schemaPath}>
|
||||
{Field}
|
||||
</FieldPathProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
|
||||
onToggle={(collapsed) => setCollapse(row.id, collapsed)}
|
||||
>
|
||||
<HiddenInput name={`${path}.id`} value={row.id} />
|
||||
<FieldPathProvider path={path}>
|
||||
<FieldPathProvider path={path} schemaPath={parentPath}>
|
||||
<RenderFields
|
||||
className={`${baseClass}__fields`}
|
||||
fieldMap={fieldMap}
|
||||
|
||||
@@ -132,7 +132,7 @@ export const BlockRow: React.FC<BlockFieldProps> = ({
|
||||
onToggle={(collapsed) => setCollapse(row.id, collapsed)}
|
||||
>
|
||||
<HiddenInput name={`${path}.id`} value={row.id} />
|
||||
<FieldPathProvider path={path}>
|
||||
<FieldPathProvider path={path} schemaPath={`${parentPath}.${block.slug}`}>
|
||||
<RenderFields
|
||||
className={`${baseClass}__fields`}
|
||||
fieldMap={block.subfields}
|
||||
|
||||
@@ -36,7 +36,7 @@ const CollapsibleField: React.FC<Props> = (props) => {
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const pathFromContext = useFieldPath()
|
||||
const { path: pathFromContext } = useFieldPath()
|
||||
const path = pathFromProps || pathFromContext
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
@@ -30,12 +30,12 @@ const Group: React.FC<Props> = (props) => {
|
||||
Label: LabelFromProps,
|
||||
label,
|
||||
required,
|
||||
name,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const path = useFieldPath()
|
||||
|
||||
const { path, schemaPath } = useFieldPath()
|
||||
const { i18n } = useTranslation()
|
||||
const isWithinCollapsible = useCollapsible()
|
||||
const isWithinGroup = useGroup()
|
||||
@@ -70,7 +70,7 @@ const Group: React.FC<Props> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<FieldPathProvider path={path}>
|
||||
<FieldPathProvider path={path} schemaPath={schemaPath}>
|
||||
<GroupProvider>
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<div className={`${baseClass}__header`}>
|
||||
|
||||
@@ -6,4 +6,5 @@ export type Props = FormFieldBase & {
|
||||
indexPath: string
|
||||
permissions: FieldPermissions
|
||||
hideGutter?: boolean
|
||||
name?: string
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ const TabsField: React.FC<Props> = (props) => {
|
||||
name,
|
||||
} = props
|
||||
|
||||
const pathFromContext = useFieldPath()
|
||||
const { path: pathFromContext, schemaPath } = useFieldPath()
|
||||
const path = pathFromContext || pathFromProps || name
|
||||
const { getPreference, setPreference } = usePreferences()
|
||||
const { preferencesKey } = useDocumentInfo()
|
||||
@@ -132,7 +132,10 @@ const TabsField: React.FC<Props> = (props) => {
|
||||
.join(' ')}
|
||||
>
|
||||
{Description}
|
||||
<FieldPathProvider path={'name' in activeTabConfig ? activeTabConfig.name : ''}>
|
||||
<FieldPathProvider
|
||||
path={'name' in activeTabConfig ? activeTabConfig.name : ''}
|
||||
schemaPath={schemaPath}
|
||||
>
|
||||
<RenderFields
|
||||
fieldMap={activeTabConfig.subfields}
|
||||
forceRender={forceRender}
|
||||
|
||||
@@ -55,7 +55,7 @@ const Text: React.FC<Props> = (props) => {
|
||||
[validate, minLength, maxLength, required],
|
||||
)
|
||||
|
||||
const { setValue, value, path, showError } = useField({
|
||||
const { setValue, value, path, showError, schemaPath } = useField({
|
||||
validate: memoizedValidate,
|
||||
path: pathFromProps || name,
|
||||
})
|
||||
|
||||
@@ -20,7 +20,7 @@ import { useFieldPath } from '../FieldPathProvider'
|
||||
const useField = <T,>(options: Options): FieldType<T> => {
|
||||
const { disableFormData = false, hasRows, validate } = options
|
||||
|
||||
const pathFromContext = useFieldPath()
|
||||
const { path: pathFromContext, schemaPath } = useFieldPath()
|
||||
|
||||
const path = options.path || pathFromContext
|
||||
|
||||
@@ -87,6 +87,7 @@ const useField = <T,>(options: Options): FieldType<T> => {
|
||||
valid: field?.valid,
|
||||
value,
|
||||
path,
|
||||
schemaPath,
|
||||
}),
|
||||
[
|
||||
field?.errorMessage,
|
||||
@@ -99,6 +100,7 @@ const useField = <T,>(options: Options): FieldType<T> => {
|
||||
value,
|
||||
initialValue,
|
||||
path,
|
||||
schemaPath,
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -22,4 +22,5 @@ export type FieldType<T> = {
|
||||
valid?: boolean
|
||||
value: T
|
||||
path: string
|
||||
schemaPath: string
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ export const withCondition = <P extends Record<string, unknown>>(
|
||||
): React.FC<P> => {
|
||||
const CheckForCondition: React.FC<P> = (props) => {
|
||||
const { name } = props
|
||||
const pathFromContext = useFieldPath()
|
||||
const { path: pathFromContext } = useFieldPath()
|
||||
const path = pathFromContext || name
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'use client'
|
||||
/* eslint-disable no-shadow */
|
||||
import { useModal } from '@faceless-ui/modal'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
|
||||
35
pnpm-lock.yaml
generated
35
pnpm-lock.yaml
generated
@@ -16,6 +16,9 @@ importers:
|
||||
'@sentry/react':
|
||||
specifier: ^7.77.0
|
||||
version: 7.101.1(react@18.2.0)
|
||||
passport-strategy:
|
||||
specifier: 1.0.0
|
||||
version: 1.0.0
|
||||
react-router-dom:
|
||||
specifier: 5.3.4
|
||||
version: 5.3.4(react@18.2.0)
|
||||
@@ -137,9 +140,6 @@ importers:
|
||||
glob:
|
||||
specifier: 8.1.0
|
||||
version: 8.1.0
|
||||
graphql-request:
|
||||
specifier: 6.1.0
|
||||
version: 6.1.0(graphql@16.8.1)
|
||||
husky:
|
||||
specifier: ^8.0.3
|
||||
version: 8.0.3
|
||||
@@ -2983,14 +2983,6 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@graphql-typed-document-node/core@3.2.0(graphql@16.8.1):
|
||||
resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==}
|
||||
peerDependencies:
|
||||
graphql: ^16.8.1
|
||||
dependencies:
|
||||
graphql: 16.8.1
|
||||
dev: true
|
||||
|
||||
/@hapi/hoek@9.3.0:
|
||||
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
|
||||
dev: false
|
||||
@@ -7431,14 +7423,6 @@ packages:
|
||||
cross-spawn: 7.0.3
|
||||
dev: true
|
||||
|
||||
/cross-fetch@3.1.8:
|
||||
resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==}
|
||||
dependencies:
|
||||
node-fetch: 2.6.12
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: true
|
||||
|
||||
/cross-spawn@5.1.0:
|
||||
resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
|
||||
dependencies:
|
||||
@@ -9713,18 +9697,6 @@ packages:
|
||||
lodash.get: 4.4.2
|
||||
dev: false
|
||||
|
||||
/graphql-request@6.1.0(graphql@16.8.1):
|
||||
resolution: {integrity: sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==}
|
||||
peerDependencies:
|
||||
graphql: ^16.8.1
|
||||
dependencies:
|
||||
'@graphql-typed-document-node/core': 3.2.0(graphql@16.8.1)
|
||||
cross-fetch: 3.1.8
|
||||
graphql: 16.8.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: true
|
||||
|
||||
/graphql-scalars@1.22.2(graphql@16.8.1):
|
||||
resolution: {integrity: sha512-my9FB4GtghqXqi/lWSVAOPiTzTnnEzdOXCsAC2bb5V7EFNQjVjwy3cSSbUvgYOtDuDibd+ZsCDhz+4eykYOlhQ==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -13002,7 +12974,6 @@ packages:
|
||||
/passport-strategy@1.0.0:
|
||||
resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==}
|
||||
engines: {node: '>= 0.4.0'}
|
||||
dev: true
|
||||
|
||||
/path-exists@3.0.0:
|
||||
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
|
||||
|
||||
@@ -19,6 +19,27 @@ export const PostsCollection: CollectionConfig = {
|
||||
relationTo: mediaSlug,
|
||||
type: 'upload',
|
||||
},
|
||||
{
|
||||
name: 'blocksField',
|
||||
type: 'blocks',
|
||||
blocks: [
|
||||
{
|
||||
slug: 'block1',
|
||||
fields: [
|
||||
{
|
||||
type: 'group',
|
||||
name: 'group1',
|
||||
fields: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'group1Text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
slug: postsSlug,
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ import type { Request } from 'express'
|
||||
|
||||
import { Strategy } from 'passport-strategy'
|
||||
|
||||
import type { Payload } from '../../../packages/payload/src/payload'
|
||||
import type { Payload } from '../../../packages/payload/src'
|
||||
|
||||
import { buildConfigWithDefaults } from '../../buildConfigWithDefaults'
|
||||
import { usersSlug } from './shared'
|
||||
|
||||
export const slug = 'users'
|
||||
export const strategyName = 'test-local'
|
||||
|
||||
export class CustomStrategy extends Strategy {
|
||||
@@ -23,7 +23,7 @@ export class CustomStrategy extends Strategy {
|
||||
}
|
||||
this.ctx
|
||||
.find({
|
||||
collection: slug,
|
||||
collection: usersSlug,
|
||||
where: {
|
||||
code: {
|
||||
equals: req.headers.code,
|
||||
@@ -36,8 +36,8 @@ export class CustomStrategy extends Strategy {
|
||||
.then((users) => {
|
||||
if (users.docs && users.docs.length) {
|
||||
const user = users.docs[0]
|
||||
user.collection = slug
|
||||
user._strategy = `${slug}-${strategyName}`
|
||||
user.collection = usersSlug
|
||||
user._strategy = `${usersSlug}-${strategyName}`
|
||||
this.success(user)
|
||||
} else {
|
||||
this.error(null)
|
||||
@@ -52,7 +52,7 @@ export default buildConfigWithDefaults({
|
||||
},
|
||||
collections: [
|
||||
{
|
||||
slug,
|
||||
slug: usersSlug,
|
||||
auth: {
|
||||
disableLocalStrategy: true,
|
||||
strategies: [
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import payload from '../../../packages/payload/src'
|
||||
import { initPayloadTest } from '../../helpers/configHelpers'
|
||||
import { slug } from './config'
|
||||
import type { Payload } from '../../../packages/payload/src'
|
||||
|
||||
import { getPayload } from '../../../packages/payload/src'
|
||||
import { NextRESTClient } from '../../helpers/NextRESTClient'
|
||||
import { startMemoryDB } from '../../startMemoryDB'
|
||||
import configPromise from './config'
|
||||
import { usersSlug } from './shared'
|
||||
|
||||
require('isomorphic-fetch')
|
||||
|
||||
let apiUrl
|
||||
let payload: Payload
|
||||
let restClient: NextRESTClient
|
||||
|
||||
const [code, secret, name] = ['test', 'strategy', 'Tester']
|
||||
|
||||
@@ -14,8 +19,9 @@ const headers = {
|
||||
|
||||
describe('AuthStrategies', () => {
|
||||
beforeAll(async () => {
|
||||
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } })
|
||||
apiUrl = `${serverURL}/api`
|
||||
const config = await startMemoryDB(configPromise)
|
||||
payload = await getPayload({ config })
|
||||
restClient = new NextRESTClient(payload.config)
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -26,21 +32,19 @@ describe('AuthStrategies', () => {
|
||||
|
||||
describe('create user', () => {
|
||||
beforeAll(async () => {
|
||||
await fetch(`${apiUrl}/${slug}`, {
|
||||
await restClient.POST(`/${usersSlug}`, {
|
||||
body: JSON.stringify({
|
||||
code,
|
||||
secret,
|
||||
name,
|
||||
}),
|
||||
headers,
|
||||
method: 'post',
|
||||
})
|
||||
})
|
||||
|
||||
it('should return a logged in user from /me', async () => {
|
||||
const response = await fetch(`${apiUrl}/${slug}/me`, {
|
||||
const response = await restClient.GET(`/${usersSlug}/me`, {
|
||||
headers: {
|
||||
...headers,
|
||||
code,
|
||||
secret,
|
||||
},
|
||||
|
||||
1
test/auth/custom-strategy/shared.ts
Normal file
1
test/auth/custom-strategy/shared.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const usersSlug = 'users'
|
||||
@@ -1,21 +1,25 @@
|
||||
import payload from '../../../packages/payload/src'
|
||||
import type { Payload } from '../../../packages/payload/src'
|
||||
|
||||
import { getPayload } from '../../../packages/payload/src'
|
||||
import { devUser } from '../../credentials'
|
||||
import { initPayloadTest } from '../../helpers/configHelpers'
|
||||
import { RESTClient } from '../../helpers/rest'
|
||||
import { NextRESTClient } from '../../helpers/NextRESTClient'
|
||||
import { startMemoryDB } from '../../startMemoryDB'
|
||||
import { collectionSlug } from './config'
|
||||
import configPromise from './config'
|
||||
|
||||
require('isomorphic-fetch')
|
||||
|
||||
let client: RESTClient
|
||||
let restClient: NextRESTClient
|
||||
let payload: Payload
|
||||
|
||||
describe('Remove token from auth responses', () => {
|
||||
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)
|
||||
payload = await getPayload({ config })
|
||||
restClient = new NextRESTClient(payload.config)
|
||||
|
||||
await client.endpoint(`/api/${collectionSlug}/first-register`, 'post', devUser)
|
||||
await client.login()
|
||||
await restClient.POST(`/${collectionSlug}/first-register`, {
|
||||
body: JSON.stringify(devUser),
|
||||
})
|
||||
await restClient.login({ slug: collectionSlug, credentials: devUser })
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -25,27 +29,28 @@ describe('Remove token from auth responses', () => {
|
||||
})
|
||||
|
||||
it('should not include token in response from /login', async () => {
|
||||
const { status, data } = await client.endpoint(`/api/${collectionSlug}/login`, 'post', devUser)
|
||||
expect(status).toBe(200)
|
||||
expect(data.token).not.toBeDefined()
|
||||
expect(data.user.email).toBeDefined()
|
||||
const result = await restClient.login({
|
||||
slug: collectionSlug,
|
||||
credentials: devUser,
|
||||
})
|
||||
expect(result.token).not.toBeDefined()
|
||||
expect(result.user.email).toBeDefined()
|
||||
})
|
||||
|
||||
it('should not include token in response from /me', async () => {
|
||||
const { status, data } = await client.endpointWithAuth(`/api/${collectionSlug}/me`)
|
||||
expect(status).toBe(200)
|
||||
expect(data.token).not.toBeDefined()
|
||||
expect(data.user.email).toBeDefined()
|
||||
const response = await restClient.GET(`/${collectionSlug}/me`)
|
||||
const result = await response.json()
|
||||
expect(response.status).toBe(200)
|
||||
expect(result.token).not.toBeDefined()
|
||||
expect(result.user.email).toBeDefined()
|
||||
})
|
||||
|
||||
it('should not include token in response from /refresh-token', async () => {
|
||||
const { status, data } = await client.endpointWithAuth(
|
||||
`/api/${collectionSlug}/refresh-token`,
|
||||
'post',
|
||||
)
|
||||
expect(status).toBe(200)
|
||||
expect(data.refreshedToken).not.toBeDefined()
|
||||
expect(data.user.email).toBeDefined()
|
||||
const response = await restClient.POST(`/${collectionSlug}/refresh-token`)
|
||||
const result = await response.json()
|
||||
expect(response.status).toBe(200)
|
||||
expect(result.refreshedToken).not.toBeDefined()
|
||||
expect(result.user.email).toBeDefined()
|
||||
})
|
||||
|
||||
it('should not include token in response from /reset-password', async () => {
|
||||
@@ -55,17 +60,13 @@ describe('Remove token from auth responses', () => {
|
||||
disableEmail: true,
|
||||
})
|
||||
|
||||
const { status, data } = await client.endpoint(
|
||||
`/api/${collectionSlug}/reset-password`,
|
||||
'post',
|
||||
{
|
||||
token,
|
||||
password: devUser.password,
|
||||
},
|
||||
)
|
||||
const response = await restClient.POST(`/${collectionSlug}/reset-password`, {
|
||||
body: JSON.stringify({ token, password: devUser.password }),
|
||||
})
|
||||
const result = await response.json()
|
||||
|
||||
expect(status).toBe(200)
|
||||
expect(data.token).not.toBeDefined()
|
||||
expect(data.user.email).toBeDefined()
|
||||
expect(response.status).toBe(200)
|
||||
expect(result.token).not.toBeDefined()
|
||||
expect(result.user.email).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import type { IndexDirection, IndexOptions } from 'mongoose'
|
||||
|
||||
import { GraphQLClient } from 'graphql-request'
|
||||
|
||||
import type { MongooseAdapter } from '../../packages/db-mongodb/src/index'
|
||||
import type { SanitizedConfig } from '../../packages/payload/src/config/types'
|
||||
import type { Payload } from '../../packages/payload/src'
|
||||
import type { PaginatedDocs } from '../../packages/payload/src/database/types'
|
||||
import type { RichTextField } from './payload-types'
|
||||
import type { GroupField } from './payload-types'
|
||||
|
||||
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 { isMongoose } from '../helpers/isMongoose'
|
||||
import { RESTClient } from '../helpers/rest'
|
||||
import configPromise from '../uploads/config'
|
||||
import { startMemoryDB } from '../startMemoryDB'
|
||||
import { arrayDefaultValue } from './collections/Array'
|
||||
import { blocksDoc } from './collections/Blocks/shared'
|
||||
import { dateDoc } from './collections/Date/shared'
|
||||
@@ -28,8 +26,8 @@ import {
|
||||
} from './collections/Tabs/constants'
|
||||
import { tabsDoc } from './collections/Tabs/shared'
|
||||
import { defaultText } from './collections/Text/shared'
|
||||
import configPromise from './config'
|
||||
import { clearAndSeedEverything } from './seed'
|
||||
import { GroupField } from './payload-types'
|
||||
import {
|
||||
arrayFieldsSlug,
|
||||
blockFieldsSlug,
|
||||
@@ -39,22 +37,19 @@ import {
|
||||
textFieldsSlug,
|
||||
} from './slugs'
|
||||
|
||||
let client: RESTClient
|
||||
let graphQLClient: GraphQLClient
|
||||
let serverURL: string
|
||||
let config: SanitizedConfig
|
||||
let token: string
|
||||
let restClient: NextRESTClient
|
||||
let user: any
|
||||
let payload: Payload
|
||||
|
||||
describe('Fields', () => {
|
||||
beforeAll(async () => {
|
||||
;({ serverURL } = await initPayloadTest({ __dirname, init: { local: false } }))
|
||||
config = await configPromise
|
||||
|
||||
client = new RESTClient(config, { defaultSlug: 'point-fields', serverURL })
|
||||
const graphQLURL = `${serverURL}${config.routes.api}${config.routes.graphQL}`
|
||||
graphQLClient = new GraphQLClient(graphQLURL)
|
||||
token = await client.login()
|
||||
const config = await startMemoryDB(configPromise)
|
||||
payload = await getPayload({ config })
|
||||
restClient = new NextRESTClient(payload.config)
|
||||
await restClient.login({
|
||||
slug: 'users',
|
||||
credentials: devUser,
|
||||
})
|
||||
|
||||
user = await payload.login({
|
||||
collection: 'users',
|
||||
@@ -67,8 +62,10 @@ describe('Fields', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await clearAndSeedEverything(payload)
|
||||
client = new RESTClient(config, { defaultSlug: 'point-fields', serverURL })
|
||||
await client.login()
|
||||
await restClient.login({
|
||||
slug: 'users',
|
||||
credentials: devUser,
|
||||
})
|
||||
})
|
||||
|
||||
describe('text', () => {
|
||||
@@ -1061,14 +1058,12 @@ describe('Fields', () => {
|
||||
}
|
||||
}
|
||||
}`
|
||||
const response = await graphQLClient.request(
|
||||
query,
|
||||
{},
|
||||
{
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
)
|
||||
const { docs }: PaginatedDocs<RichTextField> = response.RichTextFields
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
})
|
||||
.then((res) => res.json())
|
||||
const { docs }: PaginatedDocs<RichTextField> = data.RichTextFields
|
||||
const uploadElement = docs[0].richText.find((el) => el.type === 'upload') as any
|
||||
expect(uploadElement.value.media.filename).toStrictEqual('payload.png')
|
||||
})
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import type { SerializedEditorState, SerializedParagraphNode } from 'lexical'
|
||||
|
||||
import { GraphQLClient } from 'graphql-request'
|
||||
|
||||
import type { SanitizedConfig } from '../../packages/payload/src/config/types'
|
||||
import type { Payload } from '../../packages/payload/src'
|
||||
import type { PaginatedDocs } from '../../packages/payload/src/database/types'
|
||||
import type {
|
||||
SerializedBlockNode,
|
||||
@@ -12,10 +10,10 @@ import type {
|
||||
} from '../../packages/richtext-lexical/src'
|
||||
import type { LexicalField, LexicalMigrateField, RichTextField } from './payload-types'
|
||||
|
||||
import payload from '../../packages/payload/src'
|
||||
import { initPayloadTest } from '../helpers/configHelpers'
|
||||
import { RESTClient } from '../helpers/rest'
|
||||
import configPromise from '../uploads/config'
|
||||
import { getPayload } from '../../packages/payload/src'
|
||||
import { devUser } from '../credentials'
|
||||
import { NextRESTClient } from '../helpers/NextRESTClient'
|
||||
import { startMemoryDB } from '../startMemoryDB'
|
||||
import { arrayDoc } from './collections/Array/shared'
|
||||
import { lexicalDocData } from './collections/Lexical/data'
|
||||
import { lexicalMigrateDocData } from './collections/LexicalMigrate/data'
|
||||
@@ -23,6 +21,7 @@ import { richTextDocData } from './collections/RichText/data'
|
||||
import { generateLexicalRichText } from './collections/RichText/generateLexicalRichText'
|
||||
import { textDoc } from './collections/Text/shared'
|
||||
import { uploadsDoc } from './collections/Upload/shared'
|
||||
import configPromise from './config'
|
||||
import { clearAndSeedEverything } from './seed'
|
||||
import {
|
||||
arrayFieldsSlug,
|
||||
@@ -33,10 +32,8 @@ import {
|
||||
uploadsSlug,
|
||||
} from './slugs'
|
||||
|
||||
let client: RESTClient
|
||||
let graphQLClient: GraphQLClient
|
||||
let serverURL: string
|
||||
let config: SanitizedConfig
|
||||
let payload: Payload
|
||||
let restClient: NextRESTClient
|
||||
let token: string
|
||||
|
||||
let createdArrayDocID: number | string = null
|
||||
@@ -46,19 +43,17 @@ let createdRichTextDocID: number | string = null
|
||||
|
||||
describe('Lexical', () => {
|
||||
beforeAll(async () => {
|
||||
;({ serverURL } = await initPayloadTest({ __dirname, init: { local: false } }))
|
||||
config = await configPromise
|
||||
|
||||
client = new RESTClient(config, { defaultSlug: richTextFieldsSlug, serverURL })
|
||||
const graphQLURL = `${serverURL}${config.routes.api}${config.routes.graphQL}`
|
||||
graphQLClient = new GraphQLClient(graphQLURL)
|
||||
token = await client.login()
|
||||
const config = await startMemoryDB(configPromise)
|
||||
payload = await getPayload({ config })
|
||||
restClient = new NextRESTClient(payload.config)
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
await clearAndSeedEverything(payload)
|
||||
client = new RESTClient(config, { defaultSlug: richTextFieldsSlug, serverURL })
|
||||
await client.login()
|
||||
await restClient.login({
|
||||
slug: 'users',
|
||||
credentials: devUser,
|
||||
})
|
||||
|
||||
createdArrayDocID = (
|
||||
await payload.find({
|
||||
|
||||
@@ -155,7 +155,10 @@ export class NextRESTClient {
|
||||
return this._PATCH(request, { params: { slug } })
|
||||
}
|
||||
|
||||
async POST(path: ValidPath, options: RequestInit & { file?: boolean } = {}): Promise<Response> {
|
||||
async POST(
|
||||
path: ValidPath,
|
||||
options: RequestInit & RequestOptions & { file?: boolean } = {},
|
||||
): Promise<Response> {
|
||||
const { url, slug, params } = this.generateRequestParts(path)
|
||||
const queryParams = generateQueryString({}, params)
|
||||
|
||||
@@ -176,15 +179,23 @@ export class NextRESTClient {
|
||||
password: string
|
||||
}
|
||||
slug: string
|
||||
}): Promise<string> {
|
||||
this.token = await this.POST(`/${slug}/login`, {
|
||||
}): Promise<{ [key: string]: any }> {
|
||||
const response = await this.POST(`/${slug}/login`, {
|
||||
body: JSON.stringify(
|
||||
credentials ? { ...credentials } : { email: devUser.email, password: devUser.password },
|
||||
),
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((data) => data.token)
|
||||
const result = await response.json()
|
||||
|
||||
return this.token
|
||||
this.token = result.token
|
||||
|
||||
if (!result.token) {
|
||||
// If the token is not in the response body, then we can extract it from the cookies
|
||||
const setCookie = response.headers.get('Set-Cookie')
|
||||
const tokenMatchResult = setCookie?.match(/payload-token=(?<token>.+?);/)
|
||||
this.token = tokenMatchResult?.groups?.token
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ export const Media: CollectionConfig = {
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'caption',
|
||||
type: 'richText',
|
||||
},
|
||||
// {
|
||||
// name: 'caption',
|
||||
// type: 'richText',
|
||||
// },
|
||||
],
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ import { seed } from './seed'
|
||||
import { mobileBreakpoint } from './shared'
|
||||
import { formatLivePreviewURL } from './utilities/formatLivePreviewURL'
|
||||
|
||||
const mockModulePath = path.resolve(__dirname, './mocks/mockFSModule.js')
|
||||
|
||||
export default buildConfigWithDefaults({
|
||||
admin: {
|
||||
livePreview: {
|
||||
@@ -25,16 +23,6 @@ export default buildConfigWithDefaults({
|
||||
collections: ['pages', 'posts'],
|
||||
globals: ['header', 'footer'],
|
||||
},
|
||||
webpack: (config) => ({
|
||||
...config,
|
||||
resolve: {
|
||||
...config.resolve,
|
||||
alias: {
|
||||
...config?.resolve?.alias,
|
||||
fs: mockModulePath,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
cors: ['http://localhost:3001'],
|
||||
csrf: ['http://localhost:3001'],
|
||||
|
||||
@@ -9,6 +9,7 @@ import { traverseRichText } from '../../packages/live-preview/src/traverseRichTe
|
||||
import { getPayload } from '../../packages/payload/src'
|
||||
import getFileByPath from '../../packages/payload/src/uploads/getFileByPath'
|
||||
import { fieldSchemaToJSON } from '../../packages/payload/src/utilities/fieldSchemaToJSON'
|
||||
import { NextRESTClient } from '../helpers/NextRESTClient'
|
||||
import { startMemoryDB } from '../startMemoryDB'
|
||||
import { Pages } from './collections/Pages'
|
||||
import { postsSlug } from './collections/Posts'
|
||||
@@ -18,6 +19,11 @@ import { tenantsSlug } from './shared'
|
||||
const schemaJSON = fieldSchemaToJSON(Pages.fields)
|
||||
|
||||
let payload: Payload
|
||||
let restClient: NextRESTClient
|
||||
|
||||
function collectionPopulationRequestHandler({ endpoint }: { endpoint: string }) {
|
||||
return restClient.GET(`/${endpoint}`)
|
||||
}
|
||||
|
||||
describe('Collections - Live Preview', () => {
|
||||
let serverURL
|
||||
@@ -29,6 +35,7 @@ describe('Collections - Live Preview', () => {
|
||||
beforeAll(async () => {
|
||||
const config = await startMemoryDB(configPromise)
|
||||
payload = await getPayload({ config })
|
||||
restClient = new NextRESTClient(payload.config)
|
||||
|
||||
tenant = await payload.create({
|
||||
collection: tenantsSlug,
|
||||
@@ -140,6 +147,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(mergedData.title).toEqual('Test Page (Changed)')
|
||||
@@ -165,6 +173,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(mergedData.hero.media).toMatchObject(media)
|
||||
@@ -183,6 +192,7 @@ describe('Collections - Live Preview', () => {
|
||||
},
|
||||
initialData: mergedData,
|
||||
serverURL,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(mergedDataWithoutUpload.hero.media).toBeFalsy()
|
||||
@@ -210,6 +220,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1.richTextSlate).toHaveLength(1)
|
||||
@@ -236,6 +247,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge2.richTextSlate).toHaveLength(1)
|
||||
@@ -295,6 +307,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1.richTextLexical.root.children).toHaveLength(2)
|
||||
@@ -340,6 +353,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge2.richTextLexical.root.children).toHaveLength(1)
|
||||
@@ -362,6 +376,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1._numberOfRequests).toEqual(1)
|
||||
@@ -383,6 +398,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1._numberOfRequests).toEqual(1)
|
||||
@@ -404,6 +420,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1._numberOfRequests).toEqual(1)
|
||||
@@ -428,6 +445,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1._numberOfRequests).toEqual(1)
|
||||
@@ -457,6 +475,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge2._numberOfRequests).toEqual(0)
|
||||
@@ -482,6 +501,7 @@ describe('Collections - Live Preview', () => {
|
||||
},
|
||||
initialData,
|
||||
serverURL,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1.tab.relationshipInTab).toMatchObject(testPost)
|
||||
@@ -518,6 +538,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1._numberOfRequests).toEqual(1)
|
||||
@@ -574,6 +595,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData: merge1,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge2._numberOfRequests).toEqual(1)
|
||||
@@ -649,6 +671,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1._numberOfRequests).toEqual(2)
|
||||
@@ -711,6 +734,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData: merge1,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge2._numberOfRequests).toEqual(1)
|
||||
@@ -776,6 +800,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1._numberOfRequests).toEqual(2)
|
||||
@@ -842,6 +867,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData: merge1,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge2._numberOfRequests).toEqual(1)
|
||||
@@ -895,6 +921,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1._numberOfRequests).toEqual(0)
|
||||
@@ -954,6 +981,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
// Check that the relationship on the first has been removed
|
||||
@@ -982,6 +1010,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge1._numberOfRequests).toEqual(1)
|
||||
@@ -1027,6 +1056,7 @@ describe('Collections - Live Preview', () => {
|
||||
externallyUpdatedRelationship,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
expect(merge2._numberOfRequests).toEqual(1)
|
||||
@@ -1184,6 +1214,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
// Check that the blocks have been reordered
|
||||
@@ -1216,6 +1247,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
// Check that the block has been removed
|
||||
@@ -1235,6 +1267,7 @@ describe('Collections - Live Preview', () => {
|
||||
initialData,
|
||||
serverURL,
|
||||
returnNumberOfRequests: true,
|
||||
collectionPopulationRequestHandler,
|
||||
})
|
||||
|
||||
// Check that the block has been removed
|
||||
|
||||
@@ -7,13 +7,17 @@ import removeFiles from '../helpers/removeFiles'
|
||||
import { Uploads1 } from './collections/Upload1'
|
||||
import Uploads2 from './collections/Upload2'
|
||||
import AdminThumbnailCol from './collections/admin-thumbnail'
|
||||
import { audioSlug, enlargeSlug, mediaSlug, reduceSlug, relationSlug } from './shared'
|
||||
import {
|
||||
audioSlug,
|
||||
enlargeSlug,
|
||||
mediaSlug,
|
||||
reduceSlug,
|
||||
relationSlug,
|
||||
unstoredMediaSlug,
|
||||
} from './shared'
|
||||
|
||||
export default buildConfigWithDefaults({
|
||||
serverURL: undefined,
|
||||
paths: {
|
||||
configDir: __dirname,
|
||||
},
|
||||
collections: [
|
||||
{
|
||||
slug: relationSlug,
|
||||
@@ -44,7 +48,7 @@ export default buildConfigWithDefaults({
|
||||
slug: 'gif-resize',
|
||||
upload: {
|
||||
staticURL: '/media-gif',
|
||||
staticDir: './media-gif',
|
||||
staticDir: path.resolve(__dirname, './media-gif'),
|
||||
mimeTypes: ['image/gif'],
|
||||
resizeOptions: {
|
||||
position: 'center',
|
||||
@@ -75,7 +79,7 @@ export default buildConfigWithDefaults({
|
||||
slug: 'no-image-sizes',
|
||||
upload: {
|
||||
staticURL: '/no-image-sizes',
|
||||
staticDir: './no-image-sizes',
|
||||
staticDir: path.resolve(__dirname, './no-image-sizes'),
|
||||
mimeTypes: ['image/png', 'image/jpg', 'image/jpeg'],
|
||||
resizeOptions: {
|
||||
position: 'center',
|
||||
@@ -89,7 +93,7 @@ export default buildConfigWithDefaults({
|
||||
slug: 'object-fit',
|
||||
upload: {
|
||||
staticURL: '/object-fit',
|
||||
staticDir: './object-fit',
|
||||
staticDir: path.resolve(__dirname, './object-fit'),
|
||||
mimeTypes: ['image/png', 'image/jpg', 'image/jpeg'],
|
||||
imageSizes: [
|
||||
{
|
||||
@@ -125,7 +129,7 @@ export default buildConfigWithDefaults({
|
||||
upload: {
|
||||
focalPoint: false,
|
||||
staticURL: '/crop-only',
|
||||
staticDir: './crop-only',
|
||||
staticDir: path.resolve(__dirname, './crop-only'),
|
||||
mimeTypes: ['image/png', 'image/jpg', 'image/jpeg'],
|
||||
imageSizes: [
|
||||
{
|
||||
@@ -152,7 +156,7 @@ export default buildConfigWithDefaults({
|
||||
upload: {
|
||||
crop: false,
|
||||
staticURL: '/focal-only',
|
||||
staticDir: './focal-only',
|
||||
staticDir: path.resolve(__dirname, './focal-only'),
|
||||
mimeTypes: ['image/png', 'image/jpg', 'image/jpeg'],
|
||||
imageSizes: [
|
||||
{
|
||||
@@ -178,7 +182,7 @@ export default buildConfigWithDefaults({
|
||||
slug: mediaSlug,
|
||||
upload: {
|
||||
staticURL: '/media',
|
||||
staticDir: './media',
|
||||
staticDir: path.resolve(__dirname, './media'),
|
||||
// crop: false,
|
||||
// focalPoint: false,
|
||||
mimeTypes: [
|
||||
@@ -284,7 +288,7 @@ export default buildConfigWithDefaults({
|
||||
slug: enlargeSlug,
|
||||
upload: {
|
||||
staticURL: '/enlarge',
|
||||
staticDir: './media/enlarge',
|
||||
staticDir: path.resolve(__dirname, './media/enlarge'),
|
||||
mimeTypes: [
|
||||
'image/png',
|
||||
'image/jpg',
|
||||
@@ -332,7 +336,7 @@ export default buildConfigWithDefaults({
|
||||
slug: reduceSlug,
|
||||
upload: {
|
||||
staticURL: '/reduce',
|
||||
staticDir: './media/reduce',
|
||||
staticDir: path.resolve(__dirname, './media/reduce'),
|
||||
mimeTypes: [
|
||||
'image/png',
|
||||
'image/jpg',
|
||||
@@ -374,7 +378,7 @@ export default buildConfigWithDefaults({
|
||||
slug: 'media-trim',
|
||||
upload: {
|
||||
staticURL: '/media-trim',
|
||||
staticDir: './media-trim',
|
||||
staticDir: path.resolve(__dirname, './media-trim'),
|
||||
mimeTypes: ['image/png', 'image/jpg', 'image/jpeg'],
|
||||
trimOptions: 0,
|
||||
imageSizes: [
|
||||
@@ -404,7 +408,7 @@ export default buildConfigWithDefaults({
|
||||
fields: [],
|
||||
},
|
||||
{
|
||||
slug: 'unstored-media',
|
||||
slug: unstoredMediaSlug,
|
||||
upload: {
|
||||
staticURL: '/media',
|
||||
disableLocalStorage: true,
|
||||
@@ -416,7 +420,7 @@ export default buildConfigWithDefaults({
|
||||
upload: {
|
||||
// Either use another web server like `npx serve -l 4000` (http://localhost:4000) or use the static server from the previous collection to serve the media folder (http://localhost:3000/media)
|
||||
staticURL: 'http://localhost:3000/media',
|
||||
staticDir: './media',
|
||||
staticDir: path.resolve(__dirname, './media'),
|
||||
},
|
||||
fields: [],
|
||||
},
|
||||
@@ -427,7 +431,7 @@ export default buildConfigWithDefaults({
|
||||
slug: 'optional-file',
|
||||
upload: {
|
||||
staticURL: '/optional',
|
||||
staticDir: './optional',
|
||||
staticDir: path.resolve(__dirname, './optional'),
|
||||
filesRequiredOnCreate: false,
|
||||
},
|
||||
fields: [],
|
||||
@@ -436,7 +440,7 @@ export default buildConfigWithDefaults({
|
||||
slug: 'required-file',
|
||||
upload: {
|
||||
staticURL: '/required',
|
||||
staticDir: './required',
|
||||
staticDir: path.resolve(__dirname, './required'),
|
||||
filesRequiredOnCreate: true,
|
||||
},
|
||||
fields: [],
|
||||
|
||||
@@ -12,7 +12,14 @@ import getFileByPath from '../../packages/payload/src/uploads/getFileByPath'
|
||||
import { NextRESTClient } from '../helpers/NextRESTClient'
|
||||
import { startMemoryDB } from '../startMemoryDB'
|
||||
import configPromise from './config'
|
||||
import { enlargeSlug, mediaSlug, reduceSlug, relationSlug, usersSlug } from './shared'
|
||||
import {
|
||||
enlargeSlug,
|
||||
mediaSlug,
|
||||
reduceSlug,
|
||||
relationSlug,
|
||||
unstoredMediaSlug,
|
||||
usersSlug,
|
||||
} from './shared'
|
||||
|
||||
const getMimeType = (
|
||||
filePath: string,
|
||||
@@ -214,7 +221,7 @@ describe('Collections - Uploads', () => {
|
||||
formData.append('file', fileBlob)
|
||||
|
||||
// unstored media
|
||||
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||
const response = await restClient.POST(`/${unstoredMediaSlug}`, {
|
||||
body: formData,
|
||||
file: true,
|
||||
})
|
||||
@@ -368,8 +375,8 @@ describe('Collections - Uploads', () => {
|
||||
const expectedPath = path.join(__dirname, './media')
|
||||
|
||||
// Check that previously existing files were removed
|
||||
expect(await fileExists(path.join(expectedPath, mediaDoc.filename))).toBe(true)
|
||||
expect(await fileExists(path.join(expectedPath, mediaDoc.sizes.icon.filename))).toBe(true)
|
||||
expect(await fileExists(path.join(expectedPath, mediaDoc.filename))).toBe(false)
|
||||
expect(await fileExists(path.join(expectedPath, mediaDoc.sizes.icon.filename))).toBe(false)
|
||||
})
|
||||
|
||||
it('update - update many', async () => {
|
||||
@@ -404,8 +411,8 @@ describe('Collections - Uploads', () => {
|
||||
const expectedPath = path.join(__dirname, './media')
|
||||
|
||||
// Check that previously existing files were removed
|
||||
expect(await fileExists(path.join(expectedPath, mediaDoc.filename))).toBe(true)
|
||||
expect(await fileExists(path.join(expectedPath, mediaDoc.sizes.icon.filename))).toBe(true)
|
||||
expect(await fileExists(path.join(expectedPath, mediaDoc.filename))).toBe(false)
|
||||
expect(await fileExists(path.join(expectedPath, mediaDoc.sizes.icon.filename))).toBe(false)
|
||||
})
|
||||
|
||||
it('should remove existing media on re-upload', async () => {
|
||||
@@ -462,7 +469,7 @@ describe('Collections - Uploads', () => {
|
||||
// Replace the temp file with a new one
|
||||
const newFilePath = path.resolve(__dirname, './temp-renamed.png')
|
||||
const newFile = await getFileByPath(newFilePath)
|
||||
newFile.name = 'temp-renamed.png'
|
||||
newFile.name = 'temp-renamed-second.png'
|
||||
|
||||
const updatedMediaDoc = (await payload.update({
|
||||
collection: mediaSlug,
|
||||
@@ -474,6 +481,7 @@ describe('Collections - Uploads', () => {
|
||||
})) as unknown as { docs: Media[] }
|
||||
|
||||
// Check that the replacement file was created and the old one was removed
|
||||
expect(updatedMediaDoc.docs[0].filename).toEqual(newFile.name)
|
||||
expect(await fileExists(path.join(expectedPath, updatedMediaDoc.docs[0].filename))).toBe(true)
|
||||
expect(await fileExists(path.join(expectedPath, mediaDoc.filename))).toBe(false)
|
||||
})
|
||||
@@ -588,13 +596,13 @@ describe('Collections - Uploads', () => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', await bufferToFileBlob(path.join(__dirname, './image.png')))
|
||||
|
||||
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||
body: formData,
|
||||
file: true,
|
||||
})
|
||||
expect(response.status).toBe(200)
|
||||
const { doc } = await restClient
|
||||
.POST(`/${mediaSlug}`, {
|
||||
body: formData,
|
||||
file: true,
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
const { doc } = await response.json()
|
||||
const response2 = await restClient.DELETE(`/${mediaSlug}/${doc.id}`)
|
||||
expect(response2.status).toBe(200)
|
||||
|
||||
@@ -605,12 +613,12 @@ describe('Collections - Uploads', () => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', await bufferToFileBlob(path.join(__dirname, './image.png')))
|
||||
|
||||
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||
body: formData,
|
||||
file: true,
|
||||
})
|
||||
expect(response.status).toBe(200)
|
||||
const { doc } = await response.json()
|
||||
const { doc } = await restClient
|
||||
.POST(`/${mediaSlug}`, {
|
||||
body: formData,
|
||||
file: true,
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
const { errors } = await restClient
|
||||
.DELETE(`/${mediaSlug}`, {
|
||||
|
||||
@@ -11,3 +11,5 @@ export const enlargeSlug = 'enlarge'
|
||||
export const reduceSlug = 'reduce'
|
||||
|
||||
export const adminThumbnailSlug = 'admin-thumbnail'
|
||||
|
||||
export const unstoredMediaSlug = 'unstored-media'
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import type { CollectionConfig } from '../../../packages/payload/src/collections/config/types'
|
||||
|
||||
import { extractTranslations } from 'payload/dist/translations-new/extractTranslations'
|
||||
import CollectionVersionButton from '../elements/CollectionVersionButton'
|
||||
import CollectionVersionsButton from '../elements/CollectionVersionsButton'
|
||||
import { CustomPublishButton } from '../elements/CustomSaveButton'
|
||||
import { draftCollectionSlug } from '../slugs'
|
||||
|
||||
const labels = extractTranslations(['version:draft', 'version:published', 'version:status'])
|
||||
|
||||
const DraftPosts: CollectionConfig = {
|
||||
access: {
|
||||
read: ({ req: { user } }) => {
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import { GraphQLClient, request } 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 AutosavePosts from './collections/Autosave'
|
||||
import configPromise from './config'
|
||||
import AutosaveGlobal from './globals/Autosave'
|
||||
import { clearAndSeedEverything } from './seed'
|
||||
import { autosaveCollectionSlug, draftCollectionSlug } from './slugs'
|
||||
|
||||
let payload: Payload
|
||||
let restClient: NextRESTClient
|
||||
|
||||
let collectionLocalPostID: string
|
||||
let collectionLocalVersionID
|
||||
|
||||
let graphQLURL
|
||||
|
||||
let graphQLClient
|
||||
let token
|
||||
|
||||
let collectionGraphQLPostID
|
||||
@@ -34,10 +35,9 @@ const formatGraphQLID = (id: number | string) =>
|
||||
|
||||
describe('Versions', () => {
|
||||
beforeAll(async () => {
|
||||
const config = await configPromise
|
||||
|
||||
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } })
|
||||
graphQLURL = `${serverURL}${config.routes.api}${config.routes.graphQL}`
|
||||
const config = await startMemoryDB(configPromise)
|
||||
payload = await getPayload({ config })
|
||||
restClient = new NextRESTClient(payload.config)
|
||||
|
||||
const login = `
|
||||
mutation {
|
||||
@@ -48,10 +48,11 @@ describe('Versions', () => {
|
||||
token
|
||||
}
|
||||
}`
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({ body: JSON.stringify({ query: login }) })
|
||||
.then((res) => res.json())
|
||||
|
||||
const response = await request(graphQLURL, login)
|
||||
token = response.loginUser.token
|
||||
graphQLClient = new GraphQLClient(graphQLURL, { headers: { Authorization: `JWT ${token}` } })
|
||||
token = data.loginUser.token
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -67,10 +68,7 @@ describe('Versions', () => {
|
||||
})
|
||||
collectionLocalPostID = autosavePost.id
|
||||
|
||||
const updatedPost: {
|
||||
_status?: string
|
||||
title: string
|
||||
} = await payload.update({
|
||||
await payload.update({
|
||||
id: collectionLocalPostID,
|
||||
collection,
|
||||
data: {
|
||||
@@ -788,10 +786,16 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
const data = response.createAutosavePost
|
||||
collectionGraphQLPostID = data.id
|
||||
collectionGraphQLPostID = data.createAutosavePost.id
|
||||
})
|
||||
describe('Create', () => {
|
||||
it('should allow a new doc to be created with draft status', async () => {
|
||||
@@ -808,11 +812,16 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
const data = response.createAutosavePost
|
||||
|
||||
expect(data._status).toStrictEqual('draft')
|
||||
expect(data.createAutosavePost._status).toStrictEqual('draft')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -831,7 +840,12 @@ describe('Versions', () => {
|
||||
createdAt
|
||||
}
|
||||
}`
|
||||
await graphQLClient.request(update)
|
||||
await restClient.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query: update }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
|
||||
// language=graphQL
|
||||
const query = `query {
|
||||
@@ -844,9 +858,16 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
collectionGraphQLVersionID = response.versionsAutosavePosts.docs[0].id
|
||||
collectionGraphQLVersionID = data.versionsAutosavePosts.docs[0].id
|
||||
})
|
||||
|
||||
it('should allow read of versions by version id', async () => {
|
||||
@@ -862,13 +883,18 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
const data = response.versionAutosavePost
|
||||
|
||||
expect(data.id).toBeDefined()
|
||||
expect(data.parent.id).toStrictEqual(collectionGraphQLPostID)
|
||||
expect(data.version.title).toStrictEqual(updatedTitle2)
|
||||
expect(data.versionAutosavePost.id).toBeDefined()
|
||||
expect(data.versionAutosavePost.parent.id).toStrictEqual(collectionGraphQLPostID)
|
||||
expect(data.versionAutosavePost.version.title).toStrictEqual(updatedTitle2)
|
||||
})
|
||||
|
||||
it('should allow read of versions by querying version content', async () => {
|
||||
@@ -887,10 +913,16 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
const data = response.versionsAutosavePosts
|
||||
const doc = data.docs[0]
|
||||
const doc = data.versionsAutosavePosts.docs[0]
|
||||
|
||||
expect(doc.id).toBeDefined()
|
||||
expect(doc.parent.id).toStrictEqual(collectionGraphQLPostID)
|
||||
@@ -911,7 +943,12 @@ describe('Versions', () => {
|
||||
createdAt
|
||||
}
|
||||
}`
|
||||
await graphQLClient.request(update)
|
||||
await restClient.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query: update }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
|
||||
// language=graphQL
|
||||
const query = `query {
|
||||
@@ -924,9 +961,16 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
collectionGraphQLVersionID = response.versionsAutosavePosts.docs[0].id
|
||||
collectionGraphQLVersionID = data.versionsAutosavePosts.docs[0].id
|
||||
})
|
||||
it('should allow a version to be restored', async () => {
|
||||
// Update it
|
||||
@@ -939,7 +983,12 @@ describe('Versions', () => {
|
||||
createdAt
|
||||
}
|
||||
}`
|
||||
await graphQLClient.request(update)
|
||||
await restClient.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query: update }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
|
||||
// restore a versionsPost
|
||||
const restore = `mutation {
|
||||
@@ -948,7 +997,12 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
await graphQLClient.request(restore)
|
||||
await restClient.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query: restore }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
|
||||
const query = `query {
|
||||
AutosavePost(id: ${formatGraphQLID(collectionGraphQLPostID)}) {
|
||||
@@ -956,9 +1010,16 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const data = response.AutosavePost
|
||||
expect(data.title).toStrictEqual(collectionGraphQLOriginalTitle)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
expect(data.AutosavePost.title).toStrictEqual(collectionGraphQLOriginalTitle)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -973,7 +1034,7 @@ describe('Versions', () => {
|
||||
slug: globalSlug,
|
||||
})
|
||||
|
||||
const updatedGlobal = await payload.updateGlobal({
|
||||
await payload.updateGlobal({
|
||||
data: {
|
||||
title: title2,
|
||||
},
|
||||
@@ -1179,7 +1240,12 @@ describe('Versions', () => {
|
||||
title
|
||||
}
|
||||
}`
|
||||
await graphQLClient.request(update)
|
||||
await restClient.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query: update }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
|
||||
// language=graphQL
|
||||
const query = `query {
|
||||
@@ -1193,9 +1259,16 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
globalGraphQLVersionID = response.versionsAutosaveGlobal.docs[0].id
|
||||
globalGraphQLVersionID = data.versionsAutosaveGlobal.docs[0].id
|
||||
})
|
||||
describe('Read', () => {
|
||||
it('should allow read of versions by version id', async () => {
|
||||
@@ -1209,12 +1282,17 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
const data = response.versionAutosaveGlobal
|
||||
|
||||
expect(data.id).toBeDefined()
|
||||
expect(data.version.title).toStrictEqual(globalGraphQLOriginalTitle)
|
||||
expect(data.versionAutosaveGlobal.id).toBeDefined()
|
||||
expect(data.versionAutosaveGlobal.version.title).toStrictEqual(globalGraphQLOriginalTitle)
|
||||
})
|
||||
|
||||
it('should allow read of versions by querying version content', async () => {
|
||||
@@ -1230,10 +1308,16 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
||||
const data = response.versionsAutosaveGlobal
|
||||
const doc = data.docs[0]
|
||||
const doc = data.versionsAutosaveGlobal.docs[0]
|
||||
|
||||
expect(doc.id).toBeDefined()
|
||||
expect(doc.version.title).toStrictEqual(globalGraphQLOriginalTitle)
|
||||
@@ -1249,7 +1333,12 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
await graphQLClient.request(restore)
|
||||
await restClient.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query: restore }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
|
||||
const query = `query {
|
||||
AutosaveGlobal {
|
||||
@@ -1257,9 +1346,15 @@ describe('Versions', () => {
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await graphQLClient.request(query)
|
||||
const data = response.AutosaveGlobal
|
||||
expect(data.title).toStrictEqual(globalGraphQLOriginalTitle)
|
||||
const { data } = await restClient
|
||||
.GRAPHQL_POST({
|
||||
body: JSON.stringify({ query }),
|
||||
headers: {
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
expect(data.AutosaveGlobal.title).toStrictEqual(globalGraphQLOriginalTitle)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"@payloadcms/translations/api": ["./packages/translations/src/all"],
|
||||
"@payloadcms/next/*": ["./packages/next/src/*"],
|
||||
"@payloadcms/graphql": ["./packages/graphql/src"],
|
||||
"payload-config": ["./test/uploads/config.ts"]
|
||||
"payload-config": ["./test/_community/config.ts"]
|
||||
}
|
||||
},
|
||||
"exclude": ["dist", "build", "temp", "node_modules"],
|
||||
|
||||
Reference in New Issue
Block a user