// @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 });