import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import test from 'node:test'; import vm from 'node:vm'; const source = readFileSync(new URL('../deploy-admin-functions.mjs', import.meta.url), 'utf8'); const gateway = source.match(/const operationsGatewayCode = String.raw`([\s\S]*?)\n`;/)?.[1]; assert.ok(gateway, '运营网关源码可提取'); const context = vm.createContext({ Date, Intl, process: { env: {} } }); vm.runInContext(gateway, context); const startsAt = '2026-10-03T06:00:00.000Z'; const stored = [ { targetId: 'old-1', generalId: 1, sourceKey: 'legacy:model:54:general:1', startsAt, statusCode: 0, readOnly: false }, { targetId: 'old-2', generalId: 2, sourceKey: 'legacy:model:54:general:2', startsAt, statusCode: 0, readOnly: false }, { targetId: 'new-3', generalId: 3, sourceKey: 'cloud:appointment:3', startsAt, statusCode: 0, readOnly: false }, ]; test('完整旧系统快照覆盖同 ID 状态,移除已不在旧系统的迁移预约,保留新系统预约', () => { const live = [{ targetId: 'legacy-live:1', generalId: 1, startsAt, statusCode: 30, readOnly: true }]; const result = context.reconcileScheduleAppointments(stored, live, { available: true, complete: true }, '2026-10-03', '2026-10-03'); assert.deepEqual(Array.from(result, (row) => row.generalId), [3, 1]); assert.equal(result.find((row) => row.generalId === 1).statusCode, 30); assert.equal(result.find((row) => row.generalId === 3).readOnly, false); }); test('旧系统不可用、快照过期或分页不完整时不判定旧预约缺课', () => { for (const sourceState of [ { available: false, complete: false }, { available: true, complete: true, stale: true }, { available: true, complete: false }, ]) { const result = context.reconcileScheduleAppointments(stored, [], sourceState, '2026-10-03', '2026-10-03'); assert.equal(result.length, 3); assert.equal(result[0].statusUnverified, true); assert.equal(result[0].readOnly, true); assert.equal(result[2].statusUnverified, undefined); } }); test('实时排课分页以所选范围数量为准,不被全量历史数量误导', async () => { const requests = []; context.legacyScheduleConfig = async () => ({ url: 'https://example.test', apiId: 'id', apiKey: 'key' }); context.legacyScheduleRequest = async (_config, params) => { requests.push(params); if (params.dateFilter === '2000-01-01') return { items: [], page: { itemCount: 30000 } }; return { items: [{ GeneralID: 1, yysj: '2026-10-03 14:00', dszt: '30' }], page: { itemCount: 1, pageCount: 1 } }; }; const result = await context.liveAppointmentRows({ dateFrom: '2026-10-03' }); assert.equal(result.complete, true); assert.equal(result.total, 30000); assert.equal(result.allItems.length, 1); assert.equal(requests.length, 2); });