Files
wordpress-theme-aksrt/tests/widget-system/order-after-sale-assets-contract.test.cjs
T
kate522 88669f6989 refactor(after-sale): replace review decisions with direct status panel
售后面板改为状态下拉(待审核/处理中/已完成/已拒绝/已取消)加确认/取消按钮:取消仅收起手风琴,确认为纯状态更新;删除已通过状态、review() 决策机制及其专用退款流水线,无双路无迁移;举证图片并入申请说明列与详情整行。
2026-10-08 11:05:08 +08:00

79 lines
4.4 KiB
JavaScript

const test = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const root = path.resolve(__dirname, '../..')
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8')
test('orders expose four states, seven product categories and retain 22-digit IDs', () => {
const domain = read('src/Core/DomainModel.php')
const repository = read('src/Payment/OrderRepositoryCore.php')
const order = read('src/Payment/Order.php')
for (const status of ['pending', 'paid', 'refunded', 'closed']) {
assert.match(domain, new RegExp(`ORDER_STATUS_${status.toUpperCase()}\\s*=\\s*'${status}'`))
}
assert.ok(repository.includes("ORDER_NUMBER_PATTERN = '/^\\d{20}$|^\\d{22}$/';"))
for (const label of ['付费阅读', '付费下载', '付费图片', '付费视频', '购买会员', '余额充值', '购买积分']) {
assert.ok(domain.includes(label), `missing product category ${label}`)
}
assert.match(repository, /\$row\['status'\] === 'refunding'[\s\S]*?Order::STATUS_PAID/)
assert.doesNotMatch(order, /STATUS_REFUNDING\s*=/)
})
test('balance and points mutations use user meta, guard debits in SQL and cap history at 50', () => {
const assets = read('src/Credits/MetaAssetService.php')
const ledger = read('src/Ledger/LedgerService.php')
assert.match(assets, /MAX_RECORDS\s*=\s*50/)
assert.match(assets, /SELECT GET_LOCK\(%s, 5\)/)
assert.match(assets, /FOR UPDATE/)
assert.match(assets, /CAST\(meta_value AS SIGNED\) >= %d/)
assert.match(assets, /CAST\(meta_value AS DECIMAL\(20,2\)\) >= CAST\(%s AS DECIMAL\(20,2\)\)/)
assert.match(assets, /array_slice\(\$history, 0, self::MAX_RECORDS - 1\)/)
assert.match(assets, /'balance_record'/)
assert.match(assets, /'points_record'/)
assert.match(ledger, /post_meta_command\(\$command, \$guard, \$business_mutation\)/)
assert.match(ledger, /AssetType::BALANCE, AssetType::POINTS/)
})
test('free points keep a bounded daily summary alongside the recent points history', () => {
const freePoints = read('src/Credits/PointsFree.php')
const assets = read('src/Credits/MetaAssetService.php')
assert.match(freePoints, /META_DETAIL\s*=\s*'free_points_detail'/)
assert.match(freePoints, /remaining_today\(\$user_id\) < \$points/)
assert.match(freePoints, /array_slice\(\$detail, 0, 50, true\)/)
assert.match(freePoints, /LedgerService::get_instance\(\)->credit\([\s\S]*?self::bump_detail\(\$user_id, \$points\)/)
assert.match(assets, /'points_record'/)
})
test('after-sale submissions are order-locked and admins set status directly', () => {
const afterSale = read('src/Payment/AfterSaleService.php')
const schema = read('src/Core/DBMigratorPart2.php')
const repository = read('src/Payment/OrderRepositoryCore.php')
assert.match(schema, /CREATE TABLE \{\$prefix\}aksrt_order_aftersale[\s\S]*?gateway_request_id[\s\S]*?gateway_result[\s\S]*?completed_at/)
assert.match(afterSale, /GET_LOCK\(%s, 5\)[\s\S]*?get_user_order\(\$user_id, \$order_number\)[\s\S]*?find_active\(\$order_number\)/)
assert.match(afterSale, /Order::STATUS_PAID/)
assert.match(afterSale, /public function set_status\(int \$id, string \$status, string \$note = ''\)/)
assert.match(afterSale, /in_array\(\$status, \[self::STATUS_PENDING, self::STATUS_PROCESSING, self::STATUS_COMPLETED, self::STATUS_REJECTED, self::STATUS_CANCELLED\], true\)/)
assert.ok(!afterSale.includes('STATUS_APPROVED'), 'approved status removed')
assert.ok(!afterSale.includes('function review('), 'decision-based review removed')
assert.ok(!afterSale.includes('approve('), 'refund pipeline removed')
assert.match(repository, /can_finalize_order_refund\(\(int\) \(\$extra\['after_sale_id'\] \?\? 0\), \$order_number\)/)
})
test('withdrawal holds and returns use the selected user-meta or commission pool', () => {
const withdrawal = read('src/Payment/Withdrawal.php')
const assets = read('src/Credits/MetaAssetService.php')
assert.match(withdrawal, /source_balance_decimal\(\$user_id, \$source\)/)
assert.match(withdrawal, /private function source_balance_decimal\(int \$user_id, string \$source\)/)
assert.match(withdrawal, /\$this->source_asset\(\$source\)/)
assert.match(withdrawal, /\$this->source_balance_decimal\(\$user_id, \$refund_source\)/)
assert.match(assets, /AssetType::BALANCE->value, AssetType::POINTS->value/)
assert.match(assets, /function write_balance\([\s\S]*?\$wpdb->usermeta/)
})