ItemConsumeFrozenTest.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <?php
  2. namespace Tests\Unit\GameItems;
  3. use App\Module\GameItems\Enums\FREEZE_REASON_TYPE;
  4. use App\Module\GameItems\Services\ItemService;
  5. use App\Module\GameItems\Models\ItemUser;
  6. use Illuminate\Foundation\Testing\RefreshDatabase;
  7. use Illuminate\Support\Facades\DB;
  8. use Tests\TestCase;
  9. /**
  10. * 物品消耗冻结功能测试
  11. *
  12. * 测试物品消耗时是否正确处理include_frozen参数
  13. */
  14. class ItemConsumeFrozenTest extends TestCase
  15. {
  16. use RefreshDatabase;
  17. private int $testUserId = 99999;
  18. private int $testItemId = 1001;
  19. protected function setUp(): void
  20. {
  21. parent::setUp();
  22. // 创建测试用户物品
  23. DB::transaction(function () {
  24. // 添加100个未冻结物品
  25. ItemUser::create([
  26. 'user_id' => $this->testUserId,
  27. 'item_id' => $this->testItemId,
  28. 'instance_id' => null,
  29. 'quantity' => 100,
  30. 'is_frozen' => false,
  31. 'frozen_log_id' => null,
  32. ]);
  33. // 添加50个冻结物品
  34. ItemUser::create([
  35. 'user_id' => $this->testUserId,
  36. 'item_id' => $this->testItemId,
  37. 'instance_id' => null,
  38. 'quantity' => 50,
  39. 'is_frozen' => true,
  40. 'frozen_log_id' => 1, // 假设的冻结日志ID
  41. ]);
  42. });
  43. }
  44. /**
  45. * 测试不包含冻结物品的消耗(默认行为)
  46. */
  47. public function testConsumeItemWithoutFrozen()
  48. {
  49. DB::transaction(function () {
  50. // 消耗80个物品,不包含冻结物品
  51. $result = ItemService::consumeItem(
  52. $this->testUserId,
  53. $this->testItemId,
  54. null,
  55. 80,
  56. ['source_type' => 'test', 'source_id' => 1]
  57. );
  58. $this->assertTrue($result['success']);
  59. $this->assertEquals($this->testItemId, $result['item_id']);
  60. $this->assertEquals(80, $result['quantity']);
  61. // 验证剩余数量:应该还有20个未冻结物品,50个冻结物品不变
  62. $remainingItems = ItemUser::where('user_id', $this->testUserId)
  63. ->where('item_id', $this->testItemId)
  64. ->get();
  65. $unfrozenQuantity = $remainingItems->where('is_frozen', false)->sum('quantity');
  66. $frozenQuantity = $remainingItems->where('is_frozen', true)->sum('quantity');
  67. $this->assertEquals(20, $unfrozenQuantity); // 100 - 80 = 20
  68. $this->assertEquals(50, $frozenQuantity); // 冻结物品不变
  69. });
  70. }
  71. /**
  72. * 测试包含冻结物品的消耗
  73. */
  74. public function testConsumeItemWithFrozen()
  75. {
  76. DB::transaction(function () {
  77. // 消耗120个物品,包含冻结物品
  78. $result = ItemService::consumeItem(
  79. $this->testUserId,
  80. $this->testItemId,
  81. null,
  82. 120,
  83. [
  84. 'source_type' => 'test',
  85. 'source_id' => 1,
  86. 'include_frozen' => true // 包含冻结物品
  87. ]
  88. );
  89. $this->assertTrue($result['success']);
  90. $this->assertEquals($this->testItemId, $result['item_id']);
  91. $this->assertEquals(120, $result['quantity']);
  92. // 验证剩余数量:应该还有30个物品(100+50-120=30)
  93. $remainingQuantity = ItemUser::where('user_id', $this->testUserId)
  94. ->where('item_id', $this->testItemId)
  95. ->sum('quantity');
  96. $this->assertEquals(30, $remainingQuantity);
  97. });
  98. }
  99. /**
  100. * 测试不包含冻结物品时数量不足的情况
  101. */
  102. public function testConsumeItemInsufficientWithoutFrozen()
  103. {
  104. $this->expectException(\Exception::class);
  105. $this->expectExceptionMessage('数量不足');
  106. DB::transaction(function () {
  107. // 尝试消耗120个物品,但只有100个未冻结物品
  108. ItemService::consumeItem(
  109. $this->testUserId,
  110. $this->testItemId,
  111. null,
  112. 120,
  113. ['source_type' => 'test', 'source_id' => 1]
  114. );
  115. });
  116. }
  117. /**
  118. * 测试包含冻结物品时数量足够的情况
  119. */
  120. public function testConsumeItemSufficientWithFrozen()
  121. {
  122. DB::transaction(function () {
  123. // 消耗150个物品,总共有150个物品(100未冻结+50冻结)
  124. $result = ItemService::consumeItem(
  125. $this->testUserId,
  126. $this->testItemId,
  127. null,
  128. 150,
  129. [
  130. 'source_type' => 'test',
  131. 'source_id' => 1,
  132. 'include_frozen' => true
  133. ]
  134. );
  135. $this->assertTrue($result['success']);
  136. // 验证所有物品都被消耗
  137. $remainingQuantity = ItemUser::where('user_id', $this->testUserId)
  138. ->where('item_id', $this->testItemId)
  139. ->sum('quantity');
  140. $this->assertEquals(0, $remainingQuantity);
  141. });
  142. }
  143. /**
  144. * 测试优先消耗冻结物品的逻辑
  145. */
  146. public function testConsumeFrozenItemsFirst()
  147. {
  148. DB::transaction(function () {
  149. // 消耗50个物品,应该优先消耗冻结的50个物品
  150. $result = ItemService::consumeItem(
  151. $this->testUserId,
  152. $this->testItemId,
  153. null,
  154. 50,
  155. [
  156. 'source_type' => 'test',
  157. 'source_id' => 1,
  158. 'include_frozen' => true
  159. ]
  160. );
  161. $this->assertTrue($result['success']);
  162. $this->assertEquals($this->testItemId, $result['item_id']);
  163. $this->assertEquals(50, $result['quantity']);
  164. // 验证剩余物品:应该还有100个未冻结物品,0个冻结物品
  165. $remainingUnfrozen = ItemUser::where('user_id', $this->testUserId)
  166. ->where('item_id', $this->testItemId)
  167. ->where('is_frozen', false)
  168. ->sum('quantity');
  169. $remainingFrozen = ItemUser::where('user_id', $this->testUserId)
  170. ->where('item_id', $this->testItemId)
  171. ->where('is_frozen', true)
  172. ->sum('quantity');
  173. $this->assertEquals(100, $remainingUnfrozen, '应该还有100个未冻结物品');
  174. $this->assertEquals(0, $remainingFrozen, '冻结物品应该被优先消耗完');
  175. });
  176. }
  177. }