Skip to content

feat: ship a shared FakeEncryptor in marko/testing - #523

Merged
markshust merged 1 commit into
developfrom
feature/testing-fake-encryptor
Oct 6, 2026
Merged

markshust merged 1 commit into
developfrom
feature/testing-fake-encryptor

Conversation

@markshust

Copy link
Copy Markdown
Collaborator

Summary

  • Adds Marko\Testing\Fake\FakeEncryptor, which implements EncryptorInterface. It uses a reversible encoding (fake-encrypted:{n}:{base64 aad}:{base64 value}), so ciphertext differs per call like a real cipher and any instance can decrypt another's output.
  • The ciphertext is bound to its associated data. decrypt() with a different $aad throws a DecryptionException naming both values (for example decrypt() was given associated data 'users.email', but the value was encrypted with 'users.ssn'). Input the fake did not produce throws DecryptionException::invalidPayload(). Code under test that catches DecryptionException therefore behaves as it does in production.
  • Records encrypt() calls and successful decrypt() calls ($encrypted, $decrypted). Adds assertEncrypted(?value, ?aad), assertDecrypted(?value, ?aad), assertNothingEncrypted(), assertNothingDecrypted() and clear(). Nothing is auto-bound.
  • Moves the anonymous fakes in security (CsrfTokenManagerTest, CsrfRotationOnAuthTest) and database (EncryptedColumnTest, which drops its static $aads recorder for assertEncrypted(aad: ...)) onto the new fake.
  • marko/testing now requires marko/encryption (contracts only). Documents the fake on the testing docs page (usage and API reference) and in the README fakes list and usage.

Not migrated: packages/webhook/tests/Fixtures/FakeEncryptor.php is out of scope for this PR because another change touches that package. It can move to the shared fake in a follow-up. The roadrunner fixture app binds the real OpenSslEncryptor for its end-to-end flow and has no fake to replace.

Test plan

  • New packages/testing/tests/Unit/Fake/FakeEncryptorTest.php (19 tests) covers: round trip (including binary values), unique ciphertext per call, decrypting across instances, the AAD-mismatch exception, the invalid-payload exception, call recording, and every assertion helper
  • Migrated security and database suites green
  • composer test, phpcs, phpstan green locally

Fixes #515

🤖 Generated with Claude Code

https://claude.ai/code/session_01KyjR4cJTfro54iFZ9CWkv1

Packages that needed an encryptor in tests each wrote their own anonymous
EncryptorInterface fake, so the $aad signature change in #502 broke every
one of them. Marko\Testing\Fake\FakeEncryptor replaces them: a reversible
encoding that records encrypt()/decrypt() calls, differs per call like a
real cipher, and binds the ciphertext to its associated data so decrypt()
with a different $aad throws a DecryptionException naming both values.
assertEncrypted()/assertDecrypted() (value and AAD both optional) and
assertNothingEncrypted()/assertNothingDecrypted() follow the other fakes.

The security CSRF tests and the database encrypted-column tests now use
it. marko/testing requires marko/encryption (contracts only).

Fixes #515

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KyjR4cJTfro54iFZ9CWkv1
@github-actions github-actions Bot added the enhancement New feature or request label Oct 6, 2026
@markshust
markshust merged commit 84d7dcc into develop Oct 6, 2026
6 checks passed
@markshust
markshust deleted the feature/testing-fake-encryptor branch October 6, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ship a shared FakeEncryptor in marko/testing

1 participant