From 5fbe3b5afc651ef2e4e7501c314c9e46f40f4a53 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Fri, 17 Jul 2026 09:12:40 +0300 Subject: [PATCH] fix(ux): render null monthly_cost as blank in Purchase History (#1416) Correct the PurchaseHistory TypeScript interface to type monthly_cost as number | null instead of number. The API has always returned null for pre-purchase-history records; the incorrect non-nullable type caused TypeScript consumers to treat null as 0, rendering "$0" instead of a blank dash. The renderHistoryList rendering already guards with != null, so the fix is purely in the type declaration. Add a regression test that verifies explicit monthly_cost: null renders the muted dash span and not "$0". Closes #1416 --- frontend/src/__tests__/history.test.ts | 28 ++++++++++++++++++++++++++ frontend/src/api/types.ts | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/frontend/src/__tests__/history.test.ts b/frontend/src/__tests__/history.test.ts index f0e98a7b0..f9e806788 100644 --- a/frontend/src/__tests__/history.test.ts +++ b/frontend/src/__tests__/history.test.ts @@ -303,6 +303,34 @@ describe('History Module', () => { expect(html).toContain('class="muted"'); }); + test('Issue #1416: explicit null monthly_cost renders as dash, not "$0"', async () => { + (api.getHistory as jest.Mock).mockResolvedValue({ + summary: {}, + purchases: [ + { + timestamp: '2024-02-01T00:00:00Z', + provider: 'aws', + service: 'ec2', + resource_type: 't3.medium', + region: 'us-east-1', + count: 1, + term: 1, + upfront_cost: 500, + monthly_cost: null, + estimated_savings: 20, + }, + ] + }); + + await loadHistory(); + + const list = document.getElementById('history-list'); + const html = list?.innerHTML || ''; + // Explicit null must render the muted dash, never "$0". + expect(html).toContain('class="muted"'); + expect(html).not.toContain('$0'); + }); + test('shows empty message when no purchases', async () => { (api.getHistory as jest.Mock).mockResolvedValue({ summary: {}, diff --git a/frontend/src/api/types.ts b/frontend/src/api/types.ts index afd50df27..f614433f8 100644 --- a/frontend/src/api/types.ts +++ b/frontend/src/api/types.ts @@ -256,7 +256,7 @@ export interface PurchaseHistory { term: number; payment: string; upfront_cost: number; - monthly_cost: number; + monthly_cost: number | null; estimated_savings: number; plan_id?: string; plan_name?: string;