|
|
@@ -0,0 +1,262 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace Tests\Feature\Pet;
|
|
|
+
|
|
|
+use App\Module\Pet\Models\PetUser;
|
|
|
+use App\Module\Pet\Models\PetSkill;
|
|
|
+use App\Module\Pet\Services\PetService;
|
|
|
+use App\Module\GameItems\Services\ItemService;
|
|
|
+use App\Module\Farm\Models\FarmLand;
|
|
|
+use App\Module\Farm\Models\FarmCrop;
|
|
|
+use App\Module\Farm\Services\CropService;
|
|
|
+use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
+use Tests\TestCase;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 宠物自动施肥技能测试
|
|
|
+ */
|
|
|
+class AutoFertilizingSkillTest extends TestCase
|
|
|
+{
|
|
|
+ private int $testUserId = 9999;
|
|
|
+ private int $testPetId;
|
|
|
+ private int $testLandId;
|
|
|
+ private int $fertilizerItemId = 19; // 普通化肥
|
|
|
+
|
|
|
+ protected function setUp(): void
|
|
|
+ {
|
|
|
+ parent::setUp();
|
|
|
+
|
|
|
+ // 清理可能存在的测试数据
|
|
|
+ $this->cleanupTestData();
|
|
|
+
|
|
|
+ // 创建测试数据
|
|
|
+ $this->createTestData();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清理测试数据
|
|
|
+ */
|
|
|
+ private function cleanupTestData(): void
|
|
|
+ {
|
|
|
+ // 按正确顺序清理测试数据,避免外键约束问题
|
|
|
+ DB::table('pet_skill_logs')->whereIn('pet_id', function($query) {
|
|
|
+ $query->select('id')->from('pet_users')->where('user_id', $this->testUserId);
|
|
|
+ })->delete();
|
|
|
+ DB::table('pet_active_skills')->whereIn('pet_id', function($query) {
|
|
|
+ $query->select('id')->from('pet_users')->where('user_id', $this->testUserId);
|
|
|
+ })->delete();
|
|
|
+ DB::table('farm_crops')->where('user_id', $this->testUserId)->delete();
|
|
|
+ DB::table('farm_land_users')->where('user_id', $this->testUserId)->delete();
|
|
|
+ DB::table('item_users')->where('user_id', $this->testUserId)->delete();
|
|
|
+ DB::table('pet_users')->where('user_id', $this->testUserId)->delete();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建测试数据
|
|
|
+ */
|
|
|
+ private function createTestData(): void
|
|
|
+ {
|
|
|
+ // 创建测试宠物(10级以上)
|
|
|
+ $pet = PetUser::create([
|
|
|
+ 'user_id' => $this->testUserId,
|
|
|
+ 'pet_config_id' => 1,
|
|
|
+ 'name' => '测试宠物',
|
|
|
+ 'level' => 15, // 确保等级满足要求
|
|
|
+ 'exp' => 1000,
|
|
|
+ 'stamina' => 100,
|
|
|
+ 'max_stamina' => 100,
|
|
|
+ 'status' => 1,
|
|
|
+ 'grade' => 1,
|
|
|
+ 'created_at' => now(),
|
|
|
+ 'updated_at' => now()
|
|
|
+ ]);
|
|
|
+ $this->testPetId = $pet->id;
|
|
|
+
|
|
|
+ // 创建测试土地
|
|
|
+ $land = FarmLand::create([
|
|
|
+ 'user_id' => $this->testUserId,
|
|
|
+ 'position' => 1, // 土地位置
|
|
|
+ 'land_type' => 1,
|
|
|
+ 'status' => 2, // 种植中状态
|
|
|
+ 'has_crop' => true,
|
|
|
+ 'created_at' => now(),
|
|
|
+ 'updated_at' => now()
|
|
|
+ ]);
|
|
|
+ $this->testLandId = $land->id;
|
|
|
+
|
|
|
+ // 在土地上种植作物
|
|
|
+ $crop = FarmCrop::create([
|
|
|
+ 'land_id' => $this->testLandId,
|
|
|
+ 'user_id' => $this->testUserId,
|
|
|
+ 'seed_id' => 1,
|
|
|
+ 'land_level' => 1,
|
|
|
+ 'plant_time' => now(),
|
|
|
+ 'growth_stage' => 20, // 发芽期,可以施肥
|
|
|
+ 'stage_start_time' => now(),
|
|
|
+ 'stage_end_time' => now()->addHours(3),
|
|
|
+ 'disasters' => [],
|
|
|
+ 'fertilized' => false, // 未施肥
|
|
|
+ 'last_disaster_check_time' => now(),
|
|
|
+ 'can_disaster' => true,
|
|
|
+ 'final_output_item_id' => 2,
|
|
|
+ 'final_output_amount' => 1,
|
|
|
+ 'created_at' => now(),
|
|
|
+ 'updated_at' => now()
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 给用户添加肥料物品
|
|
|
+ DB::beginTransaction();
|
|
|
+ ItemService::addItem($this->testUserId, $this->fertilizerItemId, 10, [
|
|
|
+ 'source' => 'test_setup'
|
|
|
+ ]);
|
|
|
+ DB::commit();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试自动施肥技能激活
|
|
|
+ */
|
|
|
+ public function testActivateAutoFertilizingSkill(): void
|
|
|
+ {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 获取自动施肥技能
|
|
|
+ $skill = PetSkill::where('skill_name', '自动施肥')->first();
|
|
|
+ $this->assertNotNull($skill, '自动施肥技能不存在');
|
|
|
+
|
|
|
+ // 激活技能
|
|
|
+ $result = PetService::useSkill($this->testUserId, $this->testPetId, $skill->id, [
|
|
|
+ 'duration' => 3600, // 1小时
|
|
|
+ 'auto_use_items' => true
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $this->assertTrue($result['success'], '技能激活失败: ' . ($result['message'] ?? ''));
|
|
|
+ $this->assertEquals($skill->id, $result['skill_id']);
|
|
|
+
|
|
|
+ // 验证技能激活记录
|
|
|
+ $activeSkill = \App\Module\Pet\Models\PetActiveSkill::where('pet_id', $this->testPetId)
|
|
|
+ ->where('skill_name', '自动施肥')
|
|
|
+ ->where('status', 'active')
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ $this->assertNotNull($activeSkill, '技能激活记录不存在');
|
|
|
+ $this->assertEquals('自动施肥', $activeSkill->skill_name);
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ echo "✓ 自动施肥技能激活测试通过\n";
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ $this->fail('测试失败: ' . $e->getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试自动施肥处理逻辑
|
|
|
+ */
|
|
|
+ public function testAutoFertilizingProcess(): void
|
|
|
+ {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 先激活技能
|
|
|
+ $skill = PetSkill::where('skill_name', '自动施肥')->first();
|
|
|
+ PetService::useSkill($this->testUserId, $this->testPetId, $skill->id, [
|
|
|
+ 'duration' => 3600,
|
|
|
+ 'auto_use_items' => true
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 获取激活的技能
|
|
|
+ $activeSkill = \App\Module\Pet\Models\PetActiveSkill::where('pet_id', $this->testPetId)
|
|
|
+ ->where('skill_name', '自动施肥')
|
|
|
+ ->where('status', 'active')
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ $this->assertNotNull($activeSkill, '技能激活记录不存在');
|
|
|
+
|
|
|
+ // 获取施肥前的作物状态
|
|
|
+ $cropBefore = FarmCrop::where('land_id', $this->testLandId)->first();
|
|
|
+ $this->assertFalse($cropBefore->fertilized, '作物应该未施肥');
|
|
|
+
|
|
|
+ // 获取施肥前的肥料数量
|
|
|
+ $fertilizerBefore = ItemService::getUserItems($this->testUserId, ['item_id' => $this->fertilizerItemId])
|
|
|
+ ->sum('quantity');
|
|
|
+
|
|
|
+ // 执行自动施肥处理
|
|
|
+ $autoSkillLogic = new \App\Module\Pet\Logic\PetAutoSkillLogic();
|
|
|
+ $autoSkillLogic->processAutoFertilizing($activeSkill);
|
|
|
+
|
|
|
+ // 验证施肥结果
|
|
|
+ $cropAfter = FarmCrop::where('land_id', $this->testLandId)->first();
|
|
|
+ $this->assertTrue($cropAfter->fertilized, '作物应该已施肥');
|
|
|
+
|
|
|
+ // 验证肥料消耗
|
|
|
+ $fertilizerAfter = ItemService::getUserItems($this->testUserId, ['item_id' => $this->fertilizerItemId])
|
|
|
+ ->sum('quantity');
|
|
|
+ $this->assertEquals($fertilizerBefore - 1, $fertilizerAfter, '肥料应该消耗1个');
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ echo "✓ 自动施肥处理逻辑测试通过\n";
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ $this->fail('测试失败: ' . $e->getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试等级限制
|
|
|
+ */
|
|
|
+ public function testLevelRequirement(): void
|
|
|
+ {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 创建低等级宠物
|
|
|
+ $lowLevelPet = PetUser::create([
|
|
|
+ 'user_id' => $this->testUserId,
|
|
|
+ 'pet_config_id' => 1,
|
|
|
+ 'name' => '低等级宠物',
|
|
|
+ 'level' => 5, // 低于10级
|
|
|
+ 'exp' => 100,
|
|
|
+ 'stamina' => 100,
|
|
|
+ 'max_stamina' => 100,
|
|
|
+ 'status' => 1,
|
|
|
+ 'grade' => 1,
|
|
|
+ 'created_at' => now(),
|
|
|
+ 'updated_at' => now()
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 获取自动施肥技能
|
|
|
+ $skill = PetSkill::where('skill_name', '自动施肥')->first();
|
|
|
+
|
|
|
+ // 尝试激活技能(应该失败)
|
|
|
+ $result = PetService::useSkill($this->testUserId, $lowLevelPet->id, $skill->id, []);
|
|
|
+
|
|
|
+ $this->assertFalse($result['success'], '低等级宠物不应该能激活自动施肥技能');
|
|
|
+
|
|
|
+ DB::commit();
|
|
|
+ echo "✓ 等级限制测试通过\n";
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ DB::rollBack();
|
|
|
+ $this->fail('测试失败: ' . $e->getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清理测试数据
|
|
|
+ */
|
|
|
+ protected function tearDown(): void
|
|
|
+ {
|
|
|
+ // 清理测试数据
|
|
|
+ DB::table('pet_users')->where('user_id', $this->testUserId)->delete();
|
|
|
+ DB::table('farm_lands')->where('user_id', $this->testUserId)->delete();
|
|
|
+ DB::table('farm_crops')->where('user_id', $this->testUserId)->delete();
|
|
|
+ DB::table('pet_active_skills')->where('pet_id', $this->testPetId)->delete();
|
|
|
+ DB::table('item_users')->where('user_id', $this->testUserId)->delete();
|
|
|
+
|
|
|
+ parent::tearDown();
|
|
|
+ }
|
|
|
+}
|