66 lines
4.1 KiB
JavaScript
66 lines
4.1 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const crypto = require('node:crypto');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const vm = require('node:vm');
|
|
const ts = require('typescript');
|
|
|
|
function load(file, deps = {}, globals = {}) {
|
|
const exports = {};
|
|
const source = fs.readFileSync(path.resolve(__dirname, '../functions', file), 'utf8');
|
|
const code = ts.transpileModule(source, { compilerOptions: { target:ts.ScriptTarget.ES2020, module:ts.ModuleKind.CommonJS } }).outputText;
|
|
vm.runInNewContext(code, { exports, require:name=>{
|
|
if (!(name in deps)) throw new Error('Missing test dependency: '+name);
|
|
return deps[name];
|
|
}, Date, ...globals });
|
|
return exports;
|
|
}
|
|
const ids = [1,2,3,4,5,6].map(i=>'new_gold_'+i).concat([8,18,36,68,98].map(i=>'new_unlimited_health_bundle_'+i));
|
|
const prices = [600,3000,6800,12800,32800,64800,800,1800,3600,6800,9800];
|
|
function fixture() {
|
|
const state={orders:[],requests:[],user:{_id:'u',openid:'o',session_key:'session'}};
|
|
const db={collection:()=>({add:async row=>{state.orders.push(row);return {};},where:()=>({getOne:async()=>({data:state.user}),update:async()=>({})})})};
|
|
const cloud={database:()=>db,shared:{get:()=> 'token'},storage:{bucket:()=>({readFile:async()=>({Body:{transformToString:async()=> 'synthetic-key'}})})}};
|
|
const deps={
|
|
'@lafjs/cloud':{default:cloud},
|
|
'@/limitedTimeEvent':{starterPackOrderSnapshot:()=>({})},
|
|
'@/passCheckUpgrade':{passOrderFields:()=>({}),PASS_PRICES:{}},
|
|
'@/jungleConfig':{getJunglePaidTierByProductId:()=>null},
|
|
crypto:{...crypto,default:{...crypto,createSign:()=>({update(){},sign:()=> 'synthetic-signature'})}}
|
|
};
|
|
const globals={console:{log(){},error(){}},process:{env:{PAYMENT_APP_ENV:'test',WX_MIDAS_PAY_SIGN_KEY:'synthetic-key'}},
|
|
fetch:async(url,options)=>{state.requests.push({url,body:JSON.parse(options.body)});return {ok:true,json:async()=>({prepay_id:'synthetic-prepay',errcode:0})};}};
|
|
return {state,load:file=>load(file,deps,globals).default};
|
|
}
|
|
|
|
test('both signing endpoints enforce all eleven B prices and quantity one', async()=>{
|
|
for(const file of ['wx/orderPaySig.ts','wx/iosorderPaySig.ts']) {
|
|
const f=fixture(), create=f.load(file);
|
|
for(const [i,id] of ids.entries()) {
|
|
const result=await create({body:{uid:'u',itemid:id,itemCount:99,itemPrice:1}});
|
|
assert.equal(result.code,1);
|
|
const signed=JSON.parse(result.data.signData), row=f.state.orders[i];
|
|
assert.equal(row.itemid,id);assert.equal(row.itemCount,1);assert.equal(row.goodsPrice,prices[i]);
|
|
assert.equal(signed.productId,id);assert.equal(signed.buyQuantity,1);assert.equal(signed.goodsPrice,prices[i]);
|
|
assert.equal(result.data.paySig,crypto.createHmac('sha256','synthetic-key').update('requestMidasPaymentGameItem&'+result.data.signData).digest('hex'));
|
|
}
|
|
const legacy=await create({body:{uid:'u',itemid:'gold_2',itemCount:1,itemPrice:3600}});
|
|
assert.equal(legacy.code,1);assert.equal(f.state.orders.at(-1).goodsPrice,3600);
|
|
}
|
|
});
|
|
|
|
test('legacy iOS cashier uses all B prices, display names and order IDs',async()=>{
|
|
const f=fixture(), create=f.load('wx/KeFuInfo.ts');
|
|
for(const [i,id] of ids.entries()) {
|
|
await create({body:{FromUserName:'o',SessionFrom:JSON.stringify({tpye:'ios',propName:id,price:1,count:99,outTradeNo:'ios-'+i})}});
|
|
const row=f.state.orders[i];assert.ok(row,'customer-service request must create order');
|
|
assert.equal(row.goodsPrice,prices[i]);assert.equal(row.itemCount,1);assert.equal(row.itemid,id);
|
|
const payments=f.state.requests.filter(r=>r.url.includes('/v3/pay/transactions/jsapi'));
|
|
assert.equal(payments[i].body.amount.total,prices[i]);
|
|
const link=f.state.requests.filter(r=>r.body.msgtype==='link')[i].body.link;
|
|
const data=JSON.parse(decodeURIComponent(link.url.split('#data=')[1]));
|
|
assert.equal(data.name,i < 6 ? '新版金币包'+(i+1) : '新版组合礼包'+[8,18,36,68,98][i-6]+'元');assert.equal(data.price,prices[i]);assert.equal(data.outTradeNo,'ios-'+i);
|
|
}
|
|
});
|