376 行
14 KiB
PHP
376 行
14 KiB
PHP
<?php
|
|
|
|
namespace tests\partner;
|
|
|
|
@ini_set('session.use_cookies', '0');
|
|
define('APP_PATH', __DIR__ . '/../../application/');
|
|
define('ROOT_PATH', dirname(realpath(APP_PATH)) . '/');
|
|
require_once __DIR__ . '/../../thinkphp/base.php';
|
|
require_once __DIR__ . '/../../thinkphp/helper.php';
|
|
if (is_file(ROOT_PATH . '.env')) {
|
|
$env = parse_ini_file(ROOT_PATH . '.env', true);
|
|
foreach ($env as $key => $val) {
|
|
$name = 'PHP_' . strtoupper($key);
|
|
if (is_array($val)) {
|
|
foreach ($val as $k => $v) {
|
|
$item = $name . '_' . strtoupper($k);
|
|
putenv("$item=$v");
|
|
}
|
|
} else {
|
|
putenv("$name=$val");
|
|
}
|
|
}
|
|
}
|
|
require_once __DIR__ . '/../../application/common.php';
|
|
|
|
\think\Config::set(\think\Config::load(APP_PATH . 'config.php'));
|
|
\think\Config::set(include APP_PATH . 'database.php', 'database');
|
|
\think\Loader::addNamespace('app', APP_PATH);
|
|
require_once __DIR__ . '/../../addons/shopro/helper/helper.php';
|
|
|
|
// 初始化 CLI 下的 Session 并注入合法的 Admin 账号及 Auth 登录状态
|
|
\think\Session::init();
|
|
$auth = \app\admin\library\Auth::instance();
|
|
$refAuth = new \ReflectionClass($auth);
|
|
if ($refAuth->hasProperty('logined')) {
|
|
$p = $refAuth->getProperty('logined');
|
|
$p->setAccessible(true);
|
|
$p->setValue($auth, true);
|
|
}
|
|
if ($refAuth->hasProperty('rules')) {
|
|
$p = $refAuth->getProperty('rules');
|
|
$p->setAccessible(true);
|
|
$p->setValue($auth, ['*']);
|
|
}
|
|
|
|
use app\admin\controller\shopro\user\User;
|
|
use app\admin\model\shopro\user\User as UserModel;
|
|
use app\admin\model\shopro\commission\Agent as AgentModel;
|
|
use app\admin\model\shopro\partner\Reward as RewardModel;
|
|
use think\Request;
|
|
use think\Db;
|
|
|
|
class TestUserController extends User
|
|
{
|
|
public function _initialize()
|
|
{
|
|
$this->model = new UserModel();
|
|
}
|
|
}
|
|
|
|
class MultiAssetRechargeTest
|
|
{
|
|
private $passed = 0;
|
|
private $failed = 0;
|
|
private $testUserId = 0;
|
|
|
|
public function run()
|
|
{
|
|
echo "========================================================\n";
|
|
echo " 会员多资产(余额/积分/dmepa/兑换券)充值业务测试 \n";
|
|
echo "========================================================\n\n";
|
|
|
|
$this->setUp();
|
|
|
|
try {
|
|
$this->testInvalidAssetType();
|
|
$this->testMoneyRechargeAndDeduct();
|
|
$this->testMoneyOverdrawn();
|
|
$this->testScoreRechargeAndDeduct();
|
|
$this->testScoreOverdrawn();
|
|
$this->testMadowRechargeAndDeduct();
|
|
$this->testMadowOverdrawn();
|
|
$this->testVoucherRechargeAndDeduct();
|
|
$this->testVoucherOverdrawn();
|
|
} finally {
|
|
$this->tearDown();
|
|
}
|
|
|
|
echo "\n--------------------------------------------------------\n";
|
|
echo "测试执行结果: 通过 {$this->passed} 项, 失败 {$this->failed} 项\n";
|
|
echo "========================================================\n";
|
|
return $this->failed === 0 ? 0 : 1;
|
|
}
|
|
|
|
private function assert($condition, $testName, $detail = '')
|
|
{
|
|
if ($condition) {
|
|
echo " [PASS] {$testName}\n";
|
|
$this->passed++;
|
|
} else {
|
|
echo " [FAIL] {$testName} - {$detail}\n";
|
|
$this->failed++;
|
|
}
|
|
}
|
|
|
|
private function setUp()
|
|
{
|
|
// 查找或创建一个测试用户
|
|
$user = UserModel::where('username', 'test_recharge_user')->find();
|
|
if (!$user) {
|
|
$now = time();
|
|
$id = Db::name('user')->insertGetId([
|
|
'username' => 'test_recharge_user',
|
|
'nickname' => '充值测试员',
|
|
'password' => md5('123456'),
|
|
'salt' => '123456',
|
|
'mobile' => '13988889999',
|
|
'money' => 100.00,
|
|
'score' => 500,
|
|
'status' => 'normal',
|
|
'createtime' => $now,
|
|
'updatetime' => $now,
|
|
]);
|
|
$this->testUserId = $id;
|
|
} else {
|
|
$this->testUserId = $user->id;
|
|
Db::name('user')->where('id', $this->testUserId)->update([
|
|
'money' => 100.00,
|
|
'score' => 500,
|
|
]);
|
|
}
|
|
|
|
// 初始化 agent 记录
|
|
$agent = Db::name('shopro_commission_agent')->where('user_id', $this->testUserId)->find();
|
|
if (!$agent) {
|
|
Db::name('shopro_commission_agent')->insert([
|
|
'user_id' => $this->testUserId,
|
|
'level' => 1,
|
|
'status' => 'normal',
|
|
'madow' => '10.00000000',
|
|
'voucher_total' => '200.00',
|
|
'voucher_released' => '200.00',
|
|
'voucher_used' => '50.00',
|
|
'createtime' => time(),
|
|
'updatetime' => time(),
|
|
]);
|
|
} else {
|
|
Db::name('shopro_commission_agent')->where('user_id', $this->testUserId)->update([
|
|
'madow' => '10.00000000',
|
|
'voucher_total' => '200.00',
|
|
'voucher_released' => '200.00',
|
|
'voucher_used' => '50.00',
|
|
]);
|
|
}
|
|
}
|
|
|
|
private function tearDown()
|
|
{
|
|
if ($this->testUserId) {
|
|
try {
|
|
Db::name('user')->where('id', $this->testUserId)->delete();
|
|
Db::name('shopro_commission_agent')->where('user_id', $this->testUserId)->delete();
|
|
Db::name('shopro_partner_reward')->where('user_id', $this->testUserId)->delete();
|
|
Db::name('shopro_user_wallet_log')->where('user_id', $this->testUserId)->delete();
|
|
Db::name('user_money_log')->where('user_id', $this->testUserId)->delete();
|
|
Db::name('user_score_log')->where('user_id', $this->testUserId)->delete();
|
|
} catch (\Exception $e) {
|
|
// 忽略非关键日志表删除错误
|
|
}
|
|
}
|
|
}
|
|
|
|
private function invokeRecharge($params)
|
|
{
|
|
$controller = new TestUserController();
|
|
$request = Request::create('shopro/user/user/recharge', 'POST', $params, [], [], [
|
|
'HTTP_X_REQUESTED_WITH' => 'xmlhttprequest',
|
|
'HTTP_ACCEPT' => 'application/json',
|
|
]);
|
|
|
|
// 绑定 request 到 控制器
|
|
$ref = new \ReflectionClass($controller);
|
|
$reqProp = $ref->getProperty('request');
|
|
$reqProp->setAccessible(true);
|
|
$reqProp->setValue($controller, $request);
|
|
|
|
// 设置 Request 全局单例
|
|
$refInst = new \ReflectionClass(Request::class);
|
|
$instProp = $refInst->getProperty('instance');
|
|
$instProp->setAccessible(true);
|
|
$instProp->setValue(null, $request);
|
|
|
|
try {
|
|
$controller->recharge();
|
|
} catch (\think\exception\HttpResponseException $e) {
|
|
$data = $e->getResponse()->getData();
|
|
if (is_string($data)) {
|
|
$decoded = json_decode($data, true);
|
|
if (is_array($decoded)) {
|
|
return $decoded;
|
|
}
|
|
}
|
|
if (!is_array($data)) {
|
|
echo "[DEBUG RAW DATA] " . substr((string)$data, 0, 200) . "\n";
|
|
}
|
|
return is_array($data) ? $data : ['code' => 0, 'msg' => (string) $data];
|
|
}
|
|
return ['code' => 0, 'msg' => '未知响应'];
|
|
}
|
|
|
|
public function testInvalidAssetType()
|
|
{
|
|
$res = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'invalid_coin',
|
|
'amount' => 10,
|
|
'memo' => '测试非法资产类型',
|
|
]);
|
|
$this->assert($res['code'] === 0 && strpos($res['msg'], '不支持') !== false, '非法资产类型校验拦截', $res['msg'] ?? '');
|
|
}
|
|
|
|
public function testMoneyRechargeAndDeduct()
|
|
{
|
|
// 充值 50 元
|
|
$res1 = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'money',
|
|
'amount' => 50,
|
|
'memo' => '充值50元',
|
|
]);
|
|
$u1 = UserModel::get($this->testUserId);
|
|
$this->assert($res1['code'] === 1 && (float)$u1->money == 150.00, '余额充值成功且到账', "当前余额: {$u1->money}");
|
|
|
|
// 扣除 30 元
|
|
$res2 = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'money',
|
|
'amount' => -30,
|
|
'memo' => '扣除30元',
|
|
]);
|
|
$u2 = UserModel::get($this->testUserId);
|
|
$this->assert($res2['code'] === 1 && (float)$u2->money == 120.00, '余额扣除成功且准确', "当前余额: {$u2->money}");
|
|
}
|
|
|
|
public function testMoneyOverdrawn()
|
|
{
|
|
// 尝试扣除超过当前余额 (120元)
|
|
$res = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'money',
|
|
'amount' => -200,
|
|
'memo' => '超额扣除余额',
|
|
]);
|
|
$this->assert($res['code'] === 0 && strpos($res['msg'], '不足') !== false, '余额不足拦截超扣', $res['msg'] ?? '');
|
|
}
|
|
|
|
public function testScoreRechargeAndDeduct()
|
|
{
|
|
// 充值 100 积分
|
|
$res1 = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'score',
|
|
'amount' => 100,
|
|
'memo' => '充值100积分',
|
|
]);
|
|
$u1 = UserModel::get($this->testUserId);
|
|
$this->assert($res1['code'] === 1 && $u1->score == 600, '积分充值成功且到账', "当前积分: {$u1->score}");
|
|
|
|
// 扣除 200 积分
|
|
$res2 = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'score',
|
|
'amount' => -200,
|
|
'memo' => '扣除200积分',
|
|
]);
|
|
$u2 = UserModel::get($this->testUserId);
|
|
$this->assert($res2['code'] === 1 && $u2->score == 400, '积分扣除成功且准确', "当前积分: {$u2->score}");
|
|
}
|
|
|
|
public function testScoreOverdrawn()
|
|
{
|
|
// 尝试超额扣除积分
|
|
$res = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'score',
|
|
'amount' => -1000,
|
|
'memo' => '超额扣除积分',
|
|
]);
|
|
$this->assert($res['code'] === 0 && strpos($res['msg'], '不足') !== false, '积分不足拦截超扣', $res['msg'] ?? '');
|
|
}
|
|
|
|
public function testMadowRechargeAndDeduct()
|
|
{
|
|
// 充值 5.12345678 枚dmepa
|
|
$res1 = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'madow',
|
|
'amount' => '5.12345678',
|
|
'memo' => '充值dmepa',
|
|
]);
|
|
$agent1 = AgentModel::where('user_id', $this->testUserId)->find();
|
|
$this->assert($res1['code'] === 1 && $agent1->madow == '15.12345678', 'dmepa8位高精度充值到账', "当前dmepa: {$agent1->madow}");
|
|
|
|
// 扣除 3.00000000 枚dmepa
|
|
$res2 = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'madow',
|
|
'amount' => '-3.00000000',
|
|
'memo' => '扣除dmepa',
|
|
]);
|
|
$agent2 = AgentModel::where('user_id', $this->testUserId)->find();
|
|
$this->assert($res2['code'] === 1 && $agent2->madow == '12.12345678', 'dmepa高精度扣除成功', "当前dmepa: {$agent2->madow}");
|
|
|
|
// 验证流水表记录
|
|
$log = RewardModel::where('user_id', $this->testUserId)->where('reward_type', 'admin_madow')->order('id', 'desc')->find();
|
|
$this->assert($log && $log->status == 1, 'dmepa充值写入收益流水明细');
|
|
}
|
|
|
|
public function testMadowOverdrawn()
|
|
{
|
|
// 尝试超额扣除dmepa
|
|
$res = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'madow',
|
|
'amount' => '-99.00000000',
|
|
'memo' => '超额扣除dmepa',
|
|
]);
|
|
$this->assert($res['code'] === 0 && strpos($res['msg'], '不足') !== false, 'dmepa持仓不足拦截超扣', $res['msg'] ?? '');
|
|
}
|
|
|
|
public function testVoucherRechargeAndDeduct()
|
|
{
|
|
// 当前 released=200, used=50, available=150
|
|
// 充值 100 元兑换券
|
|
$res1 = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'voucher',
|
|
'amount' => 100,
|
|
'memo' => '充值兑换券',
|
|
]);
|
|
$agent1 = AgentModel::where('user_id', $this->testUserId)->find();
|
|
$avail1 = $agent1->voucher_released - $agent1->voucher_used;
|
|
$this->assert($res1['code'] === 1 && $avail1 == 250.00, '兑换券充值成功可用额度增加', "可用券: {$avail1}");
|
|
|
|
// 扣除 80 元兑换券
|
|
$res2 = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'voucher',
|
|
'amount' => -80,
|
|
'memo' => '扣除兑换券',
|
|
]);
|
|
$agent2 = AgentModel::where('user_id', $this->testUserId)->find();
|
|
$avail2 = $agent2->voucher_released - $agent2->voucher_used;
|
|
$this->assert($res2['code'] === 1 && $avail2 == 170.00, '兑换券扣除成功可用额度准确减少', "可用券: {$avail2}");
|
|
|
|
// 验证流水表记录
|
|
$log = RewardModel::where('user_id', $this->testUserId)->where('reward_type', 'admin_voucher')->order('id', 'desc')->find();
|
|
$this->assert($log && $log->amount == -80.00, '兑换券变动写入收益流水明细');
|
|
}
|
|
|
|
public function testVoucherOverdrawn()
|
|
{
|
|
// 尝试超额扣除兑换券 (当前可用 170)
|
|
$res = $this->invokeRecharge([
|
|
'id' => $this->testUserId,
|
|
'type' => 'voucher',
|
|
'amount' => -300,
|
|
'memo' => '超额扣除兑换券',
|
|
]);
|
|
$this->assert($res['code'] === 0 && strpos($res['msg'], '不足') !== false, '兑换券可用额度不足拦截超扣', $res['msg'] ?? '');
|
|
}
|
|
}
|
|
|
|
$test = new MultiAssetRechargeTest();
|
|
exit($test->run());
|