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 testTokenIsReusableAndReturnedUnchanged(): void { $this->client->disableReboot(); $user = $this->createUser(); $token = $this->issueRefresh($user); $body = $this->refresh($token); $this->assertSame(200, $this->responseCode()); $this->assertNotEmpty($body['access_token']); // not rotated → the same refresh token comes back and stays valid $this->assertSame($token, $body['refresh_token']); // reusable: the same token works again (no single-use revocation) $this->refresh($token); $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()); } }