Adds a hit counter to the bad webhook and asserts it is attempted at
least 3 times, proving the watermill retry middleware actually fires
on a failing delivery. We use GreaterOrEqual rather than an exact
count because gochannel resends nacked messages, so a permanently
failing delivery keeps running through retry cycles until the test
times out its wait window.
Previously WebhookListener.Handle fetched matching webhooks with
Find(&ws) without an explicit ORDER BY, so iteration order depended on
the DB driver. Add ORDER BY id ASC so the fan-out order is stable for
both project- and user-level webhooks, and update the sibling-blocking
regression test to insert webhooks with explicit ids so its ordering
assumption is robust to autoincrement state.
Also clear the example.com fixture webhook (id=1) in the existing
TestTaskUpdateWebhookE2E, since it now errors after sendWebhookPayload
returns non-nil for non-2xx responses.
Add comprehensive e2e tests for user-level webhook CRUD operations
and update existing project webhook tests to use LoadFixtures() for
cleanup instead of manual DELETE queries.
New pkg/e2etests/ package runs with the real Watermill event system to
verify the full async pipeline: web handler -> DB -> event dispatch ->
Watermill -> listener -> side effect.
First test (TestTaskUpdateWebhookE2E) updates a task and asserts that
a webhook HTTP POST arrives at a test server.