const test=require('node:test'); const assert=require('node:assert/strict'); const path=require('node:path'); const template='tOaqM_Z6pNSih2pVpaUmP86MgwnDT5ZlwOqd0lgmXP8'; function setup(save){ const storage={coupleId:10},calls=[]; const wx={getStorageSync:key=>storage[key],setStorageSync:(key,v)=>storage[key]=v,requestSubscribeMessage:o=>calls.push(o)}; const load=require('./load-module.cjs')({wx,console:{warn(){},error(){}}},{'./request':{api:{subscribeTemplate:save}}}); return {helper:load(path.join(__dirname,'../utils/subscribe.js')),storage,calls}; } test('authorization is immediate and concurrent calls share one prompt until persistence finishes',async()=>{ let complete,saves=0;const e=setup(()=>{saves++;return new Promise(resolve=>complete=resolve)}); const first=e.helper.requestSubscribe('notify');assert.equal(e.calls.length,1); assert.equal(e.helper.requestSubscribe('notify'),first); e.calls[0].success({[template]:'accept'}); let finished=false;first.then(()=>finished=true);await Promise.resolve(); assert.equal(finished,false);assert.equal(e.storage.subscribed_notify,undefined); complete({success:true});const result=await first;assert.equal(result.notify,true);assert.equal(saves,1);assert.equal(e.storage.subscribed_notify,true); }); test('failed persistence never reports successful subscription and a later tap can retry',async()=>{ let fail=true;const e=setup(async()=>{if(fail)throw Error('offline');return {success:true}}); let pending=e.helper.requestSubscribe('notify');e.calls[0].success({[template]:'accept'}); await assert.rejects(pending,/offline/);assert.equal(e.storage.subscribed_notify,undefined); fail=false;pending=e.helper.requestSubscribe('notify');assert.equal(e.calls.length,2);e.calls[1].success({[template]:'accept'}); assert.equal((await pending).notify,true); }); test('each subsequent user action can replenish authorization; denial does not prevent later attempts',async()=>{ const e=setup(async()=>({success:true})); let pending=e.helper.requestSubscribeAfterAction('diary');assert.equal(e.calls.length,1);e.calls[0].success({[template]:'reject'});await pending; pending=e.helper.requestSubscribeAfterAction('photo');assert.equal(e.calls.length,2);e.calls[1].success({[template]:'accept'});await pending; pending=e.helper.requestSubscribeAfterAction('checkin');assert.equal(e.calls.length,3);e.calls[2].fail(Error('cancelled'));await pending; pending=e.helper.requestSubscribeAfterAction('checkin');assert.equal(e.calls.length,4);e.calls[3].success({[template]:'accept'});await pending; }); test('explicitly disabled notifications and unbound users do not prompt during business actions',async()=>{ const e=setup(async()=>({success:true}));e.storage.subscribed_notify=false;await e.helper.requestSubscribeAfterAction('diary');assert.equal(e.calls.length,0); delete e.storage.subscribed_notify;delete e.storage.coupleId;await e.helper.requestSubscribeAfterAction('diary');assert.equal(e.calls.length,0); }); test('manual renewal requests authorization again without disabling existing notifications',async()=>{ let page, calls=0, cancelled=0, complete; const loader=require('./load-module.cjs')({Page:p=>page=p,wx:{showToast(){}}},{ '../../utils/layout':{getLayout:()=>({})}, '../../utils/request':{api:{unsubscribeTemplate:()=>cancelled++}}, '../../utils/subscribe':{requestSubscribe:()=>{calls++;return new Promise(resolve=>complete=resolve)},getSubscribeStatus:async()=>({notify:true})} }); loader(path.join(__dirname,'../pages/settings/settings.js')); const instance={data:{subscribeChecked:true},setData(v){Object.assign(this.data,v)}}; let pending=page.renewSubscribe.call(instance); assert.equal(calls,1);await page.renewSubscribe.call(instance);assert.equal(calls,1); complete({notify:true});await pending;assert.equal(instance.data.subscribeChecked,true);assert.equal(cancelled,0); pending=page.renewSubscribe.call(instance);assert.equal(calls,2);complete({notify:false});await pending; assert.equal(instance.data.subscribeChecked,true);assert.equal(instance._subscribing,false); });