53 lines
3.1 KiB
React
53 lines
3.1 KiB
React
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(<AppContext.Provider value={{ jumpToReaderVerse: jump, openBibleReader: open }}><IqDictionary /></AppContext.Provider>);
|
|
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(<AppContext.Provider value={{ jumpToReaderVerse: jump, openBibleReader: open }}><IqDictionary /></AppContext.Provider>);
|
|
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);
|
|
});
|