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:
@@ -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
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user