CI / Test & Type-Check (push) Canceled after 0s
Snapshot of in-progress module work across multiple slices: - Dealer Flow: dealerExposureEngine, dealerMapService, dealerMapExplain, dealerMapIntegrity, dealerMapReplay, dealerStudyEngine, hanStyleLevels - Mirror Portfolio (M21): fundRepository, captureIngest, mirrorAlertProducers, fund holdings strip, live book, position capture ingest - Options: BSM, NormalizedOptionSurface types, OptionsChainRouter, ConvexityGate, option legs panel - Alert producers: vixLevel, rotation, thesis, unlock, portfolioRisk, mirror (fund_capture, fund_13f, mirror_diff) - FINRA short interest adapter + queue integration - SEC company tickers adapter + ingest (symbol search index seed) - Vendor gate (rate-limit-first data plane, ADR-0009) - CUSIP registry, reverse 13F refresh, stock float service - LRU cache, portfolio backtest engine - Frontend: dealer-flow, funds, journal, lab, monitor, plan, portfolio, reports, screener, strategies, theses, guided-start, exits, more pages - Volume profile, workspace profile, visibility-aware poll - ADRs 0010 (mirror math not advice), 0011 (symbol search index) - VENDOR_INTEGRATIONS.md, END_USER_TEST.md - .gitignore: exclude DBs, .DS_Store, local config, agent scratch
67 lines
2.2 KiB
TypeScript
67 lines
2.2 KiB
TypeScript
import { test } from 'node:test';
|
|
import { strict as assert } from 'node:assert';
|
|
import { DatabaseSync } from 'node:sqlite';
|
|
import {
|
|
curatedCusipForSymbol,
|
|
resolveCusipLocal,
|
|
seedCuratedCusips,
|
|
} from '../cusipRegistry.ts';
|
|
|
|
/**
|
|
* Unit-level tests for CUSIP cache helpers via sec fetch behavior contracts.
|
|
* Network resolve is not exercised here.
|
|
*/
|
|
test('kv_cache can store and read sec:cusip keys', () => {
|
|
const db = new DatabaseSync(':memory:');
|
|
db.exec(`
|
|
CREATE TABLE kv_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, observed_at TEXT NOT NULL);
|
|
`);
|
|
const key = 'sec:cusip:IREN';
|
|
const cusip = 'Q4982L109';
|
|
db.prepare('INSERT OR REPLACE INTO kv_cache (key,value,observed_at) VALUES (?,?,?)').run(
|
|
key,
|
|
cusip,
|
|
new Date().toISOString(),
|
|
);
|
|
const row = db.prepare('SELECT value FROM kv_cache WHERE key=?').get(key) as { value: string };
|
|
assert.equal(row.value, cusip);
|
|
});
|
|
|
|
test('curated map resolves IREN offline', () => {
|
|
assert.equal(curatedCusipForSymbol('IREN'), 'Q4982L109');
|
|
assert.equal(curatedCusipForSymbol('AAPL'), '037833100');
|
|
});
|
|
|
|
test('resolveCusipLocal seeds cache from curated map', () => {
|
|
const db = new DatabaseSync(':memory:');
|
|
db.exec(`
|
|
CREATE TABLE kv_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, observed_at TEXT NOT NULL);
|
|
`);
|
|
const c = resolveCusipLocal(db, 'IREN');
|
|
assert.equal(c, 'Q4982L109');
|
|
const row = db.prepare('SELECT value FROM kv_cache WHERE key=?').get('sec:cusip:IREN') as {
|
|
value: string;
|
|
};
|
|
assert.equal(row.value, 'Q4982L109');
|
|
});
|
|
|
|
test('seedCuratedCusips is idempotent', () => {
|
|
const db = new DatabaseSync(':memory:');
|
|
db.exec(`
|
|
CREATE TABLE kv_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, observed_at TEXT NOT NULL);
|
|
`);
|
|
const n1 = seedCuratedCusips(db);
|
|
const n2 = seedCuratedCusips(db);
|
|
assert.ok(n1 > 0);
|
|
assert.equal(n2, 0);
|
|
});
|
|
|
|
test('isPermanentDataError does not quarantine cusip failures', async () => {
|
|
const { isPermanentDataError } = await import('../../queue/sourceRatePolicy.ts');
|
|
assert.equal(
|
|
isPermanentDataError('sec-fetch:IREN: cusip not resolved - 13F holder refresh blocked'),
|
|
false,
|
|
);
|
|
assert.equal(isPermanentDataError('quote not found for symbol'), true);
|
|
});
|