import { renderHook, act } from '@testing-library/react'; import { vi, test, expect, beforeEach } from 'vitest'; vi.mock('../syncService.js', () => ({ getRemotePrayers: vi.fn(), saveRemotePrayers: vi.fn() })); import { usePrayers } from './usePrayers.js'; import { getRemotePrayers, saveRemotePrayers } from '../syncService.js'; beforeEach(() => { localStorage.clear(); vi.clearAllMocks(); getRemotePrayers.mockResolvedValue({ ok: true, data: { prayers: [] } }); saveRemotePrayers.mockImplementation(async (list) => ({ ok: true, data: { prayers: list } })); }); test('prayers are added, changed, answered and kept on this device', () => { const { result } = renderHook(() => usePrayers()); let id; act(() => { id = result.current.addPrayer({ text: 'Peace at home', forWhom: 'Family' }).id; }); expect(result.current.prayers[0]).toMatchObject({ text: 'Peace at home', forWhom: 'Family' }); act(() => result.current.editPrayer(id, { text: 'Peace and joy at home' })); act(() => result.current.togglePrayed(id)); expect(result.current.prayers[0].prayedOn).toHaveLength(1); act(() => result.current.answerPrayer(id, 'Yes')); expect(result.current.prayers[0]).toMatchObject({ text: 'Peace and joy at home', answerNote: 'Yes' }); expect(result.current.prayers[0].answeredAt).toBeGreaterThan(0); act(() => result.current.reopenPrayer(id)); expect(result.current.prayers[0].answeredAt).toBeNull(); expect(JSON.parse(localStorage.getItem('prayers'))[0].text).toBe('Peace and joy at home'); }); test('a deleted prayer can be taken back', () => { const { result } = renderHook(() => usePrayers()); let id; let undo; act(() => { id = result.current.addPrayer({ text: 'Keep me' }).id; }); act(() => { undo = result.current.deletePrayer(id); }); expect(result.current.prayers[0].deleted).toBe(true); act(() => undo()); expect(result.current.prayers[0]).toMatchObject({ id, text: 'Keep me' }); expect(result.current.prayers[0].deleted).toBeUndefined(); }); test('signing in merges with the account and sends back what it lacked', async () => { localStorage.setItem('prayers', JSON.stringify([{ id: 'local', text: 'Only here', forWhom: '', verses: [], prayedOn: [], createdAt: 1, updatedAt: 5, answeredAt: null, answerNote: '' }])); getRemotePrayers.mockResolvedValue({ ok: true, data: { prayers: [{ id: 'remote', text: 'Only there', forWhom: '', verses: [], prayedOn: [], createdAt: 1, updatedAt: 6, answeredAt: null, answerNote: '' }] } }); const { result } = renderHook(() => usePrayers()); await act(async () => { await result.current.pullPrayers(); }); expect(result.current.prayers.map((p) => p.id).sort()).toEqual(['local', 'remote']); expect(saveRemotePrayers).toHaveBeenCalled(); }); test('signing out clears the journal from this device', async () => { const { result } = renderHook(() => usePrayers()); act(() => { result.current.addPrayer({ text: 'Private' }); }); act(() => result.current.stopPrayers()); expect(result.current.prayers).toEqual([]); expect(localStorage.getItem('prayers')).toBeNull(); });