// 本地:node scripts/test_proposal_dialog.cjs。内存替身,不发网络请求。 const fs=require('fs'),vm=require('vm'),assert=require('assert'); const html=fs.readFileSync(require('path').join(__dirname,'../app/web/static/index.html'),'utf8'); const block=html.slice(html.indexOf(' const decideDlg = reactive('),html.indexOf(' async function loadStrategies()')); function make(response){ let n=0,resolve; const ctx={reactive:x=>x,computed:f=>f,decideReasons:{accept:{a:'why'},decline:{}},loadDecideReasons:()=>{}, ElementPlus:{ElMessage:{warning:()=>{},success:()=>{},error:()=>{throw Error('failure must stay visible')}}}, loadProposals:async()=>{},loadInstructions:async()=>{},loadLedger:async()=>{},decideTimeoutMs:150000, call:async(m,u,p,c)=>{n++;assert.equal(c.timeout,150000);return typeof response==='function'?response(p):response}}; vm.createContext(ctx);vm.runInContext(block+';this.t={decideDlg,decide,submitDecide}',ctx); return {...ctx.t,count:()=>n}; } (async()=>{ const row={proposal_id:'p1',qty:300,hard_numbers:{proposal_revision:'old'}}; let t=make({ok:false,error:'最新研判不建议建仓:资金净流出',proposal:{...row,hard_numbers:{...row.hard_numbers,last_accept_check:{message:'资金净流出'}}}}); t.decide(row,'ACCEPTED');t.decideDlg.code='ACCEPT_CONSENSUS';await t.submitDecide(); assert(t.decideDlg.visible);assert(!t.decideDlg.busy);assert(t.decideDlg.message.includes('资金净流出'));assert(!t.decideDlg.updated); t=make({ok:false,error:'请确认更新后的建议',proposal:{...row,qty:100,judge_reason:'新理由',hard_numbers:{proposal_revision:'new'}}}); t.decide(row,'ACCEPTED');t.decideDlg.code='ACCEPT_CONSENSUS';await t.submitDecide(); assert(t.decideDlg.visible);assert(t.decideDlg.updated);assert.equal(t.decideDlg.row.qty,100);assert.equal(t.decideDlg.code,''); t=make({ok:false,error:'timeout',uncertain:true});t.decide(row,'ACCEPTED');t.decideDlg.code='ACCEPT_CONSENSUS';await t.submitDecide();await t.submitDecide(); assert.equal(t.count(),1);assert(t.decideDlg.message.includes('尚未收到'));assert(!t.decideDlg.busy); let done;t=make(()=>new Promise(r=>{done=r}));t.decide(row,'ACCEPTED');t.decideDlg.code='ACCEPT_CONSENSUS';const pending=t.submitDecide();await t.submitDecide(); t.decide({...row,proposal_id:'p2'},'DECLINED');assert.equal(t.decideDlg.row.proposal_id,'p1');assert.equal(t.count(),1);done({ok:true,instruction_id:'i1'});await pending;assert(!t.decideDlg.visible); t=make(()=>{throw new Error('unexpected')});t.decide(row,'ACCEPTED');t.decideDlg.code='ACCEPT_CONSENSUS';await t.submitDecide();assert(!t.decideDlg.busy);assert(t.decideDlg.uncertain); t=make({ok:false,withdrawn:true,error:'提议已撤下。资金流出',proposal:{...row,status:'EXPIRED'}}); t.decide(row,'ACCEPTED');t.decideDlg.code='ACCEPT_CONSENSUS';await t.submitDecide();await t.submitDecide(); assert(t.decideDlg.withdrawn);assert(t.decideDlg.visible);assert(!t.decideDlg.updated);assert.equal(t.count(),1); assert(html.includes('')); t.decide(row,'ACCEPTED');assert(!t.decideDlg.withdrawn); const script=html.match(/