| 123456789101112131415161718192021222324252627282930313233343536373839404142 |
- import {test} from 'node:test';
- import assert from 'node:assert/strict';
- import vm from 'node:vm';
- import {readFileSync} from 'node:fs';
- const source=readFileSync(new URL('../deploy-admin-functions.mjs',import.meta.url),'utf8').match(/const operationsGatewayCode = String.raw`([\s\S]*?)\n`;/)[1];
- const payroll=readFileSync(new URL('../cloud/payroll-integrity.js',import.meta.url),'utf8');
- test('business dates preserve Shanghai boundaries and invalid values without constructing formatters per record',()=>{
- let slowCalls=0,formatters=0;
- class MeasuredDate extends Date {toLocaleDateString(...args){slowCalls++;return super.toLocaleDateString(...args);}}
- const c=vm.createContext({Date:MeasuredDate,Intl:{DateTimeFormat:function(...args){formatters++;return new Intl.DateTimeFormat(...args);}}});
- vm.runInContext(source+'\n'+payroll,c);
- const values=['2026-10-31T15:59:59Z','2026-10-31T16:00:00Z','1990-07-01T16:00:00Z','2024-02-29T16:00:00Z','bad','',null,0];
- for(let i=0;i<1000;i++)values.push(new Date(Date.UTC(1985+i%45,i%12,i%28+1,i%24,i%60)).toISOString());
- for(const value of values)assert.equal(c.businessDate(value),new Date(value).toLocaleDateString('sv-SE',{timeZone:'Asia/Shanghai'}));
- for(const value of values){const iso=c.payrollDateIso(value);assert.equal(c.payrollBusinessDate(value),iso?new Date(iso).toLocaleDateString('sv-SE',{timeZone:'Asia/Shanghai'}):'');}
- assert.equal(slowCalls,0,'record loops must reuse the timezone formatter');
- assert.equal(formatters,2);
- });
- test('coach list starts its independent reads together instead of serial round trips',async()=>{
- const pending=[],calls=[];
- const c=vm.createContext({Date,Psql:{query:sql=>{calls.push(sql);return new Promise(resolve=>pending.push(resolve));}}});vm.runInContext(source,c);
- c.companyIdOf=()=> 'tenant';c.availabilityRows=async()=>[];
- const result=c.coachRows({roles:['ops-manager']},{});
- await Promise.resolve();
- const started=calls.length;
- // Let both old serial and new parallel implementations finish before asserting.
- for(let i=0;i<10;i++){for(const resolve of pending.splice(0))resolve([]);await new Promise(r=>setImmediate(r));}
- await result;
- assert.equal(started,3,'users, appointments and lesson facts have no dependency on one another');
- });
- test('release patch changes only the named read helpers and preserves unrelated deployed fixes',async()=>{
- const {patchAdminSpeed,speedHelpers}=await import('../admin-speed-patch.mjs');
- const fixture='const privateDeploymentSetting="preserve";\nfunction unrelatedLatestFix(){return 71;}\n'+speedHelpers.map(name=>`function ${name}(){return "old";}`).join('\n');
- const patched=patchAdminSpeed(fixture);assert.ok(patched.startsWith('const privateDeploymentSetting="preserve";\nfunction unrelatedLatestFix(){return 71;}'));
- assert.match(patched,/function lessonHistoryLabelColumns/);assert.match(patched,/function lessonHistoryLabelJoins/);assert.throws(()=>patchAdminSpeed('function unrelatedLatestFix(){}'),/Missing helper/);
- });
- test('store membership does not load coach payroll or lesson history',async()=>{
- const c=vm.createContext({Date,Psql:{query:async()=>[]}});vm.runInContext(source,c);
- c.companyIdOf=()=> 'tenant';c.queryUsers=async()=>[];c.optionalLegacyMemberSnapshot=async()=>({available:false,items:[],coachIds:[]});c.appointmentSnapshot=async()=>({appointments:[],live:{}});c.operationalSyncIndicator=async()=>({});
- c.coachRows=()=>{throw Error('unnecessary coach history lookup');};
- const page=await c.storeRows({roles:['ops-manager']},{});assert.equal(page.total,0);
- });
|