web/src/utils/timezone.test.js
Rama main · réplica de lectura del repositorio original.
import { describe, it, expect } from 'vitest'
import {
TIMEZONE_OPTIONS,
getBrowserTimezone,
isTimezoneInList,
getTimezoneOptions,
formatDateInTimezone,
formatDateTimeInTimezone,
getTodayInTimezone,
getTimezoneLabel,
} from './timezone'
describe('timezone utilities', () => {
describe('TIMEZONE_OPTIONS', () => {
it('should contain common timezones', () => {
expect(TIMEZONE_OPTIONS.length).toBeGreaterThan(10)
expect(TIMEZONE_OPTIONS.some(opt => opt.value === 'America/New_York')).toBe(true)
expect(TIMEZONE_OPTIONS.some(opt => opt.value === 'Europe/London')).toBe(true)
expect(TIMEZONE_OPTIONS.some(opt => opt.value === 'Asia/Tokyo')).toBe(true)
})
it('should have value and label for each option', () => {
TIMEZONE_OPTIONS.forEach(opt => {
expect(opt).toHaveProperty('value')
expect(opt).toHaveProperty('label')
expect(typeof opt.value).toBe('string')
expect(typeof opt.label).toBe('string')
})
})
})
describe('getBrowserTimezone', () => {
it('should return a string timezone', () => {
const tz = getBrowserTimezone()
expect(typeof tz).toBe('string')
expect(tz.length).toBeGreaterThan(0)
})
it('should return default timezone when Intl is unavailable', () => {
const originalIntl = global.Intl
global.Intl = undefined
const tz = getBrowserTimezone()
expect(tz).toBe('America/New_York')
global.Intl = originalIntl
})
})
describe('isTimezoneInList', () => {
it('should return true for timezones in the list', () => {
expect(isTimezoneInList('America/New_York')).toBe(true)
expect(isTimezoneInList('Europe/London')).toBe(true)
expect(isTimezoneInList('UTC')).toBe(true)
})
it('should return false for timezones not in the list', () => {
expect(isTimezoneInList('America/Phoenix')).toBe(false)
expect(isTimezoneInList('invalid/timezone')).toBe(false)
expect(isTimezoneInList('')).toBe(false)
})
})
describe('getTimezoneOptions', () => {
it('should return at least the curated options', () => {
const options = getTimezoneOptions()
expect(options.length).toBeGreaterThanOrEqual(TIMEZONE_OPTIONS.length)
})
it('should include all curated timezones', () => {
const options = getTimezoneOptions()
TIMEZONE_OPTIONS.forEach(curated => {
expect(options.some(opt => opt.value === curated.value)).toBe(true)
})
})
})
describe('formatDateInTimezone', () => {
it('should format a date with default format', () => {
const date = new Date('2024-06-15T12:00:00Z')
const formatted = formatDateInTimezone(date, 'UTC')
expect(formatted).toBe('Jun 15, 2024')
})
it('should format a date with custom format', () => {
const date = new Date('2024-06-15T12:00:00Z')
const formatted = formatDateInTimezone(date, 'UTC', 'yyyy-MM-dd')
expect(formatted).toBe('2024-06-15')
})
it('should handle string date input', () => {
const formatted = formatDateInTimezone('2024-06-15T12:00:00Z', 'UTC')
expect(formatted).toBe('Jun 15, 2024')
})
it('should return empty string for null/undefined input', () => {
expect(formatDateInTimezone(null, 'UTC')).toBe('')
expect(formatDateInTimezone(undefined, 'UTC')).toBe('')
})
it('should format dates differently based on timezone', () => {
// Use a time that straddles midnight between timezones
const date = new Date('2024-06-15T04:00:00Z')
const nyFormat = formatDateInTimezone(date, 'America/New_York', 'yyyy-MM-dd')
const tokyoFormat = formatDateInTimezone(date, 'Asia/Tokyo', 'yyyy-MM-dd')
// At 4am UTC: New York is midnight (June 15), Tokyo is 1pm (June 15)
expect(nyFormat).toBe('2024-06-15')
expect(tokyoFormat).toBe('2024-06-15')
})
})
describe('formatDateTimeInTimezone', () => {
it('should format date with time by default', () => {
const date = new Date('2024-06-15T15:30:00Z')
const formatted = formatDateTimeInTimezone(date, 'UTC')
expect(formatted).toBe('Jun 15, 2024 3:30 PM')
})
it('should accept custom format', () => {
const date = new Date('2024-06-15T15:30:00Z')
const formatted = formatDateTimeInTimezone(date, 'UTC', 'HH:mm')
expect(formatted).toBe('15:30')
})
})
describe('getTodayInTimezone', () => {
it('should return date in YYYY-MM-DD format', () => {
const today = getTodayInTimezone('UTC')
expect(today).toMatch(/^\d{4}-\d{2}-\d{2}$/)
})
it('should return valid date', () => {
const today = getTodayInTimezone('America/New_York')
const date = new Date(today)
expect(date.toString()).not.toBe('Invalid Date')
})
})
describe('getTimezoneLabel', () => {
it('should return label for known timezone', () => {
const label = getTimezoneLabel('America/New_York')
expect(label).toBe('(UTC-05:00) Eastern Time')
})
it('should return the timezone itself for unknown timezone', () => {
const label = getTimezoneLabel('America/Phoenix')
expect(label).toBe('America/Phoenix')
})
it('should return UTC label', () => {
const label = getTimezoneLabel('UTC')
expect(label).toBe('(UTC+00:00) UTC')
})
})
})