fix: enable relationship & upload field population in versions (#7533)

This commit is contained in:
Patrik
2024-08-06 12:09:53 -04:00
committed by GitHub
parent 1a0ef4824b
commit 9865ae998b
10 changed files with 354 additions and 111 deletions

View File

@@ -9,3 +9,4 @@ export const relationWithTitleSlug = 'relation-with-title'
export const relationUpdatedExternallySlug = 'relation-updated-externally'
export const collection1Slug = 'collection-1'
export const collection2Slug = 'collection-2'
export const versionedRelationshipFieldSlug = 'versioned-relationship-field'

View File

@@ -0,0 +1,21 @@
import type { CollectionConfig } from '../../../../packages/payload/src/collections/config/types'
import { collection1Slug, versionedRelationshipFieldSlug } from '../../collectionSlugs'
export const VersionedRelationshipFieldCollection: CollectionConfig = {
slug: versionedRelationshipFieldSlug,
fields: [
{
name: 'title',
type: 'text',
required: true,
},
{
name: 'relationshipField',
type: 'relationship',
relationTo: [collection1Slug],
hasMany: true,
},
],
versions: true,
}

View File

@@ -1,7 +1,6 @@
import type { CollectionConfig } from '../../packages/payload/src/collections/config/types'
import type { FilterOptionsProps } from '../../packages/payload/src/fields/config/types'
import { mapAsync } from '../../packages/payload/src/utilities/mapAsync'
import { buildConfigWithDefaults } from '../buildConfigWithDefaults'
import { devUser } from '../credentials'
import { PrePopulateFieldUI } from './PrePopulateFieldUI'
@@ -17,6 +16,7 @@ import {
relationWithTitleSlug,
slug,
} from './collectionSlugs'
import { VersionedRelationshipFieldCollection } from './collections/VersionedRelationshipField'
export interface FieldsRelationship {
createdAt: Date
@@ -301,6 +301,9 @@ export default buildConfigWithDefaults({
},
],
slug: collection1Slug,
admin: {
useAsTitle: 'name',
},
},
{
fields: [
@@ -311,7 +314,13 @@ export default buildConfigWithDefaults({
],
slug: collection2Slug,
},
VersionedRelationshipFieldCollection,
],
localization: {
locales: ['en'],
defaultLocale: 'en',
fallback: true,
},
onInit: async (payload) => {
await payload.create({
collection: 'users',
@@ -319,6 +328,8 @@ export default buildConfigWithDefaults({
email: devUser.email,
password: devUser.password,
},
depth: 0,
overrideAccess: true,
})
// Create docs to relate to
const { id: relationOneDocId } = await payload.create({
@@ -326,29 +337,35 @@ export default buildConfigWithDefaults({
data: {
name: relationOneSlug,
},
depth: 0,
overrideAccess: true,
})
const relationOneIDs: string[] = []
await mapAsync([...Array(11)], async () => {
for (let i = 0; i < 11; i++) {
const doc = await payload.create({
collection: relationOneSlug,
data: {
name: relationOneSlug,
},
depth: 0,
overrideAccess: true,
})
relationOneIDs.push(doc.id)
})
}
const relationTwoIDs: string[] = []
await mapAsync([...Array(11)], async () => {
for (let i = 0; i < 11; i++) {
const doc = await payload.create({
collection: relationTwoSlug,
data: {
name: relationTwoSlug,
},
depth: 0,
overrideAccess: true,
})
relationTwoIDs.push(doc.id)
})
}
// Existing relationships
const { id: restrictedDocId } = await payload.create({
@@ -356,13 +373,17 @@ export default buildConfigWithDefaults({
data: {
name: 'relation-restricted',
},
depth: 0,
overrideAccess: true,
})
const relationsWithTitle: string[] = []
await mapAsync(['relation-title', 'word boundary search'], async (title) => {
for (const title of ['relation-title', 'word boundary search']) {
const { id } = await payload.create({
collection: relationWithTitleSlug,
depth: 0,
overrideAccess: true,
data: {
name: title,
meta: {
@@ -371,19 +392,24 @@ export default buildConfigWithDefaults({
},
})
relationsWithTitle.push(id)
})
}
await payload.create({
collection: slug,
depth: 0,
overrideAccess: true,
data: {
relationship: relationOneDocId,
relationshipRestricted: restrictedDocId,
relationshipWithTitle: relationsWithTitle[0],
},
})
await mapAsync([...Array(11)], async () => {
for (let i = 0; i < 11; i++) {
await payload.create({
collection: slug,
depth: 0,
overrideAccess: true,
data: {
relationship: relationOneDocId,
relationshipHasManyMultiple: relationOneIDs.map((id) => ({
@@ -393,9 +419,9 @@ export default buildConfigWithDefaults({
relationshipRestricted: restrictedDocId,
},
})
})
}
await mapAsync([...Array(15)], async () => {
for (let i = 0; i < 15; i++) {
const relationOneID = relationOneIDs[Math.floor(Math.random() * 10)]
const relationTwoID = relationTwoIDs[Math.floor(Math.random() * 10)]
await payload.create({
@@ -408,20 +434,25 @@ export default buildConfigWithDefaults({
relationshipRestricted: restrictedDocId,
},
})
})
;[...Array(15)].forEach((_, i) => {
payload.create({
}
for (let i = 0; i < 15; i++) {
await payload.create({
collection: collection1Slug,
depth: 0,
overrideAccess: true,
data: {
name: `relationship-test ${i}`,
},
})
payload.create({
await payload.create({
collection: collection2Slug,
depth: 0,
overrideAccess: true,
data: {
name: `relationship-test ${i}`,
},
})
})
}
},
})

View File

@@ -0,0 +1,112 @@
import type { Collection1 } from './payload-types'
import payload from '../../packages/payload/src'
import { devUser } from '../credentials'
import { initPayloadTest } from '../helpers/configHelpers'
import { collection1Slug, versionedRelationshipFieldSlug } from './collectionSlugs'
let apiUrl: string
let jwt
const headers = {
'Content-Type': 'application/json',
}
const { email, password } = devUser
describe('Relationship Fields', () => {
beforeAll(async () => {
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } })
apiUrl = `${serverURL}/api`
const response = await fetch(`${apiUrl}/users/login`, {
body: JSON.stringify({
email,
password,
}),
headers,
method: 'post',
})
const data = await response.json()
jwt = data.token
})
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload)
}
})
describe('Versioned Relationship Field', () => {
let version2ID: string
const relatedDocName = 'Related Doc'
beforeAll(async () => {
const relatedDoc = await payload.create({
collection: collection1Slug,
data: {
name: relatedDocName,
},
})
const version1 = await payload.create({
collection: versionedRelationshipFieldSlug,
data: {
title: 'Version 1 Title',
relationshipField: {
value: relatedDoc.id,
relationTo: collection1Slug,
},
},
})
const version2 = await payload.update({
collection: versionedRelationshipFieldSlug,
id: version1.id,
data: {
title: 'Version 2 Title',
},
})
const versions = await payload.findVersions({
collection: versionedRelationshipFieldSlug,
where: {
parent: {
equals: version2.id,
},
},
sort: '-updatedAt',
limit: 1,
})
version2ID = versions.docs[0].id
})
it('should return the correct versioned relationship field via REST', async () => {
const version2Data = await fetch(
`${apiUrl}/${versionedRelationshipFieldSlug}/versions/${version2ID}?locale=all`,
{
method: 'GET',
headers: {
...headers,
Authorization: `JWT ${jwt}`,
},
},
).then((res) => res.json())
expect(version2Data.version.title).toEqual('Version 2 Title')
expect(version2Data.version.relationshipField[0].value.name).toEqual(relatedDocName)
})
it('should return the correct versioned relationship field via LocalAPI', async () => {
const version2Data = await payload.findVersionByID({
collection: versionedRelationshipFieldSlug,
id: version2ID,
locale: 'all',
})
expect(version2Data.version.title).toEqual('Version 2 Title')
expect((version2Data.version.relationshipField[0].value as Collection1).name).toEqual(
relatedDocName,
)
})
})
})

View File

@@ -16,11 +16,19 @@ export interface Config {
'relation-updated-externally': RelationUpdatedExternally
'collection-1': Collection1
'collection-2': Collection2
'versioned-relationship-field': VersionedRelationshipField
users: User
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
db: {
defaultIDType: string
}
globals: {}
locale: 'en'
user: User & {
collection: 'users'
}
}
export interface FieldsRelationship {
id: string
@@ -126,6 +134,22 @@ export interface Collection2 {
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "versioned-relationship-field".
*/
export interface VersionedRelationshipField {
id: string
title: string
relationshipField?:
| {
relationTo: 'collection-1'
value: string | Collection1
}[]
| null
updatedAt: string
createdAt: string
}
export interface User {
id: string
updatedAt: string