import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import { ProgressTracker } from '../ui/ProgressTracker'
describe('ProgressTracker', () => {
const mockOnShowTaskList = vi.fn()
beforeEach(() => {
vi.clearAllMocks()
})
describe('基礎渲染', () => {
it('應該正確顯示進度文字', () => {
render(
)
expect(screen.getByText('學習進度')).toBeInTheDocument()
expect(screen.getByText('測驗: 3/10')).toBeInTheDocument()
})
it('應該在沒有測驗時顯示 0/0', () => {
render(
)
expect(screen.getByText('測驗: 0/0')).toBeInTheDocument()
})
})
describe('進度百分比計算', () => {
it('應該正確計算進度百分比', () => {
render(
)
// 檢查進度條寬度 (50%) - 使用實際的 div 元素
const progressBar = document.querySelector('.bg-blue-500')
expect(progressBar).toHaveStyle({ width: '50%' })
})
it('應該處理 100% 完成的情況', () => {
render(
)
const progressBar = document.querySelector('.bg-blue-500')
expect(progressBar).toHaveStyle({ width: '100%' })
})
it('應該處理 0% 完成的情況', () => {
render(
)
const progressBar = document.querySelector('.bg-blue-500')
expect(progressBar).toHaveStyle({ width: '0%' })
})
it('應該處理除零情況 (totalTests = 0)', () => {
render(
)
const progressBar = document.querySelector('.bg-blue-500')
expect(progressBar).toHaveStyle({ width: '0%' })
})
})
describe('交互功能', () => {
it('應該在點擊按鈕時調用 onShowTaskList', () => {
render(
)
const button = screen.getByText('測驗: 3/10')
fireEvent.click(button)
expect(mockOnShowTaskList).toHaveBeenCalledTimes(1)
})
it('應該在點擊進度條時也調用 onShowTaskList', () => {
render(
)
const progressBarContainer = document.querySelector('.cursor-pointer.hover\\:bg-gray-300')
fireEvent.click(progressBarContainer!)
expect(mockOnShowTaskList).toHaveBeenCalledTimes(1)
})
})
describe('邊界值測試', () => {
it('應該處理負數輸入', () => {
render(
)
expect(screen.getByText('測驗: -1/5')).toBeInTheDocument()
})
it('應該處理 completedTests > totalTests 的情況', () => {
render(
)
expect(screen.getByText('測驗: 15/10')).toBeInTheDocument()
const progressBar = document.querySelector('.bg-blue-500')
expect(progressBar).toHaveStyle({ width: '150%' })
})
})
describe('可訪問性', () => {
it('應該有正確的 aria 屬性', () => {
render(
)
const button = screen.getByRole('button')
expect(button).toHaveAttribute('title', '點擊查看詳細進度')
})
it('應該有正確的進度條元素', () => {
render(
)
const progressBar = document.querySelector('.bg-blue-500')
expect(progressBar).toBeInTheDocument()
})
})
})