297 行
9.2 KiB
PHP
297 行
9.2 KiB
PHP
<?php
|
||
/**
|
||
* 复购立减(付款直接减免、不返现)单元测试
|
||
*
|
||
* 运行方式:
|
||
* php server/addons/shopro/tests/repurchase_discount_test.php
|
||
*/
|
||
|
||
require_once __DIR__ . '/../library/commission/RepurchaseService.php';
|
||
|
||
use addons\shopro\library\commission\RepurchaseService;
|
||
|
||
class RepurchaseDiscountTest
|
||
{
|
||
private $passed = 0;
|
||
private $failed = 0;
|
||
|
||
public function run()
|
||
{
|
||
echo "========================================\n";
|
||
echo " 复购立减单元测试 (TDD)\n";
|
||
echo "========================================\n\n";
|
||
|
||
$this->testNonRepurchaseGoods();
|
||
$this->testFirstBuyNoDiscount();
|
||
$this->testRepurchaseFixedDiscount();
|
||
$this->testRepurchaseRateDiscount();
|
||
$this->testDiscountCapProtection();
|
||
$this->testMixedOrderDiscounts();
|
||
$this->testGoodsDetailRepurchaseTip();
|
||
|
||
echo "\n----------------------------------------\n";
|
||
echo "测试结果: {$this->passed} 通过, {$this->failed} 失败\n";
|
||
echo "----------------------------------------\n";
|
||
|
||
if ($this->failed > 0) {
|
||
exit(1);
|
||
}
|
||
}
|
||
|
||
private function assert($condition, $message)
|
||
{
|
||
if ($condition) {
|
||
$this->passed++;
|
||
echo " [PASS] {$message}\n";
|
||
} else {
|
||
$this->failed++;
|
||
echo " [FAIL] {$message}\n";
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 测试场景 1: 商品未开启复购规则,即使买家买过多次,也不享受复购立减
|
||
*/
|
||
public function testNonRepurchaseGoods()
|
||
{
|
||
echo "场景 1: 未开启复购的普通商品测试\n";
|
||
|
||
$item = [
|
||
'goods_id' => 101,
|
||
'goods_num' => 2,
|
||
'goods_price' => 100.00,
|
||
'goods_amount' => 200.00
|
||
];
|
||
$config = [
|
||
'enable' => true,
|
||
'self_enable' => true,
|
||
'self_type' => 'fixed',
|
||
'self_amount' => 10.00,
|
||
'self_rate' => 5.0
|
||
];
|
||
|
||
// 模拟商品没有开启复购规则 (repurchase_enable = 0)
|
||
$discount = RepurchaseService::calculateItemDiscount(
|
||
$item,
|
||
$config,
|
||
false, // 商品未参与复购
|
||
true // 买家历史买过
|
||
);
|
||
|
||
$this->assert($discount === 0.0, "未开启复购的商品立减金额应为 0.00 (实际: {$discount})");
|
||
}
|
||
|
||
/**
|
||
* 测试场景 2: 指定商品首次购买(历史无订单),不享受立减
|
||
*/
|
||
public function testFirstBuyNoDiscount()
|
||
{
|
||
echo "\n场景 2: 指定商品首购(历史无该商品购买记录)\n";
|
||
|
||
$item = [
|
||
'goods_id' => 102,
|
||
'goods_num' => 1,
|
||
'goods_price' => 200.00,
|
||
'goods_amount' => 200.00
|
||
];
|
||
$config = [
|
||
'enable' => true,
|
||
'self_enable' => true,
|
||
'self_type' => 'fixed',
|
||
'self_amount' => 20.00,
|
||
'self_rate' => 10.0
|
||
];
|
||
|
||
// 商品参与复购,但买家首次购买(isRepurchase = false)
|
||
$discount = RepurchaseService::calculateItemDiscount(
|
||
$item,
|
||
$config,
|
||
true, // 商品参与复购
|
||
false // 买家首次购买
|
||
);
|
||
|
||
$this->assert($discount === 0.0, "首购指定商品立减金额应为 0.00 (实际: {$discount})");
|
||
}
|
||
|
||
/**
|
||
* 测试场景 3: 指定商品复购(固定金额模式,按件累加)
|
||
*/
|
||
public function testRepurchaseFixedDiscount()
|
||
{
|
||
echo "\n场景 3: 指定商品复购 · 固定金额模式 (买 3 件,每件立减 5 元)\n";
|
||
|
||
$item = [
|
||
'goods_id' => 103,
|
||
'goods_num' => 3,
|
||
'goods_price' => 50.00,
|
||
'goods_amount' => 150.00
|
||
];
|
||
$config = [
|
||
'enable' => true,
|
||
'self_enable' => true,
|
||
'self_type' => 'fixed',
|
||
'self_amount' => 5.00,
|
||
'self_rate' => 0
|
||
];
|
||
|
||
$discount = RepurchaseService::calculateItemDiscount(
|
||
$item,
|
||
$config,
|
||
true, // 商品参与复购
|
||
true // 买家复购
|
||
);
|
||
|
||
// 预期立减 5 * 3 = 15.00
|
||
$this->assert($discount === 15.00, "复购 3 件每件立减 5 元,总立减应为 15.00 (实际: {$discount})");
|
||
}
|
||
|
||
/**
|
||
* 测试场景 4: 指定商品复购 · 百分比模式 (立减 10%)
|
||
*/
|
||
public function testRepurchaseRateDiscount()
|
||
{
|
||
echo "\n场景 4: 指定商品复购 · 百分比模式 (100 元 × 2 件,立减 10%)\n";
|
||
|
||
$item = [
|
||
'goods_id' => 104,
|
||
'goods_num' => 2,
|
||
'goods_price' => 100.00,
|
||
'goods_amount' => 200.00
|
||
];
|
||
$config = [
|
||
'enable' => true,
|
||
'self_enable' => true,
|
||
'self_type' => 'rate',
|
||
'self_amount' => 0,
|
||
'self_rate' => 10.0
|
||
];
|
||
|
||
$discount = RepurchaseService::calculateItemDiscount(
|
||
$item,
|
||
$config,
|
||
true, // 商品参与复购
|
||
true // 买家复购
|
||
);
|
||
|
||
// 预期立减 200 * 10% = 20.00
|
||
$this->assert($discount === 20.00, "复购 200 元立减 10%,总立减应为 20.00 (实际: {$discount})");
|
||
}
|
||
|
||
/**
|
||
* 测试场景 5: 边界兜底保护(立减金额不可超过商品总额)
|
||
*/
|
||
public function testDiscountCapProtection()
|
||
{
|
||
echo "\n场景 5: 边界兜底保护 (商品单价 5 元,配置立减 10 元)\n";
|
||
|
||
$item = [
|
||
'goods_id' => 105,
|
||
'goods_num' => 1,
|
||
'goods_price' => 5.00,
|
||
'goods_amount' => 5.00
|
||
];
|
||
$config = [
|
||
'enable' => true,
|
||
'self_enable' => true,
|
||
'self_type' => 'fixed',
|
||
'self_amount' => 10.00,
|
||
'self_rate' => 0
|
||
];
|
||
|
||
$discount = RepurchaseService::calculateItemDiscount(
|
||
$item,
|
||
$config,
|
||
true, // 商品参与复购
|
||
true // 买家复购
|
||
);
|
||
|
||
// 预期立减不得超过 5.00
|
||
$this->assert($discount === 5.00, "立减金额不得超过商品金额 5.00 (实际: {$discount})");
|
||
}
|
||
|
||
/**
|
||
* 测试场景 6: 混合商品订单结算 (包含复购商品与非复购商品)
|
||
*/
|
||
public function testMixedOrderDiscounts()
|
||
{
|
||
echo "\n场景 6: 混合商品订单结算 (商品A复购立减10元,商品B首购不减)\n";
|
||
|
||
$goodsList = [
|
||
[
|
||
'goods_id' => 201,
|
||
'goods_num' => 1,
|
||
'goods_price' => 100.00,
|
||
'goods_amount' => 100.00,
|
||
'discount_fee' => 0.00
|
||
],
|
||
[
|
||
'goods_id' => 202,
|
||
'goods_num' => 2,
|
||
'goods_price' => 50.00,
|
||
'goods_amount' => 100.00,
|
||
'discount_fee' => 0.00
|
||
]
|
||
];
|
||
|
||
$config = [
|
||
'enable' => true,
|
||
'self_enable' => true,
|
||
'self_type' => 'fixed',
|
||
'self_amount' => 10.00,
|
||
'self_rate' => 0
|
||
];
|
||
|
||
// 模拟商品规则:201 参与复购,202 不参与
|
||
$goodsRuleChecker = function ($goodsId) {
|
||
return $goodsId === 201;
|
||
};
|
||
|
||
// 模拟历史购买记录:买家买过 201,未买过 202
|
||
$historyChecker = function ($userId, $goodsId) {
|
||
return $goodsId === 201;
|
||
};
|
||
|
||
$result = RepurchaseService::calculateOrderRepurchaseDiscounts(
|
||
$goodsList,
|
||
1, // userId
|
||
$config,
|
||
$goodsRuleChecker,
|
||
$historyChecker
|
||
);
|
||
|
||
$totalDiscount = $result['total_repurchase_discount'];
|
||
$newGoodsList = $result['goods_list'];
|
||
|
||
$this->assert($totalDiscount === 10.00, "整单复购立减总额应为 10.00 (实际: {$totalDiscount})");
|
||
$this->assert($newGoodsList[0]['repurchase_discount_money'] === 10.00, "商品 201 立减应为 10.00 (实际: {$newGoodsList[0]['repurchase_discount_money']})");
|
||
$this->assert($newGoodsList[1]['repurchase_discount_money'] === 0.00, "商品 202 立减应为 0.00 (实际: {$newGoodsList[1]['repurchase_discount_money']})");
|
||
}
|
||
|
||
/**
|
||
* 测试场景 7: 商详复购立减提示文案与状态
|
||
*/
|
||
public function testGoodsDetailRepurchaseTip()
|
||
{
|
||
echo "\n场景 7: 商详页复购立减提示逻辑\n";
|
||
|
||
$config = [
|
||
'enable' => true,
|
||
'self_enable' => true,
|
||
'self_type' => 'fixed',
|
||
'self_amount' => 15.00,
|
||
'self_rate' => 0
|
||
];
|
||
|
||
// 模拟已购买老客
|
||
$discountDesc = ($config['self_type'] ?? 'fixed') === 'rate' ? ($config['self_rate'] . '%') : ('¥' . $config['self_amount']);
|
||
$tipRepurchase = '您曾购买过本商品,再次下单立减' . $discountDesc;
|
||
$tipNew = '老客复购享立减' . $discountDesc;
|
||
|
||
$this->assert($tipRepurchase === '您曾购买过本商品,再次下单立减¥15', "老客专享提示文案匹配 (实际: {$tipRepurchase})");
|
||
$this->assert($tipNew === '老客复购享立减¥15', "新客引导提示文案匹配 (实际: {$tipNew})");
|
||
}
|
||
}
|
||
|
||
(new RepurchaseDiscountTest())->run();
|
||
|