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:
@@ -40,6 +40,7 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
|
|||||||
{
|
{
|
||||||
"instanceId": "%s",
|
"instanceId": "%s",
|
||||||
"applicationId": "test-group",
|
"applicationId": "test-group",
|
||||||
|
"environmentId": "default",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"routeIds": ["route-1", "route-2"],
|
"routeIds": ["route-1", "route-2"],
|
||||||
"capabilities": {"tracing": true}
|
"capabilities": {"tracing": true}
|
||||||
@@ -60,7 +61,9 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
|
|||||||
|
|
||||||
JsonNode body = objectMapper.readTree(response.getBody());
|
JsonNode body = objectMapper.readTree(response.getBody());
|
||||||
assertThat(body.get("instanceId").asText()).isEqualTo("agent-it-1");
|
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.get("heartbeatIntervalMs").asLong()).isGreaterThan(0);
|
||||||
assertThat(body.has("serverPublicKey")).isTrue();
|
assertThat(body.has("serverPublicKey")).isTrue();
|
||||||
assertThat(body.get("serverPublicKey").asText()).isNotEmpty();
|
assertThat(body.get("serverPublicKey").asText()).isNotEmpty();
|
||||||
@@ -96,14 +99,20 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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(
|
ResponseEntity<Void> response = restTemplate.exchange(
|
||||||
"/api/v1/agents/unknown-agent-xyz/heartbeat",
|
"/api/v1/agents/unknown-agent-xyz/heartbeat",
|
||||||
HttpMethod.POST,
|
HttpMethod.POST,
|
||||||
new HttpEntity<>(securityHelper.authHeadersNoBody(jwt)),
|
new HttpEntity<>(securityHelper.authHeadersNoBody(jwt)),
|
||||||
Void.class);
|
Void.class);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -112,7 +121,7 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
|
|||||||
registerAgent("agent-it-list-2", "List Agent 2");
|
registerAgent("agent-it-list-2", "List Agent 2");
|
||||||
|
|
||||||
ResponseEntity<String> response = restTemplate.exchange(
|
ResponseEntity<String> response = restTemplate.exchange(
|
||||||
"/api/v1/agents",
|
"/api/v1/environments/default/agents",
|
||||||
HttpMethod.GET,
|
HttpMethod.GET,
|
||||||
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
|
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
|
||||||
String.class);
|
String.class);
|
||||||
@@ -129,7 +138,7 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
|
|||||||
registerAgent("agent-it-filter", "Filter Agent");
|
registerAgent("agent-it-filter", "Filter Agent");
|
||||||
|
|
||||||
ResponseEntity<String> response = restTemplate.exchange(
|
ResponseEntity<String> response = restTemplate.exchange(
|
||||||
"/api/v1/agents?status=LIVE",
|
"/api/v1/environments/default/agents?status=LIVE",
|
||||||
HttpMethod.GET,
|
HttpMethod.GET,
|
||||||
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
|
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
|
||||||
String.class);
|
String.class);
|
||||||
@@ -146,7 +155,7 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
|
|||||||
@Test
|
@Test
|
||||||
void listAgentsWithInvalidStatus_returns400() {
|
void listAgentsWithInvalidStatus_returns400() {
|
||||||
ResponseEntity<String> response = restTemplate.exchange(
|
ResponseEntity<String> response = restTemplate.exchange(
|
||||||
"/api/v1/agents?status=INVALID",
|
"/api/v1/environments/default/agents?status=INVALID",
|
||||||
HttpMethod.GET,
|
HttpMethod.GET,
|
||||||
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
|
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
|
||||||
String.class);
|
String.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user