From fa4b98f1f901b005af6654ac907cc243ee07a74e Mon Sep 17 00:00:00 2001 From: Scrum4Me Agent <30029041+madhura68@users.noreply.github.com> Date: Fri, 15 May 2026 05:18:19 +0200 Subject: [PATCH] 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 --- .../components/dialogs/answer-modal.test.tsx | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 __tests__/components/dialogs/answer-modal.test.tsx diff --git a/__tests__/components/dialogs/answer-modal.test.tsx b/__tests__/components/dialogs/answer-modal.test.tsx new file mode 100644 index 0000000..26aad0f --- /dev/null +++ b/__tests__/components/dialogs/answer-modal.test.tsx @@ -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 }) => ( + {children} + ), +})) + +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 +const mockToast = toast as unknown as { + success: ReturnType + error: ReturnType +} + +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() + 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() + + 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() + + 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() + 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() + 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( + , + ) + expect(container.firstChild).toBeNull() + }) +})