schedule-live-reconciliation.test.mjs 2.8 KB

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