test: cleans up fields-relationship test suite (#11003)
The `fields-relationship` test suite is disorganized to the point of being unusable. This makes it very difficult to digest at a high level and add new tests. This PR cleans it up in the following ways: - Moves collection configs to their own standalone files - Moves the seed function to its own file - Consolidates collection slugs in their own file - Uses generated types instead of defining them statically - Wraps the `filterOptions` e2e tests within a describe block Related, there are three distinct test suites where we manage relationships: `relationships`, `fields-relationship`, and `fields > relationships`. In the future we ought to consolidate at least two of these. IMO the `fields > relationship` suite should remain in place for general _component level_ UI tests for the field itself, whereas the other suite could run the integration tests and test the more complex UI patterns that exist outside of the field component.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { useField } from '@payloadcms/ui'
|
||||
import * as React from 'react'
|
||||
|
||||
import { collection1Slug } from '../collectionSlugs.js'
|
||||
import { collection1Slug } from '../slugs.js'
|
||||
|
||||
export const PrePopulateFieldUI: React.FC<{
|
||||
hasMany?: boolean
|
||||
|
||||
8
test/fields-relationship/baseFields.ts
Normal file
8
test/fields-relationship/baseFields.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
export const baseRelationshipFields: CollectionConfig['fields'] = [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
]
|
||||
16
test/fields-relationship/collections/Collection1/index.ts
Normal file
16
test/fields-relationship/collections/Collection1/index.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { collection1Slug } from '../../slugs.js'
|
||||
|
||||
export const Collection1: CollectionConfig = {
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
slug: collection1Slug,
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
}
|
||||
13
test/fields-relationship/collections/Collection2/index.ts
Normal file
13
test/fields-relationship/collections/Collection2/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { collection2Slug } from '../../slugs.js'
|
||||
|
||||
export const Collection2: CollectionConfig = {
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
slug: collection2Slug,
|
||||
}
|
||||
12
test/fields-relationship/collections/FilterFalse/index.ts
Normal file
12
test/fields-relationship/collections/FilterFalse/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { baseRelationshipFields } from '../../baseFields.js'
|
||||
import { relationFalseFilterOptionSlug } from '../../slugs.js'
|
||||
|
||||
export const RelationshipFilterFalse: CollectionConfig = {
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationFalseFilterOptionSlug,
|
||||
}
|
||||
12
test/fields-relationship/collections/FilterTrue/index.ts
Normal file
12
test/fields-relationship/collections/FilterTrue/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { baseRelationshipFields } from '../../baseFields.js'
|
||||
import { relationTrueFilterOptionSlug } from '../../slugs.js'
|
||||
|
||||
export const RelationshipFilterTrue: CollectionConfig = {
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationTrueFilterOptionSlug,
|
||||
}
|
||||
19
test/fields-relationship/collections/MixedMedia/index.ts
Normal file
19
test/fields-relationship/collections/MixedMedia/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import {
|
||||
mixedMediaCollectionSlug,
|
||||
podcastCollectionSlug,
|
||||
videoCollectionSlug,
|
||||
} from '../../slugs.js'
|
||||
|
||||
export const MixedMedia: CollectionConfig = {
|
||||
slug: mixedMediaCollectionSlug,
|
||||
fields: [
|
||||
{
|
||||
type: 'relationship',
|
||||
name: 'relatedMedia',
|
||||
relationTo: [videoCollectionSlug, podcastCollectionSlug],
|
||||
hasMany: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
21
test/fields-relationship/collections/Podcast/index.ts
Normal file
21
test/fields-relationship/collections/Podcast/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { podcastCollectionSlug } from '../../slugs.js'
|
||||
|
||||
export const Podcast: CollectionConfig = {
|
||||
slug: podcastCollectionSlug,
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
}
|
||||
9
test/fields-relationship/collections/Relation1/index.ts
Normal file
9
test/fields-relationship/collections/Relation1/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { baseRelationshipFields } from '../../baseFields.js'
|
||||
import { relationOneSlug } from '../../slugs.js'
|
||||
|
||||
export const Relation1: CollectionConfig = {
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationOneSlug,
|
||||
}
|
||||
9
test/fields-relationship/collections/Relation2/index.ts
Normal file
9
test/fields-relationship/collections/Relation2/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { baseRelationshipFields } from '../../baseFields.js'
|
||||
import { relationTwoSlug } from '../../slugs.js'
|
||||
|
||||
export const Relation2: CollectionConfig = {
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationTwoSlug,
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { baseRelationshipFields } from '../../baseFields.js'
|
||||
import { relationWithTitleSlug } from '../../slugs.js'
|
||||
|
||||
export const RelationWithTitle: CollectionConfig = {
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
fields: [
|
||||
...baseRelationshipFields,
|
||||
{
|
||||
name: 'meta',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
label: 'Meta Title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'group',
|
||||
},
|
||||
],
|
||||
slug: relationWithTitleSlug,
|
||||
}
|
||||
130
test/fields-relationship/collections/Relationship/index.ts
Normal file
130
test/fields-relationship/collections/Relationship/index.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import type { CollectionConfig, FilterOptionsProps } from 'payload'
|
||||
|
||||
import type { FieldsRelationship } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
relationFalseFilterOptionSlug,
|
||||
relationOneSlug,
|
||||
relationRestrictedSlug,
|
||||
relationTrueFilterOptionSlug,
|
||||
relationTwoSlug,
|
||||
relationWithTitleSlug,
|
||||
slug,
|
||||
} from '../../slugs.js'
|
||||
|
||||
export const Relationship: CollectionConfig = {
|
||||
admin: {
|
||||
defaultColumns: [
|
||||
'id',
|
||||
'relationship',
|
||||
'relationshipRestricted',
|
||||
'relationshipHasManyMultiple',
|
||||
'relationshipWithTitle',
|
||||
],
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'relationship',
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipHasMany',
|
||||
hasMany: true,
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipMultiple',
|
||||
relationTo: [relationOneSlug, relationTwoSlug],
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipHasManyMultiple',
|
||||
hasMany: true,
|
||||
relationTo: [relationOneSlug, relationTwoSlug],
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipRestricted',
|
||||
relationTo: relationRestrictedSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipWithTitle',
|
||||
relationTo: relationWithTitleSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipFilteredByID',
|
||||
filterOptions: (args: FilterOptionsProps<FieldsRelationship>) => {
|
||||
return {
|
||||
id: {
|
||||
equals: args.data.relationship,
|
||||
},
|
||||
}
|
||||
},
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
admin: {
|
||||
description:
|
||||
'This will filter the relationship options based on id, which is the same as the relationship field in this document',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'relationshipFilteredAsync',
|
||||
filterOptions: (args: FilterOptionsProps<FieldsRelationship>) => {
|
||||
return {
|
||||
id: {
|
||||
equals: args.data.relationship,
|
||||
},
|
||||
}
|
||||
},
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipManyFiltered',
|
||||
filterOptions: ({ relationTo, siblingData }) => {
|
||||
if (relationTo === relationOneSlug) {
|
||||
return { name: { equals: 'include' } }
|
||||
}
|
||||
|
||||
if (relationTo === relationTrueFilterOptionSlug) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (relationTo === relationFalseFilterOptionSlug) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (siblingData.filter) {
|
||||
return { name: { contains: siblingData.filter } }
|
||||
}
|
||||
|
||||
return { and: [] }
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: [
|
||||
relationWithTitleSlug,
|
||||
relationFalseFilterOptionSlug,
|
||||
relationTrueFilterOptionSlug,
|
||||
relationOneSlug,
|
||||
],
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'filter',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'relationshipReadOnly',
|
||||
admin: {
|
||||
readOnly: true,
|
||||
},
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
],
|
||||
slug,
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { collection1Slug } from '../../slugs.js'
|
||||
|
||||
export const Collection1: CollectionConfig = {
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
slug: collection1Slug,
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
}
|
||||
16
test/fields-relationship/collections/Restricted/index.ts
Normal file
16
test/fields-relationship/collections/Restricted/index.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { baseRelationshipFields } from '../../baseFields.js'
|
||||
import { relationRestrictedSlug } from '../../slugs.js'
|
||||
|
||||
export const Restricted: CollectionConfig = {
|
||||
access: {
|
||||
create: () => false,
|
||||
read: () => false,
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationRestrictedSlug,
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { collection1Slug, collection2Slug, relationUpdatedExternallySlug } from '../../slugs.js'
|
||||
|
||||
export const RelationshipUpdatedExternally: CollectionConfig = {
|
||||
fields: [
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'relationPrePopulate',
|
||||
admin: {
|
||||
width: '75%',
|
||||
},
|
||||
relationTo: collection1Slug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'prePopulate',
|
||||
admin: {
|
||||
components: {
|
||||
Field: {
|
||||
path: '/PrePopulateFieldUI/index.js#PrePopulateFieldUI',
|
||||
clientProps: {
|
||||
hasMany: false,
|
||||
hasMultipleRelations: false,
|
||||
targetFieldPath: 'relationPrePopulate',
|
||||
},
|
||||
},
|
||||
},
|
||||
width: '25%',
|
||||
},
|
||||
type: 'ui',
|
||||
},
|
||||
],
|
||||
type: 'row',
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'relationHasMany',
|
||||
admin: {
|
||||
width: '75%',
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: collection1Slug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'prePopulateRelationHasMany',
|
||||
admin: {
|
||||
components: {
|
||||
Field: {
|
||||
path: '/PrePopulateFieldUI/index.js#PrePopulateFieldUI',
|
||||
clientProps: {
|
||||
hasMultipleRelations: false,
|
||||
targetFieldPath: 'relationHasMany',
|
||||
},
|
||||
},
|
||||
},
|
||||
width: '25%',
|
||||
},
|
||||
type: 'ui',
|
||||
},
|
||||
],
|
||||
type: 'row',
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'relationToManyHasMany',
|
||||
admin: {
|
||||
width: '75%',
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: [collection1Slug, collection2Slug],
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'prePopulateToMany',
|
||||
admin: {
|
||||
components: {
|
||||
Field: {
|
||||
path: '/PrePopulateFieldUI/index.js#PrePopulateFieldUI',
|
||||
clientProps: {
|
||||
hasMultipleRelations: true,
|
||||
targetFieldPath: 'relationToManyHasMany',
|
||||
},
|
||||
},
|
||||
},
|
||||
width: '25%',
|
||||
},
|
||||
type: 'ui',
|
||||
},
|
||||
],
|
||||
type: 'row',
|
||||
},
|
||||
],
|
||||
slug: relationUpdatedExternallySlug,
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { collection1Slug, versionedRelationshipFieldSlug } from '../../collectionSlugs.js'
|
||||
import { collection1Slug, versionedRelationshipFieldSlug } from '../../slugs.js'
|
||||
|
||||
export const VersionedRelationshipFieldCollection: CollectionConfig = {
|
||||
export const Versions: CollectionConfig = {
|
||||
slug: versionedRelationshipFieldSlug,
|
||||
fields: [
|
||||
{
|
||||
21
test/fields-relationship/collections/Video/index.ts
Normal file
21
test/fields-relationship/collections/Video/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { videoCollectionSlug } from '../../slugs.js'
|
||||
|
||||
export const Video: CollectionConfig = {
|
||||
slug: videoCollectionSlug,
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -2,54 +2,23 @@ import { fileURLToPath } from 'node:url'
|
||||
import path from 'path'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
import type { CollectionConfig, FilterOptionsProps } from 'payload'
|
||||
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||
import { devUser } from '../credentials.js'
|
||||
import { VersionedRelationshipFieldCollection } from './collections/VersionedRelationshipField/index.js'
|
||||
import {
|
||||
collection1Slug,
|
||||
collection2Slug,
|
||||
mixedMediaCollectionSlug,
|
||||
podcastCollectionSlug,
|
||||
relationFalseFilterOptionSlug,
|
||||
relationOneSlug,
|
||||
relationRestrictedSlug,
|
||||
relationTrueFilterOptionSlug,
|
||||
relationTwoSlug,
|
||||
relationUpdatedExternallySlug,
|
||||
relationWithTitleSlug,
|
||||
slug,
|
||||
videoCollectionSlug,
|
||||
} from './collectionSlugs.js'
|
||||
|
||||
export interface FieldsRelationship {
|
||||
createdAt: Date
|
||||
id: string
|
||||
relationship: RelationOne
|
||||
relationshipHasMany: RelationOne[]
|
||||
relationshipHasManyMultiple: Array<{ relationTo: string; value: string } | RelationOne>
|
||||
relationshipMultiple: Array<RelationOne>
|
||||
relationshipRestricted: RelationRestricted
|
||||
relationshipWithTitle: RelationWithTitle
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
export interface RelationOne {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export type RelationTwo = RelationOne
|
||||
export type RelationRestricted = RelationOne
|
||||
export type RelationWithTitle = RelationOne
|
||||
|
||||
const baseRelationshipFields: CollectionConfig['fields'] = [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
]
|
||||
import { Collection1 } from './collections/Collection1/index.js'
|
||||
import { Collection2 } from './collections/Collection2/index.js'
|
||||
import { RelationshipFilterFalse } from './collections/FilterFalse/index.js'
|
||||
import { RelationshipFilterTrue } from './collections/FilterTrue/index.js'
|
||||
import { MixedMedia } from './collections/MixedMedia/index.js'
|
||||
import { Podcast } from './collections/Podcast/index.js'
|
||||
import { Relation1 } from './collections/Relation1/index.js'
|
||||
import { Relation2 } from './collections/Relation2/index.js'
|
||||
import { Relationship } from './collections/Relationship/index.js'
|
||||
import { RelationWithTitle } from './collections/RelationWithTitle/index.js'
|
||||
import { Restricted } from './collections/Restricted/index.js'
|
||||
import { RelationshipUpdatedExternally } from './collections/UpdatedExternally/index.js'
|
||||
import { Versions } from './collections/Versions/index.js'
|
||||
import { Video } from './collections/Video/index.js'
|
||||
import { clearAndSeedEverything } from './seed.js'
|
||||
|
||||
export default buildConfigWithDefaults({
|
||||
admin: {
|
||||
@@ -58,329 +27,20 @@ export default buildConfigWithDefaults({
|
||||
},
|
||||
},
|
||||
collections: [
|
||||
{
|
||||
admin: {
|
||||
defaultColumns: [
|
||||
'id',
|
||||
'relationship',
|
||||
'relationshipRestricted',
|
||||
'relationshipHasManyMultiple',
|
||||
'relationshipWithTitle',
|
||||
],
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'relationship',
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipHasMany',
|
||||
hasMany: true,
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipMultiple',
|
||||
relationTo: [relationOneSlug, relationTwoSlug],
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipHasManyMultiple',
|
||||
hasMany: true,
|
||||
relationTo: [relationOneSlug, relationTwoSlug],
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipRestricted',
|
||||
relationTo: relationRestrictedSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipWithTitle',
|
||||
relationTo: relationWithTitleSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipFiltered',
|
||||
filterOptions: (args: FilterOptionsProps<FieldsRelationship>) => {
|
||||
return {
|
||||
id: {
|
||||
equals: args.data.relationship,
|
||||
},
|
||||
}
|
||||
},
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipFilteredAsync',
|
||||
filterOptions: (args: FilterOptionsProps<FieldsRelationship>) => {
|
||||
return {
|
||||
id: {
|
||||
equals: args.data.relationship,
|
||||
},
|
||||
}
|
||||
},
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipManyFiltered',
|
||||
filterOptions: ({ relationTo, siblingData }: any) => {
|
||||
if (relationTo === relationOneSlug) {
|
||||
return { name: { equals: 'include' } }
|
||||
}
|
||||
if (relationTo === relationTrueFilterOptionSlug) {
|
||||
return true
|
||||
}
|
||||
if (relationTo === relationFalseFilterOptionSlug) {
|
||||
return false
|
||||
}
|
||||
if (siblingData.filter) {
|
||||
return { name: { contains: siblingData.filter } }
|
||||
}
|
||||
return { and: [] }
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: [
|
||||
relationWithTitleSlug,
|
||||
relationFalseFilterOptionSlug,
|
||||
relationTrueFilterOptionSlug,
|
||||
relationOneSlug,
|
||||
],
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'filter',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'relationshipReadOnly',
|
||||
admin: {
|
||||
readOnly: true,
|
||||
},
|
||||
relationTo: relationOneSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
],
|
||||
slug,
|
||||
},
|
||||
{
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationFalseFilterOptionSlug,
|
||||
},
|
||||
{
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationTrueFilterOptionSlug,
|
||||
},
|
||||
{
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationOneSlug,
|
||||
},
|
||||
{
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationTwoSlug,
|
||||
},
|
||||
{
|
||||
access: {
|
||||
create: () => false,
|
||||
read: () => false,
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
fields: baseRelationshipFields,
|
||||
slug: relationRestrictedSlug,
|
||||
},
|
||||
{
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
fields: [
|
||||
...baseRelationshipFields,
|
||||
{
|
||||
name: 'meta',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
label: 'Meta Title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'group',
|
||||
},
|
||||
],
|
||||
slug: relationWithTitleSlug,
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'relationPrePopulate',
|
||||
admin: {
|
||||
width: '75%',
|
||||
},
|
||||
relationTo: collection1Slug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'prePopulate',
|
||||
admin: {
|
||||
components: {
|
||||
Field: {
|
||||
path: '/PrePopulateFieldUI/index.js#PrePopulateFieldUI',
|
||||
clientProps: {
|
||||
hasMany: false,
|
||||
hasMultipleRelations: false,
|
||||
targetFieldPath: 'relationPrePopulate',
|
||||
},
|
||||
},
|
||||
},
|
||||
width: '25%',
|
||||
},
|
||||
type: 'ui',
|
||||
},
|
||||
],
|
||||
type: 'row',
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'relationHasMany',
|
||||
admin: {
|
||||
width: '75%',
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: collection1Slug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'prePopulateRelationHasMany',
|
||||
admin: {
|
||||
components: {
|
||||
Field: {
|
||||
path: '/PrePopulateFieldUI/index.js#PrePopulateFieldUI',
|
||||
clientProps: {
|
||||
hasMultipleRelations: false,
|
||||
targetFieldPath: 'relationHasMany',
|
||||
},
|
||||
},
|
||||
},
|
||||
width: '25%',
|
||||
},
|
||||
type: 'ui',
|
||||
},
|
||||
],
|
||||
type: 'row',
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'relationToManyHasMany',
|
||||
admin: {
|
||||
width: '75%',
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: [collection1Slug, collection2Slug],
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'prePopulateToMany',
|
||||
admin: {
|
||||
components: {
|
||||
Field: {
|
||||
path: '/PrePopulateFieldUI/index.js#PrePopulateFieldUI',
|
||||
clientProps: {
|
||||
hasMultipleRelations: true,
|
||||
targetFieldPath: 'relationToManyHasMany',
|
||||
},
|
||||
},
|
||||
},
|
||||
width: '25%',
|
||||
},
|
||||
type: 'ui',
|
||||
},
|
||||
],
|
||||
type: 'row',
|
||||
},
|
||||
],
|
||||
slug: relationUpdatedExternallySlug,
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
slug: collection1Slug,
|
||||
admin: {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
slug: collection2Slug,
|
||||
},
|
||||
{
|
||||
slug: videoCollectionSlug,
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: podcastCollectionSlug,
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: mixedMediaCollectionSlug,
|
||||
fields: [
|
||||
{
|
||||
type: 'relationship',
|
||||
name: 'relatedMedia',
|
||||
relationTo: [videoCollectionSlug, podcastCollectionSlug],
|
||||
hasMany: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
VersionedRelationshipFieldCollection,
|
||||
Relationship,
|
||||
RelationshipFilterFalse,
|
||||
RelationshipFilterTrue,
|
||||
Relation1,
|
||||
Relation2,
|
||||
Restricted,
|
||||
RelationWithTitle,
|
||||
RelationshipUpdatedExternally,
|
||||
Collection1,
|
||||
Collection2,
|
||||
Video,
|
||||
Podcast,
|
||||
MixedMedia,
|
||||
Versions,
|
||||
],
|
||||
localization: {
|
||||
locales: ['en'],
|
||||
@@ -388,156 +48,8 @@ export default buildConfigWithDefaults({
|
||||
fallback: true,
|
||||
},
|
||||
onInit: async (payload) => {
|
||||
await payload.create({
|
||||
collection: 'users',
|
||||
data: {
|
||||
email: devUser.email,
|
||||
password: devUser.password,
|
||||
},
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
// Create docs to relate to
|
||||
const { id: relationOneDocId } = await payload.create({
|
||||
collection: relationOneSlug,
|
||||
data: {
|
||||
name: relationOneSlug,
|
||||
},
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const relationOneIDs: string[] = []
|
||||
|
||||
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[] = []
|
||||
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({
|
||||
collection: relationRestrictedSlug,
|
||||
data: {
|
||||
name: 'relation-restricted',
|
||||
},
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const relationsWithTitle: string[] = []
|
||||
for (const title of ['relation-title', 'word boundary search']) {
|
||||
const { id } = await payload.create({
|
||||
collection: relationWithTitleSlug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
name: title,
|
||||
meta: {
|
||||
title,
|
||||
},
|
||||
},
|
||||
})
|
||||
relationsWithTitle.push(id)
|
||||
}
|
||||
|
||||
await payload.create({
|
||||
collection: slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
relationship: relationOneDocId,
|
||||
relationshipRestricted: restrictedDocId,
|
||||
relationshipWithTitle: relationsWithTitle[0],
|
||||
},
|
||||
})
|
||||
|
||||
for (let i = 0; i < 11; i++) {
|
||||
await payload.create({
|
||||
collection: slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
relationship: relationOneDocId,
|
||||
relationshipHasManyMultiple: relationOneIDs.map((id) => ({
|
||||
relationTo: relationOneSlug,
|
||||
value: id,
|
||||
})),
|
||||
relationshipRestricted: restrictedDocId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
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({
|
||||
collection: slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
relationship: relationOneDocId,
|
||||
relationshipHasMany: [relationOneID],
|
||||
relationshipHasManyMultiple: [{ relationTo: relationTwoSlug, value: relationTwoID }],
|
||||
relationshipReadOnly: relationOneID,
|
||||
relationshipRestricted: restrictedDocId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for (let i = 0; i < 15; i++) {
|
||||
await payload.create({
|
||||
collection: collection1Slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
name: `relationship-test ${i}`,
|
||||
},
|
||||
})
|
||||
await payload.create({
|
||||
collection: collection2Slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
name: `relationship-test ${i}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
await payload.create({
|
||||
collection: videoCollectionSlug,
|
||||
data: {
|
||||
id: i,
|
||||
title: `Video ${i}`,
|
||||
},
|
||||
})
|
||||
await payload.create({
|
||||
collection: podcastCollectionSlug,
|
||||
data: {
|
||||
id: i,
|
||||
title: `Podcast ${i}`,
|
||||
},
|
||||
})
|
||||
if (process.env.SEED_IN_CONFIG_ONINIT !== 'false') {
|
||||
await clearAndSeedEverything(payload)
|
||||
}
|
||||
},
|
||||
typescript: {
|
||||
|
||||
@@ -42,7 +42,7 @@ import {
|
||||
relationWithTitleSlug,
|
||||
slug,
|
||||
versionedRelationshipFieldSlug,
|
||||
} from './collectionSlugs.js'
|
||||
} from './slugs.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
@@ -305,97 +305,99 @@ describe('Relationship Field', () => {
|
||||
await saveDocAndAssert(page)
|
||||
}
|
||||
|
||||
// TODO: Flaky test. Fix this! (This is an actual issue not just an e2e flake)
|
||||
test('should allow dynamic filterOptions', async () => {
|
||||
await runFilterOptionsTest('relationshipFiltered', 'Relationship Filtered')
|
||||
})
|
||||
|
||||
// TODO: Flaky test. Fix this! (This is an actual issue not just an e2e flake)
|
||||
test('should allow dynamic async filterOptions', async () => {
|
||||
await runFilterOptionsTest('relationshipFilteredAsync', 'Relationship Filtered Async')
|
||||
})
|
||||
|
||||
test('should allow usage of relationTo in filterOptions', async () => {
|
||||
const { id: include } = (await payload.create({
|
||||
collection: relationOneSlug,
|
||||
data: {
|
||||
name: 'include',
|
||||
},
|
||||
})) as any
|
||||
const { id: exclude } = (await payload.create({
|
||||
collection: relationOneSlug,
|
||||
data: {
|
||||
name: 'exclude',
|
||||
},
|
||||
})) as any
|
||||
|
||||
await page.goto(url.create)
|
||||
|
||||
// select relationshipMany field that relies on siblingData field above
|
||||
await page.locator('#field-relationshipManyFiltered .rs__control').click()
|
||||
|
||||
const options = page.locator('#field-relationshipManyFiltered .rs__menu')
|
||||
await expect(options).toContainText(include)
|
||||
await expect(options).not.toContainText(exclude)
|
||||
})
|
||||
|
||||
test('should allow usage of siblingData in filterOptions', async () => {
|
||||
await payload.create({
|
||||
collection: relationWithTitleSlug,
|
||||
data: {
|
||||
name: 'exclude',
|
||||
},
|
||||
describe('filterOptions', () => {
|
||||
// TODO: Flaky test. Fix this! (This is an actual issue not just an e2e flake)
|
||||
test('should allow dynamic filterOptions', async () => {
|
||||
await runFilterOptionsTest('relationshipFilteredByID', 'Relationship Filtered')
|
||||
})
|
||||
|
||||
await page.goto(url.create)
|
||||
|
||||
// enter a filter for relationshipManyFiltered to use
|
||||
await page.locator('#field-filter').fill('include')
|
||||
|
||||
// select relationshipMany field that relies on siblingData field above
|
||||
await page.locator('#field-relationshipManyFiltered .rs__control').click()
|
||||
|
||||
const options = page.locator('#field-relationshipManyFiltered .rs__menu')
|
||||
await expect(options).not.toContainText('exclude')
|
||||
})
|
||||
|
||||
// TODO: Flaky test in CI - fix. https://github.com/payloadcms/payload/actions/runs/8559547748/job/23456806365
|
||||
test.skip('should not query for a relationship when filterOptions returns false', async () => {
|
||||
await payload.create({
|
||||
collection: relationFalseFilterOptionSlug,
|
||||
data: {
|
||||
name: 'whatever',
|
||||
},
|
||||
// TODO: Flaky test. Fix this! (This is an actual issue not just an e2e flake)
|
||||
test('should allow dynamic async filterOptions', async () => {
|
||||
await runFilterOptionsTest('relationshipFilteredAsync', 'Relationship Filtered Async')
|
||||
})
|
||||
|
||||
await page.goto(url.create)
|
||||
test('should allow usage of relationTo in filterOptions', async () => {
|
||||
const { id: include } = (await payload.create({
|
||||
collection: relationOneSlug,
|
||||
data: {
|
||||
name: 'include',
|
||||
},
|
||||
})) as any
|
||||
const { id: exclude } = (await payload.create({
|
||||
collection: relationOneSlug,
|
||||
data: {
|
||||
name: 'exclude',
|
||||
},
|
||||
})) as any
|
||||
|
||||
// select relationshipMany field that relies on siblingData field above
|
||||
await page.locator('#field-relationshipManyFiltered .rs__control').click()
|
||||
await page.goto(url.create)
|
||||
|
||||
const options = page.locator('#field-relationshipManyFiltered .rs__menu')
|
||||
await expect(options).toContainText('Relation With Titles')
|
||||
await expect(options).not.toContainText('whatever')
|
||||
})
|
||||
// select relationshipMany field that relies on siblingData field above
|
||||
await page.locator('#field-relationshipManyFiltered .rs__control').click()
|
||||
|
||||
// TODO: Flaky test in CI - fix.
|
||||
test('should show a relationship when filterOptions returns true', async () => {
|
||||
await payload.create({
|
||||
collection: relationTrueFilterOptionSlug,
|
||||
data: {
|
||||
name: 'truth',
|
||||
},
|
||||
const options = page.locator('#field-relationshipManyFiltered .rs__menu')
|
||||
await expect(options).toContainText(include)
|
||||
await expect(options).not.toContainText(exclude)
|
||||
})
|
||||
|
||||
await page.goto(url.create)
|
||||
// wait for relationship options to load
|
||||
const relationFilterOptionsReq = page.waitForResponse(/api\/relation-filter-true/)
|
||||
// select relationshipMany field that relies on siblingData field above
|
||||
await page.locator('#field-relationshipManyFiltered .rs__control').click()
|
||||
await relationFilterOptionsReq
|
||||
test('should allow usage of siblingData in filterOptions', async () => {
|
||||
await payload.create({
|
||||
collection: relationWithTitleSlug,
|
||||
data: {
|
||||
name: 'exclude',
|
||||
},
|
||||
})
|
||||
|
||||
const options = page.locator('#field-relationshipManyFiltered .rs__menu')
|
||||
await expect(options).toContainText('truth')
|
||||
await page.goto(url.create)
|
||||
|
||||
// enter a filter for relationshipManyFiltered to use
|
||||
await page.locator('#field-filter').fill('include')
|
||||
|
||||
// select relationshipMany field that relies on siblingData field above
|
||||
await page.locator('#field-relationshipManyFiltered .rs__control').click()
|
||||
|
||||
const options = page.locator('#field-relationshipManyFiltered .rs__menu')
|
||||
await expect(options).not.toContainText('exclude')
|
||||
})
|
||||
|
||||
// TODO: Flaky test in CI - fix. https://github.com/payloadcms/payload/actions/runs/8559547748/job/23456806365
|
||||
test.skip('should not query for a relationship when filterOptions returns false', async () => {
|
||||
await payload.create({
|
||||
collection: relationFalseFilterOptionSlug,
|
||||
data: {
|
||||
name: 'whatever',
|
||||
},
|
||||
})
|
||||
|
||||
await page.goto(url.create)
|
||||
|
||||
// select relationshipMany field that relies on siblingData field above
|
||||
await page.locator('#field-relationshipManyFiltered .rs__control').click()
|
||||
|
||||
const options = page.locator('#field-relationshipManyFiltered .rs__menu')
|
||||
await expect(options).toContainText('Relation With Titles')
|
||||
await expect(options).not.toContainText('whatever')
|
||||
})
|
||||
|
||||
// TODO: Flaky test in CI - fix.
|
||||
test('should show a relationship when filterOptions returns true', async () => {
|
||||
await payload.create({
|
||||
collection: relationTrueFilterOptionSlug,
|
||||
data: {
|
||||
name: 'truth',
|
||||
},
|
||||
})
|
||||
|
||||
await page.goto(url.create)
|
||||
// wait for relationship options to load
|
||||
const relationFilterOptionsReq = page.waitForResponse(/api\/relation-filter-true/)
|
||||
// select relationshipMany field that relies on siblingData field above
|
||||
await page.locator('#field-relationshipManyFiltered .rs__control').click()
|
||||
await relationFilterOptionsReq
|
||||
|
||||
const options = page.locator('#field-relationshipManyFiltered .rs__menu')
|
||||
await expect(options).toContainText('truth')
|
||||
})
|
||||
})
|
||||
|
||||
test('should allow docs with same ID but different collections to be selectable', async () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { Collection1 } from './payload-types.js'
|
||||
|
||||
import { devUser } from '../credentials.js'
|
||||
import { initPayloadInt } from '../helpers/initPayloadInt.js'
|
||||
import { collection1Slug, versionedRelationshipFieldSlug } from './collectionSlugs.js'
|
||||
import { collection1Slug, versionedRelationshipFieldSlug } from './slugs.js'
|
||||
|
||||
let payload: Payload
|
||||
let restClient: NextRESTClient
|
||||
|
||||
@@ -114,7 +114,14 @@ export interface FieldsRelationship {
|
||||
| null;
|
||||
relationshipRestricted?: (string | null) | RelationRestricted;
|
||||
relationshipWithTitle?: (string | null) | RelationWithTitle;
|
||||
relationshipFiltered?: (string | null) | RelationOne;
|
||||
/**
|
||||
* This will filter the relationship options based on id, which is the same as the relationship field in this document
|
||||
*/
|
||||
relationshipFilteredByID?: (string | null) | RelationOne;
|
||||
/**
|
||||
* This will filter the relationship options if the filter field in this document is set to "Include me"
|
||||
*/
|
||||
relationshipFilteredByField?: (string | null) | RelationOne;
|
||||
relationshipFilteredAsync?: (string | null) | RelationOne;
|
||||
relationshipManyFiltered?:
|
||||
| (
|
||||
@@ -442,7 +449,8 @@ export interface FieldsRelationshipSelect<T extends boolean = true> {
|
||||
relationshipHasManyMultiple?: T;
|
||||
relationshipRestricted?: T;
|
||||
relationshipWithTitle?: T;
|
||||
relationshipFiltered?: T;
|
||||
relationshipFilteredByID?: T;
|
||||
relationshipFilteredByField?: T;
|
||||
relationshipFilteredAsync?: T;
|
||||
relationshipManyFiltered?: T;
|
||||
filter?: T;
|
||||
|
||||
191
test/fields-relationship/seed.ts
Normal file
191
test/fields-relationship/seed.ts
Normal file
@@ -0,0 +1,191 @@
|
||||
import type { Payload } from 'payload'
|
||||
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import { devUser } from '../credentials.js'
|
||||
import { seedDB } from '../helpers/seed.js'
|
||||
import {
|
||||
collection1Slug,
|
||||
collection2Slug,
|
||||
collectionSlugs,
|
||||
podcastCollectionSlug,
|
||||
relationOneSlug,
|
||||
relationRestrictedSlug,
|
||||
relationTwoSlug,
|
||||
relationWithTitleSlug,
|
||||
slug,
|
||||
videoCollectionSlug,
|
||||
} from './slugs.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
export const seed = async (_payload: Payload) => {
|
||||
await _payload.create({
|
||||
collection: 'users',
|
||||
data: {
|
||||
email: devUser.email,
|
||||
password: devUser.password,
|
||||
},
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
// Create docs to relate to
|
||||
const { id: relationOneDocId } = await _payload.create({
|
||||
collection: relationOneSlug,
|
||||
data: {
|
||||
name: relationOneSlug,
|
||||
},
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const relationOneIDs: string[] = []
|
||||
|
||||
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[] = []
|
||||
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({
|
||||
collection: relationRestrictedSlug,
|
||||
data: {
|
||||
name: 'relation-restricted',
|
||||
},
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
})
|
||||
|
||||
const relationsWithTitle: string[] = []
|
||||
|
||||
for (const title of ['relation-title', 'word boundary search']) {
|
||||
const { id } = await _payload.create({
|
||||
collection: relationWithTitleSlug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
name: title,
|
||||
meta: {
|
||||
title,
|
||||
},
|
||||
},
|
||||
})
|
||||
relationsWithTitle.push(id)
|
||||
}
|
||||
|
||||
await _payload.create({
|
||||
collection: slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
relationship: relationOneDocId,
|
||||
relationshipRestricted: restrictedDocId,
|
||||
relationshipWithTitle: relationsWithTitle[0],
|
||||
},
|
||||
})
|
||||
|
||||
for (let i = 0; i < 11; i++) {
|
||||
await _payload.create({
|
||||
collection: slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
relationship: relationOneDocId,
|
||||
relationshipHasManyMultiple: relationOneIDs.map((id) => ({
|
||||
relationTo: relationOneSlug,
|
||||
value: id,
|
||||
})),
|
||||
relationshipRestricted: restrictedDocId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
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({
|
||||
collection: slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
relationship: relationOneDocId,
|
||||
relationshipHasMany: [relationOneID],
|
||||
relationshipHasManyMultiple: [{ relationTo: relationTwoSlug, value: relationTwoID }],
|
||||
relationshipReadOnly: relationOneID,
|
||||
relationshipRestricted: restrictedDocId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for (let i = 0; i < 15; i++) {
|
||||
await _payload.create({
|
||||
collection: collection1Slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
name: `relationship-test ${i}`,
|
||||
},
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: collection2Slug,
|
||||
depth: 0,
|
||||
overrideAccess: true,
|
||||
data: {
|
||||
name: `relationship-test ${i}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
await _payload.create({
|
||||
collection: videoCollectionSlug,
|
||||
data: {
|
||||
id: i,
|
||||
title: `Video ${i}`,
|
||||
},
|
||||
})
|
||||
|
||||
await _payload.create({
|
||||
collection: podcastCollectionSlug,
|
||||
data: {
|
||||
id: i,
|
||||
title: `Podcast ${i}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export async function clearAndSeedEverything(_payload: Payload) {
|
||||
return await seedDB({
|
||||
_payload,
|
||||
collectionSlugs,
|
||||
seedFunction: seed,
|
||||
snapshotKey: 'fieldsTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
}
|
||||
@@ -13,3 +13,19 @@ export const videoCollectionSlug = 'videos'
|
||||
export const podcastCollectionSlug = 'podcasts'
|
||||
export const mixedMediaCollectionSlug = 'mixed-media'
|
||||
export const versionedRelationshipFieldSlug = 'versioned-relationship-field'
|
||||
|
||||
export const collectionSlugs = [
|
||||
relationOneSlug,
|
||||
relationTrueFilterOptionSlug,
|
||||
relationFalseFilterOptionSlug,
|
||||
relationTwoSlug,
|
||||
relationRestrictedSlug,
|
||||
relationWithTitleSlug,
|
||||
relationUpdatedExternallySlug,
|
||||
collection1Slug,
|
||||
collection2Slug,
|
||||
videoCollectionSlug,
|
||||
podcastCollectionSlug,
|
||||
mixedMediaCollectionSlug,
|
||||
versionedRelationshipFieldSlug,
|
||||
]
|
||||
Reference in New Issue
Block a user