import { describe, it, expect } from 'vitest'; import { render, screen } from '@testing-library/react'; import { computeBadgeState, FirmwareBadge } from '@/components/firmware/firmware-badge'; import type { Device } from '@/types/device'; function makeDevice(overrides: Partial = {}): Device { return { id: 'dev-1', name: 'KL520 #1', type: 'kneron_kl520', port: '/dev/usb0', status: 'connected', firmwareVersion: 'v2.2.0', bundledFirmwareVersion: 'v2.2.0', firmwareIsLegacy: false, firmwareCanUpgrade: false, ...overrides, }; } describe('computeBadgeState — AC-FW-1.1 4-color rule', () => { it('returns legacy when firmwareIsLegacy is true', () => { expect( computeBadgeState( makeDevice({ firmwareIsLegacy: true, firmwareVersion: 'KDP1' }), ), ).toBe('legacy'); }); it('returns unknown when firmwareVersion is missing', () => { expect(computeBadgeState(makeDevice({ firmwareVersion: '' }))).toBe('unknown'); }); it('returns unknown when bundledFirmwareVersion is missing or "unknown"', () => { expect( computeBadgeState(makeDevice({ bundledFirmwareVersion: '' })), ).toBe('unknown'); expect( computeBadgeState(makeDevice({ bundledFirmwareVersion: 'unknown' })), ).toBe('unknown'); }); it('returns current when firmwareVersion equals bundled', () => { expect(computeBadgeState(makeDevice())).toBe('current'); }); it('returns older when both KDP2 but versions differ', () => { expect( computeBadgeState( makeDevice({ firmwareVersion: 'KDP2.1.0', bundledFirmwareVersion: 'KDP2.2.0' }), ), ).toBe('older'); }); it('legacy precedence: if isLegacy=true, even with matching version returns legacy', () => { // 邊界 case:driver 端 isLegacy=true 但 firmwareVersion 又恰好等於 bundled // (理論不會發生、但若發生、isLegacy 優先)。 expect( computeBadgeState( makeDevice({ firmwareIsLegacy: true, firmwareVersion: 'v2.2.0' }), ), ).toBe('legacy'); }); }); describe('FirmwareBadge — renders correct state + a11y', () => { it('renders with data-state attribute matching computeBadgeState', () => { const { container } = render(); const el = container.querySelector('[data-testid="firmware-badge"]'); expect(el).not.toBeNull(); expect(el?.getAttribute('data-state')).toBe('current'); }); it('renders legacy badge with KDP1 label', () => { render( , ); const badge = screen.getByTestId('firmware-badge'); expect(badge.getAttribute('data-state')).toBe('legacy'); // 顯示 KDP1 文字(不是版本字串) expect(badge.textContent).toContain('KDP1'); }); it('renders unknown badge when firmwareVersion is missing', () => { render(); const badge = screen.getByTestId('firmware-badge'); expect(badge.getAttribute('data-state')).toBe('unknown'); }); it('has aria-label and title (tooltip)', () => { render(); const badge = screen.getByTestId('firmware-badge'); expect(badge.getAttribute('aria-label')).toBeTruthy(); expect(badge.getAttribute('title')).toBeTruthy(); }); });