fix: handle multiple locales in relationship population (#1452)

This commit is contained in:
Dan Ribbens
2022-11-28 14:24:01 -05:00
committed by GitHub
parent e9d2163601
commit 04c689c5b0
4 changed files with 446 additions and 284 deletions

View File

@@ -1,6 +1,6 @@
import { buildConfig } from '../buildConfig';
import { devUser } from '../credentials';
import { LocalizedPost } from './payload-types';
import { LocalizedPost, RelationshipLocalized } from './payload-types';
import {
defaultLocale,
englishTitle,
@@ -21,7 +21,7 @@ export type LocalizedPostAllLocale = LocalizedPost & {
export const slug = 'localized-posts';
export const withLocalizedRelSlug = 'with-localized-relationship';
export const relationshipLocalizedSlug = 'relationship-localized';
export const withRequiredLocalizedFields = 'localized-required';
const openAccess = {
@@ -133,6 +133,37 @@ export default buildConfig({
},
],
},
{
slug: relationshipLocalizedSlug,
fields: [
{
name: 'relationship',
type: 'relationship',
relationTo: slug,
localized: true,
},
{
name: 'relationshipHasMany',
type: 'relationship',
relationTo: slug,
hasMany: true,
localized: true,
},
{
name: 'relationMultiRelationTo',
type: 'relationship',
relationTo: [slug, 'dummy'],
localized: true,
},
{
name: 'relationMultiRelationToHasMany',
type: 'relationship',
relationTo: [slug, 'dummy'],
hasMany: true,
localized: true,
},
],
},
{
slug: 'dummy',
access: openAccess,
@@ -210,10 +241,10 @@ export default buildConfig({
},
});
await payload.create({
await payload.create<RelationshipLocalized>({
collection: withLocalizedRelSlug,
data: {
localizedRelationship: localizedRelation.id,
relationship: localizedRelation.id,
localizedRelationHasManyField: [localizedRelation.id, localizedRelation2.id],
localizedRelationMultiRelationTo: { relationTo: collection, value: localizedRelation.id },
localizedRelationMultiRelationToHasMany: [
@@ -222,5 +253,18 @@ export default buildConfig({
],
},
});
await payload.create({
collection: relationshipLocalizedSlug,
locale: 'en',
data: {
relationship: localizedRelation.id,
relationshipHasMany: [localizedRelation.id, localizedRelation2.id],
relationMultiRelationTo: { relationTo: collection, value: localizedRelation.id },
relationMultiRelationToHasMany: [
{ relationTo: slug, value: localizedRelation.id },
{ relationTo: slug, value: localizedRelation2.id },
],
},
});
},
});

View File

@@ -2,9 +2,14 @@ import mongoose from 'mongoose';
import { GraphQLClient } from 'graphql-request';
import { initPayloadTest } from '../helpers/configHelpers';
import payload from '../../src';
import type { LocalizedPost, WithLocalizedRelationship, LocalizedRequired } from './payload-types';
import type {
LocalizedPost,
WithLocalizedRelationship,
LocalizedRequired,
RelationshipLocalized,
} from './payload-types';
import type { LocalizedPostAllLocale } from './config';
import config, { slug, withLocalizedRelSlug, withRequiredLocalizedFields } from './config';
import config, { relationshipLocalizedSlug, slug, withLocalizedRelSlug, withRequiredLocalizedFields } from './config';
import {
defaultLocale,
englishTitle,
@@ -191,271 +196,283 @@ describe('Localization', () => {
expect(result.docs[0].id).toEqual(localizedPost.id);
});
});
});
describe('Localized Relationship', () => {
let localizedRelation: LocalizedPost;
let localizedRelation2: LocalizedPost;
let withRelationship: WithLocalizedRelationship;
describe('Localized Relationship', () => {
let localizedRelation: LocalizedPost;
let localizedRelation2: LocalizedPost;
let withRelationship: WithLocalizedRelationship;
beforeAll(async () => {
localizedRelation = await createLocalizedPost({
title: {
[defaultLocale]: relationEnglishTitle,
[spanishLocale]: relationSpanishTitle,
},
});
localizedRelation2 = await createLocalizedPost({
title: {
[defaultLocale]: relationEnglishTitle2,
[spanishLocale]: relationSpanishTitle2,
},
});
beforeAll(async () => {
localizedRelation = await createLocalizedPost({
title: {
[defaultLocale]: relationEnglishTitle,
[spanishLocale]: relationSpanishTitle,
withRelationship = await payload.create({
collection: withLocalizedRelSlug,
data: {
localizedRelationship: localizedRelation.id,
localizedRelationHasManyField: [localizedRelation.id, localizedRelation2.id],
localizedRelationMultiRelationTo: { relationTo: slug, value: localizedRelation.id },
localizedRelationMultiRelationToHasMany: [
{ relationTo: slug, value: localizedRelation.id },
{ relationTo: slug, value: localizedRelation2.id },
],
},
});
});
describe('regular relationship', () => {
it('can query localized relationship', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationship.title': {
equals: localizedRelation.title,
},
});
localizedRelation2 = await createLocalizedPost({
title: {
[defaultLocale]: relationEnglishTitle2,
[spanishLocale]: relationSpanishTitle2,
},
});
},
});
withRelationship = await payload.create({
expect(result.docs[0].id).toEqual(withRelationship.id);
});
it('specific locale', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationship.title': {
equals: relationSpanishTitle,
},
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
});
it('all locales', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: 'all',
where: {
'localizedRelationship.title.es': {
equals: relationSpanishTitle,
},
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
});
it('populates relationships with all locales', async () => {
// the relationship fields themselves are localized on this collection
const result = await payload.find<RelationshipLocalized>({
collection: relationshipLocalizedSlug,
locale: 'all',
depth: 1,
});
expect((result.docs[0].relationship as any).en.id).toBeDefined();
expect((result.docs[0].relationshipHasMany as any).en[0].id).toBeDefined();
expect((result.docs[0].relationMultiRelationTo as any).en.value.id).toBeDefined();
expect((result.docs[0].relationMultiRelationToHasMany as any).en[0].value.id).toBeDefined();
});
});
describe('relationship - hasMany', () => {
it('default locale', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationHasManyField.title': {
equals: localizedRelation.title,
},
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
// Second relationship
const result2 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationHasManyField.title': {
equals: localizedRelation2.title,
},
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
});
it('specific locale', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationHasManyField.title': {
equals: relationSpanishTitle,
},
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
// Second relationship
const result2 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationHasManyField.title': {
equals: relationSpanishTitle2,
},
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
});
it('relationship population uses locale', async () => {
const result = await payload.findByID<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
depth: 1,
id: withRelationship.id,
locale: spanishLocale,
});
expect((result.localizedRelationship as LocalizedPost).title).toEqual(relationSpanishTitle);
});
it('all locales', async () => {
const queryRelation = (where: Where) => {
return payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
data: {
localizedRelationship: localizedRelation.id,
localizedRelationHasManyField: [localizedRelation.id, localizedRelation2.id],
localizedRelationMultiRelationTo: { relationTo: slug, value: localizedRelation.id },
localizedRelationMultiRelationToHasMany: [
{ relationTo: slug, value: localizedRelation.id },
{ relationTo: slug, value: localizedRelation2.id },
],
locale: 'all',
where,
});
};
const result = await queryRelation({
'localizedRelationHasManyField.title.en': {
equals: relationEnglishTitle,
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
// First relationship - spanish
const result2 = await queryRelation({
'localizedRelationHasManyField.title.es': {
equals: relationSpanishTitle,
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
// Second relationship - english
const result3 = await queryRelation({
'localizedRelationHasManyField.title.en': {
equals: relationEnglishTitle2,
},
});
expect(result3.docs[0].id).toEqual(withRelationship.id);
// Second relationship - spanish
const result4 = await queryRelation({
'localizedRelationHasManyField.title.es': {
equals: relationSpanishTitle2,
},
});
expect(result4.docs[0].id).toEqual(withRelationship.id);
});
});
describe('relationTo multi', () => {
it('by id', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationMultiRelationTo.value': {
equals: localizedRelation.id,
},
});
},
});
describe('regular relationship', () => {
it('can query localized relationship', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationship.title': {
equals: localizedRelation.title,
},
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
expect(result.docs[0].id).toEqual(withRelationship.id);
});
it('specific locale', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationship.title': {
equals: relationSpanishTitle,
},
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
});
it('all locales', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: 'all',
where: {
'localizedRelationship.title.es': {
equals: relationSpanishTitle,
},
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
});
// Second relationship
const result2 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationMultiRelationTo.value': {
equals: localizedRelation.id,
},
},
});
describe('relationship - hasMany', () => {
it('default locale', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationHasManyField.title': {
equals: localizedRelation.title,
},
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
});
});
expect(result.docs[0].id).toEqual(withRelationship.id);
// Second relationship
const result2 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationHasManyField.title': {
equals: localizedRelation2.title,
},
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
});
it('specific locale', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationHasManyField.title': {
equals: relationSpanishTitle,
},
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
// Second relationship
const result2 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationHasManyField.title': {
equals: relationSpanishTitle2,
},
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
});
it('relationship population uses locale', async () => {
const result = await payload.findByID<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
depth: 1,
id: withRelationship.id,
locale: spanishLocale,
});
expect((result.localizedRelationship as LocalizedPost).title).toEqual(relationSpanishTitle);
});
it('all locales', async () => {
const queryRelation = (where: Where) => {
return payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: 'all',
where,
});
};
const result = await queryRelation({
'localizedRelationHasManyField.title.en': {
equals: relationEnglishTitle,
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
// First relationship - spanish
const result2 = await queryRelation({
'localizedRelationHasManyField.title.es': {
equals: relationSpanishTitle,
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
// Second relationship - english
const result3 = await queryRelation({
'localizedRelationHasManyField.title.en': {
equals: relationEnglishTitle2,
},
});
expect(result3.docs[0].id).toEqual(withRelationship.id);
// Second relationship - spanish
const result4 = await queryRelation({
'localizedRelationHasManyField.title.es': {
equals: relationSpanishTitle2,
},
});
expect(result4.docs[0].id).toEqual(withRelationship.id);
});
describe('relationTo multi hasMany', () => {
it('by id', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationMultiRelationToHasMany.value': {
equals: localizedRelation.id,
},
},
});
describe('relationTo multi', () => {
it('by id', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationMultiRelationTo.value': {
equals: localizedRelation.id,
},
},
});
expect(result.docs[0].id).toEqual(withRelationship.id);
expect(result.docs[0].id).toEqual(withRelationship.id);
// Second relationship
const result2 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationMultiRelationTo.value': {
equals: localizedRelation.id,
},
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
});
// First relationship - spanish locale
const result2 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationMultiRelationToHasMany.value': {
equals: localizedRelation.id,
},
},
});
describe('relationTo multi hasMany', () => {
it('by id', async () => {
const result = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationMultiRelationToHasMany.value': {
equals: localizedRelation.id,
},
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
expect(result.docs[0].id).toEqual(withRelationship.id);
// First relationship - spanish locale
const result2 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
locale: spanishLocale,
where: {
'localizedRelationMultiRelationToHasMany.value': {
equals: localizedRelation.id,
},
},
});
expect(result2.docs[0].id).toEqual(withRelationship.id);
// Second relationship
const result3 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationMultiRelationToHasMany.value': {
equals: localizedRelation2.id,
},
},
});
expect(result3.docs[0].id).toEqual(withRelationship.id);
// Second relationship - spanish locale
const result4 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationMultiRelationToHasMany.value': {
equals: localizedRelation2.id,
},
},
});
expect(result4.docs[0].id).toEqual(withRelationship.id);
});
// Second relationship
const result3 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationMultiRelationToHasMany.value': {
equals: localizedRelation2.id,
},
},
});
expect(result3.docs[0].id).toEqual(withRelationship.id);
// Second relationship - spanish locale
const result4 = await payload.find<WithLocalizedRelationship>({
collection: withLocalizedRelSlug,
where: {
'localizedRelationMultiRelationToHasMany.value': {
equals: localizedRelation2.id,
},
},
});
expect(result4.docs[0].id).toEqual(withRelationship.id);
});
});
});

View File

@@ -63,7 +63,7 @@ export interface LocalizedRequired {
export interface WithLocalizedRelationship {
id: string;
localizedRelationship?: string | LocalizedPost;
localizedRelationHasManyField?: (string | LocalizedPost)[];
localizedRelationHasManyField?: string[] | LocalizedPost[];
localizedRelationMultiRelationTo?:
| {
value: string | LocalizedPost;
@@ -73,16 +73,27 @@ export interface WithLocalizedRelationship {
value: string | Dummy;
relationTo: 'dummy';
};
localizedRelationMultiRelationToHasMany?: (
| {
value: string | LocalizedPost;
relationTo: 'localized-posts';
}
| {
value: string | Dummy;
relationTo: 'dummy';
}
)[];
localizedRelationMultiRelationToHasMany?:
| (
| {
value: string;
relationTo: 'localized-posts';
}
| {
value: string;
relationTo: 'dummy';
}
)[]
| (
| {
value: LocalizedPost;
relationTo: 'localized-posts';
}
| {
value: Dummy;
relationTo: 'dummy';
}
)[];
createdAt: string;
updatedAt: string;
}
@@ -96,3 +107,44 @@ export interface Dummy {
createdAt: string;
updatedAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "relationship-localized".
*/
export interface RelationshipLocalized {
id: string;
relationship?: string | LocalizedPost;
relationshipHasMany?: string[] | LocalizedPost[];
relationMultiRelationTo?:
| {
value: string | LocalizedPost;
relationTo: 'localized-posts';
}
| {
value: string | Dummy;
relationTo: 'dummy';
};
relationMultiRelationToHasMany?:
| (
| {
value: string;
relationTo: 'localized-posts';
}
| {
value: string;
relationTo: 'dummy';
}
)[]
| (
| {
value: LocalizedPost;
relationTo: 'localized-posts';
}
| {
value: Dummy;
relationTo: 'dummy';
}
)[];
createdAt: string;
updatedAt: string;
}