MexOrderCancelTest.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <?php
  2. namespace App\Module\Mex\Tests;
  3. use App\Module\Fund\Enums\FUND_CURRENCY_TYPE;
  4. use App\Module\GameItems\Enums\FREEZE_ACTION_TYPE;
  5. use App\Module\GameItems\Models\ItemFreezeLog;
  6. use App\Module\GameItems\Models\ItemUser;
  7. use App\Module\GameItems\Services\ItemService;
  8. use App\Module\Mex\Enums\OrderStatus;
  9. use App\Module\Mex\Enums\OrderType;
  10. use App\Module\Mex\Models\MexOrder;
  11. use App\Module\Mex\Services\MexOrderService;
  12. use Illuminate\Foundation\Testing\RefreshDatabase;
  13. use Tests\TestCase;
  14. /**
  15. * 农贸市场订单取消测试
  16. *
  17. * 测试订单取消时的解冻功能
  18. */
  19. class MexOrderCancelTest extends TestCase
  20. {
  21. use RefreshDatabase;
  22. private int $testUserId = 1001;
  23. private int $testItemId = 10001;
  24. protected function setUp(): void
  25. {
  26. parent::setUp();
  27. // 准备测试数据
  28. $this->prepareTestData();
  29. }
  30. /**
  31. * 准备测试数据
  32. */
  33. private function prepareTestData(): void
  34. {
  35. // 创建测试用户物品
  36. ItemUser::create([
  37. 'user_id' => $this->testUserId,
  38. 'item_id' => $this->testItemId,
  39. 'instance_id' => null,
  40. 'quantity' => 100,
  41. 'is_frozen' => false,
  42. 'expire_at' => now()->addDays(30),
  43. ]);
  44. // 创建价格配置
  45. \App\Module\Mex\Models\MexPriceConfig::create([
  46. 'item_id' => $this->testItemId,
  47. 'min_price' => 1.0,
  48. 'max_price' => 100.0,
  49. 'protection_threshold' => 10,
  50. 'is_enabled' => true,
  51. ]);
  52. }
  53. /**
  54. * 测试取消卖出订单时解冻物品
  55. */
  56. public function testCancelSellOrderUnfreezeItems(): void
  57. {
  58. // 1. 创建卖出订单(会冻结物品)
  59. $createResult = \DB::transaction(function () {
  60. return \App\Module\Mex\Logic\MexOrderLogic::createSellOrder(
  61. $this->testUserId,
  62. $this->testItemId,
  63. 20,
  64. 10.5,
  65. FUND_CURRENCY_TYPE::FUND2
  66. );
  67. });
  68. $this->assertTrue($createResult['success'], '创建卖出订单失败:' . ($createResult['message'] ?? ''));
  69. $orderId = $createResult['order_id'];
  70. // 2. 验证物品已被冻结
  71. $frozenItems = ItemUser::where('user_id', $this->testUserId)
  72. ->where('item_id', $this->testItemId)
  73. ->where('is_frozen', true)
  74. ->get();
  75. $this->assertGreaterThan(0, $frozenItems->count(), '物品应该被冻结');
  76. // 3. 验证冻结记录存在
  77. $freezeLog = ItemFreezeLog::where('source_id', $orderId)
  78. ->where('source_type', 'mex_sell_order')
  79. ->where('action_type', FREEZE_ACTION_TYPE::FREEZE)
  80. ->first();
  81. $this->assertNotNull($freezeLog, '应该存在冻结记录');
  82. // 4. 取消订单
  83. $cancelResult = MexOrderService::cancelOrder($this->testUserId, $orderId);
  84. $this->assertTrue($cancelResult['success'], '取消订单失败:' . ($cancelResult['message'] ?? ''));
  85. // 5. 验证订单状态已更新
  86. $order = MexOrder::find($orderId);
  87. $this->assertEquals(OrderStatus::CANCELLED, $order->status, '订单状态应该为已取消');
  88. // 6. 验证物品已解冻
  89. $frozenItemsAfterCancel = ItemUser::where('user_id', $this->testUserId)
  90. ->where('item_id', $this->testItemId)
  91. ->where('is_frozen', true)
  92. ->get();
  93. $this->assertEquals(0, $frozenItemsAfterCancel->count(), '物品应该已解冻');
  94. // 7. 验证解冻记录存在
  95. $unfreezeLog = ItemFreezeLog::where('source_id', $orderId)
  96. ->where('source_type', 'mex_sell_order')
  97. ->where('action_type', FREEZE_ACTION_TYPE::UNFREEZE)
  98. ->first();
  99. $this->assertNotNull($unfreezeLog, '应该存在解冻记录');
  100. }
  101. /**
  102. * 测试取消买入订单
  103. */
  104. public function testCancelBuyOrder(): void
  105. {
  106. // 1. 创建买入订单
  107. $createResult = \DB::transaction(function () {
  108. return \App\Module\Mex\Logic\MexOrderLogic::createBuyOrder(
  109. $this->testUserId,
  110. $this->testItemId,
  111. 10,
  112. 15.0,
  113. FUND_CURRENCY_TYPE::FUND2
  114. );
  115. });
  116. $this->assertTrue($createResult['success'], '创建买入订单失败:' . ($createResult['message'] ?? ''));
  117. $orderId = $createResult['order_id'];
  118. // 2. 取消订单
  119. $cancelResult = MexOrderService::cancelOrder($this->testUserId, $orderId);
  120. $this->assertTrue($cancelResult['success'], '取消订单失败:' . ($cancelResult['message'] ?? ''));
  121. // 3. 验证订单状态已更新
  122. $order = MexOrder::find($orderId);
  123. $this->assertEquals(OrderStatus::CANCELLED, $order->status, '订单状态应该为已取消');
  124. }
  125. /**
  126. * 测试取消不存在的订单
  127. */
  128. public function testCancelNonExistentOrder(): void
  129. {
  130. $cancelResult = MexOrderService::cancelOrder($this->testUserId, 99999);
  131. $this->assertFalse($cancelResult['success'], '取消不存在的订单应该失败');
  132. $this->assertStringContains('订单不存在', $cancelResult['message']);
  133. }
  134. /**
  135. * 测试取消已完成的订单
  136. */
  137. public function testCancelCompletedOrder(): void
  138. {
  139. // 1. 创建订单
  140. $order = MexOrder::create([
  141. 'user_id' => $this->testUserId,
  142. 'item_id' => $this->testItemId,
  143. 'currency_type' => FUND_CURRENCY_TYPE::FUND2,
  144. 'order_type' => OrderType::SELL,
  145. 'quantity' => 10,
  146. 'price' => 10.0,
  147. 'total_amount' => 100.0,
  148. 'status' => OrderStatus::COMPLETED, // 已完成状态
  149. ]);
  150. // 2. 尝试取消已完成的订单
  151. $cancelResult = MexOrderService::cancelOrder($this->testUserId, $order->id);
  152. $this->assertFalse($cancelResult['success'], '取消已完成的订单应该失败');
  153. $this->assertStringContains('只能取消等待中的订单', $cancelResult['message']);
  154. }
  155. /**
  156. * 测试取消其他用户的订单
  157. */
  158. public function testCancelOtherUserOrder(): void
  159. {
  160. // 1. 创建其他用户的订单
  161. $order = MexOrder::create([
  162. 'user_id' => 9999, // 其他用户
  163. 'item_id' => $this->testItemId,
  164. 'currency_type' => FUND_CURRENCY_TYPE::FUND2,
  165. 'order_type' => OrderType::SELL,
  166. 'quantity' => 10,
  167. 'price' => 10.0,
  168. 'total_amount' => 100.0,
  169. 'status' => OrderStatus::PENDING,
  170. ]);
  171. // 2. 尝试取消其他用户的订单
  172. $cancelResult = MexOrderService::cancelOrder($this->testUserId, $order->id);
  173. $this->assertFalse($cancelResult['success'], '取消其他用户的订单应该失败');
  174. $this->assertStringContains('订单不存在', $cancelResult['message']);
  175. }
  176. }