|
|
@@ -0,0 +1,73 @@
|
|
|
+import test from 'node:test';
|
|
|
+import assert from 'node:assert/strict';
|
|
|
+import vm from 'node:vm';
|
|
|
+import { readFileSync } from 'node:fs';
|
|
|
+
|
|
|
+const gatewaySource = readFileSync(new URL('../deploy-admin-functions.mjs', import.meta.url), 'utf8');
|
|
|
+const source = gatewaySource.match(/const LEGACY_APPOINTMENT_PULLS=new Map\(\),LEGACY_APPOINTMENT_VERSIONS=new Map\(\);[\s\S]*?\nconst APP_LIVE_SCOPES=/)?.[0]
|
|
|
+ .replace(/\nconst APP_LIVE_SCOPES=[\s\S]*$/, '');
|
|
|
+assert.ok(source, '未找到旧系统预约拉取实现');
|
|
|
+
|
|
|
+function contextFor(rows) {
|
|
|
+ const context = {
|
|
|
+ console,
|
|
|
+ URLSearchParams,
|
|
|
+ AbortSignal,
|
|
|
+ Map,
|
|
|
+ Date,
|
|
|
+ String,
|
|
|
+ Promise,
|
|
|
+ number(value, fallback = 0) { const parsed = Number(value); return Number.isFinite(parsed) ? parsed : fallback; },
|
|
|
+ firstValue(...values) { return values.find((value) => value !== undefined && value !== null && value !== ''); },
|
|
|
+ appOverviewScheduleRow(row) {
|
|
|
+ return {
|
|
|
+ objectId: row.objectId,
|
|
|
+ GeneralID: Number(row.generalId),
|
|
|
+ ID: Number(row.generalId),
|
|
|
+ Title: row.title,
|
|
|
+ Title2: row.courseTitle,
|
|
|
+ cancelled: Number(row.commonStatus) === -2,
|
|
|
+ dszt: row.dszt,
|
|
|
+ szyh: row.szyh,
|
|
|
+ pl: row.pl,
|
|
|
+ bxrq: row.bxrq,
|
|
|
+ yysj: row.yysj,
|
|
|
+ sdsd: row.sdsd,
|
|
|
+ dslx: row.dslx,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ async appLegacyConfig() { return { url: 'https://legacy.example/api', apiId: 'id', apiKey: 'key' }; },
|
|
|
+ async fetch(url) {
|
|
|
+ assert.match(String(url), /myfield2=szyh%3D42/);
|
|
|
+ return { ok: true, async text() { return JSON.stringify({ retcode: 1, result: JSON.stringify(rows), page: { itemCount: rows.length, pageCount: 1 } }); } };
|
|
|
+ },
|
|
|
+ };
|
|
|
+ vm.runInNewContext(`${source};this.normalize=legacyAppointmentRecord;this.sync=performLegacyAppointmentSync;this.merge=mergeCompanionRows;this.dateKey=companionDateKey`, context);
|
|
|
+ return context;
|
|
|
+}
|
|
|
+
|
|
|
+test('旧系统预约按学员读取并保留日期、状态与课程信息', async () => {
|
|
|
+ const rows = [
|
|
|
+ { GeneralID: 859161, Title: '灵灵(60分钟练习)', Subtitle: '阅读写作', szyh: 42, pl: 155, kcid: 398, bxrq: '2026-09-26', yysj: '2026-09-26 19:00', sdsd: '19:00', dslx: 2, dszt: 0, Status: 99 },
|
|
|
+ { GeneralID: 900001, Title: '其他学员', szyh: 7, pl: 155, bxrq: '2026-09-27', dszt: 0, Status: 99 },
|
|
|
+ ];
|
|
|
+ const context = contextFor(rows);
|
|
|
+ assert.equal(context.normalize(rows[1], 'szyh', 42), null);
|
|
|
+ const result = await context.sync('szyh', 42);
|
|
|
+ assert.equal(result.state, 'current');
|
|
|
+ assert.equal(result.items.length, 1);
|
|
|
+ assert.equal(result.items[0].GeneralID, 859161);
|
|
|
+ assert.equal(result.items[0].Title, '灵灵(60分钟练习)');
|
|
|
+ assert.equal(result.items[0].dszt, 0);
|
|
|
+ assert.equal(context.dateKey(result.items[0]), '2026-09-26');
|
|
|
+});
|
|
|
+
|
|
|
+test('旧系统预约覆盖过期快照并补入后续计划', () => {
|
|
|
+ const context = contextFor([]);
|
|
|
+ const stored = [{ GeneralID: 1, dszt: 0, bxrq: '2026-09-02' }];
|
|
|
+ const live = [{ GeneralID: 1, dszt: 30, bxrq: '2026-09-02' }, { GeneralID: 2, dszt: 0, bxrq: '2026-09-26' }];
|
|
|
+ const merged = context.merge(stored, live);
|
|
|
+ assert.equal(merged.length, 2);
|
|
|
+ assert.equal(merged.find((row) => row.GeneralID === 1).dszt, 30);
|
|
|
+ assert.equal(merged.find((row) => row.GeneralID === 2).bxrq, '2026-09-26');
|
|
|
+});
|