const test=require('node:test'); const assert=require('node:assert/strict'); const path=require('node:path'); function setup(){ const id='K_iQMwE_jre0j6QDVL78DZz7wiR1SKVY5h2YJCK6uPU'; const storage={userId:'user',coupleId:'couple',token:'token'},reads=[],prompts=[],saves=[],ui=[]; const app={globalData:{authState:'ready'}}; const load=require('./load-module.cjs')({console:{warn(){},error(){}},Promise,Date,getApp:()=>app,wx:{ getStorageSync:key=>storage[key],setStorageSync:(key,value)=>storage[key]=value, getSetting:o=>reads.push(o),requestSubscribeMessage:o=>prompts.push(o), showToast:o=>ui.push(o),showModal:o=>ui.push(o) }},{'./request':{api:{subscribeTemplate:async(data,options)=>{saves.push({data,options});return {success:true}}}}}); const helper=load(path.join(__dirname,'../utils/subscribe.js')); const ready=(settings={mainSwitch:true,itemSettings:{[id]:'accept'}})=>reads.at(-1).success({subscriptionsSetting:settings}); return {id,storage,reads,prompts,saves,ui,app,helper,ready}; } test('login only reads remembered settings; first real tap renews synchronously once per cold session',async()=>{ const e=setup();e.helper.resetLoginRenewal();e.helper.prepareLoginRenewal(); assert.equal(e.reads[0].withSubscriptions,true);assert.equal(e.prompts.length,0);assert.equal(e.helper.tryLoginRenewal(),undefined); e.ready();const pending=e.helper.tryLoginRenewal();assert.equal(e.prompts.length,1); assert.equal(e.helper.tryLoginRenewal(),undefined); e.prompts[0].success({[e.id]:'accept'});await pending; assert.equal(e.saves[0].data.template_type,'notify');assert.equal(e.saves[0].options.silent,true);assert.equal(e.ui.length,0); e.ready();e.helper.prepareLoginRenewal();e.ready();e.helper.tryLoginRenewal();assert.equal(e.prompts.length,1); e.helper.resetLoginRenewal();e.helper.prepareLoginRenewal();e.ready();e.helper.tryLoginRenewal();assert.equal(e.prompts.length,2); }); test('unknown permission, not remembered, rejected, banned and disabled main switch never request subscription',()=>{ for(const settings of [{},{mainSwitch:true},{mainSwitch:true,itemSettings:{}},{mainSwitch:true,itemSettings:{bad:'accept'}},{mainSwitch:true,itemSettings:{K_iQMwE_jre0j6QDVL78DZz7wiR1SKVY5h2YJCK6uPU:'reject'}},{mainSwitch:false,itemSettings:{K_iQMwE_jre0j6QDVL78DZz7wiR1SKVY5h2YJCK6uPU:'accept'}}]){ const e=setup();e.helper.prepareLoginRenewal();e.ready(settings);e.helper.tryLoginRenewal();assert.equal(e.prompts.length,0);assert.equal(e.ui.length,0); } }); test('unbound, locally disabled or unauthenticated users never auto-renew',()=>{ for(const change of [e=>e.storage.coupleId='',e=>e.storage.subscribed_notify=false,e=>e.app.globalData.authState='loading']){ const e=setup();e.helper.prepareLoginRenewal();e.ready();change(e);e.helper.tryLoginRenewal();assert.equal(e.prompts.length,0); } }); test('settings failures and stale callbacks fail closed',()=>{ const e=setup();e.helper.prepareLoginRenewal();e.reads[0].fail();e.helper.tryLoginRenewal();assert.equal(e.prompts.length,0); e.helper.prepareLoginRenewal();const stale=e.reads.at(-1);e.helper.resetLoginRenewal();stale.success({subscriptionsSetting:{mainSwitch:true,itemSettings:{[e.id]:'accept'}}});e.helper.tryLoginRenewal();assert.equal(e.prompts.length,0); e.helper.prepareLoginRenewal();e.ready();e.helper.prepareLoginRenewal();e.helper.tryLoginRenewal();assert.equal(e.prompts.length,0); }); test('renewal failures remain silent and do not retry repeatedly during the same session',async()=>{ const e=setup();e.helper.prepareLoginRenewal();e.ready();const pending=e.helper.tryLoginRenewal();e.prompts[0].fail({errCode:20001});await pending; assert.equal(e.ui.length,0);e.ready();e.helper.tryLoginRenewal();assert.equal(e.prompts.length,1); });