import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; const markStockGoneMock = vi.fn(); const getStockEntryMock = vi.fn(); const listGroupedStockEntriesMock = vi.fn(); vi.mock('../../../src/api/stock.js', () => ({ markStockGone: (...args) => markStockGoneMock(...args), getStockEntry: (...args) => getStockEntryMock(...args), adjustStockEntry: vi.fn(), lookupItemDetails: vi.fn(), patchStockItem: vi.fn(), listStockEntries: vi.fn(), listGroupedStockEntries: (...args) => listGroupedStockEntriesMock(...args), updateStockItem: vi.fn(), })); vi.mock('../../../src/api/locations.js', () => ({ fetchLocations: vi.fn(async () => ({ flat: [], tree: [] })), })); const { stockDetailPageData } = await import('../../../src/features/stock/stock-detail-page.js'); const { stockListPageData } = await import('../../../src/features/stock/stock-list-page.js'); describe('stock mark-gone behavior', () => { beforeEach(() => { markStockGoneMock.mockReset(); getStockEntryMock.mockReset(); listGroupedStockEntriesMock.mockReset(); globalThis.window = { __loncApp: { navigate: vi.fn(), }, }; }); afterEach(() => { vi.restoreAllMocks(); delete globalThis.window; }); it('stock detail markGone posts gone event and shows info for already gone', async () => { markStockGoneMock.mockResolvedValueOnce({ status: 'already_gone' }); const addAlert = vi.fn(); const data = stockDetailPageData({ addAlert }); data.entry = { uuid_b64: 'item-1', name: 'Rice' }; await data.markGone(); expect(markStockGoneMock).toHaveBeenCalledWith({ addAlert }, 'item-1', 'consumed'); expect(addAlert).toHaveBeenCalledWith({ type: 'info', message: 'Rice was already out of stock.', }); expect(globalThis.window.__loncApp.navigate).toHaveBeenCalledWith('/stock'); }); it('stock list markGone removes entry and posts gone event', async () => { markStockGoneMock.mockResolvedValueOnce({ status: 'ok' }); const addAlert = vi.fn(); const data = stockListPageData({ addAlert, isConnected: false }); data.entries = [{ id: 1, uuid_b64: 'item-1', name: 'Flour' }]; data.editForms = { 1: { level: 'plenty', quantity: 1 } }; data.editErrors = {}; await data.markGone(data.entries[0]); expect(markStockGoneMock).toHaveBeenCalledWith({ addAlert, isConnected: false }, 'item-1', 'consumed'); expect(data.entries).toEqual([]); expect(addAlert).toHaveBeenCalledWith({ type: 'success', message: 'Flour was marked used and removed from the list.', }); }); it('stock list grouped markGone removes item from grouped and flat collections', async () => { markStockGoneMock.mockResolvedValueOnce({ status: 'ok' }); listGroupedStockEntriesMock.mockResolvedValueOnce([]); const addAlert = vi.fn(); const store = { addAlert, isConnected: true }; const data = stockListPageData(store); data.groupedLoaded = true; data.groupedEntries = [ { id: 10, uuid_b64: 'group-10', name: 'Beans', stock_type: 'measured', location_initial_uuid_b64: null, date: '2026-04-12', expire_date: '2026-04-20', items: [ { id: 11, uuid_b64: 'item-11', name: 'Beans', stock_type: 'measured', quantity: 1, location_initial_uuid_b64: null, date: '2026-04-12', expire_date: '2026-04-20', }, ], }, ].map((group) => data.indexGroup(group)); data.entries = [ data.indexEntry({ id: 11, uuid_b64: 'item-11', name: 'Beans', stock_type: 'measured', quantity: 1, location_initial_uuid_b64: null, date: '2026-04-12', expire_date: '2026-04-20', }), ]; data.entriesVersion = 1; data.groupedVersion = 1; data.editForms = { 11: { level: 'plenty', quantity: 1 } }; data.editErrors = {}; await data.markGoneFromGroup(data.groupedEntries[0].items[0], data.groupedEntries[0]); expect(data.entries).toEqual([]); expect(data.groupedEntries).toEqual([]); expect(addAlert).toHaveBeenCalledWith({ type: 'success', message: 'Beans was marked used and removed from the group.', }); expect(listGroupedStockEntriesMock).toHaveBeenCalledTimes(1); expect(listGroupedStockEntriesMock).toHaveBeenCalledWith(store, { expanded: 0 }); }); });