CropPlantingBugTest.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. namespace Tests\Feature\Farm;
  3. use App\Module\Farm\Enums\GROWTH_STAGE;
  4. use App\Module\Farm\Enums\LAND_STATUS;
  5. use App\Module\Farm\Models\FarmCrop;
  6. use App\Module\Farm\Models\FarmLand;
  7. use App\Module\Farm\Models\FarmSeed;
  8. use App\Module\Farm\Services\CropService;
  9. use App\Module\GameItems\Models\Item;
  10. use App\Module\GameItems\Services\ItemService;
  11. use Illuminate\Foundation\Testing\RefreshDatabase;
  12. use Illuminate\Support\Facades\DB;
  13. use Tests\TestCase;
  14. /**
  15. * 农场作物种植bug测试
  16. *
  17. * 测试场景:一块土地多次种植不会产生新的作物的bug
  18. */
  19. class CropPlantingBugTest extends TestCase
  20. {
  21. /**
  22. * 测试种植逻辑是否正确检查现有作物记录
  23. */
  24. public function test_cannot_plant_when_crop_exists()
  25. {
  26. // 准备测试数据
  27. $userId = 39077; // 使用现有用户
  28. $landId = 296; // 使用现有土地
  29. $itemId = 1; // 种子物品ID
  30. // 先清理可能存在的作物记录
  31. FarmCrop::where('land_id', $landId)->delete();
  32. // 确保土地状态为空闲
  33. $land = FarmLand::find($landId);
  34. $this->assertNotNull($land, '土地不存在');
  35. // 设置土地为空闲状态
  36. $land->status = LAND_STATUS::IDLE->value;
  37. $land->has_crop = false;
  38. $land->save();
  39. // 确保种子配置存在
  40. $seed = FarmSeed::where('item_id', $itemId)->first();
  41. $this->assertNotNull($seed, '种子配置不存在');
  42. // 模拟已存在的作物记录(这是bug的根源)
  43. $existingCrop = new FarmCrop();
  44. $existingCrop->land_id = $landId;
  45. $existingCrop->user_id = $userId;
  46. $existingCrop->seed_id = $seed->id;
  47. $existingCrop->plant_time = now()->subHours(1);
  48. $existingCrop->growth_stage = GROWTH_STAGE::WITHERED; // 枯萎状态
  49. $existingCrop->stage_start_time = now()->subHours(1);
  50. $existingCrop->stage_end_time = null;
  51. $existingCrop->disasters = [];
  52. $existingCrop->fertilized = false;
  53. $existingCrop->last_disaster_check_time = now()->subHours(1);
  54. $existingCrop->can_disaster = false;
  55. $existingCrop->save();
  56. // 开启事务
  57. DB::beginTransaction();
  58. try {
  59. // 尝试种植新作物,应该失败
  60. $result = CropService::plantCrop($userId, $landId, $itemId);
  61. // 验证种植失败
  62. $this->assertNull($result, '种植应该失败,因为土地上已存在作物记录');
  63. // 验证没有创建新的作物记录
  64. $cropCount = FarmCrop::where('land_id', $landId)->count();
  65. $this->assertEquals(1, $cropCount, '不应该创建新的作物记录');
  66. DB::rollBack();
  67. } catch (\Exception $e) {
  68. DB::rollBack();
  69. // 验证抛出了正确的异常
  70. $this->assertStringContainsString('土地上已存在作物', $e->getMessage());
  71. }
  72. // 清理测试数据
  73. FarmCrop::where('land_id', $landId)->delete();
  74. }
  75. /**
  76. * 测试正常种植流程
  77. */
  78. public function test_normal_planting_works()
  79. {
  80. // 准备测试数据
  81. $userId = 39077; // 使用现有用户
  82. $landId = 296; // 使用现有土地
  83. $itemId = 1; // 种子物品ID
  84. // 确保土地状态为空闲且没有作物
  85. $land = FarmLand::find($landId);
  86. $this->assertNotNull($land, '土地不存在');
  87. $land->status = LAND_STATUS::IDLE->value;
  88. $land->has_crop = false;
  89. $land->save();
  90. // 清理可能存在的作物记录
  91. FarmCrop::where('land_id', $landId)->delete();
  92. // 确保种子配置存在
  93. $seed = FarmSeed::where('item_id', $itemId)->first();
  94. $this->assertNotNull($seed, '种子配置不存在');
  95. // 开启事务
  96. DB::beginTransaction();
  97. try {
  98. // 尝试种植新作物,应该成功
  99. $result = CropService::plantCrop($userId, $landId, $itemId);
  100. // 验证种植成功
  101. $this->assertNotNull($result, '种植应该成功');
  102. $this->assertArrayHasKey('crop', $result);
  103. $this->assertArrayHasKey('log_id', $result);
  104. // 验证创建了新的作物记录
  105. $newCrop = FarmCrop::where('land_id', $landId)->first();
  106. $this->assertNotNull($newCrop, '应该创建新的作物记录');
  107. $this->assertEquals(GROWTH_STAGE::SEED->value, $newCrop->growth_stage->value);
  108. // 验证土地状态更新
  109. $land->refresh();
  110. $this->assertEquals(LAND_STATUS::PLANTING->value, $land->status);
  111. $this->assertTrue($land->has_crop);
  112. DB::rollBack();
  113. } catch (\Exception $e) {
  114. DB::rollBack();
  115. $this->fail('正常种植不应该失败: ' . $e->getMessage());
  116. }
  117. // 清理测试数据
  118. FarmCrop::where('land_id', $landId)->delete();
  119. }
  120. }