import { render, screen, fireEvent } from '@testing-library/react'
import { MeetingsList, type MeetingsListItem } from '../calendar/meetings-list'
const sampleMeetings: MeetingsListItem[] = [
{
id: 1,
title: 'Sequoia partner sync',
scheduled_at: '2026-04-29T16:00:00Z',
status: 'confirmed',
duration_minutes: 30,
investor_name: 'Roelof',
investor_email: 'roelof@sequoia.com',
meeting_link: 'https://meet.google.com/abc',
},
{
id: 2,
title: 'Acme intro',
scheduled_at: '2026-04-30T14:00:00Z',
status: 'pending',
duration_minutes: 45,
investor_email: 'partner@acme.vc',
},
]
describe('MeetingsList', () => {
it('renders each meeting title', () => {
render()
expect(screen.getByText('Sequoia partner sync')).toBeInTheDocument()
expect(screen.getByText('Acme intro')).toBeInTheDocument()
})
it('shows status badges per meeting', () => {
render()
expect(screen.getByText('Confirmed')).toBeInTheDocument()
expect(screen.getByText('Pending')).toBeInTheDocument()
})
it('shows duration when provided', () => {
render()
expect(screen.getByText(/· 30min/)).toBeInTheDocument()
expect(screen.getByText(/· 45min/)).toBeInTheDocument()
})
it('renders skeletons when loading', () => {
const { container } = render(
)
expect(container.querySelectorAll('.animate-pulse')).toHaveLength(6)
})
it('renders empty state with custom message', () => {
render()
expect(screen.getByText('Nothing yet')).toBeInTheDocument()
// No CTA without onSchedule
expect(screen.queryByText('Schedule First Meeting')).not.toBeInTheDocument()
})
it('shows the Schedule CTA when onSchedule provided + fires it', () => {
const onSchedule = jest.fn()
render()
fireEvent.click(screen.getByText('Schedule First Meeting'))
expect(onSchedule).toHaveBeenCalledTimes(1)
})
it('does NOT render delete button when onDelete is absent', () => {
render()
expect(screen.queryByLabelText('Delete meeting')).not.toBeInTheDocument()
})
it('renders delete buttons + fires onDelete with the meeting id', () => {
const onDelete = jest.fn()
render()
const deleteButtons = screen.getAllByLabelText('Delete meeting')
expect(deleteButtons).toHaveLength(2)
fireEvent.click(deleteButtons[0])
expect(onDelete).toHaveBeenCalledWith(1)
})
it('fires onRowClick with the meeting payload', () => {
const onRowClick = jest.fn()
render()
fireEvent.click(screen.getByText('Sequoia partner sync'))
expect(onRowClick).toHaveBeenCalledTimes(1)
expect(onRowClick.mock.calls[0][0].id).toBe(1)
})
it('does not fire onRowClick when delete button is clicked (event bubbling guard)', () => {
const onRowClick = jest.fn()
const onDelete = jest.fn()
render(
)
fireEvent.click(screen.getAllByLabelText('Delete meeting')[0])
expect(onDelete).toHaveBeenCalledTimes(1)
expect(onRowClick).not.toHaveBeenCalled()
})
it('renders Join link when meeting_link is set', () => {
render()
const joinLink = screen.getByTitle('Join meeting')
expect(joinLink).toHaveAttribute('href', 'https://meet.google.com/abc')
})
it("does NOT propagate row click when join link is clicked", () => {
const onRowClick = jest.fn()
render()
fireEvent.click(screen.getByTitle('Join meeting'))
expect(onRowClick).not.toHaveBeenCalled()
})
})