98 lines
3.1 KiB
JavaScript
98 lines
3.1 KiB
JavaScript
import { describe, it, expect, vi } from 'vitest'
|
|
import { render, screen, fireEvent } from '@testing-library/svelte'
|
|
import ReviewsModal from './ReviewsModal.svelte'
|
|
|
|
describe('ReviewsModal', () => {
|
|
it('renders nothing when open is false', () => {
|
|
render(ReviewsModal, {
|
|
props: { open: false, deckTitle: 'Deck', reviews: [] },
|
|
})
|
|
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('shows loading message when loading', () => {
|
|
render(ReviewsModal, {
|
|
props: { open: true, deckTitle: 'My Deck', loading: true, reviews: [] },
|
|
})
|
|
expect(screen.getByText('Loading…')).toBeInTheDocument()
|
|
expect(screen.getByText(/Reviews: My Deck/)).toBeInTheDocument()
|
|
})
|
|
|
|
it('shows "No reviews yet" when not loading and reviews empty', () => {
|
|
render(ReviewsModal, {
|
|
props: { open: true, deckTitle: 'Deck', loading: false, reviews: [] },
|
|
})
|
|
expect(screen.getByText('No reviews yet.')).toBeInTheDocument()
|
|
})
|
|
|
|
it('renders review list with reviewer name and comment', () => {
|
|
const reviews = [
|
|
{
|
|
user_id: 'u1',
|
|
rating: 5,
|
|
comment: 'Great deck!',
|
|
display_name: 'Alice',
|
|
email: '[email protected]',
|
|
},
|
|
{
|
|
user_id: 'u2',
|
|
rating: 3,
|
|
comment: null,
|
|
display_name: null,
|
|
email: '[email protected]',
|
|
},
|
|
{
|
|
user_id: 'u3',
|
|
rating: 4,
|
|
comment: null,
|
|
display_name: null,
|
|
email: null,
|
|
},
|
|
{
|
|
user_id: 'u4',
|
|
rating: 2,
|
|
comment: 'Could be better',
|
|
display_name: ' ',
|
|
email: null,
|
|
},
|
|
]
|
|
render(ReviewsModal, {
|
|
props: { open: true, deckTitle: 'Deck', loading: false, reviews },
|
|
})
|
|
expect(screen.getByText('Alice')).toBeInTheDocument()
|
|
expect(screen.getByText('Great deck!')).toBeInTheDocument()
|
|
expect(screen.getByText('[email protected]')).toBeInTheDocument()
|
|
expect(screen.getAllByText('Anonymous').length).toBeGreaterThanOrEqual(1)
|
|
expect(screen.getByText('Could be better')).toBeInTheDocument()
|
|
})
|
|
|
|
it('calls onClose when Close is clicked', async () => {
|
|
const onClose = vi.fn()
|
|
render(ReviewsModal, {
|
|
props: { open: true, deckTitle: 'Deck', loading: false, reviews: [], onClose },
|
|
})
|
|
await fireEvent.click(screen.getByRole('button', { name: 'Close' }))
|
|
expect(onClose).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('calls onClose on Escape key', async () => {
|
|
const onClose = vi.fn()
|
|
render(ReviewsModal, {
|
|
props: { open: true, deckTitle: 'Deck', reviews: [], onClose },
|
|
})
|
|
const dialog = screen.getByRole('dialog')
|
|
await fireEvent.keyDown(dialog, { key: 'Escape' })
|
|
expect(onClose).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('calls onClose when backdrop is clicked', async () => {
|
|
const onClose = vi.fn()
|
|
const { container } = render(ReviewsModal, {
|
|
props: { open: true, deckTitle: 'Deck', reviews: [], onClose },
|
|
})
|
|
const backdrop = container.querySelector('.modal-backdrop')
|
|
await fireEvent.click(backdrop)
|
|
expect(onClose).toHaveBeenCalledTimes(1)
|
|
})
|
|
})
|