Files
study-bible-project/src/components/VersionHistory.test.jsx
T
nmemmertandClaude Sonnet 5.5 207bfcb919
Build and Push Docker Image / build-and-push (push) Successful in 5m13s
Version history, notes on highlights and bookmarks, "you've studied this", prayer journal
- Earlier versions of a study: the server keeps compressed copies (about one per ten minutes of
  editing, the latest 30); Export shows what differs and puts one back (the replaced copy is kept)
- Notes on highlights and bookmarks: synced, merged without loss, in exports and backups
- Reader verse panel lists your studies and chunks that cover the verse, and opens them
- Prayer journal: requests, who for, linked verses, days prayed, answers; synced, in backups
  and the account export; daily prayer reminder through ntfy
- TODO.md lists the ideas not built yet

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 10:45:32 -04:00

60 lines
3.3 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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(<VersionHistory project={project} onRestore={vi.fn()} />);
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(<VersionHistory project={project} onRestore={onRestore} />);
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(<VersionHistory project={project} onRestore={onRestore} />);
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(<VersionHistory project={project} onRestore={vi.fn()} />);
expect(await screen.findByText(/Nothing kept yet/)).toBeInTheDocument();
unmount();
listStudyVersions.mockResolvedValueOnce({ ok: false, status: 404 });
render(<VersionHistory project={project} onRestore={vi.fn()} />);
expect(await screen.findByText(/need your account and a connection/)).toBeInTheDocument();
});