'use strict'; /** Card redemption uses the public 22-digit order number as its only business number. */ const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const root = path.resolve(__dirname, '..', '..'); const card = fs.readFileSync(path.join(root, 'src/Payment/ChargeCard.php'), 'utf8'); const domain = fs.readFileSync(path.join(root, 'src/Core/DomainModel.php'), 'utf8'); test('卡密订单号不再硬编码 CARD 前缀,改走统一分配器', () => { assert.doesNotMatch(card, /'CARD'\s*\.\s*\$card_id/); assert.match(card, /allocate_redeem_order_number\(\)/); assert.match(card, /allocate_order_number\(\)/); // 两条兑换路径都必须先取号并在失败时中断 const assetPart = card.slice(card.indexOf('private function redeem_asset_card'), card.indexOf('private function redeem_vip_card')); const vipPart = card.slice(card.indexOf('private function redeem_vip_card'), card.indexOf('private function create_redeem_order')); for (const [name, part] of [['redeem_asset_card', assetPart], ['redeem_vip_card', vipPart]]) { assert.match(part, /\$order_number\s*=\s*\$this->allocate_redeem_order_number\(\);/, name); assert.match(part, /is_wp_error\(\$order_number\)/, name); } }); test('card redemption does not create a second flow number', () => { const numberHelper = card.slice(card.indexOf('private function allocate_redeem_order_number'), card.indexOf('private function create_redeem_order')); assert.doesNotMatch(card, /card_pass_transaction_number|FinancialFlowService|record_card_pass_payment|attach_order_to_ledger_flow/); assert.match(numberHelper, /OrderRepository::get_instance\(\)->allocate_order_number\(\)/); assert.match(card, /'payment_transaction_id'\s*=>\s*''/); }); test('card redemption keeps seven order types and canonical labels', () => { assert.match(card, /ORDER_PRODUCT_RECHARGE/); assert.match(card, /ORDER_PRODUCT_VIP/); assert.match(card, /ORDER_PRODUCT_POINTS/); for (const label of ['付费阅读', '付费下载', '付费图片', '付费视频', '购买会员', '余额充值', '购买积分']) { assert.ok(domain.includes(label), `missing order label: ${label}`); } });