Files
F-r-ldraledigplannerare/frontend/tests/unit/utils/dates.test.ts
T
jacobh2 a4fce16dd1 Give a new account a first run, and drop to three tabs
Registering used to land you on a bare form asking for a child, with no hint
what came next. A short wizard now walks through the child, whether you are
planning alone or together, and where the day balances come from: fetched from
Försäkringskassan, entered by hand, or skipped — and if skipped, the figures
carry a badge saying they are estimates until real ones arrive.

Fetching is the first option rather than a hidden one, so the scraper is on by
default and the script that used to force it on no longer needs to.

Planning and Tips lose their tabs. Authoring moved to the calendar and the
figures moved to the overview, so both pages were only a second way to reach
what is already on screen; their routes now redirect rather than dead-end. The
dead translations went with them.

Dates also follow the chosen language now instead of always formatting as
Swedish.
2026-09-17 22:05:54 +02:00

227 lines
6.8 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import {
formatDateForDisplay,
formatDateForInput,
parseInputDate,
isValidDate,
getDayName,
getMonthName,
getISOWeekNumber,
formatHolidayName,
datesInRange,
} from '@/utils/dates'
describe('dates.ts utilities', () => {
describe('formatDateForDisplay', () => {
it('formats ISO string to Swedish display format', () => {
const result = formatDateForDisplay('2026-06-15')
expect(result).toBe('15 juni 2026')
})
it('formats Date object to Swedish display format', () => {
const date = new Date('2026-06-15T00:00:00Z')
const result = formatDateForDisplay(date)
expect(result).toBe('15 juni 2026')
})
it('handles January correctly', () => {
const result = formatDateForDisplay('2026-01-01')
expect(result).toBe('1 januari 2026')
})
it('handles December correctly', () => {
const result = formatDateForDisplay('2026-12-25')
expect(result).toBe('25 december 2026')
})
it('returns empty string for invalid date', () => {
const result = formatDateForDisplay('invalid')
expect(result).toBe('')
})
it('defaults to Swedish when no locale is passed', () => {
expect(formatDateForDisplay('2026-06-15')).toBe(formatDateForDisplay('2026-06-15', 'sv'))
})
it('formats in English when the "en" locale is passed', () => {
const result = formatDateForDisplay('2026-06-15', 'en')
expect(result).toBe('June 15, 2026')
})
it('formats in Swedish when the "sv" locale is explicitly passed', () => {
const result = formatDateForDisplay('2026-06-15', 'sv')
expect(result).toBe('15 juni 2026')
})
it('returns empty string for invalid date in the "en" locale too', () => {
expect(formatDateForDisplay('invalid', 'en')).toBe('')
})
})
describe('formatDateForInput', () => {
it('formats ISO string to input format', () => {
const result = formatDateForInput('2026-06-15')
expect(result).toBe('2026-06-15')
})
it('formats Date object to input format', () => {
const date = new Date('2026-06-15T00:00:00Z')
const result = formatDateForInput(date)
expect(result).toBe('2026-06-15')
})
it('pads month and day with zeros', () => {
const result = formatDateForInput('2026-01-05')
expect(result).toBe('2026-01-05')
})
it('returns empty string for invalid date', () => {
const result = formatDateForInput('invalid')
expect(result).toBe('')
})
})
describe('parseInputDate', () => {
it('parses ISO date string to Date object', () => {
const result = parseInputDate('2026-06-15')
expect(result).toBeInstanceOf(Date)
expect(result.toISOString()).toContain('2026-06-15')
})
it('creates valid Date for valid input', () => {
const result = parseInputDate('2026-06-15')
expect(isValidDate(result)).toBe(true)
})
})
describe('isValidDate', () => {
it('returns true for valid Date object', () => {
const date = new Date('2026-06-15')
expect(isValidDate(date)).toBe(true)
})
it('returns false for invalid Date', () => {
const date = new Date('invalid')
expect(isValidDate(date)).toBe(false)
})
it('returns false for non-Date values', () => {
expect(isValidDate('2026-06-15')).toBe(false)
expect(isValidDate(20260615)).toBe(false)
expect(isValidDate(null)).toBe(false)
expect(isValidDate(undefined)).toBe(false)
})
})
describe('getDayName', () => {
it('returns Swedish day name', () => {
const date = new Date('2026-06-15T00:00:00Z') // Monday
const result = getDayName(date)
expect(result.toLowerCase()).toBe('måndag')
})
it('returns empty string for invalid date', () => {
const result = getDayName(new Date('invalid'))
expect(result).toBe('')
})
})
describe('getMonthName', () => {
it('returns Swedish month name', () => {
const date = new Date('2026-06-15T00:00:00Z')
const result = getMonthName(date)
expect(result).toBe('juni')
})
it('returns correct month names for all months', () => {
const monthNames = [
'januari',
'februari',
'mars',
'april',
'maj',
'juni',
'juli',
'augusti',
'september',
'oktober',
'november',
'december',
]
monthNames.forEach((monthName, index) => {
const date = new Date(`2026-${String(index + 1).padStart(2, '0')}-15T00:00:00Z`)
const result = getMonthName(date)
expect(result).toBe(monthName)
})
})
it('returns empty string for invalid date', () => {
const result = getMonthName(new Date('invalid'))
expect(result).toBe('')
})
})
describe('getISOWeekNumber', () => {
it('returns 0 for an invalid date', () => {
expect(getISOWeekNumber(new Date('invalid'))).toBe(0)
})
it('computes the ISO week number for a mid-week date', () => {
// 2026-06-15 is a Monday.
expect(getISOWeekNumber(new Date('2026-06-15T00:00:00Z'))).toBe(25)
})
it('handles a Sunday correctly (getUTCDay() === 0 falls back to ISO day 7)', () => {
// 2026-01-11 is a Sunday, closing out ISO week 2 of 2026.
expect(getISOWeekNumber(new Date('2026-01-11T00:00:00Z'))).toBe(2)
})
})
describe('formatHolidayName', () => {
it('returns the name unchanged when it has no ";" segments', () => {
expect(formatHolidayName('Midsommardagen')).toBe('Midsommardagen')
})
it('strips a trailing weekday segment', () => {
expect(formatHolidayName('Påskdagen; Söndag')).toBe('Påskdagen')
})
it('falls back to the first segment when every segment is a weekday name', () => {
// Contrived input where nothing survives the weekday filter — the
// function must not return an empty string in that case.
expect(formatHolidayName('Söndag; Måndag')).toBe('Söndag')
})
})
describe('datesInRange', () => {
it('returns an empty array when the start date is invalid', () => {
expect(datesInRange('invalid', '2026-06-15')).toEqual([])
})
it('returns an empty array when the end date is invalid', () => {
expect(datesInRange('2026-06-15', 'invalid')).toEqual([])
})
it('returns the inclusive range in ascending order for start before end', () => {
expect(datesInRange('2026-06-01', '2026-06-03')).toEqual([
'2026-06-01',
'2026-06-02',
'2026-06-03',
])
})
it('returns the same range regardless of argument order (reversed input)', () => {
expect(datesInRange('2026-06-03', '2026-06-01')).toEqual([
'2026-06-01',
'2026-06-02',
'2026-06-03',
])
})
it('returns a single date when start equals end', () => {
expect(datesInRange('2026-06-01', '2026-06-01')).toEqual(['2026-06-01'])
})
})
})