import { describe, it, expect, beforeEach, vi } from 'vitest' import { renderHook, waitFor } from '@testing-library/react' import { usePlanApply } from './usePlanApply' import * as api from '@/services/api' vi.mock('@/services/api') describe('usePlanApply', () => { beforeEach(() => { vi.clearAllMocks() }) it('initializes with null response and no loading/error', () => { const { result } = renderHook(() => usePlanApply()) expect(result.current.response).toBeNull() expect(result.current.isLoading).toBe(false) expect(result.current.error).toBeNull() }) it('calls applyPlan and returns the response', async () => { const mockResponse = { accepted: true, createdCount: 2, skippedIdenticalCount: 0, skippedFreeCount: 0, replacedCount: 0, collisions: [], rejections: [], createdDays: [], } vi.mocked(api.applyPlan).mockResolvedValue(mockResponse) const { result } = renderHook(() => usePlanApply()) const days = [ { date: '2026-06-15', parentPersonalDataUuid: 'pd-1', childId: 'c-1', dayType: 'sjukpenning' as const, isDubbeldag: false, }, ] const applyPromise = result.current.apply('ws-1', days, false) await waitFor(() => { expect(result.current.isLoading).toBe(false) }) const response = await applyPromise expect(response).toEqual(mockResponse) expect(result.current.response).toEqual(mockResponse) expect(api.applyPlan).toHaveBeenCalledWith('ws-1', days, false) }) it('sets error when applyPlan throws', async () => { vi.mocked(api.applyPlan).mockRejectedValue(new Error('Network error')) const { result } = renderHook(() => usePlanApply()) const days = [ { date: '2026-06-15', parentPersonalDataUuid: 'pd-1', childId: 'c-1', dayType: 'sjukpenning' as const, }, ] try { await result.current.apply('ws-1', days, false) } catch { // Expected to throw } await waitFor(() => { expect(result.current.isLoading).toBe(false) }) expect(result.current.error).toBe('Network error') expect(result.current.response).toBeNull() }) it('falls back to a generic message when a non-Error value is thrown', async () => { vi.mocked(api.applyPlan).mockRejectedValue('boom') const { result } = renderHook(() => usePlanApply()) const days = [ { date: '2026-06-15', parentPersonalDataUuid: 'pd-1', childId: 'c-1', dayType: 'sjukpenning' as const, }, ] try { await result.current.apply('ws-1', days, false) } catch { // Expected to throw } await waitFor(() => { expect(result.current.isLoading).toBe(false) }) expect(result.current.error).toBe('Kunde inte använda plan') expect(result.current.response).toBeNull() }) it('handles replace parameter correctly', async () => { const mockResponse = { accepted: true, createdCount: 1, skippedIdenticalCount: 0, skippedFreeCount: 0, replacedCount: 1, collisions: [], rejections: [], createdDays: [], } vi.mocked(api.applyPlan).mockResolvedValue(mockResponse) const { result } = renderHook(() => usePlanApply()) const days = [ { date: '2026-06-15', parentPersonalDataUuid: 'pd-1', childId: 'c-1', dayType: 'sjukpenning' as const, }, ] const applyPromise = result.current.apply('ws-1', days, true) await waitFor(() => { expect(result.current.isLoading).toBe(false) }) const response = await applyPromise expect(api.applyPlan).toHaveBeenCalledWith('ws-1', days, true) expect(response).toEqual(mockResponse) await waitFor(() => { expect(result.current.response).toEqual(mockResponse) }) }) })