import {render, screen, waitFor} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import {beforeAll, describe, expect, it} from 'vitest'; import PostEditor from './PostEditor'; const hidden = (container) => container.querySelector('input[type="hidden"]'); async function setup(props = {}) { const view = render(); await screen.findByRole('toolbar', {name: 'Formatting'}); return view; } describe('PostEditor', () => { // jsdom has no layout, which ProseMirror asks for when it scrolls the cursor into view. beforeAll(() => { const rects = () => ({length: 0, item: () => null, [Symbol.iterator]: [][Symbol.iterator]}); Range.prototype.getClientRects = rects; Range.prototype.getBoundingClientRect = () => ({top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0}); Element.prototype.getClientRects = rects; }); it('submits the markdown under the given name', async () => { const {container} = await setup({value: 'Hello **world**'}); expect(hidden(container)).toHaveAttribute('name', 'post[body]'); }); it('starts with the markdown it was given', async () => { const {container} = await setup({value: 'Hello **world**'}); expect(hidden(container)).toHaveValue('Hello **world**'); }); it('shows the markdown as formatted text', async () => { await setup({value: '## Pick from the plants'}); expect(await screen.findByRole('heading', {level: 2, name: 'Pick from the plants'})).toBeInTheDocument(); }); it('starts empty without a value', async () => { const {container} = await setup(); expect(hidden(container)).toHaveValue(''); }); it('opens on the Write tab', async () => { await setup(); expect(screen.getByRole('tab', {name: 'Write'})).toHaveAttribute('aria-selected', 'true'); }); it('lists the formatting buttons', async () => { await setup(); const names = screen.getAllByRole('button').map((b) => b.getAttribute('aria-label')); expect(names).toEqual(['Bold', 'Italic', 'Link', 'Bulleted list', 'Quote']); }); it('updates the markdown when a list is started', async () => { const {container} = await setup(); await userEvent.click(screen.getByRole('button', {name: 'Bulleted list'})); await waitFor(() => expect(hidden(container).value).toMatch(/^-/)); }); it('marks the list button pressed inside a list', async () => { await setup({value: '- one'}); expect(await screen.findByRole('button', {name: 'Bulleted list', pressed: true})).toBeInTheDocument(); }); it('turns a paragraph into a heading from the style menu', async () => { const {container} = await setup({value: 'Title'}); await userEvent.selectOptions(screen.getByRole('combobox', {name: 'Text style'}), 'h2'); await waitFor(() => expect(hidden(container)).toHaveValue('## Title')); }); describe('Markdown tab', () => { it('shows the raw markdown', async () => { await setup({value: 'Hello **world**'}); await userEvent.click(screen.getByRole('tab', {name: 'Markdown'})); expect(screen.getByRole('textbox', {name: 'Post body as markdown'})).toHaveValue('Hello **world**'); }); it('hides the formatting toolbar', async () => { await setup(); await userEvent.click(screen.getByRole('tab', {name: 'Markdown'})); expect(screen.queryByRole('toolbar')).not.toBeInTheDocument(); }); it('updates the markdown as it is typed', async () => { const {container} = await setup(); await userEvent.click(screen.getByRole('tab', {name: 'Markdown'})); await userEvent.type(screen.getByRole('textbox', {name: 'Post body as markdown'}), 'plain words'); expect(hidden(container)).toHaveValue('plain words'); }); it('formats what was typed when going back to Write', async () => { await setup(); await userEvent.click(screen.getByRole('tab', {name: 'Markdown'})); await userEvent.type(screen.getByRole('textbox', {name: 'Post body as markdown'}), '## Seeds'); await userEvent.click(screen.getByRole('tab', {name: 'Write'})); expect(await screen.findByRole('heading', {level: 2, name: 'Seeds'})).toBeInTheDocument(); }); it('keeps the growstuff crop link syntax', async () => { const {container} = await setup({value: 'Grow [tomato](crop) here'}); await userEvent.click(screen.getByRole('tab', {name: 'Markdown'})); await userEvent.click(screen.getByRole('tab', {name: 'Write'})); expect(hidden(container)).toHaveValue('Grow [tomato](crop) here'); }); }); });