From bc3e5d99a1000cdc10e545c164ccad5810c8bbfe Mon Sep 17 00:00:00 2001 From: dmolinari Date: Sat, 18 Apr 2026 10:17:43 -0300 Subject: [PATCH] =?UTF-8?q?test(web/udt-011):=20dateFormat.ts=20utility=20?= =?UTF-8?q?tests=20(Red=20=E2=80=94=206=20funciones=20+=20edge=20cases)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/web/src/tests/lib/dateFormat.test.ts | 111 +++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/web/src/tests/lib/dateFormat.test.ts diff --git a/src/web/src/tests/lib/dateFormat.test.ts b/src/web/src/tests/lib/dateFormat.test.ts new file mode 100644 index 0000000..c7f1934 --- /dev/null +++ b/src/web/src/tests/lib/dateFormat.test.ts @@ -0,0 +1,111 @@ +import { describe, it, expect, afterEach, vi } from 'vitest'; +import { + AR_TZ, + formatInstant, + formatCivilDate, + formatCivilDateRange, + todayArgentina, + parseCivilDate, +} from '@/lib/dateFormat'; + +describe('dateFormat.ts', () => { + describe('AR_TZ constant', () => { + it('is America/Argentina/Buenos_Aires', () => { + expect(AR_TZ).toBe('America/Argentina/Buenos_Aires'); + }); + }); + + describe('formatInstant (Cat1 — UTC → AR display)', () => { + it('converts 01:30 UTC to 22:30 ART previous day', () => { + const iso = '2026-05-01T01:30:00.000Z'; + const result = formatInstant(iso); + // format es-AR short + medium: "30/4/2026, 22:30:00" o similar + expect(result).toMatch(/30\/0?4\/2026/); + expect(result).toMatch(/22:30/); + }); + + it('uses AR timezone regardless of browser TZ', () => { + const iso = '2026-05-01T12:00:00.000Z'; // 09:00 ART + const result = formatInstant(iso); + expect(result).toMatch(/01\/0?5\/2026/); + expect(result).toMatch(/09:00/); + }); + }); + + describe('formatCivilDate (Cat2 — yyyy-MM-dd → dd/MM/yyyy)', () => { + it('splits manually without new Date()', () => { + expect(formatCivilDate('2026-05-01')).toBe('01/05/2026'); + }); + + it('preserves day for early-year dates', () => { + expect(formatCivilDate('2026-01-01')).toBe('01/01/2026'); + }); + + it('preserves day for end-of-year dates', () => { + expect(formatCivilDate('2026-12-31')).toBe('31/12/2026'); + }); + }); + + describe('formatCivilDateRange', () => { + it('renders full range with arrow', () => { + expect(formatCivilDateRange('2026-05-01', '2026-12-31')) + .toBe('01/05/2026 → 31/12/2026'); + }); + + it('renders open range when hasta is null', () => { + expect(formatCivilDateRange('2026-05-01', null)) + .toBe('desde 01/05/2026'); + }); + }); + + describe('todayArgentina (fix BUG-FE-03)', () => { + afterEach(() => { + vi.useRealTimers(); + }); + + it('returns 2026-04-30 at 22:30 ART of 30/04 (BUG-FE-03 regression)', () => { + // 22:30 ART = 01:30 UTC del día siguiente + vi.useFakeTimers(); + vi.setSystemTime(new Date('2026-05-01T01:30:00.000Z')); + + expect(todayArgentina()).toBe('2026-04-30'); + }); + + it('returns 2026-05-01 at 00:30 ART of 01/05', () => { + // 00:30 ART = 03:30 UTC + vi.useFakeTimers(); + vi.setSystemTime(new Date('2026-05-01T03:30:00.000Z')); + + expect(todayArgentina()).toBe('2026-05-01'); + }); + + it('returns 2024-02-28 at 22:30 ART of 28/02/2024 (bisiesto)', () => { + // 22:30 ART del 28/02/2024 = 01:30 UTC del 29/02/2024 + vi.useFakeTimers(); + vi.setSystemTime(new Date('2024-02-29T01:30:00.000Z')); + + expect(todayArgentina()).toBe('2024-02-28'); + }); + + it('returns 2026-12-31 at 22:30 ART of 31/12 (end of year)', () => { + // 22:30 ART del 31/12/2026 = 01:30 UTC del 01/01/2027 + vi.useFakeTimers(); + vi.setSystemTime(new Date('2027-01-01T01:30:00.000Z')); + + expect(todayArgentina()).toBe('2026-12-31'); + }); + }); + + describe('parseCivilDate', () => { + it('splits "2026-05-01" into {year, month, day}', () => { + expect(parseCivilDate('2026-05-01')).toEqual({ year: 2026, month: 5, day: 1 }); + }); + + it('does not use new Date() (no UTC creep)', () => { + const result = parseCivilDate('2026-01-01'); + expect(result.year).toBe(2026); + expect(result.month).toBe(1); + expect(result.day).toBe(1); + }); + }); +});