unrip/test/quote-lifecycle-statistics.test.mjs
philipp 8361defa53
All checks were successful
deploy / deploy (push) Successful in 50s
Fix quote statistics refresh collapse
Proof: reproduced live quote lifecycle statistics refresh stalling while persisted subject and window counts remained nonzero; fixed refresh to incrementally scan recent durable source evidence from the retained subject table, canonicalized statistic window ids, de-duped duplicate persisted grain/window rows on load, and validated with targeted stats/dashboard tests, full npm test, and dashboard bundle build.

Assumptions: quote lifecycle statistics are durable retained unique quote subjects, and a 5 minute source overlap is enough to catch ordinary insert/refresh races without re-reading the whole retained history on every dashboard refresh.

Still fake: this does not create venue-native fill truth where no durable settlement evidence exists, does not repair WebSocket client backpressure from high live quote volume, and does not reconstruct pruned raw quote detail.
2026-06-14 20:56:32 +02:00

139 lines
4.9 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
buildQuoteLifecycleStatistics,
classifyQuoteLifecycleStatisticsBucket,
quoteLifecycleStatisticId,
quoteLifecycleStatisticWindow,
} from '../src/core/quote-lifecycle-statistics.mjs';
test('quote lifecycle statistics classify states without upgrading submitted-only rows to success', () => {
assert.equal(classifyQuoteLifecycleStatisticsBucket({
lifecycle_state: 'submitted',
execution: { status: 'submitted', result_code: 'quote_response_ok' },
}), 'submitted_no_reply');
assert.equal(classifyQuoteLifecycleStatisticsBucket({
lifecycle_state: 'failed',
execution: { status: 'failed', failure_category: 'quote_not_found_or_finished' },
}), 'submission_failed');
assert.equal(classifyQuoteLifecycleStatisticsBucket({
lifecycle_state: 'command_emitted',
}), 'awaiting_executor');
assert.equal(classifyQuoteLifecycleStatisticsBucket({
lifecycle_state: 'completed',
outcome_status: 'completed',
has_settlement_evidence: true,
}), 'success');
});
test('quote lifecycle statistics can aggregate retained quote subject buckets', () => {
const rows = buildQuoteLifecycleStatistics({
computedAt: '2026-06-12T14:20:00.000Z',
lifecycleRows: [{
quote_id: 'quote-retained-success',
quote_activity_at: '2026-06-12T14:11:01.000Z',
latest_stage_at: '2026-06-12T14:11:10.000Z',
statistics_bucket: 'success',
}],
});
const allTime = rows.find((row) => row.grain === 'all_time');
const fiveMinute = rows.find((row) => (
row.grain === 'five_minute'
&& row.window_start === '2026-06-12T14:10:00.000Z'
));
assert.equal(allTime.quote_count, 1);
assert.equal(allTime.bucket_counts.success, 1);
assert.equal(fiveMinute.quote_count, 1);
assert.equal(fiveMinute.bucket_counts.success, 1);
});
test('quote lifecycle statistics use UTC grain boundaries with Monday UTC weeks', () => {
assert.deepEqual(quoteLifecycleStatisticWindow('2026-06-12T17:34:44.123Z', 'five_minute'), {
grain: 'five_minute',
window_start: '2026-06-12T17:30:00.000Z',
window_end: '2026-06-12T17:35:00.000Z',
});
assert.deepEqual(quoteLifecycleStatisticWindow('2026-06-14T23:59:00.000Z', 'week'), {
grain: 'week',
window_start: '2026-06-08T00:00:00.000Z',
window_end: '2026-06-15T00:00:00.000Z',
});
assert.deepEqual(quoteLifecycleStatisticWindow('2026-06-01T00:00:00.000Z', 'month'), {
grain: 'month',
window_start: '2026-06-01T00:00:00.000Z',
window_end: '2026-07-01T00:00:00.000Z',
});
});
test('quote lifecycle statistic ids canonicalize Date window values', () => {
assert.equal(
quoteLifecycleStatisticId({
grain: 'five_minute',
window_start: new Date('2026-06-14T18:40:00.000Z'),
}),
'quote-lifecycle-stat:five_minute:2026-06-14T18:40:00.000Z',
);
});
test('quote lifecycle statistics dedupe quotes and refresh later results in the original quote window', () => {
const rows = [
{
quote_id: 'quote-follow',
lifecycle_state: 'command_emitted',
quote_activity_at: '2026-06-12T17:31:01.000Z',
latest_stage_at: '2026-06-12T17:31:03.000Z',
},
{
quote_id: 'quote-follow',
lifecycle_state: 'failed',
quote_activity_at: '2026-06-12T17:31:01.000Z',
latest_stage_at: '2026-06-12T17:36:10.000Z',
execution: {
status: 'failed',
failure_category: 'quote_not_found_or_finished',
},
},
];
const statistics = buildQuoteLifecycleStatistics({
lifecycleRows: rows,
computedAt: '2026-06-12T17:40:00.000Z',
});
const allTime = statistics.find((row) => row.grain === 'all_time');
const fiveMinute = statistics.find((row) => (
row.grain === 'five_minute'
&& row.window_start === '2026-06-12T17:30:00.000Z'
));
const laterFiveMinute = statistics.find((row) => (
row.grain === 'five_minute'
&& row.window_start === '2026-06-12T17:35:00.000Z'
));
assert.equal(allTime.quote_count, 1);
assert.equal(allTime.bucket_counts.submission_failed, 1);
assert.equal(allTime.bucket_counts.awaiting_executor, 0);
assert.equal(fiveMinute.quote_count, 1);
assert.equal(fiveMinute.bucket_counts.submission_failed, 1);
assert.equal(laterFiveMinute, undefined);
});
test('quote lifecycle statistics preserve missing identifiers as unavailable evidence', () => {
const statistics = buildQuoteLifecycleStatistics({
lifecycleRows: [{
quote_id: null,
lifecycle_state: 'observed',
quote_activity_at: '2026-06-12T17:31:01.000Z',
}],
computedAt: '2026-06-12T17:40:00.000Z',
});
const allTime = statistics.find((row) => row.grain === 'all_time');
const fiveMinute = statistics.find((row) => row.grain === 'five_minute');
assert.equal(allTime.quote_count, 0);
assert.equal(allTime.missing_identifier_count, 1);
assert.equal(allTime.bucket_counts.unavailable, 1);
assert.equal(fiveMinute.quote_count, 0);
assert.equal(fiveMinute.missing_identifier_count, 1);
});