- Home: "Your five minutes": a rotating Observe/Interpret/Apply prompt on the passage whose matching note is thinnest in your own words, a 5:00 clock and a box that appends to that note. Pasting is blocked; sessions show in Insights. - Study: a Reading list tab (R) for the study: books and articles to consult, with a note and a tick; merges across devices. - Starting a study from a reading-plan day now uses the notes template you last picked when starting a study by hand (logic moved to utils/planStudy.js). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
47 lines
2.4 KiB
React
47 lines
2.4 KiB
React
import { render, screen, fireEvent } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { vi, test, expect, beforeEach } from 'vitest';
|
|
import { AppContext } from '../context/AppContext.js';
|
|
import { saveProjectToStorage } from '../utils/projectStorage.js';
|
|
import DailyFive from './DailyFive.jsx';
|
|
import { promptFor } from '../utils/dailyFive.js';
|
|
|
|
const project = () => ({
|
|
id: 'p1', title: 'John', translation: 'BSB', lastEdited: 1,
|
|
chapters: [{ book: 'John', bookAbbrev: 'JHN', chapter: '3', verses: [{ number: 16, text: 'For God so loved the world.' }],
|
|
chunks: [{ id: 'c1', startVerse: 16, endVerse: 16, observation: '', interpretation: '', application: '', editedAt: 1 }] }],
|
|
});
|
|
|
|
function setup() {
|
|
localStorage.clear();
|
|
saveProjectToStorage(project());
|
|
const saveChunkPatch = vi.fn();
|
|
const value = { projectIndex: [{ id: 'p1' }], saveChunkPatch };
|
|
render(<AppContext.Provider value={value}><DailyFive /></AppContext.Provider>);
|
|
return { saveChunkPatch, user: userEvent.setup() };
|
|
}
|
|
beforeEach(() => localStorage.clear());
|
|
|
|
test('the card names a passage and what kind of note the five minutes are for', () => {
|
|
setup();
|
|
expect(screen.getByText(/your five minutes/i)).toBeInTheDocument();
|
|
expect(screen.getByText(/John 3:16/)).toBeInTheDocument();
|
|
});
|
|
|
|
test('pasting is blocked, and what you type is saved to the matching note', async () => {
|
|
const { saveChunkPatch, user } = setup();
|
|
await user.click(screen.getByRole('button', { name: 'Start' }));
|
|
expect(screen.getByText('For God so loved the world.')).toBeInTheDocument();
|
|
expect(screen.getByRole('timer')).toHaveTextContent('5:00');
|
|
const box = screen.getByRole('textbox', { name: /your five minutes/i });
|
|
fireEvent.paste(box, { clipboardData: { getData: () => 'text from somewhere else' } });
|
|
expect(screen.getByText(/pasting is off here/i)).toBeInTheDocument();
|
|
expect(box).toHaveValue('');
|
|
expect(screen.getByRole('button', { name: /save to my notes/i })).toBeDisabled();
|
|
await user.type(box, 'God gave.');
|
|
await user.click(screen.getByRole('button', { name: /save to my notes/i }));
|
|
const field = promptFor().field;
|
|
expect(saveChunkPatch).toHaveBeenCalledWith('p1', 'c1', expect.objectContaining({ [field]: 'God gave.', fiveMinutes: [expect.objectContaining({ field })] }));
|
|
expect(screen.getByRole('status')).toHaveTextContent(/saved to your notes/i);
|
|
});
|