legacy-review-sync-runner.test.mjs 2.5 KB

1234567891011121314151617181920212223242526
  1. import test from 'node:test';import assert from 'node:assert/strict';
  2. import {mkdtemp,rm} from 'node:fs/promises';import {tmpdir} from 'node:os';import {join} from 'node:path';
  3. import {runDirectSync} from '../run-nightly-direct-sync.mjs';
  4. test('所有课次同步后分页核定工资,待核定原因进入回执,写入重试复用同一批次',async()=>{
  5. const root=await mkdtemp(join(tmpdir(),'review-sync-runner-')),original=globalThis.fetch,order=[],receipts=new Map();let simulatedLostResponse=false,applied=0,final;
  6. try{
  7. globalThis.fetch=async(url,options)=>{const p=JSON.parse(options.body).params;order.push(p.action==='source'?p.modelId:p.action);let data;
  8. if(p.action==='status')data={source:'old-api/WXAPP',bridgeUsed:false,reviewSyncVersion:'source-owned-v1'};
  9. else if(p.action==='claim')data={runId:'review-sync-test-run',businessDate:'2026-11-02'};
  10. else if(p.action==='supplement')data={accounts:{missing:0},nodes:{missing:0}};
  11. else if(p.action==='source')data={items:[],page:{itemCount:0,pageCount:1}};
  12. else if(p.action==='evidence')data={sourceChecksum:'d41d8cd98f00b204e9800998ecf8427e',targetChecksum:'d41d8cd98f00b204e9800998ecf8427e',reconciled:true};
  13. else if(p.action==='review-income'){
  14. if(!receipts.has(p.batchKey)){applied++;receipts.set(p.batchKey,p.afterTaskId?{processed:0,earned:0,excluded:0,amount:0,pending:1,errors:[{taskId:'z',reason:'来源课次时长仍不明确'}],hasMore:false,afterTaskId:'z'}:{processed:1,earned:1,excluded:0,amount:.5,pending:1,errors:[],hasMore:true,afterTaskId:'a'});}
  15. data=receipts.get(p.batchKey);if(!simulatedLostResponse){simulatedLostResponse=true;throw Error('response lost after commit');}
  16. }
  17. else if(p.action==='finance-members'||p.action==='read')data=[];
  18. else if(p.action==='finish'){final=p.summary;data=p.summary;}
  19. else throw Error('Unexpected action '+p.action);
  20. return {ok:true,json:async()=>({success:true,data})};};
  21. const result=await runDirectSync({XIAOSHU_SYNC_REPORT_DIR:root,XIAOSHU_SYNC_OPERATOR_TOKEN:'test'});
  22. assert.equal(result.status,'completed-with-preserved-conflicts',result.reason);assert.equal(applied,2);assert.equal(receipts.size,2);
  23. assert.equal(final.reviewIncome.earned,1);assert.equal(final.reviewIncome.amount,.5);assert.equal(final.reviewIncome.pending,1);assert.equal(final.conflicts,1);assert.match(final.reviewIncome.errors[0].reason,/时长/);
  24. assert(order.lastIndexOf(59)<order.indexOf('review-income'));assert(order.indexOf('review-income')<order.indexOf('finance-members'));
  25. }finally{globalThis.fetch=original;await rm(root,{recursive:true,force:true});}
  26. });