SpoolIcon.test.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /**
  2. * Tests for SpoolIcon component:
  3. * - Renders SVG when not empty (with correct color)
  4. * - Renders dashed circle when isEmpty=true
  5. * - Respects size prop
  6. */
  7. import { describe, it, expect } from 'vitest';
  8. import { render } from '@testing-library/react';
  9. import React from 'react';
  10. import { SpoolIcon } from '../../../components/spoolbuddy/SpoolIcon';
  11. describe('SpoolIcon', () => {
  12. it('renders SVG when not empty', () => {
  13. const { container } = render(<SpoolIcon color="#FF0000" isEmpty={false} />);
  14. const svg = container.querySelector('svg');
  15. expect(svg).not.toBeNull();
  16. });
  17. it('renders SVG with correct color in fill', () => {
  18. const { container } = render(<SpoolIcon color="#00AE42" isEmpty={false} />);
  19. const circles = container.querySelectorAll('circle');
  20. // First circle has the color as fill
  21. expect(circles[0].getAttribute('fill')).toBe('#00AE42');
  22. });
  23. it('renders dashed circle when isEmpty=true', () => {
  24. const { container } = render(<SpoolIcon color="#FF0000" isEmpty={true} />);
  25. // No SVG, should be a div with border-dashed
  26. const svg = container.querySelector('svg');
  27. expect(svg).toBeNull();
  28. const div = container.firstElementChild as HTMLElement;
  29. expect(div.className).toContain('border-dashed');
  30. });
  31. it('uses default size of 32', () => {
  32. const { container } = render(<SpoolIcon color="#FF0000" isEmpty={false} />);
  33. const svg = container.querySelector('svg');
  34. expect(svg!.getAttribute('width')).toBe('32');
  35. expect(svg!.getAttribute('height')).toBe('32');
  36. });
  37. it('respects custom size prop', () => {
  38. const { container } = render(<SpoolIcon color="#FF0000" isEmpty={false} size={64} />);
  39. const svg = container.querySelector('svg');
  40. expect(svg!.getAttribute('width')).toBe('64');
  41. expect(svg!.getAttribute('height')).toBe('64');
  42. });
  43. it('respects custom size prop for empty spool', () => {
  44. const { container } = render(<SpoolIcon color="#FF0000" isEmpty={true} size={48} />);
  45. const div = container.firstElementChild as HTMLElement;
  46. expect(div.style.width).toBe('48px');
  47. expect(div.style.height).toBe('48px');
  48. });
  49. describe('a spool with extra colours or an effect (#3033)', () => {
  50. const dualColour = { rgba: '044482FF', extra_colors: '044482,f8d008', effect_type: 'dual-color' };
  51. it('paints the disc with the Filament page background instead of a flat fill', () => {
  52. const { container, getAllByTestId, getByTestId } = render(
  53. <SpoolIcon color="#044482" isEmpty={false} size={100} spool={dualColour} />,
  54. );
  55. expect(container.querySelector('svg')).toBeNull();
  56. // Painted once, so the colour bands run straight through both rings.
  57. const paint = getAllByTestId('spool-paint');
  58. expect(paint).toHaveLength(1);
  59. // Hard-split bars, both colours present.
  60. expect(paint[0].style.backgroundImage).toContain('linear-gradient(to right');
  61. expect(paint[0].style.backgroundImage).toContain('#f8d008');
  62. // The inner ring keeps the SVG disc's darker depth.
  63. expect(getByTestId('spool-shade').style.backgroundColor).toBe('rgba(0, 0, 0, 0.15)');
  64. const box = container.firstElementChild as HTMLElement;
  65. expect(box.style.width).toBe('100px');
  66. });
  67. it('paints an effect on a single-colour spool', () => {
  68. const { getAllByTestId } = render(
  69. <SpoolIcon color="#111111" isEmpty={false} spool={{ rgba: '111111FF', effect_type: 'galaxy' }} />,
  70. );
  71. const outer = getAllByTestId('spool-paint')[0];
  72. // Effect overlay on top of the colour layer on top of the checkerboard.
  73. expect(outer.style.backgroundImage.split('gradient(').length).toBeGreaterThan(3);
  74. });
  75. it('keeps the flat SVG disc for a plain spool', () => {
  76. const { container, queryAllByTestId } = render(
  77. <SpoolIcon color="#00AE42" isEmpty={false} spool={{ rgba: '00AE42FF', extra_colors: null, effect_type: null }} />,
  78. );
  79. expect(queryAllByTestId('spool-paint')).toHaveLength(0);
  80. expect(container.querySelector('circle')!.getAttribute('fill')).toBe('#00AE42');
  81. });
  82. it('still shows the empty state for an empty slot', () => {
  83. const { container, queryAllByTestId } = render(
  84. <SpoolIcon color="#044482" isEmpty={true} spool={dualColour} />,
  85. );
  86. expect(queryAllByTestId('spool-paint')).toHaveLength(0);
  87. expect((container.firstElementChild as HTMLElement).className).toContain('border-dashed');
  88. });
  89. });
  90. });