107 lines
3.5 KiB
TypeScript
107 lines
3.5 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { mount } from '@vue/test-utils'
|
|
import { createRouter, createMemoryHistory } from 'vue-router'
|
|
import EventCard from '../EventCard.vue'
|
|
|
|
const router = createRouter({
|
|
history: createMemoryHistory(),
|
|
routes: [
|
|
{ path: '/', component: { template: '<div />' } },
|
|
{ path: '/events/:eventToken', name: 'event', component: { template: '<div />' } },
|
|
],
|
|
})
|
|
|
|
function mountCard(props: Record<string, unknown> = {}) {
|
|
return mount(EventCard, {
|
|
props: {
|
|
eventToken: 'abc-123',
|
|
title: 'Birthday Party',
|
|
relativeTime: 'in 3 days',
|
|
isPast: false,
|
|
...props,
|
|
},
|
|
global: {
|
|
plugins: [router],
|
|
},
|
|
})
|
|
}
|
|
|
|
describe('EventCard', () => {
|
|
it('renders the event title', () => {
|
|
const wrapper = mountCard()
|
|
expect(wrapper.text()).toContain('Birthday Party')
|
|
})
|
|
|
|
it('renders relative time', () => {
|
|
const wrapper = mountCard({ relativeTime: 'yesterday' })
|
|
expect(wrapper.text()).toContain('yesterday')
|
|
})
|
|
|
|
it('links to the event detail page', () => {
|
|
const wrapper = mountCard({ eventToken: 'xyz-789' })
|
|
const link = wrapper.find('a')
|
|
expect(link.attributes('href')).toBe('/events/xyz-789')
|
|
})
|
|
|
|
it('applies past modifier class when isPast is true', () => {
|
|
const wrapper = mountCard({ isPast: true })
|
|
expect(wrapper.find('.event-card--past').exists()).toBe(true)
|
|
})
|
|
|
|
it('does not apply past modifier class when isPast is false', () => {
|
|
const wrapper = mountCard({ isPast: false })
|
|
expect(wrapper.find('.event-card--past').exists()).toBe(false)
|
|
})
|
|
|
|
it('renders organizer badge when eventRole is organizer', () => {
|
|
const wrapper = mountCard({ eventRole: 'organizer' })
|
|
expect(wrapper.text()).toContain('Organizing')
|
|
})
|
|
|
|
it('renders attendee badge when eventRole is attendee', () => {
|
|
const wrapper = mountCard({ eventRole: 'attendee' })
|
|
expect(wrapper.text()).toContain('Attending')
|
|
})
|
|
|
|
it('renders watcher badge when eventRole is watcher', () => {
|
|
const wrapper = mountCard({ eventRole: 'watcher' })
|
|
expect(wrapper.find('.event-card__badge--watcher').exists()).toBe(true)
|
|
expect(wrapper.text()).toContain('Watching')
|
|
})
|
|
|
|
it('renders no badge when eventRole is undefined', () => {
|
|
const wrapper = mountCard({ eventRole: undefined })
|
|
expect(wrapper.find('.event-card__badge').exists()).toBe(false)
|
|
})
|
|
|
|
it('emits delete event with eventToken when delete button is clicked', async () => {
|
|
const wrapper = mountCard({ eventToken: 'abc-123' })
|
|
await wrapper.find('.event-card__delete').trigger('click')
|
|
expect(wrapper.emitted('delete')).toEqual([['abc-123']])
|
|
})
|
|
|
|
it('displays clock time when timeDisplayMode is clock', () => {
|
|
const wrapper = mountCard({
|
|
timeDisplayMode: 'clock',
|
|
dateTime: '2026-03-11T18:30:00',
|
|
})
|
|
const timeText = wrapper.find('.event-card__time').text()
|
|
// Locale-dependent: could be "18:30" or "06:30 PM"
|
|
expect(timeText).toMatch(/(?:18.30|6.30\s*PM)/i)
|
|
})
|
|
|
|
it('displays relative time when timeDisplayMode is relative', () => {
|
|
const wrapper = mountCard({
|
|
relativeTime: '3 days ago',
|
|
timeDisplayMode: 'relative',
|
|
dateTime: '2026-03-08T10:00:00',
|
|
})
|
|
expect(wrapper.find('.event-card__time').text()).toBe('3 days ago')
|
|
})
|
|
|
|
it('falls back to relativeTime when timeDisplayMode is not set', () => {
|
|
const wrapper = mountCard({ relativeTime: 'in 3 days' })
|
|
expect(wrapper.find('.event-card__time').text()).toBe('in 3 days')
|
|
})
|
|
})
|