From b3e8ddf30218af1b550010c5189f274bff228a27 Mon Sep 17 00:00:00 2001 From: Patrik Date: Tue, 23 Jul 2024 09:03:00 -0400 Subject: [PATCH] fix(db-mongodb): removes precedence of regular chars over international chars in sort (#7294) ## Description V2 PR [here](https://github.com/payloadcms/payload/pull/6923) - [x] I have read and understand the [CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md) document in this repository. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## Checklist: - [x] I have added tests that prove my fix is effective or that my feature works - [x] Existing test suite passes locally with my changes --- packages/db-mongodb/src/find.ts | 4 ++ packages/db-mongodb/src/findGlobalVersions.ts | 4 ++ packages/db-mongodb/src/findVersions.ts | 4 ++ packages/db-mongodb/src/queryDrafts.ts | 4 ++ test/localization/config.ts | 11 ++++ test/localization/int.spec.ts | 66 +++++++++++++++++-- test/localization/payload-types.ts | 7 +- test/localization/shared.ts | 1 + 8 files changed, 94 insertions(+), 7 deletions(-) diff --git a/packages/db-mongodb/src/find.ts b/packages/db-mongodb/src/find.ts index 5c931327ff..71d6dd8a72 100644 --- a/packages/db-mongodb/src/find.ts +++ b/packages/db-mongodb/src/find.ts @@ -54,6 +54,10 @@ export const find: Find = async function find( useEstimatedCount, } + if (locale && locale !== 'all' && locale !== '*') { + paginationOptions.collation = { locale, strength: 1 } + } + if (!useEstimatedCount && Object.keys(query).length === 0 && this.disableIndexHints !== true) { // Improve the performance of the countDocuments query which is used if useEstimatedCount is set to false by adding // a hint. By default, if no hint is provided, MongoDB does not use an indexed field to count the returned documents, diff --git a/packages/db-mongodb/src/findGlobalVersions.ts b/packages/db-mongodb/src/findGlobalVersions.ts index bc15156339..7f0039faa1 100644 --- a/packages/db-mongodb/src/findGlobalVersions.ts +++ b/packages/db-mongodb/src/findGlobalVersions.ts @@ -72,6 +72,10 @@ export const findGlobalVersions: FindGlobalVersions = async function findGlobalV useEstimatedCount, } + if (locale && locale !== 'all' && locale !== '*') { + paginationOptions.collation = { locale, strength: 1 } + } + if (!useEstimatedCount && Object.keys(query).length === 0 && this.disableIndexHints !== true) { // Improve the performance of the countDocuments query which is used if useEstimatedCount is set to false by adding // a hint. By default, if no hint is provided, MongoDB does not use an indexed field to count the returned documents, diff --git a/packages/db-mongodb/src/findVersions.ts b/packages/db-mongodb/src/findVersions.ts index 48569a7d81..f8262306cf 100644 --- a/packages/db-mongodb/src/findVersions.ts +++ b/packages/db-mongodb/src/findVersions.ts @@ -69,6 +69,10 @@ export const findVersions: FindVersions = async function findVersions( useEstimatedCount, } + if (locale && locale !== 'all' && locale !== '*') { + paginationOptions.collation = { locale, strength: 1 } + } + if (!useEstimatedCount && Object.keys(query).length === 0 && this.disableIndexHints !== true) { // Improve the performance of the countDocuments query which is used if useEstimatedCount is set to false by adding // a hint. By default, if no hint is provided, MongoDB does not use an indexed field to count the returned documents, diff --git a/packages/db-mongodb/src/queryDrafts.ts b/packages/db-mongodb/src/queryDrafts.ts index ce884b5aa8..8a84fd9291 100644 --- a/packages/db-mongodb/src/queryDrafts.ts +++ b/packages/db-mongodb/src/queryDrafts.ts @@ -57,6 +57,10 @@ export const queryDrafts: QueryDrafts = async function queryDrafts( useEstimatedCount, } + if (locale && locale !== 'all' && locale !== '*') { + paginationOptions.collation = { locale, strength: 1 } + } + if ( !useEstimatedCount && Object.keys(versionQuery).length === 0 && diff --git a/test/localization/config.ts b/test/localization/config.ts index b9fa345cb8..4ee2777109 100644 --- a/test/localization/config.ts +++ b/test/localization/config.ts @@ -12,6 +12,7 @@ import { blocksWithLocalizedSameName, defaultLocale, englishTitle, + hungarianLocale, localizedPostsSlug, localizedSortSlug, portugueseLocale, @@ -70,6 +71,11 @@ export default buildConfigWithDefaults({ name: 'description', type: 'text', }, + { + name: 'localizedDescription', + localized: true, + type: 'text', + }, { name: 'localizedCheckbox', localized: true, @@ -310,6 +316,11 @@ export default buildConfigWithDefaults({ label: 'Arabic', rtl: true, }, + { + code: hungarianLocale, + label: 'Hungarian', + rtl: false, + }, ], }, onInit: async (payload) => { diff --git a/test/localization/int.spec.ts b/test/localization/int.spec.ts index 3ad158c9fd..4c2c51e033 100644 --- a/test/localization/int.spec.ts +++ b/test/localization/int.spec.ts @@ -12,6 +12,7 @@ import configPromise from './config.js' import { defaultLocale, englishTitle, + hungarianLocale, localizedPostsSlug, localizedSortSlug, portugueseLocale, @@ -37,7 +38,6 @@ describe('Localization', () => { beforeAll(async () => { ;({ payload, restClient } = await initPayloadInt(configPromise)) - // @ts-expect-error Force typing post1 = await payload.create({ collection, data: { @@ -45,7 +45,6 @@ describe('Localization', () => { }, }) - // @ts-expect-error Force typing postWithLocalizedData = await payload.create({ collection, data: { @@ -185,7 +184,6 @@ describe('Localization', () => { }, }) - // @ts-expect-error Force typing localizedPost = await payload.update({ id, collection, @@ -276,6 +274,67 @@ describe('Localization', () => { expect(result.docs.map(({ id }) => id)).toContain(localizedPost.id) }) + + if (['mongodb'].includes(process.env.PAYLOAD_DATABASE)) { + describe('Localized sorting', () => { + let localizedAccentPostOne: LocalizedPost + let localizedAccentPostTwo: LocalizedPost + beforeEach(async () => { + localizedAccentPostOne = await payload.create({ + collection, + data: { + title: 'non accent post', + localizedDescription: 'something', + }, + locale: englishLocale, + }) + + localizedAccentPostTwo = await payload.create({ + collection, + data: { + title: 'accent post', + localizedDescription: 'veterinarian', + }, + locale: englishLocale, + }) + + await payload.update({ + id: localizedAccentPostOne.id, + collection, + data: { + title: 'non accent post', + localizedDescription: 'valami', + }, + locale: hungarianLocale, + }) + + await payload.update({ + id: localizedAccentPostTwo.id, + collection, + data: { + title: 'accent post', + localizedDescription: 'állatorvos', + }, + locale: hungarianLocale, + }) + }) + + it('should sort alphabetically even with accented letters', async () => { + const sortByDescriptionQuery = await payload.find({ + collection, + sort: 'description', + where: { + title: { + like: 'accent', + }, + }, + locale: hungarianLocale, + }) + + expect(sortByDescriptionQuery.docs[0].id).toEqual(localizedAccentPostTwo.id) + }) + }) + } }) }) @@ -352,7 +411,6 @@ describe('Localization', () => { }, }) - // @ts-expect-error Force typing withRelationship = await payload.create({ collection: withLocalizedRelSlug, data: { diff --git a/test/localization/payload-types.ts b/test/localization/payload-types.ts index 75d92a55fa..6567651aa9 100644 --- a/test/localization/payload-types.ts +++ b/test/localization/payload-types.ts @@ -27,7 +27,7 @@ export interface Config { globals: { 'global-array': GlobalArray; }; - locale: 'en' | 'es' | 'pt' | 'ar'; + locale: 'en' | 'es' | 'hu' | 'pt' | 'ar'; user: User & { collection: 'users'; }; @@ -70,6 +70,7 @@ export interface User { export interface LocalizedPost { id: string; title?: string | null; + localizedDescription?: string | null; description?: string | null; localizedCheckbox?: boolean | null; children?: (string | LocalizedPost)[] | null; @@ -316,6 +317,6 @@ export interface Auth { declare module 'payload' { - // @ts-ignore + // @ts-ignore export interface GeneratedTypes extends Config {} -} \ No newline at end of file +} diff --git a/test/localization/shared.ts b/test/localization/shared.ts index dc7501efcc..fc54d02adc 100644 --- a/test/localization/shared.ts +++ b/test/localization/shared.ts @@ -8,6 +8,7 @@ export const relationSpanishTitle2 = `${relationSpanishTitle}2` export const defaultLocale = 'en' export const spanishLocale = 'es' export const portugueseLocale = 'pt' +export const hungarianLocale = 'hu' // Slugs export const localizedPostsSlug = 'localized-posts'