/** * Tests for components/subscription-manager.js — formatTimeUntil. * * Pure math that powers the "Next refresh" label on subscription cards. * Boundary behavior (≤0 collapses to "Now", minute/hour/day transitions) * has bitten this kind of code before; lock it down here so future * refactors of the display label don't silently flip a day boundary. */ import '@js/components/subscription-manager.js'; let formatTimeUntil; beforeAll(() => { // The module wires up its singleton inside a DOMContentLoaded listener. // happy-dom usually fires the lifecycle event before the import settles, // so dispatch it manually if the singleton isn't there yet. if (!window.subscriptionManager) { document.dispatchEvent(new Event('DOMContentLoaded')); } formatTimeUntil = window.subscriptionManager.formatTimeUntil.bind( window.subscriptionManager ); }); describe('subscriptionManager.formatTimeUntil', () => { it('returns "Now" for 0 ms', () => { expect(formatTimeUntil(0)).toBe('Now'); }); it('returns "Now" for negative ms (overdue subscription)', () => { expect(formatTimeUntil(-5000)).toBe('Now'); expect(formatTimeUntil(-86_400_000)).toBe('Now'); }); it('returns minutes for sub-hour durations', () => { expect(formatTimeUntil(2 * 60 * 1000)).toBe('2m'); expect(formatTimeUntil(59 * 60 * 1000)).toBe('59m'); }); it('returns "0m" for sub-minute positive durations', () => { // 30 seconds — too short for a minute, but > 0 so not "Now". expect(formatTimeUntil(30_000)).toBe('0m'); }); it('returns hours once at the 1-hour boundary', () => { expect(formatTimeUntil(60 * 60 * 1000)).toBe('1h'); expect(formatTimeUntil(23 * 60 * 60 * 1000)).toBe('23h'); }); it('returns days once at the 24-hour boundary', () => { expect(formatTimeUntil(24 * 60 * 60 * 1000)).toBe('1d'); expect(formatTimeUntil(7 * 24 * 60 * 60 * 1000)).toBe('7d'); }); it('handles very large durations without overflow', () => { // 999 days expect(formatTimeUntil(999 * 24 * 60 * 60 * 1000)).toBe('999d'); }); it('floors at unit boundaries — 25h reports as 1d, not 1h', () => { expect(formatTimeUntil(25 * 60 * 60 * 1000)).toBe('1d'); }); it('floors just under the next unit (59m59s stays minutes)', () => { const ms = 59 * 60 * 1000 + 59 * 1000; expect(formatTimeUntil(ms)).toBe('59m'); }); });