diff --git a/src/Symfony/Command/InstallCommand.php b/src/Symfony/Command/InstallCommand.php index 0a82986f..7ad392f0 100644 --- a/src/Symfony/Command/InstallCommand.php +++ b/src/Symfony/Command/InstallCommand.php @@ -71,7 +71,14 @@ final class InstallCommand extends Command } // Prepare directories - $publicDir = $this->getPublicDir().'/vendor/flasher/'; + $publicBaseDir = $this->getPublicDir(); + if (null === $publicBaseDir) { + $output->writeln('Could not determine the public directory. Please ensure your Symfony project is properly configured.'); + + return self::FAILURE; + } + + $publicDir = $publicBaseDir.'/vendor/flasher/'; $configDir = $this->getConfigDir(); $filesystem = new Filesystem(); diff --git a/tests/Symfony/Command/InstallCommandTest.php b/tests/Symfony/Command/InstallCommandTest.php index 53ee8b85..a6a280ea 100644 --- a/tests/Symfony/Command/InstallCommandTest.php +++ b/tests/Symfony/Command/InstallCommandTest.php @@ -7,6 +7,7 @@ namespace Flasher\Tests\Symfony\Command; use Flasher\Tests\Symfony\Fixtures\FlasherKernel; use Mockery\Adapter\Phpunit\MockeryTestCase; use Symfony\Bundle\FrameworkBundle\Console\Application; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\HttpKernel\Kernel; @@ -77,4 +78,69 @@ final class InstallCommandTest extends MockeryTestCase $command = $application->find('flasher:install'); $this->commandTester = new CommandTester($command); } + + public function testExecuteFailsGracefullyWhenPublicDirIsNull(): void + { + // Create a kernel that returns a non-existent project directory + // This will cause getPublicDir() to return null + $kernel = new class() extends Kernel { + public function __construct() + { + parent::__construct('test', true); + } + + public function registerBundles(): iterable + { + return [ + new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), + new \Flasher\Symfony\FlasherSymfonyBundle(), + ]; + } + + public function registerContainerConfiguration(\Symfony\Component\Config\Loader\LoaderInterface $loader): void + { + $loader->load(function (\Symfony\Component\DependencyInjection\ContainerBuilder $container): void { + $container->register('kernel', static::class)->setPublic(true); + $container->loadFromExtension('framework', [ + 'secret' => 'test', + 'test' => true, + 'session' => [ + 'handler_id' => null, + 'storage_factory_id' => 'session.storage.factory.mock_file', + ], + ]); + }); + } + + public function getProjectDir(): string + { + // Return a non-existent directory without public/ subfolder + return '/non-existent-directory-'.uniqid(); + } + + public function getCacheDir(): string + { + return sys_get_temp_dir().'/cache'.spl_object_hash($this); + } + + public function getLogDir(): string + { + return sys_get_temp_dir().'/logs'.spl_object_hash($this); + } + }; + + $kernel->boot(); + + $application = new Application($kernel); + $application->setCatchExceptions(false); + + $commandTester = new CommandTester($application->find('flasher:install')); + $exitCode = $commandTester->execute([]); + + $output = $commandTester->getDisplay(); + + // Should fail gracefully with an error message instead of crashing + $this->assertSame(Command::FAILURE, $exitCode); + $this->assertStringContainsString('Could not determine the public directory', $output); + } }