import { describe, expect, it, vi, beforeAll, afterAll } from 'vitest'; import { MONTHS_KR, isValidMonth, getCurrentMonth, getPrevMonth, getNextMonth, formatMonthForDisplay } from '../dateUtils'; // Mock logger to prevent console output during tests vi.mock('@/utils/logger', () => ({ logger: { warn: vi.fn(), error: vi.fn(), }, })); describe('dateUtils', () => { // Mock current date for consistent testing const mockDate = new Date('2024-06-15T12:00:00.000Z'); beforeAll(() => { vi.useFakeTimers(); vi.setSystemTime(mockDate); }); afterAll(() => { vi.useRealTimers(); }); describe('MONTHS_KR', () => { it('contains all 12 months in Korean', () => { expect(MONTHS_KR).toHaveLength(12); expect(MONTHS_KR[0]).toBe('1월'); expect(MONTHS_KR[11]).toBe('12월'); }); it('has correct month names', () => { const expectedMonths = [ '1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월' ]; expect(MONTHS_KR).toEqual(expectedMonths); }); }); describe('isValidMonth', () => { it('validates correct YYYY-MM format', () => { expect(isValidMonth('2024-01')).toBe(true); expect(isValidMonth('2024-12')).toBe(true); expect(isValidMonth('2023-06')).toBe(true); expect(isValidMonth('2025-09')).toBe(true); }); it('rejects invalid month numbers', () => { expect(isValidMonth('2024-00')).toBe(false); expect(isValidMonth('2024-13')).toBe(false); expect(isValidMonth('2024-99')).toBe(false); }); it('rejects invalid formats', () => { expect(isValidMonth('24-01')).toBe(false); expect(isValidMonth('2024-1')).toBe(false); expect(isValidMonth('2024/01')).toBe(false); expect(isValidMonth('2024.01')).toBe(false); expect(isValidMonth('2024-01-01')).toBe(false); expect(isValidMonth('')).toBe(false); expect(isValidMonth('invalid')).toBe(false); }); it('handles edge cases', () => { expect(isValidMonth('0000-01')).toBe(true); // 기술적으로 valid expect(isValidMonth('9999-12')).toBe(true); }); }); describe('getCurrentMonth', () => { it('returns current month in YYYY-MM format', () => { expect(getCurrentMonth()).toBe('2024-06'); }); }); describe('getPrevMonth', () => { it('calculates previous month correctly', () => { expect(getPrevMonth('2024-06')).toBe('2024-05'); expect(getPrevMonth('2024-03')).toBe('2024-02'); expect(getPrevMonth('2024-12')).toBe('2024-11'); }); it('handles year boundary correctly', () => { expect(getPrevMonth('2024-01')).toBe('2023-12'); expect(getPrevMonth('2025-01')).toBe('2024-12'); }); it('handles invalid input gracefully', () => { expect(getPrevMonth('invalid')).toBe('2024-06'); // current month fallback expect(getPrevMonth('')).toBe('2024-06'); expect(getPrevMonth('2024-13')).toBe('2024-06'); expect(getPrevMonth('24-01')).toBe('2024-06'); }); it('handles edge cases', () => { expect(getPrevMonth('0001-01')).toBe('0001-12'); // date-fns handles year 0 differently expect(getPrevMonth('2024-00')).toBe('2024-06'); // invalid, returns current }); }); describe('getNextMonth', () => { it('calculates next month correctly', () => { expect(getNextMonth('2024-06')).toBe('2024-07'); expect(getNextMonth('2024-03')).toBe('2024-04'); expect(getNextMonth('2024-11')).toBe('2024-12'); }); it('handles year boundary correctly', () => { expect(getNextMonth('2024-12')).toBe('2025-01'); expect(getNextMonth('2023-12')).toBe('2024-01'); }); it('handles invalid input gracefully', () => { expect(getNextMonth('invalid')).toBe('2024-06'); // current month fallback expect(getNextMonth('')).toBe('2024-06'); expect(getNextMonth('2024-13')).toBe('2024-06'); expect(getNextMonth('24-01')).toBe('2024-06'); }); it('handles edge cases', () => { expect(getNextMonth('9999-12')).toBe('10000-01'); // theoretically valid expect(getNextMonth('2024-00')).toBe('2024-06'); // invalid, returns current }); }); describe('formatMonthForDisplay', () => { it('formats valid months correctly', () => { expect(formatMonthForDisplay('2024-01')).toBe('2024년 01월'); expect(formatMonthForDisplay('2024-06')).toBe('2024년 06월'); expect(formatMonthForDisplay('2024-12')).toBe('2024년 12월'); }); it('handles different years', () => { expect(formatMonthForDisplay('2023-03')).toBe('2023년 03월'); expect(formatMonthForDisplay('2025-09')).toBe('2025년 09월'); }); it('handles invalid input gracefully', () => { // Should return current date formatted when invalid input expect(formatMonthForDisplay('invalid')).toBe('2024년 06월'); expect(formatMonthForDisplay('')).toBe('2024년 06월'); expect(formatMonthForDisplay('2024-13')).toBe('2024년 06월'); }); it('preserves original format on error', () => { // For some edge cases, it might return the original string const result = formatMonthForDisplay('completely-invalid-format'); // Could be either the fallback format or the original string expect(typeof result).toBe('string'); expect(result.length).toBeGreaterThan(0); }); it('handles edge case years', () => { expect(formatMonthForDisplay('0001-01')).toBe('0001년 01월'); expect(formatMonthForDisplay('9999-12')).toBe('9999년 12월'); }); }); describe('month navigation sequences', () => { it('maintains consistency in forward/backward navigation', () => { const startMonth = '2024-06'; // Forward then backward should return to original const nextMonth = getNextMonth(startMonth); const backToPrev = getPrevMonth(nextMonth); expect(backToPrev).toBe(startMonth); // Backward then forward should return to original const prevMonth = getPrevMonth(startMonth); const backToNext = getNextMonth(prevMonth); expect(backToNext).toBe(startMonth); }); it('handles multiple month navigation', () => { let month = '2024-01'; // Navigate forward 12 months for (let i = 0; i < 12; i++) { month = getNextMonth(month); } expect(month).toBe('2025-01'); // Navigate backward 12 months for (let i = 0; i < 12; i++) { month = getPrevMonth(month); } expect(month).toBe('2024-01'); }); }); });