get(TokenService::class)->issueTokens($user)['refresh_token']; } private function refresh(string $token): array { $this->client->request( 'POST', '/oauth/token/refresh', server: ['CONTENT_TYPE' => 'application/json'], content: json_encode(['refresh_token' => $token]), ); return json_decode($this->client->getResponse()->getContent(), true) ?? []; } public function testTokenIsRotatedAndOldOneRevoked(): void { $this->client->disableReboot(); $user = $this->createUser(); $old = $this->issueRefresh($user); $body = $this->refresh($old); $this->assertSame(200, $this->responseCode()); $new = $body['refresh_token']; $this->assertNotSame($old, $new, 'refresh token was not rotated'); // the old token is now single-use-spent → rejected $this->refresh($old); $this->assertSame(401, $this->responseCode()); // the new token still works $this->refresh($new); $this->assertSame(200, $this->responseCode()); } public function testSuspendedUserCannotRefresh(): void { $this->client->disableReboot(); $user = $this->createUser(); $token = $this->issueRefresh($user); $user->setStatus(0); $this->em->flush(); $this->refresh($token); $this->assertSame(401, $this->responseCode()); } }