test(api): integration coverage — brevo ledger webhook + thin endpoints (toward 100%)#243
Merged
Merged
Conversation
…int (toward 100%) Adds REAL-DB integration tests for two handlers that previously had ONLY sqlmock (unit) coverage, closing integration gaps flagged in INTEGRATION-COVERAGE-PLAN-2026-06-04 §2.1. brevo_webhook_realdb_integration_test.go — POST /webhooks/brevo/:secret, the rule-12 email truth surface. Seeds real forwarder_sent rows, POSTs synthetic Brevo events, reads back via the production LookupForwarderSentByProviderID helper. Proves the SQL is CORRECT (not just "issued"): delivered overwrites classification + stamps delivered_at; each non-delivered event maps to its terminal class leaving delivered_at NULL; the bug-bash #6 terminal-class guard preserves bounced_hard/soft/ rejected/complaint/unsubscribed against a LATE out-of-order 'delivered' while still upgrading deferred/success; GREATEST delivered_at is monotonic on Brevo retries (idempotent); an orphan messageId is a 200 no-op that creates no row. Testable today despite the unvalidated-Brevo-sender block (synthetic payload, not a live send). status_realdb_integration_test.go — GET /api/v1/status. Seeds real service_components + uptime_samples and asserts the computed payload through a Fiber app on real DB + real Redis: operational (all-healthy) vs down (recent unhealthy probe), empty-DB clean state (never 500), the 60s cache.GetOrSet round-trip (second request served from Redis, cache-bust surfaces a mid-flight DB mutation), and the nil-Redis DB-fallback path. No production code changed. Integration coverage (handlers, -coverpkg=./...): 78.6% -> 78.7%; status.go computeOne 86.0% -> 89.5%. The pre-existing local TestQueue_CredIssueError_FallsBackToLegacyOpen 503 (NATS unreachable locally) is unchanged and unrelated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds real-DB integration tests for two handlers that previously had only sqlmock (unit) coverage, closing integration gaps flagged in
INTEGRATION-COVERAGE-PLAN-2026-06-04§2.1. No production code changed — test-only additions.1.
POST /webhooks/brevo/:secret— the rule-12 email truth surfacebrevo_webhook_realdb_integration_test.goseeds realforwarder_sentrows, POSTs synthetic Brevo events (HMAC-free URL-token auth, same shape Brevo emits), and reads the row back via the productionLookupForwarderSentByProviderIDhelper. Proves the SQL is correct against a real Postgres schema (not merely "issued", which is all the sqlmock suite could assert):delivered→ overwritesclassification+ stampsdelivered_at.hard_bounce/soft_bounce/blocked/complaint/spam→complaint/deferred/unsubscribed/error) → its terminal class,delivered_atstays NULL.delivereddoes NOT clobber a recordedbounced_hard/soft/rejected/complaint/unsubscribed, while it DOES upgrade non-terminaldeferred/success. This row-state predicate can only be proven against a real row.GREATEST(delivered_at, NOW())is monotonic on Brevo retries (idempotent).Testable today despite the unvalidated-Brevo-sender production block (synthetic payload, not a live send).
2.
GET /api/v1/status— public status aggregatorstatus_realdb_integration_test.goseeds realservice_components+uptime_samplesand asserts the computed payload through a Fiber app on real DB + real Redis:current_statusoff operational + depresses uptime %).ok:true,[]incidents, never 500).cache.GetOrSetround-trip — second request served from Redis (a mid-flight DB mutation stays masked until the cache key is busted).Integration-coverage delta
Measured with the §1.4 command for
internal/handlers(-coverpkg=./..., real local Postgres + Redis):internal/handlersvs all prod pkgs (./...)status.gocomputeOneThe brevo handler lines were already line-covered by sqlmock, so the marginal line lift is modest — the value added is behavioral integration coverage of the actual SQL (terminal-class guard, GREATEST monotonicity, idempotency), which line coverage cannot capture but is the rule-12 truth-surface guarantee.
The pre-existing local
TestQueue_CredIssueError_FallsBackToLegacyOpen503 (NATS unreachable locally) is unchanged and unrelated — CI supplies NATS.🤖 Generated with Claude Code