From d18e26147dc9dc7b0b5b3ff1b1efb891943b6bec Mon Sep 17 00:00:00 2001 From: Jannik Zschiesche Date: Thu, 26 Mar 2026 11:16:40 +0100 Subject: [PATCH 1/2] Add tests for abilities voter --- CHANGELOG.md | 6 +++ tests/Security/AbilitiesVoterTest.php | 73 +++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 tests/Security/AbilitiesVoterTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index ff8b9a2..18c1715 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +3.4.5 +===== + +* (internal) Add tests for `AbilitiesVoter`. + + 3.4.4 ===== diff --git a/tests/Security/AbilitiesVoterTest.php b/tests/Security/AbilitiesVoterTest.php new file mode 100644 index 0000000..8d7bc94 --- /dev/null +++ b/tests/Security/AbilitiesVoterTest.php @@ -0,0 +1,73 @@ +createToken(["ROLE_ADMIN"]); + $roleHierarchy = new RoleHierarchy(["ROLE_ADMIN" => ["CAN_VIEW_DASHBOARD"]]); + $voter = new AbilitiesVoter($roleHierarchy); + + self::assertSame( + VoterInterface::ACCESS_GRANTED, + $voter->vote($token, null, ["CAN_VIEW_DASHBOARD"]), + ); + } + + /** + * + */ + public function testVoteDeniedForMissingAbility () : void + { + $token = $this->createToken(["ROLE_USER"]); + $roleHierarchy = new RoleHierarchy([]); + $voter = new AbilitiesVoter($roleHierarchy); + + self::assertSame( + VoterInterface::ACCESS_DENIED, + $voter->vote($token, null, ["CAN_EDIT_USERS"]), + ); + } + + /** + * + */ + public function testVoteAbstainsForNonCanAttribute () : void + { + $token = $this->createToken(["ROLE_USER"]); + $roleHierarchy = new RoleHierarchy([]); + $voter = new AbilitiesVoter($roleHierarchy); + + self::assertSame( + VoterInterface::ACCESS_ABSTAIN, + $voter->vote($token, null, ["ROLE_USER"]), + ); + } + + /** + * + */ + private function createToken (array $roles) : UsernamePasswordToken + { + return new UsernamePasswordToken( + new InMemoryUser("test", null, $roles), + "main", + $roles, + ); + } +} From 03f7500506003c9eeee77a43be73d7ef84ae1969 Mon Sep 17 00:00:00 2001 From: Jannik Zschiesche Date: Thu, 26 Mar 2026 15:48:08 +0100 Subject: [PATCH 2/2] Deprecate `DoctrineChangeChecker`. --- CHANGELOG.md | 6 ++++++ UPGRADE.md | 1 + src/Doctrine/DoctrineChangeChecker.php | 14 +++++++++++++- tests/Doctrine/DoctrineChangeCheckerTest.php | 13 +++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18c1715..d3536f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +3.4.6 +===== + +* (deprecation) Deprecate `DoctrineChangeChecker`. + + 3.4.5 ===== diff --git a/UPGRADE.md b/UPGRADE.md index 2e3c6fa..82022f6 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -3,6 +3,7 @@ * Passing a `bool` to the constructor of `ApiResponse` was removed, pass a status code instead. * The method `ApiResponse::withStatusCode()` was removed. Pass the status code in the constructor instead. +* `DoctrineChangeChecker` was removed. There is no direct replacement. 2.x to 3.0 diff --git a/src/Doctrine/DoctrineChangeChecker.php b/src/Doctrine/DoctrineChangeChecker.php index ce0e275..386be69 100644 --- a/src/Doctrine/DoctrineChangeChecker.php +++ b/src/Doctrine/DoctrineChangeChecker.php @@ -6,13 +6,25 @@ use Doctrine\Persistence\ManagerRegistry; use Torr\Rad\Exception\Doctrine\InvalidDoctrineChangeCheckException; +/** + * @deprecated this class is deprecated and will be removed in v4 + */ final readonly class DoctrineChangeChecker { + // TODO remove in v4 /** */ public function __construct ( private ManagerRegistry $managerRegistry, - ) {} + ) + { + trigger_deprecation( + "21torr/rad", + "3.4.6", + "Using %s is deprecated and will be removed in v4.", + self::class, + ); + } /** * Determines whether any content globally in any of the entities (or the entities themselves) diff --git a/tests/Doctrine/DoctrineChangeCheckerTest.php b/tests/Doctrine/DoctrineChangeCheckerTest.php index 2b4296a..73ef6c4 100644 --- a/tests/Doctrine/DoctrineChangeCheckerTest.php +++ b/tests/Doctrine/DoctrineChangeCheckerTest.php @@ -6,6 +6,7 @@ use Doctrine\ORM\UnitOfWork; use Doctrine\Persistence\ManagerRegistry; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Torr\Rad\Doctrine\DoctrineChangeChecker; /** @@ -13,6 +14,8 @@ */ final class DoctrineChangeCheckerTest extends TestCase { + use ExpectDeprecationTrait; + /** * */ @@ -51,6 +54,8 @@ public static function provideLargeEntityChanges () : iterable /** * @dataProvider provideLargeEntityChanges + * + * @group legacy */ public function testLargeEntityChanges ( bool $expected, @@ -92,7 +97,10 @@ public function testLargeEntityChanges ( ->method("getManager") ->willReturn($entityManager); + $this->expectDeprecation("Since 21torr/rad 3.4.6: Using Torr\\Rad\\Doctrine\\DoctrineChangeChecker is deprecated and will be removed in v4."); + // @phpstan-ignore-next-line $checker = new DoctrineChangeChecker($registry); + // @phpstan-ignore-next-line self::assertSame($expected, $checker->hasContentChanged()); } @@ -114,6 +122,8 @@ public static function provideChangesets () : iterable /** * @dataProvider provideChangesets + * + * @group legacy */ public function testChangesets ( bool $expected, @@ -158,7 +168,10 @@ public function testChangesets ( ->method("getManager") ->willReturn($entityManager); + $this->expectDeprecation("Since 21torr/rad 3.4.6: Using Torr\\Rad\\Doctrine\\DoctrineChangeChecker is deprecated and will be removed in v4."); + // @phpstan-ignore-next-line $checker = new DoctrineChangeChecker($registry); + // @phpstan-ignore-next-line self::assertSame($expected, $checker->hasContentChanged()); } }