Files
ephub/tests/Controller/Security/LogoutAuditTest.php
T

72 lines
2.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Controller\Security;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Monolog\Handler\TestHandler;
use Monolog\Logger;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* Signing out through the real firewall, rather than by calling the listener.
*
* The listener itself is unit-tested; what this pins down is the wiring -- that the listener is
* reached at all on a firewall-dispatched event, which no unit test can show. A TestHandler is
* pushed onto the audit channel so the assertion reads the records instead of the rotating file.
*/
class LogoutAuditTest extends WebTestCase
{
private KernelBrowser $client;
private EntityManagerInterface $em;
private TestHandler $auditRecords;
protected function setUp(): void
{
$this->client = self::createClient(server: ['HTTPS' => true]);
$this->client->disableReboot();
$this->em = self::getContainer()->get(EntityManagerInterface::class);
$this->em->getConnection()->beginTransaction();
$this->auditRecords = new TestHandler();
$audit = self::getContainer()->get('monolog.logger.audit');
\assert($audit instanceof Logger);
$audit->pushHandler($this->auditRecords);
}
protected function tearDown(): void
{
$this->em->getConnection()->rollBack();
parent::tearDown();
}
public function testSigningOutIsAudited(): void
{
$user = new User('[email protected]', 'Anna');
$user->setRoles(['ROLE_EMPLOYEE']);
$this->em->persist($user);
$this->em->flush();
$this->client->loginUser($user);
// Submitted from the page rather than requested directly: the firewall's logout is
// CSRF-protected, so the token in the header form is part of what is being pinned down.
$crawler = $this->client->request('GET', '/');
$this->client->submit($crawler->filter('form[action$="/logout"]')->form());
self::assertResponseRedirects();
$records = array_values(array_filter(
$this->auditRecords->getRecords(),
static fn ($record): bool => 'User signed out.' === $record->message,
));
self::assertCount(1, $records);
self::assertSame('[email protected]', $records[0]->context['account']);
self::assertSame('[email protected]', $records[0]->extra['actor']);
}
}