AssignSpoolModal.test.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import { describe, it, expect, vi, beforeEach } from 'vitest';
  2. import { screen, waitFor } from '@testing-library/react';
  3. import { render } from '../utils';
  4. import { AssignSpoolModal } from '../../components/AssignSpoolModal';
  5. import { api } from '../../api/client';
  6. vi.mock('../../api/client', () => ({
  7. api: {
  8. getSpools: vi.fn(),
  9. getAssignments: vi.fn(),
  10. assignSpool: vi.fn(),
  11. getSettings: vi.fn().mockResolvedValue({}),
  12. getAuthStatus: vi.fn().mockResolvedValue({ auth_enabled: false }),
  13. },
  14. }));
  15. const defaultProps = {
  16. isOpen: true,
  17. onClose: vi.fn(),
  18. printerId: 1,
  19. amsId: 0,
  20. trayId: 0,
  21. trayInfo: { type: 'PLA', color: 'FF0000', location: 'AMS 1 - Slot 1' },
  22. };
  23. const manualSpool = {
  24. id: 1,
  25. material: 'PLA',
  26. subtype: 'Basic',
  27. brand: 'Polymaker',
  28. color_name: 'Red',
  29. rgba: 'FF0000FF',
  30. label_weight: 1000,
  31. weight_used: 0,
  32. tag_uid: null,
  33. tray_uuid: null,
  34. };
  35. const blSpool = {
  36. id: 2,
  37. material: 'PLA',
  38. subtype: 'Basic',
  39. brand: 'Bambu',
  40. color_name: 'Jade White',
  41. rgba: 'FFFFFFFE',
  42. label_weight: 1000,
  43. weight_used: 50,
  44. tag_uid: '05CC1E0F00000100',
  45. tray_uuid: 'A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4',
  46. };
  47. const anotherManualSpool = {
  48. id: 3,
  49. material: 'PETG',
  50. subtype: 'HF',
  51. brand: 'Overture',
  52. color_name: 'Black',
  53. rgba: '000000FF',
  54. label_weight: 1000,
  55. weight_used: 200,
  56. tag_uid: null,
  57. tray_uuid: null,
  58. };
  59. describe('AssignSpoolModal', () => {
  60. beforeEach(() => {
  61. vi.clearAllMocks();
  62. (api.getSpools as ReturnType<typeof vi.fn>).mockResolvedValue([manualSpool, blSpool, anotherManualSpool]);
  63. (api.getAssignments as ReturnType<typeof vi.fn>).mockResolvedValue([]);
  64. });
  65. it('renders nothing when closed', () => {
  66. render(<AssignSpoolModal {...defaultProps} isOpen={false} />);
  67. expect(screen.queryByText('Assign Spool')).not.toBeInTheDocument();
  68. });
  69. it('filters out Bambu Lab spools (with tag_uid/tray_uuid)', async () => {
  70. render(<AssignSpoolModal {...defaultProps} />);
  71. await waitFor(() => {
  72. expect(screen.getByText(/Polymaker/)).toBeInTheDocument();
  73. });
  74. // Manual spools should be visible
  75. expect(screen.getByText(/Polymaker/)).toBeInTheDocument();
  76. expect(screen.getByText(/Overture/)).toBeInTheDocument();
  77. // BL spool should NOT be visible
  78. expect(screen.queryByText(/Jade White/)).not.toBeInTheDocument();
  79. });
  80. it('filters out spools already assigned to other slots', async () => {
  81. (api.getAssignments as ReturnType<typeof vi.fn>).mockResolvedValue([
  82. { id: 1, spool_id: 3, printer_id: 1, ams_id: 0, tray_id: 1 }, // spool 3 assigned to different slot
  83. ]);
  84. render(<AssignSpoolModal {...defaultProps} />);
  85. await waitFor(() => {
  86. expect(screen.getByText(/Polymaker/)).toBeInTheDocument();
  87. });
  88. // Spool 1 (not assigned) should be visible
  89. expect(screen.getByText(/Polymaker/)).toBeInTheDocument();
  90. // Spool 3 (assigned to another slot) should NOT be visible
  91. expect(screen.queryByText(/Overture/)).not.toBeInTheDocument();
  92. });
  93. it('keeps spool visible if assigned to the current slot', async () => {
  94. (api.getAssignments as ReturnType<typeof vi.fn>).mockResolvedValue([
  95. { id: 1, spool_id: 1, printer_id: 1, ams_id: 0, tray_id: 0 }, // spool 1 assigned to THIS slot
  96. ]);
  97. render(<AssignSpoolModal {...defaultProps} />);
  98. await waitFor(() => {
  99. expect(screen.getByText(/Polymaker/)).toBeInTheDocument();
  100. });
  101. // Spool 1 (assigned to current slot) should still be visible for re-assignment
  102. expect(screen.getByText(/Polymaker/)).toBeInTheDocument();
  103. });
  104. it('shows noManualSpools message when all spools are BL or assigned', async () => {
  105. (api.getSpools as ReturnType<typeof vi.fn>).mockResolvedValue([blSpool]);
  106. render(<AssignSpoolModal {...defaultProps} />);
  107. await waitFor(() => {
  108. expect(screen.getByText(/No manually added spools/i)).toBeInTheDocument();
  109. });
  110. });
  111. });