Files
study-bible-project/src/components/LinkRules.test.jsx
T
nmemmertandClaude Sonnet 5.5 54cb1c217d
Build and Push Docker Image / build-and-push (push) Successful in 6m47s
Invite-only sign-up, present mode, series, handouts, templates, dictation, progress, sharing
- Admin: sign-up Open / Invite only / Closed with single-use invite links
- Present mode for scripts (auto-scroll) and outlines (step through, pace vs planned minutes)
- Series: group studies on the dashboard, filter by series, calendar file for a study's sessions
- Lesson handout: printable page per session (passage, outline, questions, writing lines)
- Save a chunk's notes as your own study template (synced)
- Voice dictation for notes and scripts (browser speech recognition)
- Reading progress: map of the 66 books and a calendar of days read, synced and merged across devices
- Export highlights and bookmarks as Markdown or Word, grouped by named colour
- Verse of the day push to the ntfy topic (needs IQBIBLE_API_KEY)
- Sharing: co-teacher editing via single-use invite links; read-only links can expire and take a passcode

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

51 lines
2.6 KiB
React

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { vi, test, expect } from 'vitest';
import LinkRules, { expiryText } from './LinkRules.jsx';
import SharedPasscodeForm from './SharedPasscodeForm.jsx';
test('says when a link expires and whether it has a passcode', () => {
const now = Date.UTC(2026, 9, 6);
expect(expiryText(null, now)).toBe('Never expires');
expect(expiryText(now - 1, now)).toBe('Expired');
expect(expiryText(now + 3 * 86_400_000, now)).toMatch(/3 days left/);
render(<LinkRules expiresAt={null} hasPasscode busy={false} onSave={vi.fn()} />);
expect(screen.getByText(/Needs a passcode/)).toBeInTheDocument();
});
test('only the settings you change are sent', async () => {
const onSave = vi.fn(async () => true);
const user = userEvent.setup();
render(<LinkRules expiresAt={null} hasPasscode={false} busy={false} onSave={onSave} />);
const save = screen.getByRole('button', { name: 'Save settings' });
expect(save).toBeDisabled();
await user.selectOptions(screen.getByLabelText('Stop working'), '7');
await user.click(save);
expect(onSave).toHaveBeenLastCalledWith({ expiresInDays: 7 }); // no passcode key: the passcode is left alone
await user.type(screen.getByLabelText(/Passcode/), ' moses ');
await user.click(screen.getByRole('button', { name: 'Save settings' }));
expect(onSave).toHaveBeenLastCalledWith({ passcode: 'moses' });
});
test('a passcode can be removed, and "Never" clears the expiry', async () => {
const onSave = vi.fn(async () => true);
const user = userEvent.setup();
render(<LinkRules expiresAt={Date.now() + 86_400_000} hasPasscode busy={false} onSave={onSave} />);
await user.click(screen.getByRole('button', { name: 'Remove passcode' }));
expect(onSave).toHaveBeenLastCalledWith({ passcode: null });
await user.selectOptions(screen.getByLabelText('Stop working'), 'Never');
await user.click(screen.getByRole('button', { name: 'Save settings' }));
expect(onSave).toHaveBeenLastCalledWith({ expiresInDays: null });
});
test('the viewer\'s passcode form submits what was typed and shows a wrong-passcode message', async () => {
const onSubmit = vi.fn();
const user = userEvent.setup();
render(<SharedPasscodeForm error="That passcode is not right." onSubmit={onSubmit} />);
expect(screen.getByRole('alert')).toHaveTextContent(/not right/);
expect(screen.getByRole('button', { name: 'Open' })).toBeDisabled();
await user.type(screen.getByLabelText('Passcode'), 'moses');
await user.click(screen.getByRole('button', { name: 'Open' }));
expect(onSubmit).toHaveBeenCalledWith('moses');
});