legacy-appointment-pull.test.mjs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import test from 'node:test';
  2. import assert from 'node:assert/strict';
  3. import vm from 'node:vm';
  4. import { readFileSync } from 'node:fs';
  5. const gatewaySource = readFileSync(new URL('../deploy-admin-functions.mjs', import.meta.url), 'utf8');
  6. const source = gatewaySource.match(/const LEGACY_APPOINTMENT_PULLS=new Map\(\),LEGACY_APPOINTMENT_VERSIONS=new Map\(\);[\s\S]*?\nconst APP_LIVE_SCOPES=/)?.[0]
  7. .replace(/\nconst APP_LIVE_SCOPES=[\s\S]*$/, '');
  8. assert.ok(source, '未找到旧系统预约拉取实现');
  9. function contextFor(rows) {
  10. const context = {
  11. console,
  12. URLSearchParams,
  13. AbortSignal,
  14. Map,
  15. Date,
  16. String,
  17. Promise,
  18. number(value, fallback = 0) { const parsed = Number(value); return Number.isFinite(parsed) ? parsed : fallback; },
  19. firstValue(...values) { return values.find((value) => value !== undefined && value !== null && value !== ''); },
  20. appOverviewScheduleRow(row) {
  21. return {
  22. objectId: row.objectId,
  23. GeneralID: Number(row.generalId),
  24. ID: Number(row.generalId),
  25. Title: row.title,
  26. Title2: row.courseTitle,
  27. cancelled: Number(row.commonStatus) === -2,
  28. dszt: row.dszt,
  29. szyh: row.szyh,
  30. pl: row.pl,
  31. bxrq: row.bxrq,
  32. yysj: row.yysj,
  33. sdsd: row.sdsd,
  34. dslx: row.dslx,
  35. };
  36. },
  37. async appLegacyConfig() { return { url: 'https://legacy.example/api', apiId: 'id', apiKey: 'key' }; },
  38. async fetch(url) {
  39. assert.match(String(url), /myfield2=szyh%3D42/);
  40. return { ok: true, async text() { return JSON.stringify({ retcode: 1, result: JSON.stringify(rows), page: { itemCount: rows.length, pageCount: 1 } }); } };
  41. },
  42. };
  43. vm.runInNewContext(`${source};this.normalize=legacyAppointmentRecord;this.sync=performLegacyAppointmentSync;this.merge=mergeCompanionRows;this.dateKey=companionDateKey`, context);
  44. return context;
  45. }
  46. test('旧系统预约按学员读取并保留日期、状态与课程信息', async () => {
  47. const rows = [
  48. { 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 },
  49. { GeneralID: 900001, Title: '其他学员', szyh: 7, pl: 155, bxrq: '2026-09-27', dszt: 0, Status: 99 },
  50. ];
  51. const context = contextFor(rows);
  52. assert.equal(context.normalize(rows[1], 'szyh', 42), null);
  53. const result = await context.sync('szyh', 42);
  54. assert.equal(result.state, 'current');
  55. assert.equal(result.items.length, 1);
  56. assert.equal(result.items[0].GeneralID, 859161);
  57. assert.equal(result.items[0].Title, '灵灵(60分钟练习)');
  58. assert.equal(result.items[0].dszt, 0);
  59. assert.equal(context.dateKey(result.items[0]), '2026-09-26');
  60. });
  61. test('旧系统预约覆盖过期快照并补入后续计划', () => {
  62. const context = contextFor([]);
  63. const stored = [{ GeneralID: 1, dszt: 0, bxrq: '2026-09-02' }];
  64. const live = [{ GeneralID: 1, dszt: 30, bxrq: '2026-09-02' }, { GeneralID: 2, dszt: 0, bxrq: '2026-09-26' }];
  65. const merged = context.merge(stored, live);
  66. assert.equal(merged.length, 2);
  67. assert.equal(merged.find((row) => row.GeneralID === 1).dszt, 30);
  68. assert.equal(merged.find((row) => row.GeneralID === 2).bxrq, '2026-09-26');
  69. });