Add 6 new test methods to NotificationsBase that exercise the wave3
account-alerts surface end-to-end:
- testListAccountAlertsEmpty: GET /v1/account/alerts shape check
- testWebhookFailureCreatesConsoleAlert: drives a webhook past
_APP_WEBHOOK_MAX_FAILED_ATTEMPTS via user-create events and polls
/account/alerts until the worker fans the paused alert out to the
project owner on the console channel
- testMarkAlertReadTogglesFlag: PATCH /:alertId/read happy path
- testMarkAlertReadUnauthorized: stranger console user cannot mark
someone else's alert as read; alert remains unread for the owner
- testTrackingPixelTogglesRead: GET /:alertId/track with a valid
HS256 JWT signed with _APP_OPENSSL_KEY_V1 returns the canonical 1x1
PNG and atomically marks the alert as read
- testTrackingPixelInvalidTokenReturnsPng: tampered JWT still gets a
PNG (no information disclosure) but performs no DB write
Helpers:
- seedWebhookFailureAlert: registers a webhook pointing at an
unroutable address (http://127.0.0.1:1/), drives max+2 user-create
events through the project, polls assertEventually with a 60s budget
for the paused alert keyed by the deterministic md5 of
'webhook:<id>:paused:<attempts>'
- createConsoleUser: spins up a fresh, unrelated console user with its
own session for the unauthorized assertion
- getConsoleAlertHeaders: console-session auth bundle reused across
every alerts call, so the trait works identically under SideServer
and SideConsole hosts
Mirrors the dominant e2e pattern (FunctionsBase/MigrationsBase): the
shared health-queue assertions live in a NotificationsBase trait,
with thin per-side overlays for ProjectCustom + SideServer and
ProjectCustom + SideConsole.