feat(payment): rebuild order details and asset records
This commit is contained in:
@@ -190,10 +190,12 @@ test('user asset submissions send idempotency keys', () => {
|
||||
test('profile asset records show only the reason label and the changed amount', () => {
|
||||
for (const file of ['credits-transactions.php', 'credits-wallet-ledger.php']) {
|
||||
const source = fs.readFileSync(path.join(root, 'inc', 'helpers', 'user-center-renderers', file), 'utf8')
|
||||
assert.match(source, /aksrt_asset_reason_label\(\(string\) \$row\['reason'\]\)/)
|
||||
// 记录名称后不再拼接(引用键 / 备注 / 提现单号)。
|
||||
assert.doesNotMatch(source, /\$record_note|uc-transactions__remark|\$row\['ref_key'\]|\$row\['remark'\]|withdrawal_number/)
|
||||
assert.doesNotMatch(source, /uc-transactions__balance|交易 #%d|\$row\['fee_minor'\]|\$row\['ref_id'\]/)
|
||||
assert.match(source, /get_user_meta\([^\n]*'(?:points_record|balance_record)'/)
|
||||
assert.match(source, /\$row\['value'\]/)
|
||||
assert.match(source, /\$row\['desc'\]/)
|
||||
assert.match(source, /\$row\['time'\]/)
|
||||
assert.match(source, /\$row\['order_num'\]/)
|
||||
assert.doesNotMatch(source, /ledger_entry|transaction_id|flow_number|withdrawal_number/)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -321,12 +323,18 @@ test('VIP card redemption is one locked transaction with bounded retry and repla
|
||||
assert.match(method, /vip_card_replay_result/)
|
||||
})
|
||||
|
||||
test('admin ledger keeps cash minor values as decimal strings', () => {
|
||||
test('admin recent asset records read the user-meta histories', () => {
|
||||
const controller = fs.readFileSync(path.join(root, 'src', 'Admin', 'UserController.php'), 'utf8')
|
||||
const page = fs.readFileSync(path.join(root, 'assets', 'admin', 'src', 'pages', 'CmsCredits.vue'), 'utf8')
|
||||
assert.match(controller, /asset_minor_for_response/)
|
||||
assert.match(controller, /decimal_from_minor/)
|
||||
assert.doesNotMatch(page, /\/\s*100(?:\D|$)/)
|
||||
assert.match(controller, /'balance_record'/)
|
||||
assert.match(controller, /'points_record'/)
|
||||
assert.match(controller, /'balance_value'/)
|
||||
assert.match(controller, /'points_value'/)
|
||||
assert.match(page, /用户近期资产记录/)
|
||||
assert.match(page, /api\.getCreditLog\(params\)/)
|
||||
assert.doesNotMatch(page, /统一资产账本|transaction_id|operation_key|toFixed|number_format/)
|
||||
assert.match(page, /Math\.trunc\(raw\)/)
|
||||
assert.match(page, /padStart\(3, '0'\)/)
|
||||
})
|
||||
|
||||
test('asset purchases share the order center and refresh every wallet surface', () => {
|
||||
@@ -346,8 +354,12 @@ test('asset purchases share the order center and refresh every wallet surface',
|
||||
const header = fs.readFileSync(path.join(root, 'inc', 'helpers', 'aksrt-header-userbox.php'), 'utf8')
|
||||
|
||||
assert.match(domain, /ORDER_PRODUCT_POINTS\s*=\s*'points'/)
|
||||
assert.match(domain, /self::ORDER_PRODUCT_POINTS\s*=>\s*__\('积分购买'/)
|
||||
const statuses = ['PENDING', 'PAID', 'REFUNDING', 'REFUNDED', 'CLOSED']
|
||||
const productTypes = ['READING', 'DOWNLOAD', 'IMAGE', 'VIDEO', 'VIP', 'RECHARGE', 'POINTS']
|
||||
for (const type of productTypes) assert.match(domain, new RegExp(`ORDER_PRODUCT_${type}\\s*=`))
|
||||
for (const label of ['付费阅读', '付费下载', '付费图片', '付费视频', '购买会员', '余额充值', '购买积分']) {
|
||||
assert.ok(domain.includes(label), `missing order product label: ${label}`)
|
||||
}
|
||||
const statuses = ['PENDING', 'PAID', 'REFUNDED', 'CLOSED']
|
||||
assert.deepEqual(
|
||||
[...domain.matchAll(/public const ORDER_STATUS_([A-Z_]+)\s*=\s*'([^']+)'/g)].map((match) => [match[1], match[2]]),
|
||||
statuses.map((status) => [status, status.toLowerCase()]),
|
||||
@@ -374,20 +386,21 @@ test('asset purchases share the order center and refresh every wallet surface',
|
||||
)
|
||||
assert.deepEqual(transitions, {
|
||||
PENDING: ['PAID', 'CLOSED'],
|
||||
PAID: ['REFUNDING'],
|
||||
REFUNDING: ['REFUNDED', 'PAID'],
|
||||
PAID: ['REFUNDED'],
|
||||
REFUNDED: [],
|
||||
CLOSED: [],
|
||||
})
|
||||
assert.match(userOrders, /return isset\(DomainModel::order_status_labels\(\)\[\$status\]\) \? \$status : ''/)
|
||||
assert.doesNotMatch(userOrders, /can_open|entitlement_label|resolve_entitlement_url|post_permalink_cache/)
|
||||
assert.match(repository, /SUM\(CASE WHEN status = %s THEN 1 ELSE 0 END\) AS paid/)
|
||||
assert.match(repository, /SUM\(CASE WHEN status = %s THEN 1 ELSE 0 END\) AS paid,/)
|
||||
assert.match(repository, /SUM\(CASE WHEN status = 'refunding' THEN 1 ELSE 0 END\) AS paid_legacy/)
|
||||
assert.match(repository, /'paid' => \(int\) \(\$row\['paid'\] \?\? 0\) \+ \(int\) \(\$row\['paid_legacy'\] \?\? 0\)/)
|
||||
assert.doesNotMatch(repository, /\$completed_statuses|\$completed_placeholders/)
|
||||
assert.match(adminRepository, /\$valid_statuses = array_keys\(\\AKSRT\\Core\\DomainModel::order_status_labels\(\)\)/)
|
||||
assert.doesNotMatch(payOrders, /<select name="new_status">/)
|
||||
assert.doesNotMatch(`${order}\n${repository}\n${userOrders}\n${payOrders}`, /['"]force['"]\s*=>\s*true/)
|
||||
assert.match(paymentRuntime, /\$status_keys = \['pending', 'paid', 'refunding', 'refunded', 'closed'\]/)
|
||||
for (const status of ['pending', 'paid', 'refunding', 'refunded', 'closed']) {
|
||||
assert.match(paymentRuntime, /\$status_keys = \['pending', 'paid', 'refunded', 'closed'\]/)
|
||||
for (const status of ['pending', 'paid', 'refunded', 'closed']) {
|
||||
assert.match(paymentSchema, new RegExp(`payment_order_status_${status}`))
|
||||
}
|
||||
assert.doesNotMatch(paymentSchema, /payment_order_status_(?:completed|cancelled|processing)/)
|
||||
|
||||
Reference in New Issue
Block a user