bootApp(); } public function testLogoutClearsSessionAndRedirectsToLogin(): void { // Seed a logged-in session. $_SESSION['_user'] = (new UserContext(1, 'Admin', 'admin', null, UserContext::SOURCE_LOCAL))->toArray(); $_SESSION['_last_active'] = time(); $_SESSION['_authenticated_at'] = time(); $_SESSION[CsrfMiddleware::SESSION_KEY] = 'fixed-token'; $body = http_build_query(['csrf_token' => 'fixed-token']); $response = $this->request('POST', '/logout', [], $body, 'application/x-www-form-urlencoded'); self::assertSame(303, $response->getStatusCode()); self::assertSame('/login', $response->getHeaderLine('Location')); self::assertArrayNotHasKey('_user', $_SESSION); } public function testLogoutWithoutCsrfIs403(): void { $_SESSION['_user'] = (new UserContext(1, 'Admin', 'admin', null, UserContext::SOURCE_LOCAL))->toArray(); $_SESSION['_last_active'] = time(); $_SESSION['_authenticated_at'] = time(); $response = $this->request('POST', '/logout'); self::assertSame(403, $response->getStatusCode()); self::assertArrayHasKey('_user', $_SESSION); } }