Files
study-bible-project/server/votd.test.js
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

41 lines
2.3 KiB
JavaScript

// @vitest-environment node
import { test, expect, beforeEach, afterEach, vi } from 'vitest';
import { parseVotd, fetchVerseOfDay, clearVotdCache, votdMessage } from './votd.js';
beforeEach(() => { clearVotdCache(); process.env.IQBIBLE_API_KEY = 'k'; });
afterEach(() => { delete process.env.IQBIBLE_API_KEY; vi.restoreAllMocks(); });
const body = { data: { book_usfm: 'ROM', chapter_number: 8, verse_number: 28, text: '¶ And we know that all things work together for good.' } };
const ok = () => vi.fn(async () => ({ ok: true, json: async () => body }));
test('IQ Bible\'s verse becomes a reference and clean text', () => {
expect(parseVotd(body)).toEqual({ reference: 'Romans 8:28', text: 'And we know that all things work together for good.' });
expect(parseVotd({ data: { book_usfm: 'XXX', chapter_number: 1, verse_number: 1, text: 'x' } })).toBeNull();
expect(parseVotd({})).toBeNull();
});
test('the notification carries the verse and its reference', () => {
expect(votdMessage({ reference: 'Romans 8:28', text: 'All things.' })).toEqual({ title: 'Verse of the day: Romans 8:28', body: 'All things.\n\nRomans 8:28 (KJV)', tags: 'sunrise' });
});
test('one lookup a day serves everyone, and a new day looks again', async () => {
const fetcher = ok();
const day1 = new Date('2026-10-06T12:00:00Z');
expect((await fetchVerseOfDay(day1, fetcher)).reference).toBe('Romans 8:28');
await fetchVerseOfDay(new Date('2026-10-06T23:00:00Z'), fetcher);
expect(fetcher).toHaveBeenCalledTimes(1);
await fetchVerseOfDay(new Date('2026-10-07T01:00:00Z'), fetcher);
expect(fetcher).toHaveBeenCalledTimes(2);
expect(fetcher.mock.calls[0][0]).toContain('/bibles/eng_kjv/verse-of-the-day');
expect(fetcher.mock.calls[0][1].headers['X-IQBible-API-Key']).toBe('k');
});
test('without a key, or when IQ Bible fails, there is no verse (and nothing is remembered)', async () => {
delete process.env.IQBIBLE_API_KEY;
expect(await fetchVerseOfDay(new Date(), ok())).toBeNull();
process.env.IQBIBLE_API_KEY = 'k';
expect(await fetchVerseOfDay(new Date(), vi.fn(async () => ({ ok: false })))).toBeNull();
expect(await fetchVerseOfDay(new Date(), vi.fn(async () => { throw new Error('down'); }))).toBeNull();
expect((await fetchVerseOfDay(new Date(), ok())).reference).toBe('Romans 8:28'); // a later good answer still works
});