UI enhancemnts
This commit is contained in:
@@ -255,6 +255,49 @@ test('EtfScorer', async (t) => {
|
||||
assert.equal(result.label, '🔴 REJECT');
|
||||
});
|
||||
|
||||
await t.test('does not reject ETF when Yahoo data is missing (null)', () => {
|
||||
const metrics: EtfMetrics = {
|
||||
expenseRatio: 0.05,
|
||||
yield: 1.8,
|
||||
volume: null, // Yahoo did not return averageVolume
|
||||
fiveYearReturn: null, // Yahoo did not return fiveYearAverageReturn
|
||||
totalAssets: null,
|
||||
};
|
||||
|
||||
const result = EtfScorer.score(metrics, DEFAULT_RULES);
|
||||
// Missing data skips gates — must NOT auto-fail as 0 < gate
|
||||
assert.notEqual(result.label, '🔴 REJECT');
|
||||
assert.ok(result.audit?.passedGates);
|
||||
});
|
||||
|
||||
await t.test('still enforces expense gate when other data is missing', () => {
|
||||
const metrics: EtfMetrics = {
|
||||
expenseRatio: 0.8, // above 0.2 gate
|
||||
yield: null,
|
||||
volume: null,
|
||||
fiveYearReturn: null,
|
||||
totalAssets: null,
|
||||
};
|
||||
|
||||
const result = EtfScorer.score(metrics, DEFAULT_RULES);
|
||||
assert.equal(result.label, '🔴 REJECT');
|
||||
assert.ok(result.scoreSummary.includes('Expense ratio'));
|
||||
});
|
||||
|
||||
await t.test('labels all-null metrics as No Data instead of Neutral', () => {
|
||||
const metrics: EtfMetrics = {
|
||||
expenseRatio: null,
|
||||
yield: null,
|
||||
volume: null,
|
||||
fiveYearReturn: null,
|
||||
totalAssets: null,
|
||||
};
|
||||
|
||||
const result = EtfScorer.score(metrics, DEFAULT_RULES);
|
||||
assert.equal(result.label, '🟡 Neutral (No Data)');
|
||||
assert.equal(result.audit?.coverage?.active, 0);
|
||||
});
|
||||
|
||||
await t.test('handles negative 5-year return', () => {
|
||||
const metrics: EtfMetrics = {
|
||||
expenseRatio: 0.1,
|
||||
|
||||
Reference in New Issue
Block a user