| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- <?php
- namespace Tests\Unit\GameItems;
- use App\Module\Game\Logics\ItemTemp;
- use App\Module\GameItems\Enums\FREEZE_REASON_TYPE;
- use App\Module\GameItems\Events\ItemQuantityChanged;
- use App\Module\GameItems\Logics\ItemFreeze;
- use App\Module\GameItems\Models\ItemFreezeLog;
- use App\Module\GameItems\Models\ItemUser;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Event;
- use Tests\TestCase;
- /**
- * 物品冻结lastdata同步测试
- *
- * 测试物品冻结功能的lastdata同步问题修复
- */
- class ItemFreezeLastDataSyncTest extends TestCase
- {
- protected function setUp(): void
- {
- parent::setUp();
- // 启用事件监听
- Event::fake([ItemQuantityChanged::class]);
- }
- /**
- * 测试部分冻结时的事件触发
- *
- * 验证当进行部分冻结(拆堆)时:
- * 1. 原堆叠数量减少事件被正确触发
- * 2. 新冻结堆叠创建事件被正确触发
- */
- public function test_partial_freeze_triggers_correct_events()
- {
- DB::beginTransaction();
- try {
- $userId = 1001;
- $itemId = 2001;
- $originalQuantity = 100;
- $freezeQuantity = 30;
- // 创建用户物品记录
- $userItem = ItemUser::create([
- 'user_id' => $userId,
- 'item_id' => $itemId,
- 'instance_id' => null,
- 'quantity' => $originalQuantity,
- 'expire_at' => now()->addDays(30),
- 'is_frozen' => false,
- 'frozen_log_id' => null,
- ]);
- // 执行部分冻结操作
- $result = ItemFreeze::freezeNormalItem(
- $userId,
- $itemId,
- $freezeQuantity,
- FREEZE_REASON_TYPE::TRADE_ORDER,
- 12345,
- 'order',
- null
- );
- // 验证冻结操作成功
- $this->assertTrue($result['success']);
- $this->assertEquals($freezeQuantity, $result['frozen_quantity']);
- // 验证数据库状态
- // 原堆叠数量应该减少
- $userItem->refresh();
- $this->assertEquals($originalQuantity - $freezeQuantity, $userItem->quantity);
- $this->assertFalse($userItem->is_frozen);
- // 应该创建新的冻结堆叠
- $frozenItem = ItemUser::where('user_id', $userId)
- ->where('item_id', $itemId)
- ->where('is_frozen', true)
- ->first();
- $this->assertNotNull($frozenItem);
- $this->assertEquals($freezeQuantity, $frozenItem->quantity);
- // 验证事件触发
- Event::assertDispatched(ItemQuantityChanged::class, 2); // 应该触发2个事件
- // 验证第一个事件:原堆叠数量减少
- Event::assertDispatched(ItemQuantityChanged::class, function ($event) use ($userId, $itemId, $userItem, $originalQuantity, $freezeQuantity) {
- return $event->userId === $userId
- && $event->itemId === $itemId
- && $event->userItemId === $userItem->id
- && $event->oldQuantity === $originalQuantity
- && $event->newQuantity === ($originalQuantity - $freezeQuantity)
- && $event->oldFrozenStatus === false
- && $event->newFrozenStatus === false
- && isset($event->options['change_type'])
- && $event->options['change_type'] === 'quantity_decrease';
- });
- // 验证第二个事件:新冻结堆叠创建
- Event::assertDispatched(ItemQuantityChanged::class, function ($event) use ($userId, $itemId, $freezeQuantity) {
- return $event->userId === $userId
- && $event->itemId === $itemId
- && $event->oldQuantity === 0 // 新创建的物品,旧数量为0
- && $event->newQuantity === $freezeQuantity
- && $event->oldFrozenStatus === null // 新创建的物品,旧冻结状态为null
- && $event->newFrozenStatus === true
- && isset($event->options['change_type'])
- && $event->options['change_type'] === 'frozen_item_create';
- });
- } finally {
- DB::rollBack();
- }
- }
- /**
- * 测试全部冻结时的事件触发
- *
- * 验证当进行全部冻结时:
- * 只触发冻结状态变更事件,不涉及数量变更
- */
- public function test_full_freeze_triggers_correct_event()
- {
- DB::beginTransaction();
- try {
- $userId = 1002;
- $itemId = 2002;
- $quantity = 50;
- // 创建用户物品记录
- $userItem = ItemUser::create([
- 'user_id' => $userId,
- 'item_id' => $itemId,
- 'instance_id' => null,
- 'quantity' => $quantity,
- 'expire_at' => now()->addDays(30),
- 'is_frozen' => false,
- 'frozen_log_id' => null,
- ]);
- // 执行全部冻结操作
- $result = ItemFreeze::freezeNormalItem(
- $userId,
- $itemId,
- $quantity, // 冻结全部数量
- FREEZE_REASON_TYPE::ADMIN_FREEZE,
- null,
- null,
- 1
- );
- // 验证冻结操作成功
- $this->assertTrue($result['success']);
- $this->assertEquals($quantity, $result['frozen_quantity']);
- // 验证数据库状态
- $userItem->refresh();
- $this->assertEquals($quantity, $userItem->quantity); // 数量不变
- $this->assertTrue($userItem->is_frozen); // 冻结状态变为true
- // 验证事件触发
- Event::assertDispatched(ItemQuantityChanged::class, 1); // 应该只触发1个事件
- // 验证事件:冻结状态变更
- Event::assertDispatched(ItemQuantityChanged::class, function ($event) use ($userId, $itemId, $userItem, $quantity) {
- return $event->userId === $userId
- && $event->itemId === $itemId
- && $event->userItemId === $userItem->id
- && $event->oldQuantity === $quantity
- && $event->newQuantity === $quantity // 数量不变
- && $event->oldFrozenStatus === false
- && $event->newFrozenStatus === true
- && isset($event->options['change_type'])
- && $event->options['change_type'] === 'freeze_status_change';
- });
- } finally {
- DB::rollBack();
- }
- }
- /**
- * 测试lastdata同步数据的正确性
- *
- * 验证事件触发后,临时数据是否正确存储
- */
- public function test_lastdata_sync_data_correctness()
- {
- DB::beginTransaction();
- try {
- $userId = 1003;
- $itemId = 2003;
- $originalQuantity = 80;
- $freezeQuantity = 25;
- // 创建用户物品记录
- $userItem = ItemUser::create([
- 'user_id' => $userId,
- 'item_id' => $itemId,
- 'instance_id' => null,
- 'quantity' => $originalQuantity,
- 'expire_at' => now()->addDays(30),
- 'is_frozen' => false,
- 'frozen_log_id' => null,
- ]);
- // 清空事件fake,使用真实的事件监听器
- Event::fake([]); // 清空fake
- // 执行部分冻结操作
- ItemFreeze::freezeNormalItem(
- $userId,
- $itemId,
- $freezeQuantity,
- FREEZE_REASON_TYPE::SYSTEM_FREEZE,
- null,
- null,
- null
- );
- // 获取临时数据
- $tempData = ItemTemp::getUserItemChanges($userId);
-
- // 验证临时数据包含了物品变更信息
- $this->assertNotEmpty($tempData);
- $this->assertArrayHasKey($itemId, $tempData);
- $itemChange = $tempData[$itemId];
-
- // 验证临时数据的正确性
- // 注意:由于同一物品的多次变更会覆盖,这里应该是最后一次变更(冻结堆叠创建)的数据
- $this->assertEquals($itemId, $itemChange->itemId);
- $this->assertEquals($freezeQuantity, $itemChange->newQuantity);
- $this->assertTrue($itemChange->newFrozenStatus);
- } finally {
- DB::rollBack();
- }
- }
- }
|