fix: keep starter pack rewards client-side
This commit is contained in:
parent
60f8fc4047
commit
b8e02e08d0
|
|
@ -2692,7 +2692,7 @@ export default class JiaZai extends cc.Component {
|
|||
coinTemp = 1000;
|
||||
}
|
||||
else if (/^starter_pack(?:_[2-5])?$/.test(order.itemid)) {
|
||||
coinTemp = starterPackReward(order.starterPackOffer || res.starterPackOffer).coin;
|
||||
coinTemp = starterPackReward(order.itemid).coin;
|
||||
} else if (order.itemid == "battlepass") {
|
||||
// 通行证订单
|
||||
this.reissuePaaCheck();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
/** Use the order's offer for delivery; missing snapshots retain legacy rewards. */
|
||||
export function starterPackReward(offer?: any) {
|
||||
if (offer?.reward) return { ...offer.reward };
|
||||
return { coin: 3000, hammer: 3, freeze: 3, magic_wand: 3, infinite_health: 30 * 60 };
|
||||
const STARTER_PACK_REWARDS = {
|
||||
starter_pack: { coin: 3000, hammer: 1, freeze: 1, magic_wand: 1, infinite_health: 30 * 60 },
|
||||
starter_pack_2: { coin: 3000, hammer: 1, freeze: 1, magic_wand: 1, infinite_health: 30 * 60 },
|
||||
starter_pack_3: { coin: 4500, hammer: 3, freeze: 3, magic_wand: 3, infinite_health: 45 * 60 },
|
||||
starter_pack_4: { coin: 5000, hammer: 5, freeze: 5, magic_wand: 5, infinite_health: 60 * 60 },
|
||||
starter_pack_5: { coin: 8000, hammer: 8, freeze: 8, magic_wand: 8, infinite_health: 180 * 60 },
|
||||
};
|
||||
|
||||
/** Rewards are fixed by the client SKU; the server only selects the offer tier. */
|
||||
export function starterPackReward(productId = "starter_pack") {
|
||||
return { ...(STARTER_PACK_REWARDS[productId] || STARTER_PACK_REWARDS.starter_pack) };
|
||||
}
|
||||
|
||||
export function starterPackNow(): number {
|
||||
|
|
|
|||
|
|
@ -1003,7 +1003,6 @@ var GameTool = {
|
|||
|
||||
//商城购买
|
||||
shopBuy(productId, compensate, orderContext: any = null) {
|
||||
if (/^starter_pack_[2-5]$/.test(productId) && !orderContext?.starterPackOffer?.reward) return false;
|
||||
const newProduct = getNewShopProduct(productId);
|
||||
const newOrderKey = newProduct && orderContext?.outTradeNo
|
||||
? "ShopBGranted_" + cc.fx.GameConfig.GM_INFO.uid + "_" + orderContext.outTradeNo : "";
|
||||
|
|
@ -1304,7 +1303,7 @@ var GameTool = {
|
|||
case "starter_pack_3":
|
||||
case "starter_pack_4":
|
||||
case "starter_pack_5": {
|
||||
const reward = starterPackReward(orderContext?.starterPackOffer);
|
||||
const reward = starterPackReward(productId);
|
||||
coin = reward.coin;
|
||||
price = orderContext?.starterPackOffer?.priceFen || 300;
|
||||
cc.fx.GameTool.changeCoin(coin);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export default class NewbieGift extends cc.Component {
|
|||
private refreshOffer() {
|
||||
const price = Number(this.offer?.priceFen) || 300;
|
||||
for (const value of [3, 6, 12, 18, 30]) cc.find("btnContainer/" + value, this.node).active = value * 100 === price;
|
||||
const reward = starterPackReward(this.offer);
|
||||
const reward = starterPackReward(this.offer?.productId);
|
||||
const bundle = cc.assetManager.getBundle("action_bundle");
|
||||
bundle.load("img/newbieGift/newbieGiftFont", cc.SpriteAtlas, (error, atlas: cc.SpriteAtlas) => {
|
||||
if (error || !cc.isValid(this)) return;
|
||||
|
|
@ -110,13 +110,6 @@ export default class NewbieGift extends cc.Component {
|
|||
server: version === "开发版" || version === "体验版" ? Utils.testHttpip : Utils.httpip,
|
||||
});
|
||||
const done = (data) => {
|
||||
if (/^starter_pack_[2-5]$/.test(data?.data?.itemid || data?.data?.payment_name || "") && !data.data.starterPackOffer?.reward) {
|
||||
this.polling = false;
|
||||
this.paying = false;
|
||||
this.openConfirmBox();
|
||||
this.refreshCountdown();
|
||||
return;
|
||||
}
|
||||
if (data?.data && /^starter_pack(?:_[2-5])?$/.test(data.data.itemid || data.data.payment_name || "")) {
|
||||
this.orderContext = data.data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,11 +70,11 @@ const DAY = 24 * 60 * 60 * 1000;
|
|||
const BEIJING_OFFSET = 8 * 60 * 60 * 1000;
|
||||
const STARTER_REWARD_VERSION = PAYMENT_PROFILE_RULE.starterPackRewardVersion;
|
||||
const STARTER_TIERS = [
|
||||
{ productId: 'starter_pack', priceFen: 300, coin: 3000, props: 1, minutes: 30 },
|
||||
{ productId: 'starter_pack_2', priceFen: 600, coin: 3000, props: 1, minutes: 30 },
|
||||
{ productId: 'starter_pack_3', priceFen: 1200, coin: 4500, props: 3, minutes: 45 },
|
||||
{ productId: 'starter_pack_4', priceFen: 1800, coin: 5000, props: 5, minutes: 60 },
|
||||
{ productId: 'starter_pack_5', priceFen: 3000, coin: 8000, props: 8, minutes: 180 },
|
||||
{ productId: 'starter_pack', priceFen: 300 },
|
||||
{ productId: 'starter_pack_2', priceFen: 600 },
|
||||
{ productId: 'starter_pack_3', priceFen: 1200 },
|
||||
{ productId: 'starter_pack_4', priceFen: 1800 },
|
||||
{ productId: 'starter_pack_5', priceFen: 3000 },
|
||||
];
|
||||
|
||||
// A live offer is immutable, including when payment identity or daily factors change.
|
||||
|
|
@ -82,12 +82,11 @@ export function starterPackPatch(user: any, now: number, trigger = false, option
|
|||
const expiry = Number(user.starter_pack) || 0;
|
||||
if (expiry > now) {
|
||||
if (user.starterPackOffer) return null;
|
||||
// Preserve an existing legacy offer's original deadline and promised rewards.
|
||||
// Preserve an existing legacy offer's original deadline and tier.
|
||||
return {
|
||||
starterPackVersion: 3, starterPackRound: starterPackRound(user),
|
||||
starterPackOffer: {
|
||||
version: 3, legacy: true, round: starterPackRound(user), productId: 'starter_pack', priceFen: 300,
|
||||
reward: { coin: 3000, hammer: 3, freeze: 3, magic_wand: 3, infinite_health: 1800 },
|
||||
startsAt: expiry - ((Number(user.starterPackVersion) || 1) < 2 ? DAY : 2 * DAY), expiresAt: expiry,
|
||||
rewardVersion: 'starter_pack_legacy', selectionBasis: 'legacy',
|
||||
},
|
||||
|
|
@ -137,7 +136,6 @@ export function starterPackPatch(user: any, now: number, trigger = false, option
|
|||
starter_pack: expiresAt, starter_packState: 0, starterPackVersion: 3, starterPackRound: round,
|
||||
starterPackOffer: {
|
||||
version: 3, round, productId: tier.productId, priceFen: tier.priceFen,
|
||||
reward: { coin: tier.coin, hammer: tier.props, freeze: tier.props, magic_wand: tier.props, infinite_health: tier.minutes * 60 },
|
||||
startsAt: now, expiresAt, rewardVersion: STARTER_REWARD_VERSION, selectionBasis,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,17 +22,17 @@
|
|||
|
||||
- 等级至少 15。金币小于 500、普通体力为 0 且无限体力无效、三个道具各不超过 3、商城/局内购买意向、真实购买行为、当前关卡连续失败至少 4 次,任一满足即可。失败次数仍由客户端按账号和关卡计数,后端校验关卡和整数次数。
|
||||
- 新轮只在满足触发条件且可安全展示的界面开始计时。普通读取不启动。购买意向恢复入口,不强制弹窗;资源提醒每轮最多自动展示一次,玩法、支付及领奖过程延后处理。
|
||||
- 本轮 `starterPackOffer` 固定商品、价格、奖励、起止时间和轮号;期间身份或画像改变不会重选。
|
||||
- 本轮 `starterPackOffer` 固定商品、价格、起止时间和轮号;期间身份或画像改变不会重选。奖励由客户端按商品 ID 固定配置。
|
||||
- 下轮最早为原截止时间所属北京时间日期加 2 天的零点:9 月 23 日 02:00 到期,9 月 25 日 00:00 才能再触发。提前购买不改变这个截止时间。购买状态按轮次重置。
|
||||
- 旧有效礼包保留原截止时间和原奖励(3000 金币、三个道具各 3、无限体力 1800 秒);旧已购用户无可信截止时间时可在下一次合格触发进入新轮。
|
||||
- 旧有效礼包保留原截止时间并按 `starter_pack` 使用客户端固定的 3 元奖励;旧已购用户无可信截止时间时可在下一次合格触发进入新轮。
|
||||
|
||||
`limitedTimeEvent` 保留 read/save/reactivate/shown 动作;save/reactivate 需 reason。返回新增 `starterPackOffer` 和 `starterPackAutoShownRound`。shown 传本轮 expiry 和 automatic;支持客户端表单的字符串编码。`starterPackLastShownAt` 保留作为记录,不再决定冷却。
|
||||
|
||||
## 支付及兼容
|
||||
|
||||
现有下单接口仅对上述五个 SKU 校验当前有效轮次、未购买状态与商品匹配,并固定服务端报价和数量 1。订单保存 `starterPackOffer`、`starterPackBuyRound`、`starterPackExpiresAt`、`activityType`、`rewardVersion`,旧 iOS 转单继续携带这些字段。
|
||||
现有下单接口仅对上述五个 SKU 校验当前有效轮次、未购买状态与商品匹配,并固定服务端报价和数量 1。订单保存不含奖励内容的 `starterPackOffer`、`starterPackBuyRound`、`starterPackExpiresAt`、`activityType`、`rewardVersion`,旧 iOS 转单继续携带这些字段。
|
||||
|
||||
新订单到期后不可创建;到期前的有效订单可继续原支付流程。回调只关闭所属轮次,不关闭后开的礼包。查单携带订单快照;`getOrderReward` 仍返回 `data="ok"`,礼包快照位于响应顶层。前端从该订单的快照发奖,缺快照旧单走原奖励,不使用当前轮报价替换旧单。登录和账号迁移保留轮次及报价。
|
||||
新订单到期后不可创建;到期前的有效订单可继续原支付流程。回调只关闭所属轮次,不关闭后开的礼包。查单携带商品和轮次快照;`getOrderReward` 仍返回 `data="ok"`,礼包快照位于响应顶层。前端只按订单商品 ID 读取本地固定奖励,不读取后端奖励字段。登录和账号迁移保留轮次及报价。
|
||||
|
||||
保留原跨设备并发下单、客户端发奖及旧 iOS 响应中断的边界,未新增订单占位锁或服务端发奖事务。礼包待支付订单不再按原通用 3 小时期限清理,以免删除仍可能支付的旧单;关闭但未成功的礼包订单也会保留,不因此发奖。退款不在本次范围内。
|
||||
|
||||
|
|
|
|||
|
|
@ -79,15 +79,15 @@ function order(user, extra = {}) {
|
|||
const ctx = body => ({ body, headers: {}, socket: { remoteAddress: '127.0.0.1' } });
|
||||
const notification = () => ctx({ MiniGame: { Payload: JSON.stringify({ OutTradeNo: 'wcx_test' }) } });
|
||||
|
||||
function setOffer(user, productId, priceFen, reward = { coin: 3000, hammer: 1, freeze: 1, magic_wand: 1, infinite_health: 1800 }) {
|
||||
function setOffer(user, productId, priceFen) {
|
||||
user.starterPackVersion = 3;
|
||||
user.pay_user = productId !== 'starter_pack';
|
||||
user.starterPackOffer = { version: 3, round: user.starterPackRound, productId, priceFen, reward,
|
||||
user.starterPackOffer = { version: 3, round: user.starterPackRound, productId, priceFen,
|
||||
startsAt: NOW - 10000, expiresAt: user.starter_pack, rewardVersion: 'starter_pack_v3_20260930', selectionBasis: 'profile' };
|
||||
return user.starterPackOffer;
|
||||
}
|
||||
|
||||
test('each lucky tier uses the server offer price, quantity and reward snapshot on native payment', async () => {
|
||||
test('each lucky tier uses the server offer price, quantity and tier snapshot on native payment', async () => {
|
||||
for (const create of [androidOrder, nativeIosOrder]) {
|
||||
for (const [productId, priceFen] of [['starter_pack', 300], ['starter_pack_2', 600], ['starter_pack_3', 1200], ['starter_pack_4', 1800], ['starter_pack_5', 3000]]) {
|
||||
const user = reset(), offer = setOffer(user, productId, priceFen);
|
||||
|
|
@ -96,6 +96,7 @@ test('each lucky tier uses the server offer price, quantity and reward snapshot
|
|||
const saved = tables.order[0];
|
||||
assert.equal(saved.goodsPrice, priceFen); assert.equal(saved.itemCount, 1);
|
||||
assert.deepEqual(saved.starterPackOffer, offer);
|
||||
assert.equal(saved.starterPackOffer.reward, undefined);
|
||||
assert.equal(saved.activityType, 'lucky'); assert.equal(saved.rewardVersion, offer.rewardVersion);
|
||||
const signed = JSON.parse(result.data.signData);
|
||||
assert.equal(signed.productId, productId); assert.equal(signed.goodsPrice, priceFen); assert.equal(signed.buyQuantity, 1);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ registerHooks({
|
|||
});
|
||||
const { default: activity, starterPackPatch, starterPackOrderSnapshot } = await import('../functions/limitedTimeEvent.ts');
|
||||
const { PAYMENT_PROFILE_RULE } = await import('../functions/paymentProfile.ts');
|
||||
const { starterPackReward } = await import('../../../assets/Script/module/Config/StarterPack.ts');
|
||||
function reset(patch = {}) {
|
||||
now = NOW; beforeUpdate = null; failProfile = false;
|
||||
for (const name of Object.keys(tables)) tables[name] = [];
|
||||
|
|
@ -68,10 +69,11 @@ test('read or save without a reason cannot start; first unpaid offer lasts 12 ho
|
|||
assert.equal(user.starter_pack, NOW + DAY / 2);
|
||||
assert.equal(user.starterPackRound, 1);
|
||||
assert.equal(user.starterPackOffer.productId, 'starter_pack');
|
||||
assert.deepEqual(user.starterPackOffer.reward, { coin: 3000, hammer: 1, freeze: 1, magic_wand: 1, infinite_health: 1800 });
|
||||
assert.equal(user.starterPackOffer.reward, undefined);
|
||||
assert.deepEqual(starterPackReward('starter_pack'), { coin: 3000, hammer: 1, freeze: 1, magic_wand: 1, infinite_health: 1800 });
|
||||
});
|
||||
|
||||
test('formula thresholds select four paid products and exact rewards for six hours', async () => {
|
||||
test('formula thresholds select four paid products while the client fixes rewards by SKU', async () => {
|
||||
for (const [daily, id, price, coin, props, minutes] of [
|
||||
[0, 'starter_pack_2', 600, 3000, 1, 30], [1199, 'starter_pack_2', 600, 3000, 1, 30],
|
||||
[1200, 'starter_pack_3', 1200, 4500, 3, 45], [1800, 'starter_pack_4', 1800, 5000, 5, 60],
|
||||
|
|
@ -82,7 +84,8 @@ test('formula thresholds select four paid products and exact rewards for six hou
|
|||
assert.equal(user.starter_pack, NOW + DAY / 4);
|
||||
assert.equal(user.starterPackOffer.productId, id);
|
||||
assert.equal(user.starterPackOffer.priceFen, price);
|
||||
assert.deepEqual(user.starterPackOffer.reward, { coin, hammer: props, freeze: props, magic_wand: props, infinite_health: minutes * 60 });
|
||||
assert.equal(user.starterPackOffer.reward, undefined);
|
||||
assert.deepEqual(starterPackReward(id), { coin, hammer: props, freeze: props, magic_wand: props, infinite_health: minutes * 60 });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -134,15 +137,16 @@ test('a displayed offer stays fixed when payment identity and daily factors chan
|
|||
assert.equal(starterPackOrderSnapshot(user, 'starter_pack').starterPackOffer.priceFen, 300);
|
||||
});
|
||||
|
||||
test('legacy active offers retain their original deadline and old promised reward', async () => {
|
||||
test('legacy active offers retain their original deadline and use the client 3 yuan reward', async () => {
|
||||
for (const version of [undefined, 1, 2]) {
|
||||
const user = reset({ starter_pack: NOW + DAY, starterPackVersion: version });
|
||||
await Promise.all([read(), read()]);
|
||||
assert.equal(user.starter_pack, NOW + DAY);
|
||||
assert.equal(user.starterPackRound, 1);
|
||||
assert.equal(user.starterPackOffer.legacy, true);
|
||||
assert.equal(user.starterPackOffer.reward.hammer, 3);
|
||||
assert.equal(user.starterPackOffer.reward.infinite_health, 1800);
|
||||
assert.equal(user.starterPackOffer.reward, undefined);
|
||||
assert.deepEqual(starterPackReward(user.starterPackOffer.productId),
|
||||
{ coin: 3000, hammer: 1, freeze: 1, magic_wand: 1, infinite_health: 1800 });
|
||||
const locked = copy(user); await read(); assert.deepEqual(user, locked);
|
||||
}
|
||||
});
|
||||
|
|
@ -227,11 +231,11 @@ test('form-encoded failure counts and automatic flags match the client transport
|
|||
}
|
||||
});
|
||||
|
||||
test('order snapshots bind a valid current SKU, price, reward and cycle', async () => {
|
||||
test('order snapshots bind a valid current SKU, price and cycle without reward data', async () => {
|
||||
const user = reset({ pay_user: true }); profile(user, 3000); await trigger();
|
||||
const snapshot = starterPackOrderSnapshot(user, 'starter_pack_5');
|
||||
assert.equal(snapshot.starterPackOffer.priceFen, 3000);
|
||||
assert.equal(snapshot.starterPackOffer.reward.coin, 8000);
|
||||
assert.equal(snapshot.starterPackOffer.reward, undefined);
|
||||
assert.equal(snapshot.activityType, 'lucky');
|
||||
assert.equal(snapshot.rewardVersion, PAYMENT_PROFILE_RULE.starterPackRewardVersion);
|
||||
assert.throws(() => starterPackOrderSnapshot(user, 'starter_pack'), /档位/);
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ test('pending order still completes after expiry while a fresh order is forbidde
|
|||
let grantedOrder; f.cc.fx.GameTool.shopBuy = (id, comp, data) => { grantedOrder = data.outTradeNo; };
|
||||
f.gift.onShow(); assert.equal(grantedOrder, 'late'); assert.equal(f.gift.node.active, false);
|
||||
});
|
||||
for (const remaining of [0, -60, 600]) test(`starter pack grants 3000/3 and 30 minutes for purchases and compensation, with ${remaining}s existing health`, () => {
|
||||
for (const remaining of [0, -60, 600]) test(`starter pack grants 3000/1 and 30 minutes for purchases and compensation, with ${remaining}s existing health`, () => {
|
||||
const f = fixture();
|
||||
const ast = source('assets/Script/module/Tool/GameTool.ts');
|
||||
const obj = ast.statements.find(n => ts.isVariableStatement(n) && n.declarationList.declarations.some(d => d.name.getText(ast) === 'GameTool'));
|
||||
|
|
@ -203,7 +203,7 @@ for (const remaining of [0, -60, 600]) test(`starter pack grants 3000/3 and 30 m
|
|||
tool.shopBuy('starter_pack', true, { outTradeNo: 'new', starterPackVersion: 2 });
|
||||
tool.shopBuy('starter_pack', false, { outTradeNo: 'new', starterPackVersion: 2 });
|
||||
assert.deepEqual(coins, [3000,3000]);
|
||||
assert.deepEqual(props.map(p => [p.hammer,p.freeze,p.magic_wand]), [[3,3,3],[3,3,3]]);
|
||||
assert.deepEqual(props.map(p => [p.hammer,p.freeze,p.magic_wand]), [[1,1,1],[1,1,1]]);
|
||||
const base = nowSeconds + Math.max(0, remaining);
|
||||
assert.deepEqual(synced, [base + 1800, base + 3600]);
|
||||
assert.equal(f.storage.get('userPowerTime'), base + 3600);
|
||||
|
|
@ -680,9 +680,9 @@ const tiers = [
|
|||
['starter_pack_3', 1200, 4500, 3, 2700], ['starter_pack_4', 1800, 5000, 5, 3600],
|
||||
['starter_pack_5', 3000, 8000, 8, 10800],
|
||||
];
|
||||
for (const [productId, priceFen, coin, props, seconds] of tiers) test(`${productId} uses order snapshot for UI, payment and legacy grant flow`, () => {
|
||||
for (const [productId, priceFen, coin, props, seconds] of tiers) test(`${productId} uses server tier and client-fixed rewards`, () => {
|
||||
const f=fixture(), coins=[], grants=[], health=[], displayed=[];
|
||||
const offer={version:3,round:2,productId,priceFen,reward:{coin,hammer:props,freeze:props,magic_wand:props,infinite_health:seconds}};
|
||||
const offer={version:3,round:2,productId,priceFen};
|
||||
Object.assign(f.info,{starterPackRound:2,starterPackOffer:offer});
|
||||
f.gift.init(true);
|
||||
for(const value of [3,6,12,18,30]) assert.equal(f.cc.find('btnContainer/'+value,f.gift.node).active,value*100===priceFen);
|
||||
|
|
@ -717,14 +717,14 @@ test('new round resets purchased status but stale round and same-round factor ch
|
|||
assert.equal(f.info.starterPackRound,2); assert.equal(f.info.starterPackPurchased,false);
|
||||
});
|
||||
|
||||
test('late old order gives its original reward and leaves the current round purchasable', () => {
|
||||
const f=fixture(); f.info.starterPackRound=4; f.info.starterPackOffer={round:4,reward:{coin:8000}};
|
||||
test('late old order uses its SKU reward and leaves the current round purchasable', () => {
|
||||
const f=fixture(); f.info.starterPackRound=4; f.info.starterPackOffer={round:4,productId:'starter_pack_5',priceFen:3000};
|
||||
const coins=[], props=[]; f.globals.MapConroler={_instance:null};
|
||||
const tool=gameToolMethods(f,['shopBuy']);
|
||||
f.cc.fx.GameTool.changeCoin=n=>coins.push(n); tool.getShopProp=data=>props.push(data); tool.setUserPowerTime=()=>{};
|
||||
tool.shopBuy('starter_pack',true,{outTradeNo:'legacy'});
|
||||
assert.equal(coins[0],3000); assert.equal(props[0].hammer,3); assert.equal(f.info.starterPackPurchased,false);
|
||||
tool.shopBuy('starter_pack_3',true,{outTradeNo:'old3',starterPackBuyRound:3,starterPackOffer:{priceFen:1200,reward:{coin:4500,freeze:3,hammer:3,magic_wand:3,infinite_health:2700}}});
|
||||
assert.equal(coins[0],3000); assert.equal(props[0].hammer,1); assert.equal(f.info.starterPackPurchased,false);
|
||||
tool.shopBuy('starter_pack_3',true,{outTradeNo:'old3',starterPackBuyRound:3,starterPackOffer:{priceFen:1200}});
|
||||
assert.equal(coins[1],4500); assert.equal(f.info.starterPackPurchased,false);
|
||||
});
|
||||
|
||||
|
|
@ -740,13 +740,19 @@ test('level purchase waits for a safe screen and queued purchase intent never fo
|
|||
});
|
||||
|
||||
|
||||
test('new SKU without its order snapshot is not acknowledged or granted legacy rewards', () => {
|
||||
const f=fixture(); const tool=gameToolMethods(f,['shopBuy']);
|
||||
assert.equal(tool.shopBuy('starter_pack_5',true,{outTradeNo:'missing'}),false);
|
||||
test('new SKU is acknowledged and uses client rewards without a server reward snapshot', () => {
|
||||
const f=fixture(), coins=[], props=[], health=[];
|
||||
f.globals.MapConroler={_instance:null};
|
||||
const tool=gameToolMethods(f,['shopBuy']);
|
||||
f.cc.fx.GameTool.changeCoin=n=>coins.push(n); tool.getShopProp=data=>props.push(data); tool.setUserPowerTime=n=>health.push(n);
|
||||
tool.shopBuy('starter_pack_5',true,{outTradeNo:'fixed-reward'});
|
||||
assert.deepEqual(coins,[8000]); assert.equal(props[0].hammer,8); assert.deepEqual(health,[10800]);
|
||||
f.gift.pendingOrder='missing';
|
||||
f.api.getPayInfo=done=>done({code:1,data:{pay_state:2,itemid:'starter_pack_5'}});
|
||||
f.api.setPayInfo=()=>assert.fail('missing snapshot acknowledged');
|
||||
f.cc.fx.GameTool.shopBuy=()=>assert.fail('missing snapshot rewarded');
|
||||
let acknowledged=false, granted='';
|
||||
f.api.setPayInfo=done=>{acknowledged=true;done({code:1,data:'ok'});};
|
||||
f.cc.fx.GameTool.shopBuy=id=>{granted=id;};
|
||||
f.gift.onShow();
|
||||
assert.equal(f.gift.pendingOrder,'missing'); assert.equal(f.gift.polling,false); assert.equal(f.gift.paying,false);
|
||||
assert.equal(acknowledged,true); assert.equal(granted,'starter_pack_5');
|
||||
assert.equal(f.gift.pendingOrder,''); assert.equal(f.gift.polling,false); assert.equal(f.gift.paying,false);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user