import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import vm from 'node:vm'; const source=fs.readFileSync(new URL('../common/request.js',import.meta.url),'utf8').replace(/^import .*$/mg,''); function harness(refresh) { const storage=new Map([['token','old'],['refreshToken','refresh'],['clientId','client']]); let failure, retried=0, redirects=0; const context={module:{exports:{}},console:{log(){}},dayjs:()=>({unix:()=>123}),refreshToken:refresh, uni:{getStorageSync:k=>storage.get(k),setStorageSync:(k,v)=>storage.set(k,v),removeStorageSync:k=>storage.delete(k), redirectTo:()=>redirects++, $u:{toast(){},http:{request:async()=>{retried++;return 'retried';}, interceptors:{request:{use(){}},response:{use:(ok,bad)=>failure=bad}}}}}}; vm.runInNewContext(source,context); context.module.exports({}); return {storage, failure:e=>failure(e), counts:()=>({retried,redirects})}; } const unauthorized=()=>({statusCode:401,config:{url:'/app/me',header:{},custom:{auth:true}}}); test('successful refresh retries once with new access credential', async()=>{ const h=harness(async()=>({success:true,accessToken:'new'})); const error=unauthorized(); assert.equal(await h.failure(error),'retried'); assert.equal(error.config.header.Authorization,'new'); assert.equal(h.storage.get('refreshToken'),'refresh'); await assert.rejects(h.failure(error)); assert.equal(h.counts().retried,1); }); test('failed, malformed or missing refresh stops original request',async()=>{ for(const mode of ['failure','malformed','missing']) { let calls=0; const h=harness(async()=>{calls++;if(mode==='failure')throw new Error('denied');return {success:false};}); if(mode==='missing')h.storage.delete('refreshToken'); await assert.rejects(h.failure(unauthorized())); assert.equal(h.counts().retried,0);assert.equal(h.storage.has('token'),false); assert.equal(calls,mode==='missing'?0:1); } });