forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1import { beforeEach, describe, expect, it, vi } from 'vitest'
2import { mountSuspended } from '@nuxt/test-utils/runtime'
3import DateTime from '~/components/DateTime.vue'
4
5// Mock the useRelativeDates composable
6const mockRelativeDates = shallowRef(false)
7vi.mock('~/composables/useSettings', () => ({
8 useRelativeDates: () => mockRelativeDates,
9 useSettings: () => ({
10 settings: ref({ relativeDates: mockRelativeDates.value }),
11 }),
12 useAccentColor: () => ({}),
13}))
14
15describe('DateTime', () => {
16 const testDate = '2024-01-15T12:00:00.000Z'
17 const testDateObject = new Date('2024-06-15T10:30:00.000Z')
18 const testYear = testDateObject.getUTCFullYear()
19
20 beforeEach(() => {
21 mockRelativeDates.value = false
22 })
23
24 describe('props handling', () => {
25 it('accepts datetime as ISO string', async () => {
26 const component = await mountSuspended(DateTime, {
27 props: { datetime: testDate },
28 })
29 expect(component.html()).toContain('time')
30 })
31
32 it('accepts datetime as Date object', async () => {
33 const component = await mountSuspended(DateTime, {
34 props: { datetime: testDateObject },
35 })
36 expect(component.html()).toContain('time')
37 })
38
39 it('passes date-style prop to NuxtTime', async () => {
40 const component = await mountSuspended(DateTime, {
41 props: {
42 datetime: testDate,
43 dateStyle: 'medium',
44 },
45 })
46 // The component should render with the specified dateStyle
47 expect(component.html()).toBeTruthy()
48 })
49
50 it('passes individual date parts to NuxtTime', async () => {
51 const component = await mountSuspended(DateTime, {
52 props: {
53 datetime: testDate,
54 year: 'numeric',
55 month: 'short',
56 day: 'numeric',
57 },
58 })
59 expect(component.html()).toBeTruthy()
60 })
61 })
62
63 describe('title attribute', () => {
64 it('has title with formatted date by default', async () => {
65 const component = await mountSuspended(DateTime, {
66 props: { datetime: testDate },
67 })
68 const timeEl = component.find('time')
69 expect(timeEl.attributes('title')).toContain(testYear)
70 })
71
72 it('uses custom title when provided', async () => {
73 const customTitle = 'Custom date title'
74 const component = await mountSuspended(DateTime, {
75 props: {
76 datetime: testDate,
77 title: customTitle,
78 },
79 })
80 const timeEl = component.find('time')
81 expect(timeEl.attributes('title')).toBe(customTitle)
82 })
83
84 it('converts Date object to formatted date in title', async () => {
85 const component = await mountSuspended(DateTime, {
86 props: { datetime: testDateObject },
87 })
88 const timeEl = component.find('time')
89 expect(timeEl.attributes('title')).toContain(testYear)
90 })
91 })
92
93 describe('relative dates setting', () => {
94 it('renders absolute date when relativeDates is false', async () => {
95 mockRelativeDates.value = false
96 const component = await mountSuspended(DateTime, {
97 props: {
98 datetime: testDate,
99 dateStyle: 'medium',
100 },
101 })
102 // Should not have the "relative" attribute behavior
103 // The NuxtTime component will render with date formatting
104 expect(component.html()).toContain('time')
105 })
106
107 it('renders with relative prop when relativeDates is true', async () => {
108 mockRelativeDates.value = true
109 const component = await mountSuspended(DateTime, {
110 props: { datetime: testDate },
111 })
112 // Component should still render a time element
113 expect(component.html()).toContain('time')
114 })
115
116 it('always preserves title attribute for accessibility regardless of mode', async () => {
117 // Test with relative dates off
118 mockRelativeDates.value = false
119 let component = await mountSuspended(DateTime, {
120 props: { datetime: testDate },
121 })
122 expect(component.find('time').attributes('title')).toContain(testYear)
123
124 // Test with relative dates on
125 mockRelativeDates.value = true
126 component = await mountSuspended(DateTime, {
127 props: { datetime: testDate },
128 })
129 expect(component.find('time').attributes('title')).toContain(testYear)
130 })
131 })
132
133 describe('SSR fallback', () => {
134 it('renders time element in fallback (SSR) mode', async () => {
135 // The ClientOnly component has a fallback slot for SSR
136 // This test ensures the fallback renders correctly
137 const component = await mountSuspended(DateTime, {
138 props: {
139 datetime: testDate,
140 dateStyle: 'medium',
141 },
142 })
143 // Should have a time element rendered
144 expect(component.find('time').exists()).toBe(true)
145 })
146 })
147})