import { render, screen, fireEvent } from '@testing-library/react' import { describe, test, expect, vi } from 'vitest' import React from 'react' import { DocumentCard, NewDocumentCard } from '../../../src/components/project-tasks/DocumentCard' import type { ProjectDoc } from '../../../src/components/project-tasks/DocumentCard' describe('DocumentCard', () => { const mockDocument: ProjectDoc = { id: 'doc-1', title: 'Test Document', content: { test: 'content' }, document_type: 'prp', updated_at: '2025-07-30T12:00:00Z', } const mockHandlers = { onSelect: vi.fn(), onDelete: vi.fn(), } beforeEach(() => { vi.clearAllMocks() }) test('renders document card with correct content', () => { render( ) expect(screen.getByText('Test Document')).toBeInTheDocument() expect(screen.getByText('prp')).toBeInTheDocument() expect(screen.getByText('7/30/2025')).toBeInTheDocument() }) test('shows correct icon and color for different document types', () => { const documentTypes = [ { type: 'prp', expectedClass: 'text-blue-600' }, { type: 'technical', expectedClass: 'text-green-600' }, { type: 'business', expectedClass: 'text-purple-600' }, { type: 'meeting_notes', expectedClass: 'text-orange-600' }, ] documentTypes.forEach(({ type, expectedClass }) => { const { container, rerender } = render( ) const badge = container.querySelector(`.${expectedClass}`) expect(badge).toBeInTheDocument() }) }) test('applies active styles when selected', () => { const { container } = render( ) const card = container.firstChild as HTMLElement expect(card.className).toContain('border-blue-500') expect(card.className).toContain('scale-105') }) test('calls onSelect when clicked', () => { render( ) const card = screen.getByText('Test Document').closest('div') fireEvent.click(card!) expect(mockHandlers.onSelect).toHaveBeenCalledWith(mockDocument) }) test('shows delete button on hover', () => { const { container } = render( ) const card = container.firstChild as HTMLElement // Delete button should not be visible initially expect(screen.queryByLabelText('Delete Test Document')).not.toBeInTheDocument() // Hover over the card fireEvent.mouseEnter(card) // Delete button should now be visible expect(screen.getByLabelText('Delete Test Document')).toBeInTheDocument() // Mouse leave fireEvent.mouseLeave(card) // Delete button should be hidden again expect(screen.queryByLabelText('Delete Test Document')).not.toBeInTheDocument() }) test('does not show delete button on active card', () => { const { container } = render( ) const card = container.firstChild as HTMLElement fireEvent.mouseEnter(card) expect(screen.queryByLabelText('Delete Test Document')).not.toBeInTheDocument() }) test('confirms before deleting', () => { const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(true) const { container } = render( ) const card = container.firstChild as HTMLElement fireEvent.mouseEnter(card) const deleteButton = screen.getByLabelText('Delete Test Document') fireEvent.click(deleteButton) expect(confirmSpy).toHaveBeenCalledWith('Delete "Test Document"?') expect(mockHandlers.onDelete).toHaveBeenCalledWith('doc-1') confirmSpy.mockRestore() }) test('cancels delete when user declines', () => { const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(false) const { container } = render( ) const card = container.firstChild as HTMLElement fireEvent.mouseEnter(card) const deleteButton = screen.getByLabelText('Delete Test Document') fireEvent.click(deleteButton) expect(confirmSpy).toHaveBeenCalled() expect(mockHandlers.onDelete).not.toHaveBeenCalled() confirmSpy.mockRestore() }) test('applies dark mode styles correctly', () => { const { container } = render( ) const card = container.firstChild as HTMLElement expect(card.className).toContain('dark:') }) }) describe('NewDocumentCard', () => { test('renders new document card', () => { const onClick = vi.fn() render() expect(screen.getByText('New Document')).toBeInTheDocument() }) test('calls onClick when clicked', () => { const onClick = vi.fn() render() const card = screen.getByText('New Document').closest('div') fireEvent.click(card!) expect(onClick).toHaveBeenCalledTimes(1) }) })