From 086c08990b10f299219ae417c18e201805158672 Mon Sep 17 00:00:00 2001 From: Gustavo Nieves Date: Thu, 3 Sep 2026 20:38:49 -0500 Subject: [PATCH] Add functional tests for schema validation and voter assertions Cover seeDoctrineSchemaIsValid(), seeUserIsGranted() and dontSeeUserIsGranted() from Codeception/module-symfony#246. They pass once composer.lock points at a module-symfony revision containing that pull request. The application gains a UserVoter that grants USER_EDIT only on the account of the authenticated user, so the new assertions run against a real voter instead of a plain role check. It implements VoterInterface rather than extending Voter, whose abstract voteOnAttribute() signature is not the same across the Symfony versions covered by the branches of this repository. --- src/Security/Voter/UserVoter.php | 39 +++++++++++++++++++++++++++++++ tests/Functional/DoctrineCest.php | 5 ++++ tests/Functional/SecurityCest.php | 25 ++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/Security/Voter/UserVoter.php diff --git a/src/Security/Voter/UserVoter.php b/src/Security/Voter/UserVoter.php new file mode 100644 index 0000000..1d859e1 --- /dev/null +++ b/src/Security/Voter/UserVoter.php @@ -0,0 +1,39 @@ +getUser(); + + return $user instanceof User && $user->getUserIdentifier() === $subject->getUserIdentifier() + ? self::ACCESS_GRANTED + : self::ACCESS_DENIED; + } +} diff --git a/tests/Functional/DoctrineCest.php b/tests/Functional/DoctrineCest.php index c6281ee..cc54e0a 100644 --- a/tests/Functional/DoctrineCest.php +++ b/tests/Functional/DoctrineCest.php @@ -44,6 +44,11 @@ public function seeNumRecords(FunctionalTester $I) $I->seeNumRecords(1, User::class); } + public function seeDoctrineSchemaIsValid(FunctionalTester $I): void + { + $I->seeDoctrineSchemaIsValid(); + } + public function queryCountAssertions(FunctionalTester $I): void { $I->amOnPage('/run-queries'); diff --git a/tests/Functional/SecurityCest.php b/tests/Functional/SecurityCest.php index beddba0..5d3152e 100644 --- a/tests/Functional/SecurityCest.php +++ b/tests/Functional/SecurityCest.php @@ -5,6 +5,7 @@ namespace App\Tests\Functional; use App\Entity\User; +use App\Security\Voter\UserVoter; use App\Tests\Support\FunctionalTester; final class SecurityCest @@ -70,6 +71,30 @@ public function seeUserHasRoles(FunctionalTester $I) $I->seeUserHasRoles(['ROLE_USER', 'ROLE_CUSTOMER']); } + public function seeUserIsGranted(FunctionalTester $I): void + { + $user = $I->grabEntityFromRepository(User::class, [ + 'email' => 'john_doe@gmail.com', + ]); + $I->amLoggedInAs($user); + $I->amOnPage('/'); + + $I->seeUserIsGranted('ROLE_CUSTOMER'); + $I->seeUserIsGranted(UserVoter::EDIT, $user); + } + + public function dontSeeUserIsGranted(FunctionalTester $I): void + { + $user = $I->grabEntityFromRepository(User::class, [ + 'email' => 'john_doe@gmail.com', + ]); + $I->amLoggedInAs($user); + $I->amOnPage('/'); + + $I->dontSeeUserIsGranted('ROLE_ADMIN'); + $I->dontSeeUserIsGranted(UserVoter::EDIT, User::create('jane_doe@gmail.com', '123456')); + } + public function seeUserPasswordDoesNotNeedRehash(FunctionalTester $I) { $user = $I->grabEntityFromRepository(User::class, [