PrintModalDispatchToast.test.tsx 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /**
  2. * Test that reprint mode does not show the "Print queued for printer" toast.
  3. * The background dispatch websocket toast handles feedback instead.
  4. *
  5. * Separate file because vi.mock(ToastContext) must be module-scoped
  6. * and would interfere with the main PrintModal test suite.
  7. */
  8. import { describe, it, expect, vi, beforeEach } from 'vitest';
  9. import { screen, waitFor } from '@testing-library/react';
  10. import userEvent from '@testing-library/user-event';
  11. import { http, HttpResponse } from 'msw';
  12. import { server } from '../mocks/server';
  13. // Mock the toast context before importing the component
  14. const mockShowToast = vi.fn();
  15. vi.mock('../../contexts/ToastContext', async (importOriginal) => {
  16. const actual = await importOriginal<typeof import('../../contexts/ToastContext')>();
  17. return {
  18. ...actual,
  19. useToast: () => ({ showToast: mockShowToast }),
  20. };
  21. });
  22. import { render } from '../utils';
  23. import { PrintModal } from '../../components/PrintModal';
  24. const mockPrinters = [
  25. { id: 1, name: 'X1 Carbon', model: 'X1C', ip_address: '192.168.1.100', enabled: true, is_active: true },
  26. ];
  27. describe('PrintModal dispatch toast', () => {
  28. const mockOnClose = vi.fn();
  29. const mockOnSuccess = vi.fn();
  30. beforeEach(() => {
  31. vi.clearAllMocks();
  32. server.use(
  33. http.get('/api/v1/printers/', () => {
  34. return HttpResponse.json(mockPrinters);
  35. }),
  36. http.get('/api/v1/archives/:id/plates', () => {
  37. return HttpResponse.json({ is_multi_plate: false, plates: [] });
  38. }),
  39. http.get('/api/v1/archives/:id/filament-requirements', () => {
  40. return HttpResponse.json({ filaments: [] });
  41. }),
  42. http.get('/api/v1/printers/:id/status', () => {
  43. return HttpResponse.json({ connected: true, state: 'IDLE', ams: [], vt_tray: [] });
  44. }),
  45. http.post('/api/v1/archives/:id/reprint', () => {
  46. return HttpResponse.json({ status: 'dispatched', dispatch_job_id: 1 });
  47. }),
  48. );
  49. });
  50. it('does not show "queued" toast in reprint mode (dispatch toast handles it)', async () => {
  51. const user = userEvent.setup();
  52. render(
  53. <PrintModal
  54. mode="reprint"
  55. archiveId={1}
  56. archiveName="Benchy"
  57. onClose={mockOnClose}
  58. onSuccess={mockOnSuccess}
  59. />
  60. );
  61. // Wait for printers to load, then select one
  62. await waitFor(() => {
  63. expect(screen.getByText('X1 Carbon')).toBeInTheDocument();
  64. });
  65. await user.click(screen.getByText('X1 Carbon'));
  66. // Submit the print
  67. const printButton = screen.getByRole('button', { name: /^print$/i });
  68. await user.click(printButton);
  69. // Wait for the API call to complete and modal to close
  70. await waitFor(() => {
  71. expect(mockOnClose).toHaveBeenCalled();
  72. });
  73. // showToast should NOT have been called with "Print queued for printer"
  74. const toastMessages = mockShowToast.mock.calls.map(call => call[0]);
  75. expect(toastMessages).not.toContain('Print queued for printer');
  76. });
  77. });