import { describe, expect, it } from '@jest/globals';
import { userEvent } from '@testing-library/user-event';
import { render, screen as rtlScreen } from '../../../../tests/utils';
import { type CommentData, CommentsList } from './comments-list';
describe('CommentsList', () => {
it('renders a list of approved comments', () => {
const comments = [
{
author: { name: 'Milan0' },
content: 'Fugit veniam quas qui dolor explicabo.',
id: 1,
isApproved: true,
publicationDate: '2023-01-23',
},
{
author: { name: 'Haskell42' },
content: 'Error quas accusamus nesciunt enim quae a.',
id: 2,
isApproved: true,
publicationDate: '2023-02-04',
},
] satisfies CommentData[];
render();
expect(rtlScreen.getAllByRole('listitem')).toHaveLength(comments.length);
expect(rtlScreen.getByText(comments[0].author.name)).toBeInTheDocument();
expect(rtlScreen.getByText(comments[0].content)).toBeInTheDocument();
expect(rtlScreen.getByText(comments[1].author.name)).toBeInTheDocument();
expect(rtlScreen.getByText(comments[1].content)).toBeInTheDocument();
});
it('renders a list of pending comments', () => {
const comments = [
{
author: { name: 'Milan0' },
content: 'Fugit veniam quas qui dolor explicabo.',
id: 1,
isApproved: false,
publicationDate: '2023-01-23',
},
{
author: { name: 'Haskell42' },
content: 'Error quas accusamus nesciunt enim quae a.',
id: 2,
isApproved: false,
publicationDate: '2023-02-04',
},
] satisfies CommentData[];
render();
expect(rtlScreen.getAllByRole('listitem')).toHaveLength(comments.length);
expect(
rtlScreen.queryByText(comments[0].author.name)
).not.toBeInTheDocument();
expect(rtlScreen.queryByText(comments[0].content)).not.toBeInTheDocument();
expect(
rtlScreen.queryByText(comments[1].author.name)
).not.toBeInTheDocument();
expect(rtlScreen.queryByText(comments[1].content)).not.toBeInTheDocument();
});
it('renders a mixed list of approved and pending comments', () => {
const comments = [
{
author: { name: 'Milan0' },
content: 'Fugit veniam quas qui dolor explicabo.',
id: 1,
isApproved: true,
publicationDate: '2023-01-23',
},
{
author: { name: 'Haskell42' },
content: 'Error quas accusamus nesciunt enim quae a.',
id: 2,
isApproved: false,
publicationDate: '2023-02-04',
},
] satisfies CommentData[];
render();
expect(rtlScreen.getAllByRole('listitem')).toHaveLength(comments.length);
expect(rtlScreen.getByText(comments[0].author.name)).toBeInTheDocument();
expect(rtlScreen.getByText(comments[0].content)).toBeInTheDocument();
expect(
rtlScreen.queryByText(comments[1].author.name)
).not.toBeInTheDocument();
expect(rtlScreen.queryByText(comments[1].content)).not.toBeInTheDocument();
});
it('does not render the replies by default', () => {
const comments = [
{
author: { name: 'Milan0' },
content: 'Fugit veniam quas qui dolor explicabo.',
id: 1,
isApproved: true,
publicationDate: '2023-01-23',
replies: [
{
author: { name: 'Haskell42' },
content: 'Error quas accusamus nesciunt enim quae a.',
id: 2,
isApproved: true,
publicationDate: '2023-02-04',
},
{
author: { name: 'Hanna49' },
content:
'Ut ducimus neque aliquam soluta sed totam commodi cum sit.',
id: 3,
isApproved: true,
publicationDate: '2023-03-10',
},
],
},
] satisfies CommentData[];
render();
expect(rtlScreen.getAllByRole('listitem')).toHaveLength(1);
expect(rtlScreen.getByText(comments[0].author.name)).toBeInTheDocument();
expect(rtlScreen.getByText(comments[0].content)).toBeInTheDocument();
expect(
rtlScreen.queryByText(comments[0].replies[0].author.name)
).not.toBeInTheDocument();
expect(
rtlScreen.queryByText(comments[0].replies[0].content)
).not.toBeInTheDocument();
expect(rtlScreen.queryByText(/Reply/)).not.toBeInTheDocument();
});
it('can render the replies by providing a depth', () => {
const comments = [
{
author: { name: 'Milan0' },
content: 'Fugit veniam quas qui dolor explicabo.',
id: 1,
isApproved: true,
publicationDate: '2023-01-23',
replies: [
{
author: { name: 'Haskell42' },
content: 'Error quas accusamus nesciunt enim quae a.',
id: 2,
isApproved: true,
publicationDate: '2023-02-04',
},
{
author: { name: 'Hanna49' },
content:
'Ut ducimus neque aliquam soluta sed totam commodi cum sit.',
id: 3,
isApproved: true,
publicationDate: '2023-03-10',
},
],
},
] satisfies CommentData[];
render();
const totalComments =
comments.length +
comments.reduce(
(accumulator, currentValue) =>
accumulator + currentValue.replies.length,
0
);
expect(rtlScreen.getAllByRole('listitem')).toHaveLength(totalComments);
expect(rtlScreen.getByText(comments[0].author.name)).toBeInTheDocument();
expect(rtlScreen.getByText(comments[0].content)).toBeInTheDocument();
expect(
rtlScreen.getByText(comments[0].replies[0].author.name)
).toBeInTheDocument();
expect(
rtlScreen.getByText(comments[0].replies[0].content)
).toBeInTheDocument();
expect(rtlScreen.getByText(/Reply/)).toBeInTheDocument();
});
it('can allow replies on replies by providing a depth', () => {
const comments = [
{
author: { name: 'Milan0' },
content: 'Fugit veniam quas qui dolor explicabo.',
id: 1,
isApproved: true,
publicationDate: '2023-01-23',
replies: [
{
author: { name: 'Haskell42' },
content: 'Error quas accusamus nesciunt enim quae a.',
id: 2,
isApproved: true,
publicationDate: '2023-02-04',
},
{
author: { name: 'Hanna49' },
content:
'Ut ducimus neque aliquam soluta sed totam commodi cum sit.',
id: 3,
isApproved: true,
publicationDate: '2023-03-10',
},
],
},
] satisfies CommentData[];
render();
const totalComments =
comments.length +
comments.reduce(
(accumulator, currentValue) =>
accumulator + currentValue.replies.length,
0
);
expect(rtlScreen.getAllByRole('listitem')).toHaveLength(totalComments);
expect(rtlScreen.getAllByText(/Reply/)).toHaveLength(totalComments);
});
it('can render a reply form when clicking on the reply button', async () => {
const user = userEvent.setup();
const comments = [
{
author: { name: 'Milan0' },
content: 'Fugit veniam quas qui dolor explicabo.',
id: 1,
isApproved: true,
publicationDate: '2023-01-23',
},
{
author: { name: 'Haskell42' },
content: 'Error quas accusamus nesciunt enim quae a.',
id: 2,
isApproved: true,
publicationDate: '2023-02-04',
},
] satisfies CommentData[];
render();
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
expect.assertions(3);
const replyButtons = rtlScreen.getAllByText(/Reply/);
expect(rtlScreen.queryByRole('form')).not.toBeInTheDocument();
await user.click(replyButtons[0]);
expect(rtlScreen.getByRole('form')).toHaveAccessibleName(/Leave a reply/);
await user.click(replyButtons[0]);
expect(rtlScreen.queryByRole('form')).not.toBeInTheDocument();
});
it('does not render a reply button when replies are forbidden', () => {
const comments = [
{
author: { name: 'Milan0' },
content: 'Fugit veniam quas qui dolor explicabo.',
id: 1,
isApproved: true,
publicationDate: '2023-01-23',
},
{
author: { name: 'Haskell42' },
content: 'Error quas accusamus nesciunt enim quae a.',
id: 2,
isApproved: true,
publicationDate: '2023-02-04',
},
] satisfies CommentData[];
render();
expect(rtlScreen.queryAllByRole('button', { name: /Reply/ })).toHaveLength(
0
);
expect(rtlScreen.queryByRole('form')).not.toBeInTheDocument();
});
});