import { h } from 'preact'; import '@testing-library/jest-dom'; import { fireEvent, screen, waitFor } from '@testing-library/preact'; import { useIntl, IntlShape } from 'react-intl'; import { render } from 'tests/utils'; import { StaticStore } from 'common/static-store'; import { Comment, CommentProps } from './comment'; import { CommentMode } from 'common/types'; function CommentWithIntl(props: CommentProps) { const intl = useIntl(); return ; } function getProps(): CommentProps { return { isCommentsDisabled: false, theme: 'light', post_info: { url: 'http://localhost/post/1', count: 2, read_only: false, }, view: 'main', data: { id: 'comment_id', text: 'test comment', vote: 0, time: new Date().toString(), pid: 'parent_id', score: 0, voted_ips: [], locator: { url: 'somelocatorurl', site: 'remark', }, user: { id: 'someone', picture: 'http://localhost/somepicture-url', name: 'username', ip: '', admin: false, block: false, verified: false, }, }, user: { id: 'testuser', picture: 'http://localhost/testuser-url', name: 'test', ip: '', admin: false, block: false, verified: false, }, intl: {} as IntlShape, }; } describe('', () => { let props = getProps(); beforeEach(() => { props = getProps(); }); it('should render patreon subscriber icon', async () => { const props = getProps(); props.data.user.paid_sub = true; render(); const patreonSubscriberIcon = await screen.findByAltText('Patreon Paid Subscriber'); expect(patreonSubscriberIcon).toBeVisible(); expect(patreonSubscriberIcon.tagName).toBe('IMG'); }); describe('verification', () => { it('should render active verification icon', () => { props.data.user.verified = true; render(); expect(screen.getByTitle('Verified user')).toBeVisible(); }); it('should not render verification icon', () => { const props = getProps(); render(); expect(screen.queryByTitle('Verified user')).not.toBeInTheDocument(); }); it('should render verification button for admin', () => { props.user!.admin = true; render(); expect(screen.getByTitle('Toggle verification')).toBeVisible(); }); it('should render active verification icon for admin', () => { props.user!.admin = true; props.data.user.verified = true; render(); expect(screen.queryByTitle('Verified user')).toBeVisible(); }); }); describe('voting', () => { let props = getProps(); beforeEach(() => { props = getProps(); }); it('should render vote component', () => { render(); expect(screen.getByTitle('Votes score')).toBeVisible(); }); it.each([ [ 'when the comment is pinned', () => { props.view = 'pinned'; }, ], [ 'when rendered in profile', () => { props.view = 'user'; }, ], [ 'when rendered in preview', () => { props.view = 'preview'; }, ], [ 'when post is read only', () => { props.post_info!.read_only = true; }, ], [ 'when comment was deleted', () => { props.data.delete = true; }, ], [ 'on current user comments', () => { props.user!.id = 'testuser'; props.data.user.id = 'testuser'; }, ], [ 'for guest users', () => { props.user = null; }, ], [ 'for anonymous users', () => { props.user!.id = 'anonymous_1'; }, ], ])('should not render vote component %s', (_, action) => { action(); render(); expect(screen.queryByText('Votes score')).not.toBeInTheDocument(); }); }); it('should render action buttons', () => { render(); expect(screen.getByText('Reply')).toBeVisible(); }); it.each([ [ 'pinned', () => { props.view = 'pinned'; }, ], [ 'deleted', () => { props.data.delete = true; }, ], [ 'collapsed', () => { props.collapsed = true; }, ], ])('should not render actions when comment is %s', (_, mutateProps) => { mutateProps(); render(); expect(screen.queryByTitle('Reply')).not.toBeInTheDocument(); }); it('should be editable', async () => { StaticStore.config.edit_duration = 300; props.repliesCount = 0; props.user!.id = '100'; props.data.user.id = '100'; Object.assign(props.data, { id: '101', vote: 1, time: Date.now(), delete: false, orig: 'test', }); render(); expect(screen.getByText('Edit')).toBeVisible(); }); it('should not be editable', () => { StaticStore.config.edit_duration = 300; Object.assign(props.data, { user: props.user, id: '100', vote: 1, time: new Date(new Date().getDate() - 300).toString(), orig: 'test', }); render(); expect(screen.queryByRole('timer')).not.toBeInTheDocument(); }); it('toggles edit mode', async () => { props = getProps(); props.repliesCount = 0; props.data.user = props.user!; props.data.time = new Date().toString(); props.setReplyEditState = jest.fn().mockImplementation(() => { props.editMode = props.editMode === undefined ? CommentMode.Edit : CommentMode.None; }); StaticStore.config.edit_duration = 300; const { rerender } = render(); fireEvent(screen.getByText('Edit'), new MouseEvent('click', { bubbles: true })); rerender(); await waitFor(() => { expect(screen.getByText('Cancel')).toBeVisible(); }); fireEvent(screen.getByText('Cancel'), new MouseEvent('click', { bubbles: true })); rerender(); await waitFor(() => { expect(screen.getByText('Edit')).toBeVisible(); }); }); });