test(priceOracle): unit tests for median, anomaly detection, and aggregation#63
Open
storm-beyndtech wants to merge 1 commit into
Open
Conversation
…aggregation Covers the core oracle business logic (closes SmartDropLabs#7): - median: empty/single/even/odd, non-mutation, numeric sort, outlier resistance - detectAnomaly: no-history, below/at/above the strict-`>` 20% threshold, symmetric down-moves, re-store-on-anomaly, issuer-scoped keys, cache read/write failure branches - fetchFromAllSources: all-succeed, partial failure, all-fail, null/zero filtering, single healthy source (no quorum rule) - getPrice: cache hit (fresh + stale flag), cache miss -> fresh fetch + write-back, cache-read-throw -> redis_unavailable - fetchFreshPrice: unavailable shape, anomaly path, redisUnavailable short-circuit, write-fail degradation - refreshAllCachedPrices: not-connected skip, scan + refresh (history keys excluded), scan-throw abort Coverage for priceOracle.js: 98% (gate is 80%). Suite mocks cache, the three price sources, config, and logger; needs no external services. detectAnomaly is temporal (compares the aggregate to the last cached aggregate) and log-only -- it does not exclude an outlier source from the median. Tests document this actual behavior. Also: - Export median/detectAnomaly/fetchFromAllSources for unit testing. - Fix latent bug: fetchFreshPrice mapped a non-existent `.name` field over source results (which expose `.source`), so sources_attempted was always [undefined, ...] on every fresh fetch and was cached and served. The new tests surfaced it. - Ignore generated coverage/ output.
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.
Summary
Adds unit test coverage for the core price oracle business logic in
src/services/priceOracle.js— median aggregation, temporal anomalydetection, and multi-source fan-out. Closes #7.
Coverage for
priceOracle.js: 98% (acceptance gate is 80%). The suitemocks
cache, the three price sources,config, andlogger, so it needsno external services.
Heads-up for the reviewer
fetchFreshPricemapped a non-existent.namefield over source results(which expose
.source), sosources_attemptedwas always[undefined, …]on every fresh fetch — and that value was cached andserved. It was never filed because the existing
test/prices.test.jsstubsthe whole oracle, so this line had never run under assertion. Fixed in the
same change since it lives in the function under test.
detectAnomalyis temporal and log-only. It compares the currentaggregate against the last cached aggregate over time; it does not
exclude an outlier source from the median, and its return value is
discarded by
fetchFreshPrice. The tests document this actual behaviorrather than an assumed cross-source rejection scheme.
Changes
test/priceOracle.test.js— 34 tests:median— empty/single/even/odd, non-mutation, numeric (not lexical)sort, single-outlier resistance
detectAnomaly— no-history, below / at / above the strict->20%threshold, symmetric down-moves, re-store-on-anomaly, issuer-scoped keys,
cache read/write failure branches
fetchFromAllSources— all-succeed, partial failure, all-fail, null/zerofiltering, single healthy source (no quorum rule)
getPrice— cache hit (fresh + staleis_staleflag), cache miss →fresh fetch + write-back, cache-read-throw →
redis_unavailablefetchFreshPrice— unavailable shape, anomaly path,redisUnavailableshort-circuit, write-fail degradation
refreshAllCachedPrices— not-connected skip, scan + refresh (historykeys excluded), scan-throw abort
src/services/priceOracle.jsmedian/detectAnomaly/fetchFromAllSourcesfor unit testingr.name→r.sourceinfetchFreshPrice(the bug above).gitignore— ignore generatedcoverage/outputTest suite note
The repository's broader suite has pre-existing failures that require Redis /
Postgres (and a
config.test.jsthat spawns subprocesses). For reference:main(baseline)The branch is strictly better, and none of the remaining failures are
introduced here. The new
priceOraclesuite passes fully on its own.Acceptance criteria
npm test(Jest — already configured)medianfully tested (edge cases included)detectAnomalytested below/at/above thresholdfetchFromAllSourcestested with partial failuresgetPricetested for cache hit and miss pathspriceOracle.js(98%)