MexMatchLogicTest.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. namespace App\Module\Mex\Tests;
  3. use App\Module\Mex\Logic\MexMatchLogic;
  4. use App\Module\Mex\Models\MexOrder;
  5. use App\Module\Mex\Models\MexWarehouse;
  6. use App\Module\Mex\Models\MexPriceConfig;
  7. use App\Module\Mex\Enums\OrderType;
  8. use App\Module\Mex\Enums\OrderStatus;
  9. use Illuminate\Foundation\Testing\RefreshDatabase;
  10. use Illuminate\Foundation\Testing\WithFaker;
  11. use Tests\TestCase;
  12. /**
  13. * Mex撮合逻辑测试
  14. *
  15. * 测试用户买入物品和用户卖出物品的撮合逻辑
  16. */
  17. class MexMatchLogicTest extends TestCase
  18. {
  19. use RefreshDatabase, WithFaker;
  20. /**
  21. * 测试用户买入物品撮合条件检查
  22. */
  23. public function test_check_user_buy_item_match_conditions()
  24. {
  25. // 创建测试数据
  26. $itemId = 1001;
  27. // 测试没有价格配置的情况
  28. $result = MexMatchLogic::checkUserBuyItemMatchConditions($itemId);
  29. $this->assertFalse($result['can_match']);
  30. $this->assertStringContains('未配置价格信息', $result['message']);
  31. // 创建价格配置
  32. MexPriceConfig::create([
  33. 'item_id' => $itemId,
  34. 'min_price' => '10.00000',
  35. 'max_price' => '20.00000',
  36. 'protection_threshold' => 300,
  37. 'is_enabled' => true,
  38. ]);
  39. // 测试没有仓库库存的情况
  40. $result = MexMatchLogic::checkUserBuyItemMatchConditions($itemId);
  41. $this->assertFalse($result['can_match']);
  42. $this->assertStringContains('仓库库存不足', $result['message']);
  43. // 创建仓库库存
  44. MexWarehouse::create([
  45. 'item_id' => $itemId,
  46. 'quantity' => 1000,
  47. ]);
  48. // 测试没有符合条件订单的情况
  49. $result = MexMatchLogic::checkUserBuyItemMatchConditions($itemId);
  50. $this->assertFalse($result['can_match']);
  51. $this->assertStringContains('没有符合条件的待撮合用户买入物品订单', $result['message']);
  52. // 创建符合条件的用户买入物品订单
  53. MexOrder::create([
  54. 'user_id' => 1,
  55. 'item_id' => $itemId,
  56. 'order_type' => OrderType::BUY,
  57. 'quantity' => 100,
  58. 'price' => '20.00000', // 等于最高价
  59. 'total_amount' => '2000.00000',
  60. 'status' => OrderStatus::PENDING,
  61. ]);
  62. // 测试条件满足的情况
  63. $result = MexMatchLogic::checkUserBuyItemMatchConditions($itemId);
  64. $this->assertTrue($result['can_match']);
  65. $this->assertStringContains('撮合条件满足', $result['message']);
  66. }
  67. /**
  68. * 测试用户卖出物品撮合条件检查
  69. */
  70. public function test_check_user_sell_item_match_conditions()
  71. {
  72. // 创建测试数据
  73. $itemId = 1002;
  74. // 测试没有价格配置的情况
  75. $result = MexMatchLogic::checkUserSellItemMatchConditions($itemId);
  76. $this->assertFalse($result['can_match']);
  77. $this->assertStringContains('未配置价格信息', $result['message']);
  78. // 创建价格配置
  79. MexPriceConfig::create([
  80. 'item_id' => $itemId,
  81. 'min_price' => '10.00000',
  82. 'max_price' => '20.00000',
  83. 'protection_threshold' => 300,
  84. 'is_enabled' => true,
  85. ]);
  86. // 测试没有待撮合订单的情况
  87. $result = MexMatchLogic::checkUserSellItemMatchConditions($itemId);
  88. $this->assertFalse($result['can_match']);
  89. $this->assertStringContains('没有待撮合的用户卖出物品订单', $result['message']);
  90. // 创建用户卖出物品订单
  91. MexOrder::create([
  92. 'user_id' => 2,
  93. 'item_id' => $itemId,
  94. 'order_type' => OrderType::SELL,
  95. 'quantity' => 50,
  96. 'price' => '10.00000', // 等于最低价
  97. 'total_amount' => '500.00000',
  98. 'status' => OrderStatus::PENDING,
  99. ]);
  100. // 测试条件满足的情况
  101. $result = MexMatchLogic::checkUserSellItemMatchConditions($itemId);
  102. $this->assertTrue($result['can_match']);
  103. $this->assertStringContains('撮合条件满足', $result['message']);
  104. }
  105. /**
  106. * 测试用户买入物品撮合统计
  107. */
  108. public function test_get_user_buy_item_match_stats()
  109. {
  110. // 创建测试订单
  111. MexOrder::create([
  112. 'user_id' => 1,
  113. 'item_id' => 1003,
  114. 'order_type' => OrderType::BUY,
  115. 'quantity' => 100,
  116. 'price' => '15.00000',
  117. 'total_amount' => '1500.00000',
  118. 'status' => OrderStatus::PENDING,
  119. ]);
  120. MexOrder::create([
  121. 'user_id' => 2,
  122. 'item_id' => 1004,
  123. 'order_type' => OrderType::BUY,
  124. 'quantity' => 200,
  125. 'price' => '25.00000',
  126. 'total_amount' => '5000.00000',
  127. 'status' => OrderStatus::PENDING,
  128. ]);
  129. $stats = MexMatchLogic::getUserBuyItemMatchStats();
  130. $this->assertEquals(2, $stats['pending_orders']);
  131. $this->assertEquals(2, $stats['pending_items']);
  132. $this->assertEquals(300, $stats['pending_quantity']);
  133. $this->assertEquals('6500.00000', $stats['pending_amount']);
  134. }
  135. /**
  136. * 测试用户卖出物品撮合统计
  137. */
  138. public function test_get_user_sell_item_match_stats()
  139. {
  140. // 创建测试订单
  141. MexOrder::create([
  142. 'user_id' => 3,
  143. 'item_id' => 1005,
  144. 'order_type' => OrderType::SELL,
  145. 'quantity' => 150,
  146. 'price' => '12.00000',
  147. 'total_amount' => '1800.00000',
  148. 'status' => OrderStatus::PENDING,
  149. ]);
  150. $stats = MexMatchLogic::getUserSellItemMatchStats();
  151. $this->assertEquals(1, $stats['pending_orders']);
  152. $this->assertEquals(1, $stats['pending_items']);
  153. $this->assertEquals(150, $stats['pending_quantity']);
  154. $this->assertEquals('1800.00000', $stats['pending_amount']);
  155. }
  156. /**
  157. * 测试价格验证逻辑
  158. */
  159. public function test_price_validation_logic()
  160. {
  161. $itemId = 1006;
  162. // 创建价格配置
  163. MexPriceConfig::create([
  164. 'item_id' => $itemId,
  165. 'min_price' => '10.00000',
  166. 'max_price' => '20.00000',
  167. 'protection_threshold' => 300,
  168. 'is_enabled' => true,
  169. ]);
  170. // 创建仓库库存
  171. MexWarehouse::create([
  172. 'item_id' => $itemId,
  173. 'quantity' => 1000,
  174. ]);
  175. // 创建价格低于最高价的用户买入物品订单(不应该被撮合)
  176. MexOrder::create([
  177. 'user_id' => 1,
  178. 'item_id' => $itemId,
  179. 'order_type' => OrderType::BUY,
  180. 'quantity' => 100,
  181. 'price' => '15.00000', // 低于最高价20.00000
  182. 'total_amount' => '1500.00000',
  183. 'status' => OrderStatus::PENDING,
  184. ]);
  185. // 检查撮合条件
  186. $result = MexMatchLogic::checkUserBuyItemMatchConditions($itemId);
  187. $this->assertFalse($result['can_match']);
  188. $this->assertStringContains('没有符合条件的待撮合用户买入物品订单', $result['message']);
  189. // 创建价格等于最高价的用户买入物品订单(应该被撮合)
  190. MexOrder::create([
  191. 'user_id' => 2,
  192. 'item_id' => $itemId,
  193. 'order_type' => OrderType::BUY,
  194. 'quantity' => 100,
  195. 'price' => '20.00000', // 等于最高价
  196. 'total_amount' => '2000.00000',
  197. 'status' => OrderStatus::PENDING,
  198. ]);
  199. // 检查撮合条件
  200. $result = MexMatchLogic::checkUserBuyItemMatchConditions($itemId);
  201. $this->assertTrue($result['can_match']);
  202. $this->assertEquals(1, $result['pending_orders']); // 只有一个符合条件的订单
  203. }
  204. /**
  205. * 测试数量保护机制
  206. */
  207. public function test_quantity_protection_mechanism()
  208. {
  209. $itemId = 1007;
  210. // 创建价格配置,保护阈值为300
  211. MexPriceConfig::create([
  212. 'item_id' => $itemId,
  213. 'min_price' => '10.00000',
  214. 'max_price' => '20.00000',
  215. 'protection_threshold' => 300,
  216. 'is_enabled' => true,
  217. ]);
  218. // 创建仓库库存
  219. MexWarehouse::create([
  220. 'item_id' => $itemId,
  221. 'quantity' => 1000,
  222. ]);
  223. // 创建超过保护阈值的用户买入物品订单(不应该被撮合)
  224. MexOrder::create([
  225. 'user_id' => 1,
  226. 'item_id' => $itemId,
  227. 'order_type' => OrderType::BUY,
  228. 'quantity' => 500, // 超过保护阈值300
  229. 'price' => '20.00000',
  230. 'total_amount' => '10000.00000',
  231. 'status' => OrderStatus::PENDING,
  232. ]);
  233. // 检查撮合条件
  234. $result = MexMatchLogic::checkUserBuyItemMatchConditions($itemId);
  235. $this->assertFalse($result['can_match']);
  236. $this->assertStringContains('没有符合条件的待撮合用户买入物品订单', $result['message']);
  237. // 创建不超过保护阈值的用户买入物品订单(应该被撮合)
  238. MexOrder::create([
  239. 'user_id' => 2,
  240. 'item_id' => $itemId,
  241. 'order_type' => OrderType::BUY,
  242. 'quantity' => 200, // 不超过保护阈值300
  243. 'price' => '20.00000',
  244. 'total_amount' => '4000.00000',
  245. 'status' => OrderStatus::PENDING,
  246. ]);
  247. // 检查撮合条件
  248. $result = MexMatchLogic::checkUserBuyItemMatchConditions($itemId);
  249. $this->assertTrue($result['can_match']);
  250. $this->assertEquals(1, $result['pending_orders']); // 只有一个符合条件的订单
  251. }
  252. }