import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; const lookupItemDetailsMock = vi.fn(); const patchStockItemMock = vi.fn(); const getStockEntryMock = vi.fn(); vi.mock('../../../src/api/stock.js', () => ({ adjustStockEntry: vi.fn(), getStockEntry: (...args) => getStockEntryMock(...args), lookupItemDetails: (...args) => lookupItemDetailsMock(...args), patchStockItem: (...args) => patchStockItemMock(...args), useStockItem: vi.fn(), })); vi.mock('../../../src/api/labels.js', () => ({ printItemLabel: vi.fn(), formatPrintErrorMessage: (error) => error?.message || 'Printing failed.', })); vi.mock('../../../src/api/locations.js', () => ({ fetchLocations: vi.fn(async () => ({ flat: [], tree: [] })), })); const { stockDetailPageData } = await import('../../../src/features/stock/stock-detail-page.js'); describe('stock detail identifier and OFF lookup', () => { beforeEach(() => { lookupItemDetailsMock.mockReset(); patchStockItemMock.mockReset(); getStockEntryMock.mockReset(); globalThis.window = { __loncApp: { navigate: vi.fn(), }, }; }); afterEach(() => { vi.restoreAllMocks(); delete globalThis.window; }); it('saves normalized identifier code via PATCH', async () => { patchStockItemMock.mockResolvedValueOnce({ uuid_b64: 'item-1', name: 'Milk', identifier_code: '3830012345678', }); const addAlert = vi.fn(); const store = { addAlert, isConnected: false }; const data = stockDetailPageData(store); data.entry = { uuid_b64: 'item-1', name: 'Milk', identifier_code: '' }; data.identifierDraft = ' 3830 0123 45678 '; await data.saveIdentifierCode(); expect(patchStockItemMock).toHaveBeenCalledWith(store, 'item-1', { identifier_code: '3830012345678', }); expect(data.identifierDraft).toBe('3830012345678'); expect(addAlert).toHaveBeenCalledWith({ type: 'success', message: 'Identifier code saved for Milk.', }); }); it('refreshes OFF details and surfaces stale-cache metadata', async () => { lookupItemDetailsMock.mockResolvedValueOnce({ status: 'ok', update: false, updatedFields: ['name', 'nutrition_facts'], staleCache: true, offPayloadFetchedAt: '2026-04-11T09:00:00Z', item: { uuid_b64: 'item-1', name: 'Milk', identifier_code: '3830012345678', }, }); const addAlert = vi.fn(); const store = { addAlert, isConnected: false }; const data = stockDetailPageData(store); data.entry = { uuid_b64: 'item-1', name: 'Milk', identifier_code: '3830012345678' }; data.identifierDraft = '3830012345678'; await data.runItemLookup(false); expect(lookupItemDetailsMock).toHaveBeenCalledWith(store, 'item-1', { update: false }); expect(data.offLookupFeedback.type).toBe('success'); expect(data.offLookupFeedback.message).toContain('Using stale cache data.'); expect(addAlert).toHaveBeenCalledWith({ type: 'success', message: data.offLookupFeedback.message, }); }); it('apply missing fields reloads entry after successful lookup', async () => { lookupItemDetailsMock.mockResolvedValueOnce({ status: 'ok', update: true, updatedFields: ['description'], staleCache: false, offPayloadFetchedAt: null, item: null, }); getStockEntryMock.mockResolvedValueOnce({ uuid_b64: 'item-1', name: 'Milk', identifier_code: '3830012345678', description: 'Whole milk', }); const addAlert = vi.fn(); const store = { addAlert, isConnected: false }; const data = stockDetailPageData(store); data.entry = { uuid_b64: 'item-1', name: 'Milk', identifier_code: '3830012345678' }; data.identifierDraft = '3830012345678'; await data.runItemLookup(true); expect(getStockEntryMock).toHaveBeenCalledWith(store, 'item-1'); expect(data.entry.description).toBe('Whole milk'); expect(data.offLookupFeedback.type).toBe('success'); }); });