diff --git a/app/Services/ObjectService.php b/app/Services/ObjectService.php index 37b034c1..5c694a2b 100644 --- a/app/Services/ObjectService.php +++ b/app/Services/ObjectService.php @@ -376,19 +376,27 @@ public static function objectRequirementsWithLevelsMet(string $machine_name, int */ public static function objectRequirementsMetWithQueue(string $machine_name, int $target_level, PlanetService $planet, PlayerService $player): bool { - // Check the object's requirements against the existing objects $object = self::getObjectByMachineName($machine_name); - $incompleteRequirements = self::filterCompletedRequirements($object->requirements, $planet, $player); + // Check object's previous levels against queued objects if (!self::hasPreviousLevelsInQueue($target_level, $object, $planet, $player)) { return false; } - if (count($incompleteRequirements) === 0) { + // Disallow researching when Research Lab is upgrading + if ($object->type === GameObjectType::Research && $player->isBuildingObject('research_lab')) { + return false; + } + + // Check object's requirements against built objects + $missingRequirements = self::filterCompletedRequirements($object->requirements, $planet, $player); + + if (count($missingRequirements) === 0) { return true; } - return count(self::filterQueuedRequirements($incompleteRequirements, $planet, $player)) === 0; + // Check object's requirements against queued objects + return count(self::filterQueuedRequirements($missingRequirements, $planet, $player)) === 0; } /** diff --git a/tests/AccountTestCase.php b/tests/AccountTestCase.php index 1ed6571f..bfd3b41c 100644 --- a/tests/AccountTestCase.php +++ b/tests/AccountTestCase.php @@ -502,6 +502,27 @@ protected function assertRequirementsNotMet(TestResponse $response, string $mach } } + protected function assertObjectNotInResearchQueue(TestResponse $response, string $machine_name, string $error_message = ''): void + { + // Get object name from machine name. + try { + $object = ObjectService::getObjectByMachineName($machine_name); + } catch (Exception $e) { + $this->fail('Failed to get object by machine name: ' . $machine_name . '. Error: ' . $e->getMessage()); + } + + // Check if cancel text is present on page. + try { + $response->assertDontSee('cancel ' . $object->title); + } catch (Exception $e) { + if (!empty($error_message)) { + $this->fail($error_message . '. Error: ' . $e->getMessage()); + } else { + $this->fail('Object ' . $object->title . ' is in the research queue. Error: ' . $e->getMessage()); + } + } + } + /** * Add a resource build request to the current users current planet. * @param string $machine_name diff --git a/tests/Feature/ResearchQueueTest.php b/tests/Feature/ResearchQueueTest.php index d19cc08e..1d17d261 100644 --- a/tests/Feature/ResearchQueueTest.php +++ b/tests/Feature/ResearchQueueTest.php @@ -213,4 +213,30 @@ public function testResearchLabRequirement(): void $response->assertStatus(200); $this->assertObjectLevelOnPage($response, 'energy_technology', 1, 'Energy technology is not at level one 2 minutes after build request issued.'); } + + /** + * Verify that ongoing upgrade of research lab prevents researching. + * @throws Exception + */ + public function testResearchLabUpgradingPreventsResearching(): void + { + // Add required resources for research to planet + $this->planetAddResources(new Resources(5000, 5000, 5000, 0)); + $this->planetSetObjectLevel('research_lab', 1); + + // Add Research Lab level 2 to build queue + $this->addFacilitiesBuildRequest('research_lab'); + $response = $this->get('/facilities'); + $response->assertStatus(200); + $this->assertObjectInQueue($response, 'research_lab', 2, 'Research Lab level 2 is not in build queue'); + + $this->assertThrows( + fn () => $this->addResearchBuildRequest('energy_technology'), + ); + + // Verify that Energy Technology is not in research queue + $response = $this->get('/research'); + $response->assertStatus(200); + $this->assertObjectNotInResearchQueue($response, 'energy_technology', 'Energy Technology is in research queue but should not be added.'); + } }