test(notifications): voeg component-tests toe voor AnswerModal
Dekt: optieknoppen + textarea + Verstuur zichtbaar met opties, submit via optieknop, submit via vrij tekstveld, disabled Verstuur bij leeg veld, en demo-modus (textarea + Verstuur disabled). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a67ea73f2e
commit
fa4b98f1f9
1 changed files with 104 additions and 0 deletions
104
__tests__/components/dialogs/answer-modal.test.tsx
Normal file
104
__tests__/components/dialogs/answer-modal.test.tsx
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// @vitest-environment jsdom
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
|
||||
import React from 'react'
|
||||
|
||||
vi.mock('@/actions/questions', () => ({
|
||||
answerQuestion: vi.fn(),
|
||||
}))
|
||||
vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }))
|
||||
vi.mock('@/stores/notifications-store', () => ({
|
||||
useNotificationsStore: {
|
||||
getState: () => ({ remove: vi.fn() }),
|
||||
},
|
||||
}))
|
||||
vi.mock('next/link', () => ({
|
||||
default: ({ href, children }: { href: string; children: React.ReactNode }) => (
|
||||
<a href={href}>{children}</a>
|
||||
),
|
||||
}))
|
||||
|
||||
import { AnswerModal } from '@/components/notifications/answer-modal'
|
||||
import { answerQuestion } from '@/actions/questions'
|
||||
import { toast } from 'sonner'
|
||||
import type { NotificationQuestion } from '@/stores/notifications-store'
|
||||
|
||||
const mockAnswerQuestion = answerQuestion as ReturnType<typeof vi.fn>
|
||||
const mockToast = toast as unknown as {
|
||||
success: ReturnType<typeof vi.fn>
|
||||
error: ReturnType<typeof vi.fn>
|
||||
}
|
||||
|
||||
const QUESTION: NotificationQuestion = {
|
||||
kind: 'idea',
|
||||
id: 'q-1',
|
||||
product_id: 'prod-1',
|
||||
idea_id: 'idea-1',
|
||||
idea_code: 'IDEA-42',
|
||||
idea_title: 'Mijn Idee',
|
||||
question: 'Wat denk jij?',
|
||||
options: ['Optie A', 'Optie B'],
|
||||
created_at: '2026-01-01T00:00:00Z',
|
||||
expires_at: '2026-12-31T00:00:00Z',
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('AnswerModal — met opties', () => {
|
||||
it('toont optieknoppen, textarea en Verstuur-knop', () => {
|
||||
render(<AnswerModal question={QUESTION} isDemo={false} onClose={vi.fn()} />)
|
||||
expect(screen.getByRole('button', { name: 'Optie A' })).toBeTruthy()
|
||||
expect(screen.getByRole('button', { name: 'Optie B' })).toBeTruthy()
|
||||
expect(screen.getByLabelText(/Antwoord op Claude/)).toBeTruthy()
|
||||
expect(screen.getByRole('button', { name: 'Verstuur' })).toBeTruthy()
|
||||
})
|
||||
|
||||
it('roept answerQuestion aan met optiewaarde bij klik op optieknop', async () => {
|
||||
mockAnswerQuestion.mockResolvedValue({ ok: true })
|
||||
render(<AnswerModal question={QUESTION} isDemo={false} onClose={vi.fn()} />)
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Optie A' }))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAnswerQuestion).toHaveBeenCalledWith('q-1', 'Optie A')
|
||||
})
|
||||
})
|
||||
|
||||
it('roept answerQuestion aan met getypte tekst bij klik op Verstuur', async () => {
|
||||
mockAnswerQuestion.mockResolvedValue({ ok: true })
|
||||
render(<AnswerModal question={QUESTION} isDemo={false} onClose={vi.fn()} />)
|
||||
|
||||
fireEvent.change(screen.getByLabelText(/Antwoord op Claude/), {
|
||||
target: { value: 'Mijn eigen antwoord' },
|
||||
})
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Verstuur' }))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAnswerQuestion).toHaveBeenCalledWith('q-1', 'Mijn eigen antwoord')
|
||||
})
|
||||
})
|
||||
|
||||
it('Verstuur-knop is disabled zolang het tekstveld leeg is', () => {
|
||||
render(<AnswerModal question={QUESTION} isDemo={false} onClose={vi.fn()} />)
|
||||
expect(screen.getByRole('button', { name: 'Verstuur' })).toHaveProperty('disabled', true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('AnswerModal — demo-modus', () => {
|
||||
it('textarea is disabled en Verstuur is disabled bij isDemo=true', () => {
|
||||
render(<AnswerModal question={QUESTION} isDemo={true} onClose={vi.fn()} />)
|
||||
expect(screen.getByLabelText(/Antwoord op Claude/)).toHaveProperty('disabled', true)
|
||||
expect(screen.getByRole('button', { name: 'Verstuur' })).toHaveProperty('disabled', true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('AnswerModal — geen vraag', () => {
|
||||
it('rendert niets wanneer question null is', () => {
|
||||
const { container } = render(
|
||||
<AnswerModal question={null} isDemo={false} onClose={vi.fn()} />,
|
||||
)
|
||||
expect(container.firstChild).toBeNull()
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue