test(alerts): close repo IT gaps — filterInEnvLive other-env + bulkMarkRead soft-delete
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ class PostgresAlertInstanceRepositoryIT extends AbstractPostgresIT {
|
|||||||
|
|
||||||
private PostgresAlertInstanceRepository repo;
|
private PostgresAlertInstanceRepository repo;
|
||||||
private UUID envId;
|
private UUID envId;
|
||||||
|
private UUID otherEnvId;
|
||||||
private UUID ruleId;
|
private UUID ruleId;
|
||||||
private final String userId = "inbox-user-" + UUID.randomUUID();
|
private final String userId = "inbox-user-" + UUID.randomUUID();
|
||||||
private final String groupId = UUID.randomUUID().toString();
|
private final String groupId = UUID.randomUUID().toString();
|
||||||
@@ -31,11 +32,15 @@ class PostgresAlertInstanceRepositoryIT extends AbstractPostgresIT {
|
|||||||
void setup() {
|
void setup() {
|
||||||
repo = new PostgresAlertInstanceRepository(jdbcTemplate, new ObjectMapper());
|
repo = new PostgresAlertInstanceRepository(jdbcTemplate, new ObjectMapper());
|
||||||
envId = UUID.randomUUID();
|
envId = UUID.randomUUID();
|
||||||
|
otherEnvId = UUID.randomUUID();
|
||||||
ruleId = UUID.randomUUID();
|
ruleId = UUID.randomUUID();
|
||||||
|
|
||||||
jdbcTemplate.update(
|
jdbcTemplate.update(
|
||||||
"INSERT INTO environments (id, slug, display_name) VALUES (?, ?, ?)",
|
"INSERT INTO environments (id, slug, display_name) VALUES (?, ?, ?)",
|
||||||
envId, "test-env-" + UUID.randomUUID(), "Test Env");
|
envId, "test-env-" + UUID.randomUUID(), "Test Env");
|
||||||
|
jdbcTemplate.update(
|
||||||
|
"INSERT INTO environments (id, slug, display_name) VALUES (?, ?, ?)",
|
||||||
|
otherEnvId, "other-env-" + UUID.randomUUID(), "Other Env");
|
||||||
jdbcTemplate.update(
|
jdbcTemplate.update(
|
||||||
"INSERT INTO users (user_id, provider, email) VALUES (?, 'local', ?) ON CONFLICT (user_id) DO NOTHING",
|
"INSERT INTO users (user_id, provider, email) VALUES (?, 'local', ?) ON CONFLICT (user_id) DO NOTHING",
|
||||||
userId, userId + "@example.com");
|
userId, userId + "@example.com");
|
||||||
@@ -52,9 +57,14 @@ class PostgresAlertInstanceRepositoryIT extends AbstractPostgresIT {
|
|||||||
void cleanup() {
|
void cleanup() {
|
||||||
jdbcTemplate.update("DELETE FROM alert_notifications WHERE alert_instance_id IN " +
|
jdbcTemplate.update("DELETE FROM alert_notifications WHERE alert_instance_id IN " +
|
||||||
"(SELECT id FROM alert_instances WHERE environment_id = ?)", envId);
|
"(SELECT id FROM alert_instances WHERE environment_id = ?)", envId);
|
||||||
|
jdbcTemplate.update("DELETE FROM alert_notifications WHERE alert_instance_id IN " +
|
||||||
|
"(SELECT id FROM alert_instances WHERE environment_id = ?)", otherEnvId);
|
||||||
jdbcTemplate.update("DELETE FROM alert_instances WHERE environment_id = ?", envId);
|
jdbcTemplate.update("DELETE FROM alert_instances WHERE environment_id = ?", envId);
|
||||||
|
jdbcTemplate.update("DELETE FROM alert_instances WHERE environment_id = ?", otherEnvId);
|
||||||
jdbcTemplate.update("DELETE FROM alert_rules WHERE environment_id = ?", envId);
|
jdbcTemplate.update("DELETE FROM alert_rules WHERE environment_id = ?", envId);
|
||||||
|
jdbcTemplate.update("DELETE FROM alert_rules WHERE environment_id = ?", otherEnvId);
|
||||||
jdbcTemplate.update("DELETE FROM environments WHERE id = ?", envId);
|
jdbcTemplate.update("DELETE FROM environments WHERE id = ?", envId);
|
||||||
|
jdbcTemplate.update("DELETE FROM environments WHERE id = ?", otherEnvId);
|
||||||
jdbcTemplate.update("DELETE FROM users WHERE user_id = ?", userId);
|
jdbcTemplate.update("DELETE FROM users WHERE user_id = ?", userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,8 +390,34 @@ class PostgresAlertInstanceRepositoryIT extends AbstractPostgresIT {
|
|||||||
|
|
||||||
UUID unknownId = UUID.randomUUID(); // not in DB at all
|
UUID unknownId = UUID.randomUUID(); // not in DB at all
|
||||||
|
|
||||||
var kept = repo.filterInEnvLive(List.of(a.id(), b.id(), unknownId), envId);
|
// Insert a rule + instance in the second environment (otherEnvId) to prove
|
||||||
|
// that the SQL env-filter actually excludes rows from a different environment.
|
||||||
|
UUID otherRuleId = seedRuleInEnv("other-rule", otherEnvId);
|
||||||
|
var otherEnvInst = newInstanceInEnv(otherRuleId, otherEnvId, List.of(userId), List.of(), List.of());
|
||||||
|
repo.save(otherEnvInst);
|
||||||
|
|
||||||
|
var kept = repo.filterInEnvLive(List.of(a.id(), b.id(), unknownId, otherEnvInst.id()), envId);
|
||||||
assertThat(kept).containsExactly(a.id());
|
assertThat(kept).containsExactly(a.id());
|
||||||
|
assertThat(kept).doesNotContain(otherEnvInst.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void bulkMarkRead_respects_deleted_at() {
|
||||||
|
var live = insertFreshFiring();
|
||||||
|
// second instance — need a fresh ruleId due to the open-rule unique index
|
||||||
|
UUID ruleId2 = seedRule("rule-deleted");
|
||||||
|
var deleted = newInstance(ruleId2, List.of(userId), List.of(), List.of());
|
||||||
|
repo.save(deleted);
|
||||||
|
|
||||||
|
repo.softDelete(deleted.id(), Instant.parse("2026-04-21T10:00:00Z"));
|
||||||
|
|
||||||
|
repo.bulkMarkRead(List.of(live.id(), deleted.id()), Instant.parse("2026-04-21T10:05:00Z"));
|
||||||
|
|
||||||
|
// live row is marked read
|
||||||
|
assertThat(repo.findById(live.id()).orElseThrow().readAt())
|
||||||
|
.isEqualTo(Instant.parse("2026-04-21T10:05:00Z"));
|
||||||
|
// soft-deleted row is NOT touched by bulkMarkRead
|
||||||
|
assertThat(repo.findById(deleted.id()).orElseThrow().readAt()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@@ -453,6 +489,32 @@ class PostgresAlertInstanceRepositoryIT extends AbstractPostgresIT {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Inserts a minimal alert_rule in a specific environment and returns its id. */
|
||||||
|
private UUID seedRuleInEnv(String name, UUID targetEnvId) {
|
||||||
|
UUID id = UUID.randomUUID();
|
||||||
|
jdbcTemplate.update(
|
||||||
|
"INSERT INTO alert_rules (id, environment_id, name, severity, condition_kind, condition, " +
|
||||||
|
"notification_title_tmpl, notification_message_tmpl, created_by, updated_by) " +
|
||||||
|
"VALUES (?, ?, ?, 'WARNING', 'AGENT_STATE', '{}'::jsonb, 't', 'm', 'sys-user', 'sys-user')",
|
||||||
|
id, targetEnvId, name + "-" + id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates an AlertInstance bound to a specific environment (not the default envId). */
|
||||||
|
private AlertInstance newInstanceInEnv(UUID ruleId,
|
||||||
|
UUID targetEnvId,
|
||||||
|
List<String> userIds,
|
||||||
|
List<UUID> groupIds,
|
||||||
|
List<String> roleNames) {
|
||||||
|
return new AlertInstance(
|
||||||
|
UUID.randomUUID(), ruleId, Map.of(), targetEnvId,
|
||||||
|
AlertState.FIRING, AlertSeverity.WARNING,
|
||||||
|
Instant.now(), null, null, null, null, null, null,
|
||||||
|
false, null, null,
|
||||||
|
Map.of(), "title", "message",
|
||||||
|
userIds, groupIds, roleNames);
|
||||||
|
}
|
||||||
|
|
||||||
/** Inserts a minimal alert_rule with re_notify_minutes=1 and returns its id. */
|
/** Inserts a minimal alert_rule with re_notify_minutes=1 and returns its id. */
|
||||||
private UUID seedReNotifyRule(String name) {
|
private UUID seedReNotifyRule(String name) {
|
||||||
UUID id = UUID.randomUUID();
|
UUID id = UUID.randomUUID();
|
||||||
|
|||||||
Reference in New Issue
Block a user