mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Added Playwright test for comment reply pagination
refs https://github.com/TryGhost/Team/issues/3504
This commit is contained in:
parent
9035a87e50
commit
9135ca92e0
3 changed files with 147 additions and 7 deletions
|
@ -58,5 +58,60 @@ test.describe('Pagination', async () => {
|
|||
// Check the pagination button is not visible
|
||||
await expect(frame.getByTestId('pagination-component')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('Shows pagination button for replies', async ({page}) => {
|
||||
const mockedApi = new MockedApi({});
|
||||
|
||||
mockedApi.addComment({
|
||||
html: '<p>This is comment 1</p>',
|
||||
replies: [
|
||||
mockedApi.buildReply({
|
||||
html: '<p>This is reply 1</p>'
|
||||
}),
|
||||
mockedApi.buildReply({
|
||||
html: '<p>This is reply 2</p>'
|
||||
}),
|
||||
mockedApi.buildReply({
|
||||
html: '<p>This is reply 3</p>'
|
||||
}),
|
||||
mockedApi.buildReply({
|
||||
html: '<p>This is reply 4</p>'
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
const {frame} = await initialize({
|
||||
mockedApi,
|
||||
page,
|
||||
publication: 'Publisher Weekly'
|
||||
});
|
||||
|
||||
await expect(frame.getByTestId('reply-pagination-button')).toBeVisible();
|
||||
|
||||
// Check text in pagination button
|
||||
await expect(frame.getByTestId('reply-pagination-button')).toContainText('Show 1 more reply');
|
||||
|
||||
await expect(frame.getByTestId('comment-component')).toHaveCount(4);
|
||||
|
||||
// Check only the first 5 comments are visible
|
||||
await expect(frame.getByText('This is comment 1')).toBeVisible();
|
||||
await expect(frame.getByText('This is reply 1')).toBeVisible();
|
||||
await expect(frame.getByText('This is reply 2')).toBeVisible();
|
||||
await expect(frame.getByText('This is reply 3')).toBeVisible();
|
||||
await expect(frame.getByText('This is reply 4')).not.toBeVisible();
|
||||
|
||||
// Click the pagination button
|
||||
await frame.getByTestId('reply-pagination-button').click();
|
||||
|
||||
// No longer visible
|
||||
await expect(frame.getByTestId('reply-pagination-button')).not.toBeVisible();
|
||||
|
||||
await expect(frame.getByTestId('comment-component')).toHaveCount(5);
|
||||
await expect(frame.getByText('This is comment 1')).toBeVisible();
|
||||
await expect(frame.getByText('This is reply 1')).toBeVisible();
|
||||
await expect(frame.getByText('This is reply 2')).toBeVisible();
|
||||
await expect(frame.getByText('This is reply 3')).toBeVisible();
|
||||
await expect(frame.getByText('This is reply 4')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import nql from '@tryghost/nql';
|
||||
import {buildComment, buildMember} from './fixtures';
|
||||
import {buildComment, buildMember, buildReply} from './fixtures';
|
||||
|
||||
export class MockedApi {
|
||||
comments: any[];
|
||||
|
@ -27,6 +27,18 @@ export class MockedApi {
|
|||
this.comments.push(fixture);
|
||||
}
|
||||
|
||||
buildReply(overrides: any = {}) {
|
||||
if (!overrides.created_at) {
|
||||
overrides.created_at = this.#lastCommentDate.toISOString();
|
||||
this.#lastCommentDate = new Date(this.#lastCommentDate.getTime() + 1);
|
||||
}
|
||||
|
||||
return buildReply({
|
||||
...overrides,
|
||||
post_id: this.postId
|
||||
});
|
||||
}
|
||||
|
||||
addComments(count, overrides = {}) {
|
||||
for (let i = 0; i < count; i += 1) {
|
||||
this.addComment(overrides);
|
||||
|
@ -72,7 +84,16 @@ export class MockedApi {
|
|||
const comments = filteredComments.slice(startIndex, endIndex);
|
||||
|
||||
return {
|
||||
comments,
|
||||
comments: comments.map((comment) => {
|
||||
return {
|
||||
...comment,
|
||||
replies: comment.replies.slice(0, 3),
|
||||
count: {
|
||||
...comment.count,
|
||||
replies: comment.replies.length
|
||||
}
|
||||
};
|
||||
}),
|
||||
meta: {
|
||||
pagination: {
|
||||
pages: Math.ceil(filteredComments.length / limit),
|
||||
|
@ -84,6 +105,51 @@ export class MockedApi {
|
|||
};
|
||||
}
|
||||
|
||||
browseReplies({commentId, filter, limit = 5}: {commentId: string, filter?: string, limit?: number}) {
|
||||
const comment = this.comments.find(c => c.id === commentId);
|
||||
if (!comment) {
|
||||
return {
|
||||
error: 'Comment ' + commentId + ' not found'
|
||||
};
|
||||
}
|
||||
|
||||
let replies: any[] = comment.replies;
|
||||
|
||||
// Sort replies on created at + id
|
||||
replies.sort((a, b) => {
|
||||
const aDate = new Date(a.created_at).getTime();
|
||||
const bDate = new Date(b.created_at).getTime();
|
||||
|
||||
if (aDate === bDate) {
|
||||
return a.id > b.id ? 1 : -1;
|
||||
}
|
||||
|
||||
return aDate > bDate ? 1 : -1;
|
||||
});
|
||||
|
||||
// Parse NQL filter
|
||||
if (filter) {
|
||||
const parsed = nql(filter);
|
||||
replies = replies.filter((reply) => {
|
||||
return parsed.queryJSON(reply);
|
||||
});
|
||||
}
|
||||
|
||||
const limitedReplies = replies.slice(0, limit);
|
||||
|
||||
return {
|
||||
comments: limitedReplies,
|
||||
meta: {
|
||||
pagination: {
|
||||
pages: Math.ceil(replies.length / limit),
|
||||
total: replies.length,
|
||||
page: 1,
|
||||
limit
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async listen({page, path}: {page: any, path: string}) {
|
||||
await page.route(`${path}/members/api/member/`, async (route) => {
|
||||
if (!this.member) {
|
||||
|
@ -105,13 +171,32 @@ export class MockedApi {
|
|||
const p = parseInt(url.searchParams.get('page') ?? '1');
|
||||
const limit = parseInt(url.searchParams.get('limit') ?? '5');
|
||||
const order = url.searchParams.get('order') ?? '';
|
||||
const filter = url.searchParams.get('filter') ?? '';
|
||||
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(this.browseComments({
|
||||
page: p,
|
||||
limit,
|
||||
order
|
||||
order,
|
||||
filter
|
||||
}))
|
||||
});
|
||||
});
|
||||
|
||||
await page.route(`${path}/members/api/comments/*/replies/*`, async (route) => {
|
||||
const url = new URL(route.request().url());
|
||||
|
||||
const limit = parseInt(url.searchParams.get('limit') ?? '5');
|
||||
const commentId = url.pathname.split('/').reverse()[2];
|
||||
const filter = url.searchParams.get('filter') ?? '';
|
||||
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(this.browseReplies({
|
||||
limit,
|
||||
filter,
|
||||
commentId
|
||||
}))
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,11 +5,11 @@ export function buildMember(override: any = {}) {
|
|||
memberCounter += 1;
|
||||
|
||||
return {
|
||||
id: ObjectId().toString(),
|
||||
avatar_image: 'https://www.gravatar.com/avatar/7a68f69cc9c9e9b45d97ecad6f24184a?s=250&r=g&d=blank',
|
||||
expertise: 'Head of Testing',
|
||||
id: ObjectId(),
|
||||
name: 'Test Member ' + memberCounter,
|
||||
uuid: ObjectId(),
|
||||
uuid: ObjectId().toString(),
|
||||
paid: override.status === 'paid',
|
||||
status: 'free',
|
||||
...override
|
||||
|
@ -18,7 +18,7 @@ export function buildMember(override: any = {}) {
|
|||
|
||||
export function buildComment(override: any = {}) {
|
||||
return {
|
||||
id: ObjectId(),
|
||||
id: ObjectId().toString(),
|
||||
html: '<p>Empty</p>',
|
||||
replies: [],
|
||||
count: {
|
||||
|
@ -36,7 +36,7 @@ export function buildComment(override: any = {}) {
|
|||
|
||||
export function buildReply(override: any = {}) {
|
||||
return {
|
||||
id: ObjectId(),
|
||||
id: ObjectId().toString(),
|
||||
html: '<p>Empty</p>',
|
||||
count: {
|
||||
likes: 0
|
||||
|
|
Loading…
Add table
Reference in a new issue