feat: filter notifications to warnings/errors/ready only and add clear-all button
Notification filtering: - lifecycle_hooks.py: only instance.error and instance.health_changed with status=running generate notifications. All other lifecycle events (created, started, stopped, restarted, deleted) are filtered out. - health_monitor.py: only error and unhealthy states generate notifications. Running/recovered state no longer creates info notifications. - _derive_title now maps instance.health_changed to "Container ready". Clear-all button: - Added dismiss_all() to NotificationService - Added DELETE /notifications endpoint for bulk dismiss - Frontend: clearAllNotifications API, clearAll in notification context, "Clear all" button in notification drawer alongside "Mark all as read" - Added CSS for .notification-clear-all with danger hover state - Updated notification-center tests Quality gates: pytest (21 passed), vitest (11 passed)
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
"""Unit tests for lifecycle hook helpers."""
|
||||
|
||||
import pytest
|
||||
|
||||
from src.services.lifecycle_hooks import _derive_title, _should_notify
|
||||
|
||||
|
||||
class TestDeriveTitle:
|
||||
"""Tests for _derive_title."""
|
||||
|
||||
def test_known_event_types(self) -> None:
|
||||
assert _derive_title("instance.created") == "Container created"
|
||||
assert _derive_title("instance.started") == "Container started"
|
||||
assert _derive_title("instance.stopped") == "Container stopped"
|
||||
assert _derive_title("instance.restarted") == "Container restarted"
|
||||
assert _derive_title("instance.deleted") == "Container deleted"
|
||||
assert _derive_title("instance.error") == "Container error"
|
||||
assert _derive_title("instance.health_changed") == "Container ready"
|
||||
|
||||
def test_unknown_event_type(self) -> None:
|
||||
assert _derive_title("instance.custom_event") == "Custom Event"
|
||||
|
||||
|
||||
class TestShouldNotify:
|
||||
"""Tests for _should_notify filtering."""
|
||||
|
||||
def test_error_events_are_notified(self) -> None:
|
||||
assert _should_notify("instance.error", "error") is True
|
||||
assert _should_notify("instance.error", None) is True
|
||||
|
||||
def test_health_changed_running_is_notified(self) -> None:
|
||||
assert _should_notify("instance.health_changed", "running") is True
|
||||
|
||||
def test_created_started_stopped_restarted_deleted_filtered(self) -> None:
|
||||
for event in [
|
||||
"instance.created",
|
||||
"instance.started",
|
||||
"instance.stopped",
|
||||
"instance.restarted",
|
||||
"instance.deleted",
|
||||
]:
|
||||
assert _should_notify(event, "pending") is False
|
||||
assert _should_notify(event, "running") is False
|
||||
assert _should_notify(event, None) is False
|
||||
|
||||
def test_health_changed_non_running_filtered(self) -> None:
|
||||
assert _should_notify("instance.health_changed", "unhealthy") is False
|
||||
assert _should_notify("instance.health_changed", "starting") is False
|
||||
assert _should_notify("instance.health_changed", None) is False
|
||||
Reference in New Issue
Block a user