import { render, screen, within } 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 IqDictionary from './IqDictionary.jsx'; const LIST = { count: 2, data: [ { id: 'easton', name: "Easton's Bible Dictionary", author: 'Matthew George Easton', year: '1897', license: 'Public domain', entry_count: 3962 }, { id: 'smith', name: "Smith's Bible Dictionary", author: 'William Smith', year: '1863', license: 'Public domain', entry_count: 4488 }, ] }; const ANSWER = { count: 2, data: [ { term: 'Alabaster', slug: 'alabaster', definition: 'A stone box. It mentions a talent.', scripture_refs: ['Matthew 26:7'] }, { term: 'Talent', slug: 'talent', definition: 'The largest Hebrew weight, about 75 pounds.', scripture_refs: ['Exodus 38:25', 'Matthew 25:15'] }, ] }; const jump = vi.fn(); const open = vi.fn(); const asked = []; beforeEach(() => { asked.length = 0; jump.mockClear(); open.mockClear(); localStorage.clear(); vi.stubGlobal('fetch', vi.fn(async (url) => { asked.push(String(url)); const body = String(url).includes('/api/iq/dictionaries/') ? ANSWER : LIST; return { ok: true, status: 200, json: async () => body, text: async () => JSON.stringify(body) }; })); }); test('look up a word: the entry named for it comes first, its Scripture references open in the Reader', async () => { const user = userEvent.setup(); render(); await user.click(screen.getByText('Bible dictionary')); await user.type(await screen.findByRole('textbox', { name: 'Look up a word' }), 'talent{Enter}'); const entry = (await screen.findByRole('heading', { name: 'Talent' })).closest('article'); expect(within(entry).getByText(/about 75 pounds/)).toBeInTheDocument(); expect(asked.some((u) => /dictionaries\/easton\?q=talent/.test(u))).toBe(true); await user.click(within(entry).getByRole('button', { name: 'Matthew 25:15' })); expect(jump).toHaveBeenCalledWith('MAT', 25, 15); expect(open).toHaveBeenCalled(); expect(within(entry).getByText(/Easton's Bible Dictionary, Matthew George Easton, 1897\. Public domain\./)).toBeInTheDocument(); expect(screen.getByText(/Entries that mention|Other entries that mention/)).toBeInTheDocument(); // Alabaster only mentions it }); test('the chosen dictionary is remembered and used for the next lookup', async () => { const user = userEvent.setup(); render(); await user.click(screen.getByText('Bible dictionary')); await user.selectOptions(await screen.findByRole('combobox', { name: 'Dictionary' }), 'smith'); expect(localStorage.getItem('dictionary')).toBe('smith'); await user.type(screen.getByRole('textbox', { name: 'Look up a word' }), 'cubit{Enter}'); await screen.findByRole('heading', { name: 'Talent' }); expect(asked.some((u) => /dictionaries\/smith\?q=cubit/.test(u))).toBe(true); });