Skip to content

feat: inject the http session into use() - #213

Open
Amoifr wants to merge 1 commit into
zenstruck:1.xfrom
Amoifr:feat-149-http-session-in-use
Open

feat: inject the http session into use()#213
Amoifr wants to merge 1 commit into
zenstruck:1.xfrom
Amoifr:feat-149-http-session-in-use

Conversation

@Amoifr

@Amoifr Amoifr commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Closes #149

This is the API you sketched in the issue:

$browser
    ->use(function(SessionInterface $session) {
        $session->set('cart', ['product-1']);
    })
    ->visit('/cart')
    ->assertSee('product-1')
;

It is on KernelBrowser only, not on Browser, since it needs the app's container and the test process's cookie jar. Panther and Playwright drive a real server, so the same trick does not apply there.

The one change outside KernelBrowser is a hook: use() now calls a no-op protected afterUse() after the callback. It is needed because the session has to be saved after the callback has mutated it, and Callback::invokeAll() gives no point to do that. The alternative was to hand out a save-through decorator, which I dropped: it would not be a real Session any more, so getFlashBag() and instanceof Session would break. Handing out the real object seemed worth the five line seam, but say the word if you would rather have it another way.

Things I measured rather than assumed:

  • The session cookie is written without a domain. CookieJar::allValues() skips the domain check entirely when the cookie has none (if ($domain)), so it is sent whatever host is visited. That avoids guessing a host, which cannot be done anyway before the first request: getCurrentUrl() throws Unable to access the request before visiting a page on a fresh browser. A test covers a non-localhost host.
  • The id is preserved. If the jar already has a session cookie, its value becomes the session id, so nothing the app stored is dropped. using_the_session_keeps_the_existing_session_cookie asserts the id is the same before and after.
  • Saving twice is safe. I checked that set() after a save() works and persists, which is what happens when a test uses the session in two separate ->use() calls.

The round trip goes both ways in the tests: the app reads what the test wrote (new /read-session route on the test kernel), and the test reads what the app wrote (the existing /page1?start-session=1).

When sessions are not enabled, httpSession() throws Sessions are not available/enabled., matching the wording of the existing securityToken() guard.

280 tests green, PHPStan clean. I could not run php-cs-fixer locally, it is not in the dev deps, so the bot may still have something to fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

How to access Session variable

1 participant