test(auth): JwtRevocationIT cleanup + unrevoked-token coverage

Adds @AfterEach to delete the test users so Testcontainers reuse does
not leak an authenticated user with a future token_revoked_before into
the shared schema (visible to LicenseUsageReader.snapshot, user-admin
listing tests, etc.). Adds unrevokedUserTokenIsAccepted to pin the
revoked == null no-op branch as a first-class assertion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-27 09:18:10 +02:00
parent 7066795c3c
commit b4c6e45d35

View File

@@ -4,6 +4,7 @@ import com.cameleer.server.app.AbstractPostgresIT;
import com.cameleer.server.core.security.JwtService;
import com.cameleer.server.core.security.UserInfo;
import com.cameleer.server.core.security.UserRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
@@ -35,6 +36,12 @@ class JwtRevocationIT extends AbstractPostgresIT {
@Autowired
private UserRepository userRepository;
@AfterEach
void cleanup() {
userRepository.delete("revoke-me");
userRepository.delete("never-revoked");
}
@Test
void revokedTokenIsRejectedOnAuthenticatedRequest() {
userRepository.upsert(new UserInfo(
@@ -51,6 +58,17 @@ class JwtRevocationIT extends AbstractPostgresIT {
assertThat(after.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
}
@Test
void unrevokedUserTokenIsAccepted() {
userRepository.upsert(new UserInfo(
"never-revoked", "local", "", "Never Revoked", Instant.now()));
String accessToken = jwtService.createAccessToken(
"user:never-revoked", "user", List.of("VIEWER"));
ResponseEntity<String> resp = call(accessToken);
assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
}
private ResponseEntity<String> call(String accessToken) {
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(accessToken);