/* Run with node: actual page functions in a minimal browser context. */ const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const vm = require('node:vm'); const source = fs.readFileSync(path.join(__dirname, '../static/js/app.js'), 'utf8'); function functionSource(start, end) { const offset = source.indexOf(start); assert.ok(offset >= 0, start); const finish = source.indexOf(end, offset); assert.ok(finish > offset, end); return source.slice(offset, finish); } function context() { const calls = []; const overlays = []; const mainContent = { querySelectorAll: () => [], appendChild: element => { element.isConnected = true; } }; const elements = { mainContent }; const environment = { window: { _pageCache: {}, _pageDataCache: {}, _pageReloaders: {} }, document: { getElementById: id => elements[id] || null, querySelectorAll: () => [], querySelector: () => null, createElement: () => ({ style: {}, innerHTML: '' }), body: { appendChild: element => overlays.push(element) } }, domesticOrderPage: 3, overseasOrderPage: 2, packagingOrderPage: 4, domesticLoadOrders: page => calls.push(['domestic', page]), overseasLoadOrders: page => calls.push(['overseas', page]), packagingLoadOrders: page => calls.push(['packaging', page]), loadBackupList: reset => calls.push(['backup', reset]), invalidateOrderColumnCache: type => calls.push(['invalidate', type]), requestAnimationFrame: callback => callback(), setTimeout: callback => callback(), }; vm.createContext(environment); vm.runInContext(functionSource('function _refreshLinkedOrderLists()', '// 防重复提交锁'), environment); vm.runInContext(functionSource('function loadPage(page)', '// ============ SPA 导航系统'), environment); return { environment, calls, overlays, elements }; } // Returning to a previously visited domestic order page queries current records, // even when the order was confirmed in another user's browser. { const { environment: env, calls } = context(); const cached = { style: {}, isConnected: false, querySelectorAll: () => [] }; env.window._pageCache.orders_domestic = cached; env.loadPage('orders_domestic'); assert.equal(cached.isConnected, true); assert.deepEqual(calls, [['invalidate', 'domestic'], ['domestic', 3]]); } // Confirming an order while its destination pages are detached removes their // old containers/data, while unrelated pages remain intact. { const { environment: env, calls } = context(); const pages = ['orders_domestic', 'orders_overseas', 'orders_packaging', 'purchase_ready']; pages.forEach(page => { env.window._pageCache[page] = { isConnected: false }; env.window._pageDataCache[page] = { old: true }; }); const unrelated = { isConnected: false }; env.window._pageCache.planning = unrelated; env._refreshLinkedOrderLists(); pages.forEach(page => { assert.equal(env.window._pageCache[page], undefined); assert.equal(env.window._pageDataCache[page], undefined); }); assert.equal(env.window._pageCache.planning, unrelated); assert.deepEqual(calls, ['domestic', 'overseas', 'packaging', 'backup'].map(type => ['invalidate', type])); } // A currently mounted list stays mounted and refreshes with its current page. { const { environment: env, elements, calls } = context(); const current = { isConnected: true }; env.window._pageCache.orders_domestic = current; elements.domesticOrdersTbody = {}; env._refreshLinkedOrderLists(); assert.equal(env.window._pageCache.orders_domestic, current); assert.deepEqual(calls.at(-1), ['domestic', 3]); } // Finished-product navigation follows the server's route and the backup link // actually opens the backup menu rather than returning to pending orders. for (const [route, url] of [['orders_domestic', '/orders/domestic'], ['orders_overseas', '/orders/overseas']]) { const { environment: env, overlays } = context(); env.showConfirmRedirect(true, false, route); const html = overlays[0].innerHTML; assert.ok(html.includes(`href="${url}"`)); assert.ok(html.includes('href="/purchase/ready"')); assert.ok(!html.includes('href="/purchase"')); } { const { environment: env, overlays } = context(); env.showConfirmRedirect(false, true, null); assert.ok(overlays[0].innerHTML.includes('href="/orders/packaging"')); assert.ok(!overlays[0].innerHTML.includes('href="/orders/domestic"')); } console.log('Order navigation regression tests passed (6 scenarios).');