fix: findVersions pagination (#3906)
This commit is contained in:
@@ -20,6 +20,7 @@ export type Arguments = {
|
||||
limit?: number
|
||||
overrideAccess?: boolean
|
||||
page?: number
|
||||
pagination?: boolean
|
||||
req?: PayloadRequest
|
||||
showHiddenFields?: boolean
|
||||
sort?: string
|
||||
@@ -35,6 +36,7 @@ async function findVersions<T extends TypeWithVersion<T>>(
|
||||
limit,
|
||||
overrideAccess,
|
||||
page,
|
||||
pagination = true,
|
||||
req: { locale, payload },
|
||||
req,
|
||||
showHiddenFields,
|
||||
@@ -76,6 +78,7 @@ async function findVersions<T extends TypeWithVersion<T>>(
|
||||
limit: limit ?? 10,
|
||||
locale,
|
||||
page: page || 1,
|
||||
pagination,
|
||||
req,
|
||||
sort,
|
||||
where: fullWhere,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Page } from '@playwright/test'
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
@@ -85,3 +85,26 @@ export async function changeLocale(page: Page, newLocale: string) {
|
||||
export function exactText(text: string) {
|
||||
return new RegExp(`^${text}$`)
|
||||
}
|
||||
|
||||
export const selectTableRow = async (page: Page, title: string): Promise<void> => {
|
||||
const selector = `tbody tr:has-text("${title}") .select-row__checkbox input[type=checkbox]`
|
||||
await page.locator(selector).check()
|
||||
expect(await page.locator(selector).isChecked()).toBe(true)
|
||||
}
|
||||
|
||||
export const findTableCell = async (
|
||||
page: Page,
|
||||
fieldName: string,
|
||||
rowTitle?: string,
|
||||
): Promise<Locator> => {
|
||||
const parentEl = rowTitle ? await findTableRow(page, rowTitle) : page.locator('tbody tr')
|
||||
const cell = parentEl.locator(`td.cell-${fieldName}`)
|
||||
expect(cell).toBeTruthy()
|
||||
return cell
|
||||
}
|
||||
|
||||
export const findTableRow = async (page: Page, title: string): Promise<Locator> => {
|
||||
const row = page.locator(`tbody tr:has-text("${title}")`)
|
||||
expect(row).toBeTruthy()
|
||||
return row
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ import type { Page } from '@playwright/test'
|
||||
import { expect, test } from '@playwright/test'
|
||||
|
||||
import wait from '../../packages/payload/src/utilities/wait'
|
||||
import { changeLocale, saveDocAndAssert } from '../helpers'
|
||||
import { globalSlug } from '../admin/shared'
|
||||
import { changeLocale, exactText, findTableCell, selectTableRow } from '../helpers'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil'
|
||||
import { initPayloadE2E } from '../helpers/configHelpers'
|
||||
import { autosaveSlug, draftGlobalSlug, draftSlug, titleToDelete } from './shared'
|
||||
@@ -39,29 +40,10 @@ let page: Page
|
||||
let url: AdminUrlUtil
|
||||
let serverURL: string
|
||||
|
||||
const goToDoc = async (page: Page) => {
|
||||
await page.goto(url.list)
|
||||
const linkToDoc = page.locator('tbody tr:first-child .cell-title a').first()
|
||||
expect(linkToDoc).toBeTruthy()
|
||||
await linkToDoc.click()
|
||||
}
|
||||
|
||||
const goToCollectionVersions = async (page: Page): Promise<void> => {
|
||||
await goToDoc(page)
|
||||
await page.goto(`${page.url()}/versions`)
|
||||
}
|
||||
|
||||
const goToGlobalVersions = async (page: Page, slug: string): Promise<void> => {
|
||||
const global = new AdminUrlUtil(serverURL, slug)
|
||||
const versionsURL = `${global.global(slug)}/versions`
|
||||
await page.goto(versionsURL)
|
||||
}
|
||||
|
||||
describe('versions', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
const config = await initPayloadE2E(__dirname)
|
||||
serverURL = config.serverURL
|
||||
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
})
|
||||
@@ -89,40 +71,54 @@ describe('versions', () => {
|
||||
await expect(page.locator('.row-1 .cell-title')).not.toHaveText(titleToDelete)
|
||||
})
|
||||
|
||||
test('should bulk publish', async () => {
|
||||
test('bulk update - should publish many', async () => {
|
||||
await page.goto(url.list)
|
||||
|
||||
await page.locator('.checkbox-input:has(#select-all) input').check()
|
||||
// Select specific rows by title
|
||||
await selectTableRow(page, 'Published Title')
|
||||
await selectTableRow(page, 'Draft Title')
|
||||
|
||||
// Bulk edit the selected rows
|
||||
await page.locator('.publish-many__toggle').click()
|
||||
|
||||
await page.locator('#confirm-publish').click()
|
||||
|
||||
await expect(page.locator('.row-1 .cell-_status')).toContainText('Published')
|
||||
await expect(page.locator('.row-2 .cell-_status')).toContainText('Published')
|
||||
// Check that the statuses for each row has been updated to `published`
|
||||
await expect(await findTableCell(page, '_status', 'Published Title')).toContainText(
|
||||
'Published',
|
||||
)
|
||||
|
||||
await expect(await findTableCell(page, '_status', 'Draft Title')).toContainText('Published')
|
||||
})
|
||||
|
||||
test('should bulk unpublish', async () => {
|
||||
test('bulk update - should unpublish many', async () => {
|
||||
await page.goto(url.list)
|
||||
|
||||
await page.locator('.checkbox-input:has(#select-all) input').check()
|
||||
// Select specific rows by title
|
||||
await selectTableRow(page, 'Published Title')
|
||||
await selectTableRow(page, 'Draft Title')
|
||||
|
||||
// Bulk edit the selected rows
|
||||
await page.locator('.unpublish-many__toggle').click()
|
||||
|
||||
await page.locator('#confirm-unpublish').click()
|
||||
|
||||
await expect(page.locator('.row-1 .cell-_status')).toContainText('Draft')
|
||||
await expect(page.locator('.row-2 .cell-_status')).toContainText('Draft')
|
||||
// Check that the statuses for each row has been updated to `draft`
|
||||
await expect(await findTableCell(page, '_status', 'Published Title')).toContainText('Draft')
|
||||
await expect(await findTableCell(page, '_status', 'Draft Title')).toContainText('Draft')
|
||||
})
|
||||
|
||||
test('should publish while editing many', async () => {
|
||||
test('bulk update - should publish changes', async () => {
|
||||
const description = 'published document'
|
||||
await page.goto(url.list)
|
||||
await page.locator('.checkbox-input:has(#select-all) input').check()
|
||||
|
||||
// Select specific rows by title
|
||||
await selectTableRow(page, 'Published Title')
|
||||
await selectTableRow(page, 'Draft Title')
|
||||
|
||||
// Bulk edit the selected rows to `published` status
|
||||
await page.locator('.edit-many__toggle').click()
|
||||
await page.locator('.field-select .rs__control').click()
|
||||
const options = page.locator('.rs__option')
|
||||
const field = options.locator('text=description')
|
||||
const field = options.locator('text=Description')
|
||||
await field.click()
|
||||
await page.locator('#field-description').fill(description)
|
||||
await page.locator('.form-submit .edit-many__publish').click()
|
||||
@@ -130,18 +126,28 @@ describe('versions', () => {
|
||||
await expect(page.locator('.Toastify__toast--success')).toContainText(
|
||||
'Draft Posts successfully.',
|
||||
)
|
||||
await expect(page.locator('.row-1 .cell-_status')).toContainText('Published')
|
||||
await expect(page.locator('.row-2 .cell-_status')).toContainText('Published')
|
||||
|
||||
// Check that the statuses for each row has been updated to `published`
|
||||
await expect(await findTableCell(page, '_status', 'Published Title')).toContainText(
|
||||
'Published',
|
||||
)
|
||||
|
||||
await expect(await findTableCell(page, '_status', 'Draft Title')).toContainText('Published')
|
||||
})
|
||||
|
||||
test('should save as draft while editing many', async () => {
|
||||
test('bulk update - should draft changes', async () => {
|
||||
const description = 'draft document'
|
||||
await page.goto(url.list)
|
||||
await page.locator('.checkbox-input:has(#select-all) input').check()
|
||||
|
||||
// Select specific rows by title
|
||||
await selectTableRow(page, 'Published Title')
|
||||
await selectTableRow(page, 'Draft Title')
|
||||
|
||||
// Bulk edit the selected rows to `draft` status
|
||||
await page.locator('.edit-many__toggle').click()
|
||||
await page.locator('.field-select .rs__control').click()
|
||||
const options = page.locator('.rs__option')
|
||||
const field = options.locator('text=description')
|
||||
const field = options.locator('text=Description')
|
||||
await field.click()
|
||||
await page.locator('#field-description').fill(description)
|
||||
await page.locator('.form-submit .edit-many__draft').click()
|
||||
@@ -149,12 +155,15 @@ describe('versions', () => {
|
||||
await expect(page.locator('.Toastify__toast--success')).toContainText(
|
||||
'Draft Posts successfully.',
|
||||
)
|
||||
await expect(page.locator('.row-1 .cell-_status')).toContainText('Draft')
|
||||
await expect(page.locator('.row-2 .cell-_status')).toContainText('Draft')
|
||||
|
||||
// Check that the statuses for each row has been updated to `draft`
|
||||
await expect(await findTableCell(page, '_status', 'Published Title')).toContainText('Draft')
|
||||
await expect(await findTableCell(page, '_status', 'Draft Title')).toContainText('Draft')
|
||||
})
|
||||
|
||||
test('collection - has versions tab', async () => {
|
||||
await goToDoc(page)
|
||||
await page.goto(url.list)
|
||||
await page.locator('tbody tr .cell-title a').first().click()
|
||||
const docURL = page.url()
|
||||
const pathname = new URL(docURL).pathname
|
||||
|
||||
@@ -167,48 +176,31 @@ describe('versions', () => {
|
||||
expect(href).toBe(`${pathname}/versions`)
|
||||
})
|
||||
|
||||
test('collection - displays proper versions pagination', async () => {
|
||||
await page.goto(url.create)
|
||||
|
||||
// save a version and check count
|
||||
await page.locator('#field-title').fill('title')
|
||||
await page.locator('#field-description').fill('description')
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
await page.goto(`${page.url()}/versions`)
|
||||
|
||||
const paginationItems = page.locator('.versions__page-info')
|
||||
await expect(paginationItems).toHaveText('1-1 of 1')
|
||||
})
|
||||
|
||||
test('collection - tab displays proper number of versions', async () => {
|
||||
await page.goto(url.create)
|
||||
await page.goto(url.list)
|
||||
|
||||
// save a version and check count
|
||||
await page.locator('#field-title').fill('Title')
|
||||
await page.locator('#field-description').fill('Description')
|
||||
await saveDocAndAssert(page)
|
||||
const linkToDoc = page
|
||||
.locator('tbody tr .cell-title a', {
|
||||
hasText: exactText('Title With Many Versions 11'),
|
||||
})
|
||||
.first()
|
||||
|
||||
expect(linkToDoc).toBeTruthy()
|
||||
await linkToDoc.click()
|
||||
|
||||
const versionsTab = page.locator('.doc-tab', {
|
||||
hasText: 'Versions',
|
||||
})
|
||||
|
||||
const versionCount = await versionsTab.locator('.doc-tab__count').first().textContent()
|
||||
expect(versionCount).toBe('1')
|
||||
|
||||
// save another version and check count again
|
||||
await page.locator('#field-title').fill('Title 2')
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
await wait(100) // wait for save and rerender
|
||||
const versionCount2 = await versionsTab.locator('.doc-tab__count').first().textContent()
|
||||
expect(versionCount2).toBe('2')
|
||||
expect(versionCount).toBe('11')
|
||||
})
|
||||
|
||||
test('collection - has versions route', async () => {
|
||||
const url = page.url()
|
||||
await goToCollectionVersions(page)
|
||||
expect(page.url()).toBe(`${url}/versions`)
|
||||
await page.goto(url.list)
|
||||
await page.locator('tbody tr .cell-title a').first().click()
|
||||
await page.goto(`${page.url()}/versions`)
|
||||
expect(page.url()).toMatch(/\/versions$/)
|
||||
})
|
||||
|
||||
test('global - has versions tab', async () => {
|
||||
@@ -228,9 +220,10 @@ describe('versions', () => {
|
||||
})
|
||||
|
||||
test('global - has versions route', async () => {
|
||||
const url = page.url()
|
||||
await goToGlobalVersions(page, draftGlobalSlug)
|
||||
expect(page.url()).toBe(`${url}/versions`)
|
||||
const global = new AdminUrlUtil(serverURL, globalSlug)
|
||||
const versionsURL = `${global.global(globalSlug)}/versions`
|
||||
await page.goto(versionsURL)
|
||||
expect(page.url()).toMatch(/\/versions$/)
|
||||
})
|
||||
|
||||
test('should retain localized data during autosave', async () => {
|
||||
|
||||
@@ -217,6 +217,7 @@ describe('Versions', () => {
|
||||
draft: true,
|
||||
sort: 'title',
|
||||
})
|
||||
|
||||
const draftsDescending = await payload.find({
|
||||
collection: draftSlug,
|
||||
draft: true,
|
||||
@@ -230,16 +231,19 @@ describe('Versions', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should findVersions with sort', async () => {
|
||||
it('should `findVersions` with sort', async () => {
|
||||
const draftsAscending = await payload.findVersions({
|
||||
collection: draftSlug,
|
||||
draft: true,
|
||||
sort: 'createdAt',
|
||||
limit: 100,
|
||||
})
|
||||
|
||||
const draftsDescending = await payload.findVersions({
|
||||
collection: draftSlug,
|
||||
draft: true,
|
||||
sort: '-updatedAt',
|
||||
sort: '-createdAt',
|
||||
limit: 100,
|
||||
})
|
||||
|
||||
expect(draftsAscending).toBeDefined()
|
||||
@@ -251,7 +255,7 @@ describe('Versions', () => {
|
||||
})
|
||||
|
||||
describe('Restore', () => {
|
||||
it('should return findVersions in correct order', async () => {
|
||||
it('should return `findVersions` in correct order', async () => {
|
||||
const somePost = await payload.create({
|
||||
collection: draftSlug,
|
||||
data: {
|
||||
@@ -675,6 +679,41 @@ describe('Versions', () => {
|
||||
expect(findResults.docs[0].title).toStrictEqual(originalTitle)
|
||||
})
|
||||
|
||||
it('should return more than 10 `totalDocs`', async () => {
|
||||
const { id } = await payload.create({
|
||||
collection: 'draft-posts',
|
||||
data: {
|
||||
title: 'Title',
|
||||
description: 'Description',
|
||||
},
|
||||
})
|
||||
|
||||
const createVersions = async (int: number = 1) => {
|
||||
for (let i = 0; i < int; i++) {
|
||||
await payload.update({
|
||||
id,
|
||||
collection: 'draft-posts',
|
||||
data: {
|
||||
title: `Title ${i}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
await createVersions(10)
|
||||
|
||||
const findResults = await payload.findVersions({
|
||||
collection: 'draft-posts',
|
||||
where: {
|
||||
parent: {
|
||||
equals: id,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(findResults.totalDocs).toBe(11)
|
||||
})
|
||||
|
||||
it('should not be able to query an old draft version with draft=true', async () => {
|
||||
const draftFindResults = await payload.find({
|
||||
collection: 'draft-posts',
|
||||
|
||||
@@ -20,27 +20,46 @@ export const seed: Config['onInit'] = async (payload) => {
|
||||
},
|
||||
]
|
||||
|
||||
const { id: draftID } = await payload.create({
|
||||
await payload.create({
|
||||
collection: draftSlug,
|
||||
data: {
|
||||
id: 1,
|
||||
blocksField,
|
||||
description: 'draft description',
|
||||
description: 'Description',
|
||||
radio: 'test',
|
||||
title: 'draft title',
|
||||
title: 'Draft Title',
|
||||
},
|
||||
draft: true,
|
||||
})
|
||||
|
||||
const { id: manyDraftsID } = await payload.create({
|
||||
collection: draftSlug,
|
||||
data: {
|
||||
blocksField,
|
||||
description: 'Description',
|
||||
radio: 'test',
|
||||
title: 'Title With Many Versions',
|
||||
},
|
||||
draft: true,
|
||||
})
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await payload.update({
|
||||
id: manyDraftsID,
|
||||
collection: draftSlug,
|
||||
data: {
|
||||
title: `Title With Many Versions ${i + 2}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
await payload.create({
|
||||
collection: draftSlug,
|
||||
data: {
|
||||
id: 2,
|
||||
_status: 'published',
|
||||
blocksField,
|
||||
description: 'published description',
|
||||
description: 'Description',
|
||||
radio: 'test',
|
||||
title: 'published title',
|
||||
title: 'Published Title',
|
||||
},
|
||||
draft: false,
|
||||
})
|
||||
@@ -49,27 +68,9 @@ export const seed: Config['onInit'] = async (payload) => {
|
||||
collection: draftSlug,
|
||||
data: {
|
||||
blocksField,
|
||||
description: 'published description',
|
||||
description: 'Description',
|
||||
title: titleToDelete,
|
||||
},
|
||||
draft: true,
|
||||
})
|
||||
|
||||
await payload.update({
|
||||
id: draftID,
|
||||
collection: draftSlug,
|
||||
data: {
|
||||
title: 'draft title 2',
|
||||
},
|
||||
draft: true,
|
||||
})
|
||||
|
||||
await payload.update({
|
||||
id: draftID,
|
||||
collection: draftSlug,
|
||||
data: {
|
||||
title: 'draft title 3',
|
||||
},
|
||||
draft: true,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@ export const versionSlug = 'version-posts'
|
||||
export const autoSaveGlobalSlug = 'autosave-global'
|
||||
export const draftGlobalSlug = 'draft-global'
|
||||
|
||||
export const titleToDelete = 'title to delete'
|
||||
export const titleToDelete = 'Title To Delete'
|
||||
|
||||
Reference in New Issue
Block a user