import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { vi, test, expect, beforeEach } from 'vitest';
vi.mock('../syncService.js', () => ({ listStudyVersions: vi.fn(), getStudyVersion: vi.fn() }));
import VersionHistory from './VersionHistory.jsx';
import { getStudyVersion, listStudyVersions } from '../syncService.js';
const project = { id: 'p1', title: 'Romans', chapters: [{ book: 'Romans', chapter: '8', chunks: [{ id: 'a', startVerse: 1, endVerse: 4, observation: 'new words' }] }] };
const older = { id: 'p1', title: 'Romans', chapters: [{ book: 'Romans', chapter: '8', chunks: [{ id: 'a', startVerse: 1, endVerse: 4, observation: 'old words' }, { id: 'b', startVerse: 5, endVerse: 9, observation: 'lost' }] }] };
const at = new Date(2026, 9, 5, 14, 30).getTime();
beforeEach(() => {
vi.clearAllMocks();
listStudyVersions.mockResolvedValue({ ok: true, data: { versions: [{ id: 7, savedAt: at, chunks: 2, words: 12 }] } });
getStudyVersion.mockResolvedValue({ ok: true, data: older });
vi.spyOn(window, 'confirm').mockReturnValue(true);
});
test('lists the kept versions and says what is different from now', async () => {
const user = userEvent.setup();
render();
expect(await screen.findByText(/2 chunks · 12 words/)).toBeInTheDocument();
await user.click(screen.getByRole('button', { name: /what’s different/i }));
expect(await screen.findByText('Romans 8:1–4: Observe differs.')).toBeInTheDocument();
expect(screen.getByText(/Brings back 1 chunk deleted since: Romans 8:5–9/)).toBeInTheDocument();
expect(getStudyVersion).toHaveBeenCalledWith('p1', 7);
});
test('putting one back asks first, then restores and refreshes the list', async () => {
const onRestore = vi.fn(async () => true);
const user = userEvent.setup();
render();
await user.click(await screen.findByRole('button', { name: /put this back/i }));
expect(window.confirm).toHaveBeenCalled();
expect(onRestore).toHaveBeenCalledWith(7);
expect(listStudyVersions).toHaveBeenCalledTimes(2); // reloaded after
});
test('declining the question restores nothing; a failed restore says so', async () => {
const onRestore = vi.fn(async () => false);
const user = userEvent.setup();
window.confirm.mockReturnValueOnce(false);
render();
await user.click(await screen.findByRole('button', { name: /put this back/i }));
expect(onRestore).not.toHaveBeenCalled();
await user.click(screen.getByRole('button', { name: /put this back/i }));
expect(await screen.findByRole('alert')).toHaveTextContent(/Could not restore/);
});
test('with nothing kept, or no connection, it says so', async () => {
listStudyVersions.mockResolvedValueOnce({ ok: true, data: { versions: [] } });
const { unmount } = render();
expect(await screen.findByText(/Nothing kept yet/)).toBeInTheDocument();
unmount();
listStudyVersions.mockResolvedValueOnce({ ok: false, status: 404 });
render();
expect(await screen.findByText(/need your account and a connection/)).toBeInTheDocument();
});