/** * Tests for SpoolIcon component: * - Renders SVG when not empty (with correct color) * - Renders dashed circle when isEmpty=true * - Respects size prop */ import { describe, it, expect } from 'vitest'; import { render } from '@testing-library/react'; import React from 'react'; import { SpoolIcon } from '../../../components/spoolbuddy/SpoolIcon'; describe('SpoolIcon', () => { it('renders SVG when not empty', () => { const { container } = render(); const svg = container.querySelector('svg'); expect(svg).not.toBeNull(); }); it('renders SVG with correct color in fill', () => { const { container } = render(); const circles = container.querySelectorAll('circle'); // First circle has the color as fill expect(circles[0].getAttribute('fill')).toBe('#00AE42'); }); it('renders dashed circle when isEmpty=true', () => { const { container } = render(); // No SVG, should be a div with border-dashed const svg = container.querySelector('svg'); expect(svg).toBeNull(); const div = container.firstElementChild as HTMLElement; expect(div.className).toContain('border-dashed'); }); it('uses default size of 32', () => { const { container } = render(); const svg = container.querySelector('svg'); expect(svg!.getAttribute('width')).toBe('32'); expect(svg!.getAttribute('height')).toBe('32'); }); it('respects custom size prop', () => { const { container } = render(); const svg = container.querySelector('svg'); expect(svg!.getAttribute('width')).toBe('64'); expect(svg!.getAttribute('height')).toBe('64'); }); it('respects custom size prop for empty spool', () => { const { container } = render(); const div = container.firstElementChild as HTMLElement; expect(div.style.width).toBe('48px'); expect(div.style.height).toBe('48px'); }); describe('a spool with extra colours or an effect (#3033)', () => { const dualColour = { rgba: '044482FF', extra_colors: '044482,f8d008', effect_type: 'dual-color' }; it('paints the disc with the Filament page background instead of a flat fill', () => { const { container, getAllByTestId, getByTestId } = render( , ); expect(container.querySelector('svg')).toBeNull(); // Painted once, so the colour bands run straight through both rings. const paint = getAllByTestId('spool-paint'); expect(paint).toHaveLength(1); // Hard-split bars, both colours present. expect(paint[0].style.backgroundImage).toContain('linear-gradient(to right'); expect(paint[0].style.backgroundImage).toContain('#f8d008'); // The inner ring keeps the SVG disc's darker depth. expect(getByTestId('spool-shade').style.backgroundColor).toBe('rgba(0, 0, 0, 0.15)'); const box = container.firstElementChild as HTMLElement; expect(box.style.width).toBe('100px'); }); it('paints an effect on a single-colour spool', () => { const { getAllByTestId } = render( , ); const outer = getAllByTestId('spool-paint')[0]; // Effect overlay on top of the colour layer on top of the checkerboard. expect(outer.style.backgroundImage.split('gradient(').length).toBeGreaterThan(3); }); it('keeps the flat SVG disc for a plain spool', () => { const { container, queryAllByTestId } = render( , ); expect(queryAllByTestId('spool-paint')).toHaveLength(0); expect(container.querySelector('circle')!.getAttribute('fill')).toBe('#00AE42'); }); it('still shows the empty state for an empty slot', () => { const { container, queryAllByTestId } = render( , ); expect(queryAllByTestId('spool-paint')).toHaveLength(0); expect((container.firstElementChild as HTMLElement).className).toContain('border-dashed'); }); }); });