fix(test): align AgentRegistrationControllerIT with current spec

Four drifts against the current server contract, all now corrected:
- Registration body missing required environmentId (spec: 400 if absent).
- Agent list moved to env-scoped /api/v1/environments/{envSlug}/agents;
  flat /api/v1/agents no longer exists.
- heartbeatUnknownAgent now auto-heals via JWT env claim (fb54f9cb);
  the 404 branch is only reachable without a JWT, which the security
  filter rejects before the controller sees the request.
- sseEndpoint is an absolute URL (ServletUriComponentsBuilder.fromCurrentContextPath),
  so assert endsWith the path rather than equals-to-relative.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-21 21:15:16 +02:00
parent 9046070529
commit 7436a37b99

View File

@@ -40,6 +40,7 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
{
"instanceId": "%s",
"applicationId": "test-group",
"environmentId": "default",
"version": "1.0.0",
"routeIds": ["route-1", "route-2"],
"capabilities": {"tracing": true}
@@ -60,7 +61,9 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
JsonNode body = objectMapper.readTree(response.getBody());
assertThat(body.get("instanceId").asText()).isEqualTo("agent-it-1");
assertThat(body.get("sseEndpoint").asText()).isEqualTo("/api/v1/agents/agent-it-1/events");
// Controller returns an absolute URL via ServletUriComponentsBuilder.fromCurrentContextPath(),
// so only assert the path suffix — the host:port varies per RANDOM_PORT test run.
assertThat(body.get("sseEndpoint").asText()).endsWith("/api/v1/agents/agent-it-1/events");
assertThat(body.get("heartbeatIntervalMs").asLong()).isGreaterThan(0);
assertThat(body.has("serverPublicKey")).isTrue();
assertThat(body.get("serverPublicKey").asText()).isNotEmpty();
@@ -96,14 +99,20 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
}
@Test
void heartbeatUnknownAgent_returns404() {
void heartbeatUnknownAgent_autoHealsFromJwtEnv_returns200() {
// Post-fb54f9cb: heartbeat for an agent not in the registry auto-heals
// from the JWT env claim + heartbeat body (covers agent-side survival of
// server restarts). The no-registry 404 branch is only reachable without
// a JWT, which Spring Security rejects at the filter chain before the
// controller sees the request. See CLAUDE.md "Auto-heals from JWT env
// claim + heartbeat body on heartbeat/SSE after server restart".
ResponseEntity<Void> response = restTemplate.exchange(
"/api/v1/agents/unknown-agent-xyz/heartbeat",
HttpMethod.POST,
new HttpEntity<>(securityHelper.authHeadersNoBody(jwt)),
Void.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@Test
@@ -112,7 +121,7 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
registerAgent("agent-it-list-2", "List Agent 2");
ResponseEntity<String> response = restTemplate.exchange(
"/api/v1/agents",
"/api/v1/environments/default/agents",
HttpMethod.GET,
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
String.class);
@@ -129,7 +138,7 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
registerAgent("agent-it-filter", "Filter Agent");
ResponseEntity<String> response = restTemplate.exchange(
"/api/v1/agents?status=LIVE",
"/api/v1/environments/default/agents?status=LIVE",
HttpMethod.GET,
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
String.class);
@@ -146,7 +155,7 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
@Test
void listAgentsWithInvalidStatus_returns400() {
ResponseEntity<String> response = restTemplate.exchange(
"/api/v1/agents?status=INVALID",
"/api/v1/environments/default/agents?status=INVALID",
HttpMethod.GET,
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
String.class);