ItemFreezeTest.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. <?php
  2. namespace App\Module\GameItems\Tests;
  3. use App\Module\GameItems\Enums\FREEZE_ACTION_TYPE;
  4. use App\Module\GameItems\Enums\FREEZE_REASON_TYPE;
  5. use App\Module\GameItems\Logics\ItemFreeze;
  6. use App\Module\GameItems\Models\Item;
  7. use App\Module\GameItems\Models\ItemFreezeLog;
  8. use App\Module\GameItems\Models\ItemUser;
  9. use App\Module\GameItems\Services\ItemService;
  10. use Illuminate\Foundation\Testing\RefreshDatabase;
  11. use Tests\TestCase;
  12. use UCore\Db\Helper;
  13. /**
  14. * 物品冻结功能测试
  15. */
  16. class ItemFreezeTest extends TestCase
  17. {
  18. use RefreshDatabase;
  19. private int $testUserId = 1001;
  20. private int $testItemId = 2001;
  21. protected function setUp(): void
  22. {
  23. parent::setUp();
  24. // 创建测试物品
  25. Item::create([
  26. 'id' => $this->testItemId,
  27. 'name' => '测试物品',
  28. 'description' => '用于测试冻结功能的物品',
  29. 'category_id' => 1,
  30. 'type' => 1,
  31. 'is_unique' => false,
  32. 'max_stack' => 100,
  33. 'sell_price' => 10,
  34. 'tradable' => true,
  35. 'dismantlable' => true,
  36. 'default_expire_seconds' => 0,
  37. ]);
  38. }
  39. /**
  40. * 测试冻结统一属性物品
  41. */
  42. public function testFreezeNormalItem()
  43. {
  44. Helper::begin_tr();
  45. try {
  46. // 先给用户添加物品
  47. ItemService::addItem($this->testUserId, $this->testItemId, 50);
  48. // 验证添加成功
  49. $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId);
  50. $this->assertEquals(50, $availableQuantity);
  51. // 冻结部分物品
  52. $result = ItemFreeze::freezeNormalItem(
  53. $this->testUserId,
  54. $this->testItemId,
  55. 20,
  56. FREEZE_REASON_TYPE::TRADE_ORDER,
  57. 123,
  58. 'order'
  59. );
  60. // 验证冻结结果
  61. $this->assertTrue($result['success']);
  62. $this->assertEquals(20, $result['frozen_quantity']);
  63. // 验证可用数量减少
  64. $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId);
  65. $this->assertEquals(30, $availableQuantity);
  66. // 验证冻结记录
  67. $freezeLog = ItemFreezeLog::where('user_id', $this->testUserId)
  68. ->where('item_id', $this->testItemId)
  69. ->where('action_type', FREEZE_ACTION_TYPE::FREEZE)
  70. ->first();
  71. $this->assertNotNull($freezeLog);
  72. $this->assertEquals(20, $freezeLog->quantity);
  73. $this->assertEquals('交易订单', $freezeLog->reason);
  74. Helper::commit_tr();
  75. } catch (\Exception $e) {
  76. Helper::rollback_tr();
  77. throw $e;
  78. }
  79. }
  80. /**
  81. * 测试解冻物品
  82. */
  83. public function testUnfreezeItem()
  84. {
  85. Helper::begin_tr();
  86. try {
  87. // 先添加物品并冻结
  88. ItemService::addItem($this->testUserId, $this->testItemId, 50);
  89. $freezeResult = ItemFreeze::freezeNormalItem(
  90. $this->testUserId,
  91. $this->testItemId,
  92. 20,
  93. FREEZE_REASON_TYPE::TRADE_ORDER,
  94. 123,
  95. 'order'
  96. );
  97. $freezeLogId = $freezeResult['frozen_items'][0]['freeze_log_id'];
  98. // 验证冻结状态
  99. $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId);
  100. $this->assertEquals(30, $availableQuantity);
  101. // 解冻物品
  102. $unfreezeResult = ItemFreeze::unfreezeByLogId($freezeLogId);
  103. // 验证解冻结果
  104. $this->assertTrue($unfreezeResult['success']);
  105. $this->assertEquals(20, $unfreezeResult['unfrozen_quantity']);
  106. // 验证可用数量恢复
  107. $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId);
  108. $this->assertEquals(50, $availableQuantity);
  109. // 验证解冻记录
  110. $unfreezeLog = ItemFreezeLog::where('user_id', $this->testUserId)
  111. ->where('item_id', $this->testItemId)
  112. ->where('action_type', FREEZE_ACTION_TYPE::UNFREEZE)
  113. ->first();
  114. $this->assertNotNull($unfreezeLog);
  115. $this->assertEquals(20, $unfreezeLog->quantity);
  116. Helper::commit_tr();
  117. } catch (\Exception $e) {
  118. Helper::rollback_tr();
  119. throw $e;
  120. }
  121. }
  122. /**
  123. * 测试消耗物品时排除冻结物品
  124. */
  125. public function testConsumeExcludesFrozenItems()
  126. {
  127. Helper::begin_tr();
  128. try {
  129. // 添加物品
  130. ItemService::addItem($this->testUserId, $this->testItemId, 50);
  131. // 冻结部分物品
  132. ItemFreeze::freezeNormalItem(
  133. $this->testUserId,
  134. $this->testItemId,
  135. 20,
  136. FREEZE_REASON_TYPE::TRADE_ORDER,
  137. 123,
  138. 'order'
  139. );
  140. // 尝试消耗物品,应该只能消耗未冻结的30个
  141. $result = ItemService::consumeItem($this->testUserId, $this->testItemId, null, 25);
  142. // 验证消耗成功
  143. $this->assertTrue($result['success']);
  144. $this->assertEquals(25, $result['quantity']);
  145. // 验证剩余可用数量
  146. $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId);
  147. $this->assertEquals(5, $availableQuantity);
  148. // 尝试消耗超过可用数量的物品,应该失败
  149. $this->expectException(\Exception::class);
  150. ItemService::consumeItem($this->testUserId, $this->testItemId, null, 10);
  151. Helper::commit_tr();
  152. } catch (\Exception $e) {
  153. Helper::rollback_tr();
  154. throw $e;
  155. }
  156. }
  157. /**
  158. * 测试批量冻结物品
  159. */
  160. public function testBatchFreezeItems()
  161. {
  162. Helper::check_tr();
  163. try {
  164. // 添加多种物品
  165. ItemService::addItem($this->testUserId, $this->testItemId, 100);
  166. // 创建另一个测试物品
  167. $testItemId2 = $this->testItemId + 1;
  168. Item::create([
  169. 'id' => $testItemId2,
  170. 'name' => '测试物品2',
  171. 'description' => '用于测试批量冻结的物品',
  172. 'category_id' => 1,
  173. 'type' => 1,
  174. 'is_unique' => false,
  175. 'max_stack' => 100,
  176. 'sell_price' => 10,
  177. 'tradable' => true,
  178. 'dismantlable' => true,
  179. 'default_expire_seconds' => 0,
  180. ]);
  181. ItemService::addItem($this->testUserId, $testItemId2, 50);
  182. // 批量冻结
  183. $items = [
  184. ['item_id' => $this->testItemId, 'quantity' => 30],
  185. ['item_id' => $testItemId2, 'quantity' => 20],
  186. ];
  187. $result = ItemFreeze::batchFreezeItems(
  188. $this->testUserId,
  189. $items,
  190. FREEZE_REASON_TYPE::SYSTEM_FREEZE,
  191. null,
  192. 'system'
  193. );
  194. // 验证批量冻结结果
  195. $this->assertTrue($result['success']);
  196. $this->assertEquals(2, $result['frozen_items_count']);
  197. // 验证各物品的可用数量
  198. $availableQuantity1 = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId);
  199. $availableQuantity2 = ItemFreeze::getAvailableQuantity($this->testUserId, $testItemId2);
  200. $this->assertEquals(70, $availableQuantity1);
  201. $this->assertEquals(30, $availableQuantity2);
  202. Helper::commit_tr();
  203. } catch (\Exception $e) {
  204. Helper::rollback_tr();
  205. throw $e;
  206. }
  207. }
  208. /**
  209. * 测试获取冻结统计信息
  210. */
  211. public function testGetFreezeStatistics()
  212. {
  213. Helper::begin_tr();
  214. try {
  215. // 添加物品并冻结
  216. ItemService::addItem($this->testUserId, $this->testItemId, 100);
  217. ItemFreeze::freezeNormalItem(
  218. $this->testUserId,
  219. $this->testItemId,
  220. 30,
  221. FREEZE_REASON_TYPE::TRADE_ORDER,
  222. 123,
  223. 'order'
  224. );
  225. ItemFreeze::freezeNormalItem(
  226. $this->testUserId,
  227. $this->testItemId,
  228. 20,
  229. FREEZE_REASON_TYPE::ADMIN_FREEZE,
  230. null,
  231. 'admin'
  232. );
  233. // 获取统计信息
  234. $statistics = ItemFreeze::getFreezeStatistics($this->testUserId);
  235. // 验证统计结果
  236. $this->assertEquals(2, $statistics['total_frozen_items']);
  237. $this->assertEquals(50, $statistics['total_frozen_quantity']);
  238. $this->assertArrayHasKey('frozen_by_reason', $statistics);
  239. $this->assertArrayHasKey('frozen_by_source_type', $statistics);
  240. Helper::commit_tr();
  241. } catch (\Exception $e) {
  242. Helper::rollback_tr();
  243. throw $e;
  244. }
  245. }
  246. }