Files
accounted/lib/import/bank-file/__tests__/date-utils.test.ts
T
Jakob WennbergandClaude Opus 4.6 9753f18533 fix: address user feedback — RC preview, bank sync lookback, CSV import robustness (#233)
Three confirmed issues from user feedback:

1. Reverse charge preview now uses per-item VAT rates and correct accounts
   (2645/2647, 2614/2624/2634) instead of hardcoded 25%/2614
2. Bank sync uses 90-day lookback on first sync (when last_synced_at is null)
   instead of hardcoded 7 days for all syncs
3. Bank file import improvements:
   - Shared date normalizer supporting DD.MM.YYYY, DD/MM/YYYY, YYYYMMDD
   - Silent row skips now reported with reason in issues[]
   - Decimal separator mismatch detection in generic CSV
   - Swedish error message with format diagnostics on detection failure
   - Date format selector in column mapping UI

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 17:34:50 +02:00

93 lines
3.0 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import { normalizeDate } from '../date-utils'
describe('normalizeDate', () => {
// Pass-through for canonical format
it('passes through YYYY-MM-DD', () => {
expect(normalizeDate('2024-01-15')).toBe('2024-01-15')
expect(normalizeDate('2026-12-31')).toBe('2026-12-31')
})
// European dot format
it('normalizes DD.MM.YYYY', () => {
expect(normalizeDate('15.01.2024')).toBe('2024-01-15')
expect(normalizeDate('31.12.2026')).toBe('2026-12-31')
})
it('normalizes D.M.YYYY (single-digit day/month)', () => {
expect(normalizeDate('5.1.2024')).toBe('2024-01-05')
expect(normalizeDate('9.3.2025')).toBe('2025-03-09')
})
// European slash format
it('normalizes DD/MM/YYYY', () => {
expect(normalizeDate('15/01/2024')).toBe('2024-01-15')
expect(normalizeDate('31/12/2026')).toBe('2026-12-31')
})
it('normalizes D/M/YYYY (single-digit)', () => {
expect(normalizeDate('5/1/2024')).toBe('2024-01-05')
})
// US format with hint
it('normalizes MM/DD/YYYY when hint is provided', () => {
expect(normalizeDate('01/15/2024', 'MM/DD/YYYY')).toBe('2024-01-15')
expect(normalizeDate('12/31/2026', 'MM/DD/YYYY')).toBe('2026-12-31')
})
// Compact format
it('normalizes YYYYMMDD', () => {
expect(normalizeDate('20240115')).toBe('2024-01-15')
expect(normalizeDate('20261231')).toBe('2026-12-31')
})
// Slash year-first format
it('normalizes YYYY/MM/DD', () => {
expect(normalizeDate('2024/01/15')).toBe('2024-01-15')
expect(normalizeDate('2026/12/31')).toBe('2026-12-31')
})
// Whitespace handling
it('trims whitespace', () => {
expect(normalizeDate(' 2024-01-15 ')).toBe('2024-01-15')
expect(normalizeDate(' 15.01.2024 ')).toBe('2024-01-15')
})
// Invalid dates
it('returns null for empty/null/undefined', () => {
expect(normalizeDate('')).toBeNull()
expect(normalizeDate(null)).toBeNull()
expect(normalizeDate(undefined)).toBeNull()
expect(normalizeDate(' ')).toBeNull()
})
it('returns null for unrecognized formats', () => {
expect(normalizeDate('Jan 15, 2024')).toBeNull()
expect(normalizeDate('15-Jan-2024')).toBeNull()
expect(normalizeDate('abc')).toBeNull()
expect(normalizeDate('2024')).toBeNull()
})
it('returns null for invalid month', () => {
expect(normalizeDate('2024-13-01')).toBeNull()
expect(normalizeDate('2024-00-01')).toBeNull()
})
it('returns null for invalid day', () => {
expect(normalizeDate('2024-02-30')).toBeNull() // Feb 30 doesn't exist
expect(normalizeDate('2024-04-31')).toBeNull() // Apr has 30 days
expect(normalizeDate('2024-01-32')).toBeNull()
expect(normalizeDate('2024-01-00')).toBeNull()
})
it('handles leap year correctly', () => {
expect(normalizeDate('2024-02-29')).toBe('2024-02-29') // 2024 is leap year
expect(normalizeDate('2023-02-29')).toBeNull() // 2023 is not
})
it('returns null for years out of range', () => {
expect(normalizeDate('1899-01-01')).toBeNull()
expect(normalizeDate('2101-01-01')).toBeNull()
})
})