Skip to content

test(shared): direct coverage for the blockchain event bus and HTTP metrics hook - #162

Merged
dev-fani merged 1 commit into
fanilabs:mainfrom
hartz0:test/shared-bus-and-metrics-coverage
Aug 30, 2026
Merged

test(shared): direct coverage for the blockchain event bus and HTTP metrics hook#162
dev-fani merged 1 commit into
fanilabs:mainfrom
hartz0:test/shared-bus-and-metrics-coverage

Conversation

@hartz0

@hartz0 hartz0 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Two pieces of shared infrastructure that every module depends on had no dedicated test — coverage was entirely incidental, coming from module-level tests that call handlers directly or from a full HTTP integration test that happens to run the plugin as a side effect. This PR adds a spec file for each, testing the component's own contract at its own boundary.

src/shared/events/index.spec.tscloses #125

The in-process publishBlockchainEvent / onBlockchainEvent bus that all seven event-consuming modules subscribe to. New tests, all going through the real bus rather than a handler:

  • a published event reaches every current subscriber (fan-out)
  • calling the unsubscribe function returned by onBlockchainEvent stops further delivery to that listener only, leaving others attached
  • publishing with zero subscribers is a no-op, not an error
  • multiple publishBlockchainEvent calls are each delivered independently — not batched or coalesced
  • calling an unsubscribe function twice is harmless

The unsubscribe test is a genuine regression guard: if onBlockchainEvent's teardown stopped detaching the listener, the "without affecting others" assertion (leaves called exactly once) fails.

src/shared/http/plugins/metrics.spec.tscloses #126

The onResponse hook that records http_requests_total / http_request_duration_seconds. New tests build a minimal Fastify instance with one parameterized route and assert:

  • a request to a concrete URL (/api/v1/deliveries/abc-123) is recorded under the route pattern (/api/v1/deliveries/:chainDeliveryId), and the concrete ids never become their own time series — the label-cardinality guard the file's header comment describes
  • a request to an unregistered path (404) is recorded with route="unmatched" rather than dropped

Assertions read the shared prom-client registry via a before/after delta, since it accumulates across the suite.

Testing

  • pnpm exec vitest run src/shared/events/index.spec.ts src/shared/http/plugins/metrics.spec.ts → 7 passing
  • pnpm exec eslint clean on both new files
  • tsc --noEmit introduces no new errors

…rectly

Adds two dedicated spec files for shared infrastructure that was only ever
covered incidentally through module-level tests.

src/shared/events/index.spec.ts exercises the in-process bus's own contract
independent of any module handler: fan-out to every current subscriber, the
returned unsubscribe function detaching one listener without affecting
others, publishing with zero subscribers being a no-op, each publish being
delivered independently (not coalesced), and a double unsubscribe being
harmless. The unsubscribe test fails if onBlockchainEvent's teardown is
broken.

src/shared/http/plugins/metrics.spec.ts builds a minimal Fastify instance
with one parameterized route and asserts the http_requests_total counter is
labeled by route *pattern* rather than the concrete URL (the cardinality
guard the file comment describes), and that an unmatched 404 is recorded as
`unmatched` rather than dropped.

closes fanilabs#125
closes fanilabs#126
@drips-wave

drips-wave Bot commented Aug 30, 2026

Copy link
Copy Markdown

@hartz0 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@dev-fani
dev-fani merged commit fa9e956 into fanilabs:main Aug 30, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants