| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- <?php
- namespace App\Module\Mex\Tests;
- use App\Module\Mex\Logic\MexMatchLogic;
- use App\Module\Mex\Models\MexOrder;
- use App\Module\Mex\Models\MexTransaction;
- use App\Module\Mex\Models\MexWarehouse;
- use App\Module\Mex\Models\MexPriceConfig;
- use App\Module\Mex\Enums\OrderStatus;
- use App\Module\Mex\Enums\OrderType;
- use App\Module\Mex\Enums\TransactionType;
- use App\Module\Fund\Enums\FUND_CURRENCY_TYPE;
- use Illuminate\Foundation\Testing\RefreshDatabase;
- use Illuminate\Support\Facades\DB;
- use Tests\TestCase;
- /**
- * Mex撮合逻辑Bug修复测试
- *
- * 测试修复后的撮合逻辑确保订单状态更新和成交记录创建的一致性
- */
- class MexMatchLogicBugFixTest extends TestCase
- {
- use RefreshDatabase;
- /**
- * 仓库账户ID
- */
- const WAREHOUSE_USER_ID = 15;
- /**
- * 测试用户ID
- */
- const TEST_USER_ID = 39999;
- /**
- * 测试商品ID
- */
- const TEST_ITEM_ID = 999;
- protected function setUp(): void
- {
- parent::setUp();
-
- // 创建测试数据
- $this->createTestData();
- }
- /**
- * 创建测试数据
- */
- private function createTestData()
- {
- // 创建价格配置
- MexPriceConfig::create([
- 'item_id' => self::TEST_ITEM_ID,
- 'min_price' => 10.00000,
- 'max_price' => 20.00000,
- 'protection_threshold' => 1000,
- 'is_enabled' => true,
- ]);
- // 创建仓库库存(用于买入测试)
- MexWarehouse::create([
- 'item_id' => self::TEST_ITEM_ID,
- 'quantity' => 1000,
- 'total_buy_quantity' => 0,
- 'total_buy_amount' => '0.00000',
- 'total_sell_quantity' => 0,
- 'total_sell_amount' => '0.00000',
- 'last_transaction_at' => now(),
- ]);
- }
- /**
- * 测试用户买入物品订单撮合的数据一致性
- */
- public function testUserBuyItemOrderMatchConsistency()
- {
- // 创建买入订单
- $order = MexOrder::create([
- 'user_id' => self::TEST_USER_ID,
- 'item_id' => self::TEST_ITEM_ID,
- 'currency_type' => FUND_CURRENCY_TYPE::DIAMOND,
- 'order_type' => OrderType::BUY,
- 'quantity' => 100,
- 'price' => 20.00000,
- 'total_amount' => 2000.00000,
- 'status' => OrderStatus::PENDING,
- 'frozen_amount' => 2000.00000,
- ]);
- $warehouse = MexWarehouse::where('item_id', self::TEST_ITEM_ID)->first();
- // 模拟撮合过程中的异常情况
- DB::beginTransaction();
- try {
- // 执行撮合(这里会因为资金流转失败而抛出异常,但我们要确保数据一致性)
- $result = MexMatchLogic::executeUserBuyItemOrderMatch($order, $warehouse);
-
- // 由于没有实际的资金和物品服务,这里会失败
- $this->assertFalse($result['success']);
-
- // 重要:确保订单状态没有被错误更新
- $order->refresh();
- $this->assertEquals(OrderStatus::PENDING, $order->status);
-
- // 确保没有创建成交记录
- $transactionCount = MexTransaction::where('buy_order_id', $order->id)->count();
- $this->assertEquals(0, $transactionCount);
-
- } catch (\Exception $e) {
- // 异常情况下也要确保数据一致性
- $order->refresh();
- $this->assertEquals(OrderStatus::PENDING, $order->status);
-
- $transactionCount = MexTransaction::where('buy_order_id', $order->id)->count();
- $this->assertEquals(0, $transactionCount);
- }
-
- DB::rollBack();
- }
- /**
- * 测试用户卖出物品订单撮合的数据一致性
- */
- public function testUserSellItemOrderMatchConsistency()
- {
- // 创建卖出订单
- $order = MexOrder::create([
- 'user_id' => self::TEST_USER_ID,
- 'item_id' => self::TEST_ITEM_ID,
- 'currency_type' => FUND_CURRENCY_TYPE::DIAMOND,
- 'order_type' => OrderType::SELL,
- 'quantity' => 100,
- 'price' => 10.00000,
- 'total_amount' => 1000.00000,
- 'status' => OrderStatus::PENDING,
- ]);
- // 模拟撮合过程中的异常情况
- DB::beginTransaction();
- try {
- // 执行撮合(这里会因为物品流转失败而抛出异常,但我们要确保数据一致性)
- $result = MexMatchLogic::executeUserSellItemOrderMatch($order);
-
- // 由于没有实际的资金和物品服务,这里会失败
- $this->assertFalse($result['success']);
-
- // 重要:确保订单状态没有被错误更新
- $order->refresh();
- $this->assertEquals(OrderStatus::PENDING, $order->status);
-
- // 确保没有创建成交记录
- $transactionCount = MexTransaction::where('sell_order_id', $order->id)->count();
- $this->assertEquals(0, $transactionCount);
-
- } catch (\Exception $e) {
- // 异常情况下也要确保数据一致性
- $order->refresh();
- $this->assertEquals(OrderStatus::PENDING, $order->status);
-
- $transactionCount = MexTransaction::where('sell_order_id', $order->id)->count();
- $this->assertEquals(0, $transactionCount);
- }
-
- DB::rollBack();
- }
- /**
- * 测试修复命令能正确识别数据不一致问题
- */
- public function testFixCommandCanIdentifyInconsistentData()
- {
- // 手动创建一个已完成但没有成交记录的订单(模拟bug情况)
- $order = MexOrder::create([
- 'user_id' => self::TEST_USER_ID,
- 'item_id' => self::TEST_ITEM_ID,
- 'currency_type' => FUND_CURRENCY_TYPE::DIAMOND,
- 'order_type' => OrderType::SELL,
- 'quantity' => 100,
- 'price' => 10.00000,
- 'total_amount' => 1000.00000,
- 'status' => OrderStatus::COMPLETED, // 已完成
- 'completed_quantity' => 100,
- 'completed_amount' => 1000.00000,
- 'completed_at' => now(),
- ]);
- // 验证订单没有对应的成交记录
- $this->assertFalse($order->buyTransactions()->exists());
- $this->assertFalse($order->sellTransactions()->exists());
- // 使用修复命令的查询逻辑
- $missingTransactionOrders = MexOrder::where('status', OrderStatus::COMPLETED)
- ->whereDoesntHave('buyTransactions')
- ->whereDoesntHave('sellTransactions')
- ->get();
- $this->assertCount(1, $missingTransactionOrders);
- $this->assertEquals($order->id, $missingTransactionOrders->first()->id);
- }
- }
|