Merge branch 'main' into feat/folders
This commit is contained in:
@@ -460,6 +460,7 @@ export default buildConfigWithDefaults({
|
||||
{
|
||||
slug: 'virtual-relations',
|
||||
admin: { useAsTitle: 'postTitle' },
|
||||
access: { read: () => true },
|
||||
fields: [
|
||||
{
|
||||
name: 'postTitle',
|
||||
|
||||
@@ -2151,8 +2151,6 @@ describe('database', () => {
|
||||
expect(descDocs[0]?.id).toBe(doc_2.id)
|
||||
})
|
||||
|
||||
it.todo('should allow to sort by a virtual field with reference')
|
||||
|
||||
it('should allow virtual field 2x deep', async () => {
|
||||
const category = await payload.create({
|
||||
collection: 'categories',
|
||||
@@ -2213,6 +2211,77 @@ describe('database', () => {
|
||||
})
|
||||
expect(globalData.postTitle).toBe('post')
|
||||
})
|
||||
|
||||
it('should allow to sort by a virtual field with a refence, Local / GraphQL', async () => {
|
||||
const post_1 = await payload.create({ collection: 'posts', data: { title: 'A' } })
|
||||
const post_2 = await payload.create({ collection: 'posts', data: { title: 'B' } })
|
||||
const doc_1 = await payload.create({
|
||||
collection: 'virtual-relations',
|
||||
data: { post: post_1 },
|
||||
})
|
||||
const doc_2 = await payload.create({
|
||||
collection: 'virtual-relations',
|
||||
data: { post: post_2 },
|
||||
})
|
||||
|
||||
const queryDesc = `query {
|
||||
VirtualRelations(
|
||||
where: {OR: [{ id: { equals: ${JSON.stringify(doc_1.id)} } }, { id: { equals: ${JSON.stringify(doc_2.id)} } }],
|
||||
}, sort: "-postTitle") {
|
||||
docs {
|
||||
id
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
const {
|
||||
data: {
|
||||
VirtualRelations: { docs: graphqlDesc },
|
||||
},
|
||||
} = await restClient
|
||||
.GRAPHQL_POST({ body: JSON.stringify({ query: queryDesc }) })
|
||||
.then((res) => res.json())
|
||||
|
||||
const { docs: localDesc } = await payload.find({
|
||||
collection: 'virtual-relations',
|
||||
sort: '-postTitle',
|
||||
where: { id: { in: [doc_1.id, doc_2.id] } },
|
||||
})
|
||||
|
||||
expect(graphqlDesc[0].id).toBe(doc_2.id)
|
||||
expect(graphqlDesc[1].id).toBe(doc_1.id)
|
||||
expect(localDesc[0].id).toBe(doc_2.id)
|
||||
expect(localDesc[1].id).toBe(doc_1.id)
|
||||
|
||||
const queryAsc = `query {
|
||||
VirtualRelations(
|
||||
where: {OR: [{ id: { equals: ${JSON.stringify(doc_1.id)} } }, { id: { equals: ${JSON.stringify(doc_2.id)} } }],
|
||||
}, sort: "postTitle") {
|
||||
docs {
|
||||
id
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
const {
|
||||
data: {
|
||||
VirtualRelations: { docs: graphqlAsc },
|
||||
},
|
||||
} = await restClient
|
||||
.GRAPHQL_POST({ body: JSON.stringify({ query: queryAsc }) })
|
||||
.then((res) => res.json())
|
||||
|
||||
const { docs: localAsc } = await payload.find({
|
||||
collection: 'virtual-relations',
|
||||
sort: 'postTitle',
|
||||
where: { id: { in: [doc_1.id, doc_2.id] } },
|
||||
})
|
||||
|
||||
expect(graphqlAsc[1].id).toBe(doc_2.id)
|
||||
expect(graphqlAsc[0].id).toBe(doc_1.id)
|
||||
expect(localAsc[1].id).toBe(doc_2.id)
|
||||
expect(localAsc[0].id).toBe(doc_1.id)
|
||||
})
|
||||
})
|
||||
|
||||
it('should convert numbers to text', async () => {
|
||||
|
||||
@@ -5,8 +5,8 @@ import { pagesSlug } from '../shared.js'
|
||||
export const Pages: CollectionConfig = {
|
||||
slug: pagesSlug,
|
||||
labels: {
|
||||
singular: 'Page',
|
||||
plural: 'Pages',
|
||||
singular: { en: 'Page', es: 'Página' },
|
||||
plural: { en: 'Pages', es: 'Páginas' },
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
|
||||
@@ -3,12 +3,13 @@ import path from 'path'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
import { importExportPlugin } from '@payloadcms/plugin-import-export'
|
||||
import { en } from '@payloadcms/translations/languages/en'
|
||||
import { es } from '@payloadcms/translations/languages/es'
|
||||
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||
import { Pages } from './collections/Pages.js'
|
||||
import { Users } from './collections/Users.js'
|
||||
import { seed } from './seed/index.js'
|
||||
|
||||
export default buildConfigWithDefaults({
|
||||
admin: {
|
||||
importMap: {
|
||||
@@ -21,6 +22,13 @@ export default buildConfigWithDefaults({
|
||||
fallback: true,
|
||||
locales: ['en', 'es', 'de'],
|
||||
},
|
||||
i18n: {
|
||||
supportedLanguages: {
|
||||
en,
|
||||
es,
|
||||
},
|
||||
fallbackLanguage: 'en',
|
||||
},
|
||||
onInit: async (payload) => {
|
||||
await seed(payload)
|
||||
},
|
||||
|
||||
@@ -41,7 +41,7 @@ export default buildConfigWithDefaults({
|
||||
isGlobal: true,
|
||||
},
|
||||
},
|
||||
tenantSelectorLabel: 'Site',
|
||||
tenantSelectorLabel: { en: 'Site', es: 'Site in es' },
|
||||
}),
|
||||
],
|
||||
typescript: {
|
||||
|
||||
17
test/sort/collections/NonUniqueSort/index.ts
Normal file
17
test/sort/collections/NonUniqueSort/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
export const nonUniqueSortSlug = 'non-unique-sort'
|
||||
|
||||
export const NonUniqueSortCollection: CollectionConfig = {
|
||||
slug: nonUniqueSortSlug,
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'order',
|
||||
type: 'number',
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -2,12 +2,14 @@ import type { CollectionSlug, Payload } from 'payload'
|
||||
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import path from 'path'
|
||||
import { wait } from 'payload/shared'
|
||||
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||
import { devUser } from '../credentials.js'
|
||||
import { DefaultSortCollection } from './collections/DefaultSort/index.js'
|
||||
import { DraftsCollection } from './collections/Drafts/index.js'
|
||||
import { LocalizedCollection } from './collections/Localized/index.js'
|
||||
import { NonUniqueSortCollection, nonUniqueSortSlug } from './collections/NonUniqueSort/index.js'
|
||||
import { OrderableCollection } from './collections/Orderable/index.js'
|
||||
import { OrderableJoinCollection } from './collections/OrderableJoin/index.js'
|
||||
import { PostsCollection } from './collections/Posts/index.js'
|
||||
@@ -19,6 +21,7 @@ export default buildConfigWithDefaults({
|
||||
PostsCollection,
|
||||
DraftsCollection,
|
||||
DefaultSortCollection,
|
||||
NonUniqueSortCollection,
|
||||
LocalizedCollection,
|
||||
OrderableCollection,
|
||||
OrderableJoinCollection,
|
||||
@@ -87,6 +90,28 @@ async function seedSortable(payload: Payload) {
|
||||
|
||||
await payload.create({ collection: 'orderable-join', data: { title: 'Join B' } })
|
||||
|
||||
// Create 10 items to be sorted by non-unique field
|
||||
for (const i of Array.from({ length: 10 }, (_, index) => index)) {
|
||||
let order = 1
|
||||
|
||||
if (i > 3) {
|
||||
order = 2
|
||||
} else if (i > 6) {
|
||||
order = 3
|
||||
}
|
||||
|
||||
await payload.create({
|
||||
collection: nonUniqueSortSlug,
|
||||
data: {
|
||||
title: `Post ${i}`,
|
||||
order,
|
||||
},
|
||||
})
|
||||
|
||||
// Wait 2 seconds to guarantee that the createdAt date is different
|
||||
// await wait(2000)
|
||||
}
|
||||
|
||||
return new Response(JSON.stringify({ success: true }), {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
status: 200,
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { Draft, Orderable, OrderableJoin } from './payload-types.js'
|
||||
|
||||
import { initPayloadInt } from '../helpers/initPayloadInt.js'
|
||||
import { draftsSlug } from './collections/Drafts/index.js'
|
||||
import { nonUniqueSortSlug } from './collections/NonUniqueSort/index.js'
|
||||
import { orderableSlug } from './collections/Orderable/index.js'
|
||||
import { orderableJoinSlug } from './collections/OrderableJoin/index.js'
|
||||
|
||||
@@ -133,6 +134,154 @@ describe('Sort', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('Non-unique sorting', () => {
|
||||
// There are situations where the sort order is not guaranteed to be consistent, such as when sorting by a non-unique field in MongoDB which does not keep an internal order of items
|
||||
// As a result, every time you fetch, including fetching specific pages, the order of items may change and appear as duplicated to some users.
|
||||
it('should always be consistent when sorting', async () => {
|
||||
const posts = await payload.find({
|
||||
collection: nonUniqueSortSlug,
|
||||
sort: 'order',
|
||||
})
|
||||
|
||||
const initialMap = posts.docs.map((post) => post.title)
|
||||
|
||||
const dataFetches = await Promise.all(
|
||||
Array.from({ length: 3 }).map(() =>
|
||||
payload.find({
|
||||
collection: nonUniqueSortSlug,
|
||||
sort: 'order',
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
const [fetch1, fetch2, fetch3] = dataFetches.map((fetch) =>
|
||||
fetch.docs.map((post) => post.title),
|
||||
)
|
||||
|
||||
expect(fetch1).toEqual(initialMap)
|
||||
|
||||
expect(fetch2).toEqual(initialMap)
|
||||
|
||||
expect(fetch3).toEqual(initialMap)
|
||||
})
|
||||
|
||||
it('should always be consistent when sorting - with limited pages', async () => {
|
||||
const posts = await payload.find({
|
||||
collection: nonUniqueSortSlug,
|
||||
sort: 'order',
|
||||
limit: 5,
|
||||
page: 2,
|
||||
})
|
||||
|
||||
const initialMap = posts.docs.map((post) => post.title)
|
||||
|
||||
const dataFetches = await Promise.all(
|
||||
Array.from({ length: 3 }).map(() =>
|
||||
payload.find({
|
||||
collection: nonUniqueSortSlug,
|
||||
sort: 'order',
|
||||
limit: 5,
|
||||
page: 2,
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
const [fetch1, fetch2, fetch3] = dataFetches.map((fetch) =>
|
||||
fetch.docs.map((post) => post.title),
|
||||
)
|
||||
|
||||
expect(fetch1).toEqual(initialMap)
|
||||
|
||||
expect(fetch2).toEqual(initialMap)
|
||||
|
||||
expect(fetch3).toEqual(initialMap)
|
||||
})
|
||||
|
||||
it('should sort by createdAt as fallback', async () => {
|
||||
// This is the (reverse - newest first) order that the posts are created in so this should remain consistent as the sort should fallback to '-createdAt'
|
||||
const postsInOrder = ['Post 9', 'Post 8', 'Post 7', 'Post 6']
|
||||
|
||||
const dataFetches = await Promise.all(
|
||||
Array.from({ length: 3 }).map(() =>
|
||||
payload.find({
|
||||
collection: nonUniqueSortSlug,
|
||||
sort: 'order',
|
||||
page: 2,
|
||||
limit: 4,
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
const [fetch1, fetch2, fetch3] = dataFetches.map((fetch) =>
|
||||
fetch.docs.map((post) => post.title),
|
||||
)
|
||||
|
||||
console.log({ fetch1, fetch2, fetch3 })
|
||||
|
||||
expect(fetch1).toEqual(postsInOrder)
|
||||
|
||||
expect(fetch2).toEqual(postsInOrder)
|
||||
|
||||
expect(fetch3).toEqual(postsInOrder)
|
||||
})
|
||||
|
||||
it('should always be consistent without sort params in the query', async () => {
|
||||
const posts = await payload.find({
|
||||
collection: nonUniqueSortSlug,
|
||||
})
|
||||
|
||||
const initialMap = posts.docs.map((post) => post.title)
|
||||
|
||||
const dataFetches = await Promise.all(
|
||||
Array.from({ length: 3 }).map(() =>
|
||||
payload.find({
|
||||
collection: nonUniqueSortSlug,
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
const [fetch1, fetch2, fetch3] = dataFetches.map((fetch) =>
|
||||
fetch.docs.map((post) => post.title),
|
||||
)
|
||||
|
||||
expect(fetch1).toEqual(initialMap)
|
||||
|
||||
expect(fetch2).toEqual(initialMap)
|
||||
|
||||
expect(fetch3).toEqual(initialMap)
|
||||
})
|
||||
|
||||
it('should always be consistent without sort params in the query - with limited pages', async () => {
|
||||
const posts = await payload.find({
|
||||
collection: nonUniqueSortSlug,
|
||||
page: 2,
|
||||
limit: 4,
|
||||
})
|
||||
|
||||
const initialMap = posts.docs.map((post) => post.title)
|
||||
|
||||
const dataFetches = await Promise.all(
|
||||
Array.from({ length: 3 }).map(() =>
|
||||
payload.find({
|
||||
collection: nonUniqueSortSlug,
|
||||
page: 2,
|
||||
limit: 4,
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
const [fetch1, fetch2, fetch3] = dataFetches.map((fetch) =>
|
||||
fetch.docs.map((post) => post.title),
|
||||
)
|
||||
|
||||
expect(fetch1).toEqual(initialMap)
|
||||
|
||||
expect(fetch2).toEqual(initialMap)
|
||||
|
||||
expect(fetch3).toEqual(initialMap)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Sort by multiple fields', () => {
|
||||
it('should sort posts by multiple fields', async () => {
|
||||
const posts = await payload.find({
|
||||
|
||||
@@ -70,6 +70,7 @@ export interface Config {
|
||||
posts: Post;
|
||||
drafts: Draft;
|
||||
'default-sort': DefaultSort;
|
||||
'non-unique-sort': NonUniqueSort;
|
||||
localized: Localized;
|
||||
orderable: Orderable;
|
||||
'orderable-join': OrderableJoin;
|
||||
@@ -89,6 +90,7 @@ export interface Config {
|
||||
posts: PostsSelect<false> | PostsSelect<true>;
|
||||
drafts: DraftsSelect<false> | DraftsSelect<true>;
|
||||
'default-sort': DefaultSortSelect<false> | DefaultSortSelect<true>;
|
||||
'non-unique-sort': NonUniqueSortSelect<false> | NonUniqueSortSelect<true>;
|
||||
localized: LocalizedSelect<false> | LocalizedSelect<true>;
|
||||
orderable: OrderableSelect<false> | OrderableSelect<true>;
|
||||
'orderable-join': OrderableJoinSelect<false> | OrderableJoinSelect<true>;
|
||||
@@ -98,7 +100,7 @@ export interface Config {
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
defaultIDType: number;
|
||||
};
|
||||
globals: {};
|
||||
globalsSelect: {};
|
||||
@@ -134,7 +136,7 @@ export interface UserAuthOperations {
|
||||
* via the `definition` "posts".
|
||||
*/
|
||||
export interface Post {
|
||||
id: string;
|
||||
id: number;
|
||||
text?: string | null;
|
||||
number?: number | null;
|
||||
number2?: number | null;
|
||||
@@ -164,18 +166,29 @@ export interface Draft {
|
||||
* via the `definition` "default-sort".
|
||||
*/
|
||||
export interface DefaultSort {
|
||||
id: string;
|
||||
id: number;
|
||||
text?: string | null;
|
||||
number?: number | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "non-unique-sort".
|
||||
*/
|
||||
export interface NonUniqueSort {
|
||||
id: number;
|
||||
title?: string | null;
|
||||
order?: number | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "localized".
|
||||
*/
|
||||
export interface Localized {
|
||||
id: string;
|
||||
id: number;
|
||||
text?: string | null;
|
||||
number?: number | null;
|
||||
number2?: number | null;
|
||||
@@ -196,7 +209,7 @@ export interface Orderable {
|
||||
_orderable_orderableJoinField1_order?: string | null;
|
||||
_order?: string | null;
|
||||
title?: string | null;
|
||||
orderableField?: (string | null) | OrderableJoin;
|
||||
orderableField?: (number | null) | OrderableJoin;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
@@ -205,20 +218,20 @@ export interface Orderable {
|
||||
* via the `definition` "orderable-join".
|
||||
*/
|
||||
export interface OrderableJoin {
|
||||
id: string;
|
||||
id: number;
|
||||
title?: string | null;
|
||||
orderableJoinField1?: {
|
||||
docs?: (string | Orderable)[];
|
||||
docs?: (number | Orderable)[];
|
||||
hasNextPage?: boolean;
|
||||
totalDocs?: number;
|
||||
};
|
||||
orderableJoinField2?: {
|
||||
docs?: (string | Orderable)[];
|
||||
docs?: (number | Orderable)[];
|
||||
hasNextPage?: boolean;
|
||||
totalDocs?: number;
|
||||
};
|
||||
nonOrderableJoinField?: {
|
||||
docs?: (string | Orderable)[];
|
||||
docs?: (number | Orderable)[];
|
||||
hasNextPage?: boolean;
|
||||
totalDocs?: number;
|
||||
};
|
||||
@@ -230,7 +243,7 @@ export interface OrderableJoin {
|
||||
* via the `definition` "users".
|
||||
*/
|
||||
export interface User {
|
||||
id: string;
|
||||
id: number;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
email: string;
|
||||
@@ -247,40 +260,44 @@ export interface User {
|
||||
* via the `definition` "payload-locked-documents".
|
||||
*/
|
||||
export interface PayloadLockedDocument {
|
||||
id: string;
|
||||
id: number;
|
||||
document?:
|
||||
| ({
|
||||
relationTo: 'posts';
|
||||
value: string | Post;
|
||||
value: number | Post;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'drafts';
|
||||
value: string | Draft;
|
||||
value: number | Draft;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'default-sort';
|
||||
value: string | DefaultSort;
|
||||
value: number | DefaultSort;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'non-unique-sort';
|
||||
value: number | NonUniqueSort;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'localized';
|
||||
value: string | Localized;
|
||||
value: number | Localized;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'orderable';
|
||||
value: string | Orderable;
|
||||
value: number | Orderable;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'orderable-join';
|
||||
value: string | OrderableJoin;
|
||||
value: number | OrderableJoin;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
value: number | User;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
value: number | User;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
@@ -290,10 +307,10 @@ export interface PayloadLockedDocument {
|
||||
* via the `definition` "payload-preferences".
|
||||
*/
|
||||
export interface PayloadPreference {
|
||||
id: string;
|
||||
id: number;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
value: number | User;
|
||||
};
|
||||
key?: string | null;
|
||||
value?:
|
||||
@@ -313,7 +330,7 @@ export interface PayloadPreference {
|
||||
* via the `definition` "payload-migrations".
|
||||
*/
|
||||
export interface PayloadMigration {
|
||||
id: string;
|
||||
id: number;
|
||||
name?: string | null;
|
||||
batch?: number | null;
|
||||
updatedAt: string;
|
||||
@@ -359,6 +376,16 @@ export interface DefaultSortSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "non-unique-sort_select".
|
||||
*/
|
||||
export interface NonUniqueSortSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
order?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "localized_select".
|
||||
@@ -458,6 +485,6 @@ export interface Auth {
|
||||
|
||||
|
||||
declare module 'payload' {
|
||||
// @ts-ignore
|
||||
// @ts-ignore
|
||||
export interface GeneratedTypes extends Config {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
relationSlug,
|
||||
unstoredMediaSlug,
|
||||
versionSlug,
|
||||
withoutEnlargeSlug,
|
||||
} from './shared.js'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
@@ -490,6 +491,19 @@ export default buildConfigWithDefaults({
|
||||
staticDir: path.resolve(dirname, './media/enlarge'),
|
||||
},
|
||||
},
|
||||
{
|
||||
slug: withoutEnlargeSlug,
|
||||
fields: [],
|
||||
upload: {
|
||||
resizeOptions: {
|
||||
width: 1000,
|
||||
height: undefined,
|
||||
fit: 'inside',
|
||||
withoutEnlargement: true,
|
||||
},
|
||||
staticDir: path.resolve(dirname, './media/without-enlarge'),
|
||||
},
|
||||
},
|
||||
{
|
||||
slug: reduceSlug,
|
||||
fields: [],
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
relationSlug,
|
||||
withMetadataSlug,
|
||||
withOnlyJPEGMetadataSlug,
|
||||
withoutEnlargeSlug,
|
||||
withoutMetadataSlug,
|
||||
} from './shared.js'
|
||||
import { startMockCorsServer } from './startMockCorsServer.js'
|
||||
@@ -69,6 +70,7 @@ let uploadsTwo: AdminUrlUtil
|
||||
let customUploadFieldURL: AdminUrlUtil
|
||||
let hideFileInputOnCreateURL: AdminUrlUtil
|
||||
let bestFitURL: AdminUrlUtil
|
||||
let withoutEnlargementResizeOptionsURL: AdminUrlUtil
|
||||
let consoleErrorsFromPage: string[] = []
|
||||
let collectErrorsFromPage: () => boolean
|
||||
let stopCollectingErrorsFromPage: () => boolean
|
||||
@@ -104,6 +106,7 @@ describe('Uploads', () => {
|
||||
customUploadFieldURL = new AdminUrlUtil(serverURL, customUploadFieldSlug)
|
||||
hideFileInputOnCreateURL = new AdminUrlUtil(serverURL, hideFileInputOnCreateSlug)
|
||||
bestFitURL = new AdminUrlUtil(serverURL, 'best-fit')
|
||||
withoutEnlargementResizeOptionsURL = new AdminUrlUtil(serverURL, withoutEnlargeSlug)
|
||||
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
@@ -1257,7 +1260,7 @@ describe('Uploads', () => {
|
||||
})
|
||||
|
||||
// without focal point update this generated size was equal to 1736
|
||||
expect(redDoc.sizes.focalTest.filesize).toEqual(1598)
|
||||
expect(redDoc.sizes.focalTest.filesize).toEqual(1586)
|
||||
})
|
||||
|
||||
test('should resize image after crop if resizeOptions defined', async () => {
|
||||
@@ -1355,6 +1358,35 @@ describe('Uploads', () => {
|
||||
await expect(page.locator('.file-field .file-details__remove')).toBeHidden()
|
||||
})
|
||||
|
||||
test('should skip applying resizeOptions after updating an image if resizeOptions.withoutEnlargement is true and the original image size is smaller than the dimensions defined in resizeOptions', async () => {
|
||||
await page.goto(withoutEnlargementResizeOptionsURL.create)
|
||||
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await wait(1000)
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
|
||||
await page.locator('.file-field__edit').click()
|
||||
|
||||
// no need to make any changes to the image if resizeOptions.withoutEnlargement is actually being respected now
|
||||
await page.locator('button:has-text("Apply Changes")').click()
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
|
||||
const resizeOptionMedia = page.locator('.file-meta .file-meta__size-type')
|
||||
|
||||
// expect the image to be the original size since the original image is smaller than the dimensions defined in resizeOptions
|
||||
await expect(resizeOptionMedia).toContainText('800x800')
|
||||
})
|
||||
|
||||
describe('imageSizes best fit', () => {
|
||||
test('should select adminThumbnail if one exists', async () => {
|
||||
await page.goto(bestFitURL.create)
|
||||
|
||||
@@ -3,6 +3,7 @@ export const mediaSlug = 'media'
|
||||
export const relationSlug = 'relation'
|
||||
export const audioSlug = 'audio'
|
||||
export const enlargeSlug = 'enlarge'
|
||||
export const withoutEnlargeSlug = 'without-enlarge'
|
||||
export const focalNoSizesSlug = 'focal-no-sizes'
|
||||
export const focalOnlySlug = 'focal-only'
|
||||
export const reduceSlug = 'reduce'
|
||||
|
||||
Reference in New Issue
Block a user