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