From 847c1f792b800f3cefa63e9cf9809e66212f6395 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Tue, 7 Apr 2026 23:20:58 +0200 Subject: [PATCH] test: add integration tests for claim mapping admin API - ClaimMappingAdminControllerIT with create+list and delete tests - Add adminHeaders() convenience method to TestSecurityHelper - Add jwt-secret to test profile (fixes pre-existing Ed25519 init failure) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../server/app/TestSecurityHelper.java | 7 ++ .../ClaimMappingAdminControllerIT.java | 64 +++++++++++++++++++ .../src/test/resources/application-test.yml | 1 + 3 files changed, 72 insertions(+) create mode 100644 cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/ClaimMappingAdminControllerIT.java diff --git a/cameleer3-server-app/src/test/java/com/cameleer3/server/app/TestSecurityHelper.java b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/TestSecurityHelper.java index 58ca0a0c..0eb7f550 100644 --- a/cameleer3-server-app/src/test/java/com/cameleer3/server/app/TestSecurityHelper.java +++ b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/TestSecurityHelper.java @@ -84,6 +84,13 @@ public class TestSecurityHelper { return headers; } + /** + * Returns HttpHeaders with ADMIN JWT Bearer authorization, protocol version, and JSON content type. + */ + public HttpHeaders adminHeaders() { + return authHeaders(adminToken()); + } + /** * Returns HttpHeaders with bootstrap token authorization, protocol version, and JSON content type. */ diff --git a/cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/ClaimMappingAdminControllerIT.java b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/ClaimMappingAdminControllerIT.java new file mode 100644 index 00000000..cf64e592 --- /dev/null +++ b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/ClaimMappingAdminControllerIT.java @@ -0,0 +1,64 @@ +package com.cameleer3.server.app.controller; + +import com.cameleer3.server.app.AbstractPostgresIT; +import com.cameleer3.server.app.TestSecurityHelper; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.*; + +import static org.assertj.core.api.Assertions.assertThat; + +class ClaimMappingAdminControllerIT extends AbstractPostgresIT { + + @Autowired private TestRestTemplate restTemplate; + @Autowired private ObjectMapper objectMapper; + @Autowired private TestSecurityHelper securityHelper; + + private HttpHeaders adminHeaders; + + @BeforeEach + void setUp() { + adminHeaders = securityHelper.adminHeaders(); + } + + @Test + void createAndListRules() throws Exception { + String body = """ + {"claim":"groups","matchType":"contains","matchValue":"admins","action":"assignRole","target":"ADMIN","priority":0} + """; + var createResponse = restTemplate.exchange("/api/v1/admin/claim-mappings", + HttpMethod.POST, new HttpEntity<>(body, adminHeaders), String.class); + assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.CREATED); + + var listResponse = restTemplate.exchange("/api/v1/admin/claim-mappings", + HttpMethod.GET, new HttpEntity<>(adminHeaders), String.class); + assertThat(listResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + + JsonNode rules = objectMapper.readTree(listResponse.getBody()); + assertThat(rules.isArray()).isTrue(); + assertThat(rules.size()).isGreaterThanOrEqualTo(1); + } + + @Test + void deleteRule() throws Exception { + String body = """ + {"claim":"dept","matchType":"equals","matchValue":"eng","action":"assignRole","target":"VIEWER","priority":0} + """; + var createResponse = restTemplate.exchange("/api/v1/admin/claim-mappings", + HttpMethod.POST, new HttpEntity<>(body, adminHeaders), String.class); + JsonNode created = objectMapper.readTree(createResponse.getBody()); + String id = created.get("id").asText(); + + var deleteResponse = restTemplate.exchange("/api/v1/admin/claim-mappings/" + id, + HttpMethod.DELETE, new HttpEntity<>(adminHeaders), Void.class); + assertThat(deleteResponse.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); + + var getResponse = restTemplate.exchange("/api/v1/admin/claim-mappings/" + id, + HttpMethod.GET, new HttpEntity<>(adminHeaders), String.class); + assertThat(getResponse.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + } +} diff --git a/cameleer3-server-app/src/test/resources/application-test.yml b/cameleer3-server-app/src/test/resources/application-test.yml index e17b8027..cb49626d 100644 --- a/cameleer3-server-app/src/test/resources/application-test.yml +++ b/cameleer3-server-app/src/test/resources/application-test.yml @@ -17,3 +17,4 @@ agent-registry: security: bootstrap-token: test-bootstrap-token bootstrap-token-previous: old-bootstrap-token + jwt-secret: test-jwt-secret-for-ed25519-derivation