'use strict' const assert=require('assert'),fs=require('fs'),path=require('path'),vm=require('vm') const {createMock,install,ORIGIN}=require('./runtime') async function main(){ const data={};const storage={get:k=>data[k],set:(k,v)=>{data[k]=v}};const mock=createMock(storage) const call=(p,method='GET',input={})=>mock.request(ORIGIN+p,method,input) assert.equal(call('/login','POST').data.user.id,900000001) assert.equal(call('/user/center').data.rank_profile.rank_id,0) assert.equal(call('/other/user/rand/square').data.data.length,3) assert.equal(call('/other/user/rand/square?page=2').data.data.length,0) assert.equal(call('/other/user/999').code,1) assert.equal(call('/user/other/profie','PUT',{introduction:'edited',rank_id:999,is_approved:1}).code,0) assert.equal(call('/user/profile').data.introduction,'edited');assert.equal(call('/user/center').data.user.rank_id,0) assert.equal(call('/moment/add','POST',{content:''}).code,1) const added=call('/moment/add','POST',{content:'local test'}).data assert.equal(call('/moment/list').data.data[0].id,added.id) assert.equal(call('/moment/'+added.id+'/like','POST').data.like_count,1) assert.equal(call('/moment/'+added.id+'/like','POST').data.like_count,0) assert.equal(createMock(storage).snapshot().moments.length,2) assert.equal(call('/register/sms/code','POST').data.mock,true) assert.equal(call('/user/register/profile','PUT',{code:'wrong'}).code,1) assert.equal(call('/user/register/profile','PUT',{code:'000000'}).code,0) for(const p of ['/pay','/refund','/not-implemented','/upload','/certification'])assert.equal(call(p,'POST').code,1) for(const url of ['https://example.invalid/login','http://127.0.0.1:18765.evil/go/api/login',ORIGIN+'evil/login','//example.invalid'])assert.equal(mock.request(url,'POST',{}).code,1) mock.scenario('failure',true);assert.equal(call('/user/profile').code,1);mock.reset();assert.equal(call('/user/profile').code,0) let external=0;const saved={token:'real-state-must-stay'} const wx={getStorageSync:k=>saved[k],setStorageSync:(k,v)=>{saved[k]=v},removeStorageSync:k=>{delete saved[k]},getStorageInfoSync:()=>({keys:Object.keys(saved)}),showToast(){},request(){external++;throw Error('Network accessed')},login(){external++},getImageInfo(o){o.success({path:o.src})}} const isolated=install(wx) function invoke(name,opts={}){return new Promise(resolve=>wx[name]({...opts,success:r=>resolve({ok:true,r}),fail:r=>resolve({ok:false,r})}))} assert.equal((await invoke('login')).r.code,'LOCAL-MOCK-CODE') assert.equal((await invoke('request',{url:ORIGIN+'/login',method:'POST'})).r.data.code,0) assert.equal((await invoke('request',{url:'https://example.invalid'})).r.data.code,1) for(const name of ['uploadFile','downloadFile','connectSocket','requestPayment','requestVirtualPayment','navigateToMiniProgram','requestSubscribeMessage','openCustomerServiceChat','makePhoneCall'])assert.equal((await invoke(name)).ok,false,name) wx.setStorageSync('token','local');assert.equal(saved.token,'real-state-must-stay');assert.equal(wx.getStorageSync('token'),'local') wx.clearStorageSync();assert.equal(saved.token,'real-state-must-stay');assert.equal(wx.getStorageSync('token'),undefined) assert.equal(external,0);isolated.reset() console.log('PASS: login, pagination, profile persistence, privilege isolation, publish/like, SMS fixture, unsupported operations, failures, storage isolation and zero native transport calls') const build=path.resolve(__dirname,'../../../.local-acceptance/mp-mock-build/weapp') if(fs.existsSync(build)){ let count=0;function walk(dir){for(const e of fs.readdirSync(dir,{withFileTypes:true})){const p=path.join(dir,e.name);if(e.isDirectory())walk(p);else if(e.name.endsWith('.js')){new vm.Script(fs.readFileSync(p,'utf8'),{filename:p});count++}}}walk(build) assert(fs.readFileSync(path.join(build,'app.js'),'utf8').startsWith("require('./acceptance-runtime').install(wx);")) assert.equal(JSON.parse(fs.readFileSync(path.join(build,'app.json'))).pages[0],'local-acceptance/index') console.log('PASS: '+count+' generated JavaScript files parse; isolation loads before application; acceptance launch page configured') } } main().catch(error=>{console.error(error);process.exitCode=1})