From d40e44db7adda703a44d5436d39e51fa800f9115 Mon Sep 17 00:00:00 2001 From: Santiago San Martin Date: Mon, 4 Aug 2025 19:02:21 -0300 Subject: [PATCH] [SecurityBundle] Add tests for `debug:firewall` command --- .../Command/DebugFirewallCommandTest.php | 197 ++++++++++++++++++ .../Descriptor/firewall_main_output.txt | 30 +++ .../firewall_main_with_events_output.txt | 39 ++++ .../firewall_main_with_switch_user.txt | 36 ++++ .../Tests/Fixtures/DummyAuthenticator.php | 50 +++++ 5 files changed, 352 insertions(+) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Command/DebugFirewallCommandTest.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_output.txt create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_with_events_output.txt create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_with_switch_user.txt create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/DummyAuthenticator.php diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Command/DebugFirewallCommandTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Command/DebugFirewallCommandTest.php new file mode 100644 index 0000000000000..673f0c434a4bc --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Command/DebugFirewallCommandTest.php @@ -0,0 +1,197 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Bundle\SecurityBundle\Command\DebugFirewallCommand; +use Symfony\Bundle\SecurityBundle\Security\FirewallConfig; +use Symfony\Bundle\SecurityBundle\Security\FirewallContext; +use Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; + +class DebugFirewallCommandTest extends TestCase +{ + public function testFirewallListOutputMatchesFixture() + { + $firewallNames = ['main', 'api']; + $contexts = $this->createMock(ContainerInterface::class); + $eventDispatchers = $this->createMock(ContainerInterface::class); + + $command = new DebugFirewallCommand($firewallNames, $contexts, $eventDispatchers, []); + $tester = new CommandTester($command); + + $this->assertSame(0, $tester->execute([])); + $this->assertStringContainsString('Firewalls', $tester->getDisplay()); + $this->assertStringContainsString('The following firewalls are defined:', $tester->getDisplay()); + $this->assertStringContainsString('* main', $tester->getDisplay()); + $this->assertStringContainsString('* api', $tester->getDisplay()); + $this->assertStringContainsString('To view details of a specific firewall', $tester->getDisplay()); + } + + public function testFirewallNotFoundDisplaysError() + { + $firewallNames = ['main', 'api']; + + $contexts = $this->createMock(ContainerInterface::class); + $contexts->method('has')->willReturn(false); + + $eventDispatchers = $this->createMock(ContainerInterface::class); + $authenticators = []; + + $command = new DebugFirewallCommand( + $firewallNames, + $contexts, + $eventDispatchers, + $authenticators + ); + + $tester = new CommandTester($command); + + $this->assertSame(1, $tester->execute(['name' => 'admin'])); + $this->assertStringContainsString('Firewall admin was not found.', $tester->getDisplay()); + $this->assertStringContainsString('Available firewalls are: main, api', $tester->getDisplay()); + } + + public function testFirewallMainOutputMatchesFixture() + { + $firewallNames = ['main']; + + $config = new FirewallConfig( + name: 'main', + userChecker: 'user_checker_service', + requestMatcher: null, + securityEnabled: true, + stateless: false, + provider: 'user_provider_service', + context: 'main', + entryPoint: 'entry_point_service', + accessDeniedHandler: 'access_denied_handler_service', + accessDeniedUrl: '/access-denied', + authenticators: [], + switchUser: null + ); + + $context = new FirewallContext([], config: $config); + + $contexts = $this->createMock(ContainerInterface::class); + $contexts->method('has')->willReturn(true); + $contexts->method('get')->willReturn($context); + + $eventDispatchers = $this->createMock(ContainerInterface::class); + $authenticator = new DummyAuthenticator(); + $authenticators = ['main' => [$authenticator]]; + + $command = new DebugFirewallCommand($firewallNames, $contexts, $eventDispatchers, $authenticators); + $tester = new CommandTester($command); + + $this->assertSame(0, $tester->execute(['name' => 'main', '--events' => true])); + $this->assertEquals($this->getFixtureOutput('firewall_main_output.txt'), trim(str_replace(\PHP_EOL, "\n", $tester->getDisplay()))); + } + + public function testFirewallWithEventsOutputMatchesFixture() + { + $firewallNames = ['main']; + + $config = new FirewallConfig( + name: 'main', + userChecker: 'user_checker_service', + context: 'main', + stateless: false, + provider: 'user_provider_service', + entryPoint: 'entry_point_service', + accessDeniedHandler: 'access_denied_handler_service', + accessDeniedUrl: '/access-denied', + ); + + $context = new FirewallContext([], config: $config); + + $contexts = $this->createMock(ContainerInterface::class); + $contexts->method('has')->willReturn(true); + $contexts->method('get')->willReturn($context); + + $dispatcher = $this->createMock(EventDispatcherInterface::class); + $listener = fn () => null; + $listenerTwo = fn (int $number) => $number * 2; + $dispatcher->method('getListeners')->willReturn([ + 'security.event' => [$listener, $listenerTwo], + ]); + $dispatcher->method('getListenerPriority')->willReturn(42); + + $eventDispatchers = $this->createMock(ContainerInterface::class); + $eventDispatchers->method('has')->willReturn(true); + $eventDispatchers->method('get')->willReturn($dispatcher); + + $authenticator = new DummyAuthenticator(); + $authenticatorTwo = new DummyAuthenticator(); + $authenticatorThree = new DummyAuthenticator(); + $authenticators = ['main' => [$authenticator, $authenticatorTwo], 'api' => [$authenticatorThree]]; + + $command = new DebugFirewallCommand($firewallNames, $contexts, $eventDispatchers, $authenticators); + $tester = new CommandTester($command); + + $this->assertSame(0, $tester->execute(['name' => 'main', '--events' => true])); + $this->assertEquals($this->getFixtureOutput('firewall_main_with_events_output.txt'), trim(str_replace(\PHP_EOL, "\n", $tester->getDisplay()))); + } + + public function testFirewallWithSwitchUserDisplaysSection() + { + $firewallNames = ['main']; + + $switchUserConfig = [ + 'parameter' => '_switch_user_test', + 'provider' => 'custom_provider_test', + 'role' => 'ROLE_ALLOWED_TO_SWITCH', + ]; + + $config = new FirewallConfig( + name: 'main', + userChecker: 'user_checker_service_test', + context: 'main', + stateless: false, + provider: 'user_provider_service_test', + entryPoint: 'entry_point_service_test', + accessDeniedHandler: 'access_denied_handler_service_test', + accessDeniedUrl: '/access-denied-test', + switchUser: $switchUserConfig, + ); + + $context = new FirewallContext([], config: $config); + + $contexts = $this->createMock(ContainerInterface::class); + $contexts->method('has')->willReturn(true); + $contexts->method('get')->willReturn($context); + + $eventDispatchers = $this->createMock(ContainerInterface::class); + $authenticator = new DummyAuthenticator(); + $authenticatorTwo = $this->createMock(AuthenticatorInterface::class); + $authenticators = ['main' => [$authenticator], 'api' => [$authenticatorTwo]]; + + $command = new DebugFirewallCommand( + $firewallNames, + $contexts, + $eventDispatchers, + $authenticators + ); + $tester = new CommandTester($command); + + $this->assertSame(0, $tester->execute(['name' => 'main'])); + $this->assertEquals($this->getFixtureOutput('firewall_main_with_switch_user.txt'), trim(str_replace(\PHP_EOL, "\n", $tester->getDisplay()))); + } + + private function getFixtureOutput(string $file): string + { + return trim(file_get_contents(__DIR__.'/../Fixtures/Descriptor/'.$file)); + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_output.txt b/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_output.txt new file mode 100644 index 0000000000000..d224162575d45 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_output.txt @@ -0,0 +1,30 @@ +Firewall "main" +=============== + + ----------------------- ------------------------------- + Option Value + ----------------------- ------------------------------- + Name main + Context main + Lazy No + Stateless No + User Checker user_checker_service + Provider user_provider_service + Entry Point entry_point_service + Access Denied URL /access-denied + Access Denied Handler access_denied_handler_service + ----------------------- ------------------------------- + +Event listeners for firewall "main" +=================================== + + No event dispatcher has been registered for this firewall. + +Authenticators for firewall "main" +================================== + + ----------------------------------------------------------------- + Classname + ----------------------------------------------------------------- + Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator + ----------------------------------------------------------------- diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_with_events_output.txt b/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_with_events_output.txt new file mode 100644 index 0000000000000..2d02f34b8a017 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_with_events_output.txt @@ -0,0 +1,39 @@ +Firewall "main" +=============== + + ----------------------- ------------------------------- + Option Value + ----------------------- ------------------------------- + Name main + Context main + Lazy No + Stateless No + User Checker user_checker_service + Provider user_provider_service + Entry Point entry_point_service + Access Denied URL /access-denied + Access Denied Handler access_denied_handler_service + ----------------------- ------------------------------- + +Event listeners for firewall "main" +=================================== + +"security.event" event +---------------------- + + ------- ----------- ---------- + Order Callable Priority + ------- ----------- ---------- + #1 Closure() 42 + #2 Closure() 42 + ------- ----------- ---------- + +Authenticators for firewall "main" +================================== + + ----------------------------------------------------------------- + Classname + ----------------------------------------------------------------- + Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator + Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator + ----------------------------------------------------------------- diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_with_switch_user.txt b/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_with_switch_user.txt new file mode 100644 index 0000000000000..4843b86f7e224 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/Descriptor/firewall_main_with_switch_user.txt @@ -0,0 +1,36 @@ +Firewall "main" +=============== + + ----------------------- ------------------------------------ + Option Value + ----------------------- ------------------------------------ + Name main + Context main + Lazy No + Stateless No + User Checker user_checker_service_test + Provider user_provider_service_test + Entry Point entry_point_service_test + Access Denied URL /access-denied-test + Access Denied Handler access_denied_handler_service_test + ----------------------- ------------------------------------ + +User switching +-------------- + + ----------- ------------------------ + Option Value + ----------- ------------------------ + Parameter _switch_user_test + Provider custom_provider_test + User Role ROLE_ALLOWED_TO_SWITCH + ----------- ------------------------ + +Authenticators for firewall "main" +================================== + + ----------------------------------------------------------------- + Classname + ----------------------------------------------------------------- + Symfony\Bundle\SecurityBundle\Tests\Fixtures\DummyAuthenticator + ----------------------------------------------------------------- diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/DummyAuthenticator.php b/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/DummyAuthenticator.php new file mode 100644 index 0000000000000..8ac51a1e9df56 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Fixtures/DummyAuthenticator.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Fixtures; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; +use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; + +class DummyAuthenticator implements AuthenticatorInterface +{ + public function supports(Request $request): ?bool + { + return null; + } + + public function authenticate(Request $request): Passport + { + } + + public function createToken(Passport $passport, string $firewallName): TokenInterface + { + } + + public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response + { + return null; + } + + public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response + { + return null; + } + + public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface + { + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy