import { describe, it, expect, vi } from 'vitest'; import { render, screen } from '@testing-library/svelte'; import ScheduleWidget from '$lib/components/organisms/StudentSchedule/ScheduleWidget.svelte'; import type { ScheduleSlot } from '$lib/features/schedule/api/schedule'; vi.mock('$lib/features/schedule/stores/scheduleCache', () => ({ isOffline: vi.fn(() => false), getLastSyncDate: vi.fn(() => null) })); function makeSlot(overrides: Partial = {}): ScheduleSlot { return { slotId: 'slot-1', date: '2026-03-05', dayOfWeek: 4, startTime: '08:00', endTime: '09:00', subjectId: 'sub-1', subjectName: 'Mathématiques', teacherId: 'teacher-1', teacherName: 'M. Dupont', room: 'Salle 101', isModified: false, exceptionId: null, ...overrides }; } describe('ScheduleWidget', () => { it('renders slots with subject, teacher, time and room', () => { const slot = makeSlot(); render(ScheduleWidget, { props: { slots: [slot], nextSlotId: null } }); expect(screen.getByText('Mathématiques')).toBeTruthy(); expect(screen.getByText('M. Dupont')).toBeTruthy(); expect(screen.getByText('08:00')).toBeTruthy(); expect(screen.getByText('09:00')).toBeTruthy(); expect(screen.getByText('Salle 101')).toBeTruthy(); }); it('shows empty message when no slots', () => { render(ScheduleWidget, { props: { slots: [], nextSlotId: null } }); expect(screen.getByText("Aucun cours aujourd'hui")).toBeTruthy(); }); it('shows loading state', () => { render(ScheduleWidget, { props: { slots: [], nextSlotId: null, isLoading: true } }); expect(screen.getByText('Chargement...')).toBeTruthy(); }); it('shows error message', () => { render(ScheduleWidget, { props: { slots: [], nextSlotId: null, error: 'Erreur réseau' } }); expect(screen.getByText('Erreur réseau')).toBeTruthy(); }); it('highlights next slot with "Prochain" badge', () => { const slots = [ makeSlot({ slotId: 'slot-1', startTime: '08:00', endTime: '09:00' }), makeSlot({ slotId: 'slot-2', startTime: '10:00', endTime: '11:00', subjectName: 'Français', teacherName: 'Mme Martin' }) ]; render(ScheduleWidget, { props: { slots, nextSlotId: 'slot-2' } }); expect(screen.getByText('Prochain')).toBeTruthy(); }); it('does not show "Prochain" badge when nextSlotId is null', () => { render(ScheduleWidget, { props: { slots: [makeSlot()], nextSlotId: null } }); expect(screen.queryByText('Prochain')).toBeNull(); }); it('does not render room when room is null', () => { const slot = makeSlot({ room: null }); const { container } = render(ScheduleWidget, { props: { slots: [slot], nextSlotId: null } }); expect(container.querySelector('.slot-room')).toBeNull(); }); it('renders multiple slots with data-testid', () => { const slots = [ makeSlot({ slotId: 'slot-1' }), makeSlot({ slotId: 'slot-2', subjectName: 'Français' }), makeSlot({ slotId: 'slot-3', subjectName: 'Histoire' }) ]; const { container } = render(ScheduleWidget, { props: { slots, nextSlotId: null } }); const items = container.querySelectorAll('[data-testid="schedule-slot"]'); expect(items.length).toBe(3); }); });