test(alerts): cover global read — one user marks read, others see readAt

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-21 18:20:21 +02:00
parent efd8396045
commit c70fa130ab

View File

@@ -442,6 +442,62 @@ class AlertControllerIT extends AbstractPostgresIT {
assertThat(bothRead).as("read must appear with no read filter").isTrue();
}
@Test
void read_is_global_other_users_see_readAt_set() throws Exception {
// Seed an alert targeting BOTH users so the viewer's GET /{id} is visible
AlertInstance instance = new AlertInstance(
UUID.randomUUID(), null, null, envIdA,
AlertState.FIRING, AlertSeverity.WARNING,
Instant.now(), null, null, null, null, null, null, false,
42.0, 1000.0, null, "Global read test", "Operator reads, viewer sees it",
List.of("test-operator", "test-viewer"), List.of(), List.of());
instance = instanceRepo.save(instance);
// Operator (user A) marks the alert as read
ResponseEntity<String> readResp = restTemplate.exchange(
"/api/v1/environments/" + envSlugA + "/alerts/" + instance.id() + "/read",
HttpMethod.POST,
new HttpEntity<>(securityHelper.authHeaders(operatorJwt)),
String.class);
assertThat(readResp.getStatusCode()).isEqualTo(HttpStatus.OK);
// Viewer (user B) fetches the same alert and must see readAt != null
ResponseEntity<String> getResp = restTemplate.exchange(
"/api/v1/environments/" + envSlugA + "/alerts/" + instance.id(),
HttpMethod.GET,
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
String.class);
assertThat(getResp.getStatusCode()).isEqualTo(HttpStatus.OK);
JsonNode node = objectMapper.readTree(getResp.getBody());
assertThat(node.path("readAt").isNull())
.as("viewer must see readAt as non-null after operator marked read")
.isFalse();
assertThat(node.path("readAt").isMissingNode())
.as("readAt field must be present in response")
.isFalse();
// Viewer's list endpoint must also show the alert with readAt set
ResponseEntity<String> listResp = restTemplate.exchange(
"/api/v1/environments/" + envSlugA + "/alerts",
HttpMethod.GET,
new HttpEntity<>(securityHelper.authHeadersNoBody(viewerJwt)),
String.class);
assertThat(listResp.getStatusCode()).isEqualTo(HttpStatus.OK);
JsonNode listBody = objectMapper.readTree(listResp.getBody());
UUID instanceId = instance.id();
boolean foundWithReadAt = false;
for (JsonNode item : listBody) {
if (item.path("id").asText().equals(instanceId.toString())) {
assertThat(item.path("readAt").isNull())
.as("list entry readAt must be non-null for viewer after global read")
.isFalse();
foundWithReadAt = true;
break;
}
}
assertThat(foundWithReadAt).as("alert must appear in viewer's list with readAt set").isTrue();
}
// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------