test(user): add unit test for the User entity#71
Merged
Conversation
Covers the four behaviour contracts on App\Entity\User that today are only verified as side effects of the auth-flow integration tests: - getRoles() always includes ROLE_USER and dedupes when the role is already present, so a regression that strips the implicit grant breaks visibly here instead of silently affecting authorisation. - getUserIdentifier() returns '' when email is null and the email string otherwise. - __serialize() replaces the password with its CRC32C hash so the session never carries the real hash; the test fails loudly if the redaction is removed. - Setters mutate and return $this. Pins each invariant in a focused test so future User fields can land with their own test method right next to the entity instead of relying on whichever integration test happens to hit the new lines. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Martin Yde Granath <yde001@gmail.com>
tuj
approved these changes
Jun 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Links to issues
None — direct follow-up to a coverage-strategy discussion on
feature/issue-14-assistant-base-entity.App\Entity\Usercurrently has its lines covered only as a sideeffect of the auth-flow integration tests; this PR pins the
behaviour contracts in a focused unit test next to the entity.
Description
Adds
tests/Unit/Entity/UserTest.phpcovering four invariants onApp\Entity\User:getRoles()always includesROLE_USERand dedupes when the roleis already present, so a regression that strips the implicit grant
fails loudly here instead of silently affecting authorisation.
getUserIdentifier()returns''when the email isnulland theemail string otherwise (covers the
(string)cast fallback).__serialize()replaces the password with its CRC32C hash, so thesession never carries the real hash; the test fails if the
redaction is removed.
$this.Pure
TestCase: no kernel boot, no DB, no DAMA. Sits next to theexisting
AssistantTestundertests/Unit/Entity/.Screenshot of the result
N/A — test-only change, no UI.
Checklist
If your code does not pass all the requirements on the checklist you have to add a comment explaining why this change
should be exempt from the list.
Additional comments or questions
The "covered by test cases" box is intentionally unchecked: this PR
is the test — there is no production code change to cover.
Coverage on
src/Entity/User.phpwas already at 100% indirectly viathe auth-flow integration tests; this PR doesn't change the gate
result, only the shape of the coverage so future User fields can
be tested next to the entity rather than via side-channel hunts.
Details - AI specificities
Goal and motivation
User's behaviour was previously verified only by integration testsof the auth flow (login, password upgrade, session serialisation).
That arrangement covers the lines but couples each
Userinvariantto a different downstream test — a future regression in
getRoles()'sROLE_USERguarantee or in__serialize()'s passwordredaction would surface as an unrelated auth-flow failure, and any
new
Userfield without a downstream consumer would immediatelydrop the coverage gate below 100%.
This PR shifts those invariants into a focused unit test so they
fail loudly at the source and so the next
Userfield can land withits own test method instead of triggering a coverage scavenger hunt.
Scope
tests/Unit/Entity/UserTest.php(sixfinalTestCasemethods).
touched.
Non-goals
App\Entity\User.shape of the integration suite.
exercise
Useras a side effect — they remain valid and are notduplicated by these unit-level assertions.
Conventions applied
tests/Unit/Entity/AssistantTest.phpin layout:final class,declare(strict_types=1),App\Tests\Unit\Entitynamespace,self::assert*style.__serialize()test pins the exact null-byte-prefixed key formatPHP uses for private-property array casts, since that is the
serialised payload's contract — changing the property visibility on
User::$passwordwould break this test, which is the desiredsignal.
Areas needing scrutiny
__serialize()test asserts both that the password key holdsthe CRC32C hash and that no value in the serialised array equals
the original input. The second assertion is the defence-in-depth
bit: even if the property structure changes, the test still catches
a regression that re-introduces the plaintext into the session.
Follow-up work intentionally out of scope
Assistantshould keep its fullgetter/setter surface or be pruned (YAGNI) was raised in the
discussion but is deliberately not bundled here.
Related
here.
tests/Unit/Entity/AssistantTest.php(onfeature/issue-14-assistant-base-entity) is the template this filefollows.