<?php

namespace App\Tests\Auth;

use App\Auth\Entity\User;
use App\Auth\Service\TokenService;
use App\Tests\ApiTestCase;

/**
 * Refresh tokens are reusable within their TTL (not single-use rotated — the
 * public site refreshes per server-render and can't persist a rotated token), but
 * a suspended user (status != 1) cannot refresh.
 */
class RefreshTokenTest extends ApiTestCase
{
    private function issueRefresh(User $user): string
    {
        return static::getContainer()->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());
    }
}
