// @vitest-environment jsdom /** * What the LinkCard and LinkParts pages claim, pinned: the pickers for a * reader who may change it and words for one who may not, the conversation * count and its unread, what each kind draws, and the loading and * not-available states. */ import { cleanup, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { afterEach, describe, expect, it, vi } from 'vitest' import { LinkCard } from './LinkCard' import { GROUP, ITEM, ITEM_NO_SUMMARY, ITEM_READ_ONLY, ITEM_UNREAD, LOADING, PAGE, PLACE, ready, SAID, UNAVAILABLE } from './linked.examples' afterEach(cleanup) describe('LinkCard', () => { it('opens what it links from its title', () => { render() expect(screen.getByRole('link', { name: ITEM.title }).getAttribute('href')).toBe('#item') }) it('lets a reader who may change it pick a new status and owner', async () => { const user = userEvent.setup() const onStatus = vi.fn() const onOwner = vi.fn() render() await user.click(screen.getByRole('combobox', { name: 'Status' })) await user.click(await screen.findByRole('option', { name: /Done/ })) expect(onStatus).toHaveBeenCalledWith('done') await user.click(screen.getByRole('combobox', { name: 'Owner' })) await user.click(await screen.findByRole('option', { name: /Person three/ })) expect(onOwner).toHaveBeenCalledWith('c') }) it('shows the same values as words to a reader who may not change them', () => { render() expect(screen.queryByRole('combobox')).toBeNull() expect(screen.getByText('In progress')).toBeTruthy() expect(screen.getByText('Person one')).toBeTruthy() }) it('shows words, never pickers, when read only, even to a reader who could change it', () => { render() expect(screen.queryByRole('combobox')).toBeNull() }) it('says nobody owns it when nobody does', () => { render() expect(screen.getByText('Unassigned')).toBeTruthy() }) it('shows the title alone when there is no summary', () => { render() expect(screen.getByRole('link', { name: 'Item two' })).toBeTruthy() expect(screen.queryByText(ITEM.summary!)).toBeNull() }) it('opens the conversation from its count, and says when it holds something unread', () => { const { rerender } = render() const count = screen.getByRole('link', { name: /comments — open the conversation/ }) expect(count.getAttribute('href')).toBe('#item-conversation') expect(count.textContent).not.toContain('unread') rerender() expect(screen.getByRole('link', { name: /comments, unread — open the conversation/ })).toBeTruthy() }) it('opens each item inside it on its own', () => { render() expect(screen.getByRole('link', { name: 'Item three' }).getAttribute('href')).toBe('#c3') expect(screen.getByText('2/5')).toBeTruthy() }) it('shows the newest conversation where it is given, and who wrote a page', () => { render( <> , ) expect(screen.getByText('Latest conversation')).toBeTruthy() expect(screen.getByText(PLACE.latest!.body)).toBeTruthy() expect(screen.getByText('Yesterday')).toBeTruthy() }) it('draws a person’s words as theirs, with the time as the link', () => { render() expect(screen.getByText('Person one')).toBeTruthy() expect(screen.getByText(SAID.body!)).toBeTruthy() expect(screen.getByRole('link', { name: '10:42' }).getAttribute('href')).toBe('#said') }) it('while it loads, is busy and shows nothing of it', () => { const { container } = render() expect(container.querySelector('[aria-busy="true"]')).not.toBeNull() expect(screen.queryByRole('link')).toBeNull() }) it('says it is not available, and where it may still open', () => { render() expect(screen.getByText('Item — not available.')).toBeTruthy() expect(screen.getByRole('link', { name: /Open in App one/ }).getAttribute('href')).toBe('#elsewhere') }) })