AiDetectionModal.test.tsx 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { describe, it, expect, afterEach, vi } from 'vitest';
  2. import { screen, waitFor } from '@testing-library/react';
  3. import { http, HttpResponse } from 'msw';
  4. import { render } from '../utils';
  5. import { server } from '../mocks/server';
  6. import { AiDetectionModal } from '../../components/AiDetectionModal';
  7. import { setAuthToken } from '../../api/client';
  8. const limitDetection = {
  9. class: 'error',
  10. frame_count: 0,
  11. print_quality: null,
  12. error: 'Remote quota error',
  13. error_code: 'OE_FREE_USAGE_LIMIT_REACHED',
  14. };
  15. afterEach(() => setAuthToken(null));
  16. describe('AiDetectionModal usage limit', () => {
  17. it('uses a structured printer error code and clears the notice when that printer recovers', async () => {
  18. const { rerender } = render(<AiDetectionModal printerName="X1 Carbon" detection={limitDetection} lastError={null} onClose={vi.fn()} />);
  19. expect(await screen.findByText('Usage limit reached.')).toBeInTheDocument();
  20. expect(screen.getByRole('link', { name: 'Set up billing to continue' })).toHaveAttribute('href', 'https://octoeverywhere.com/gadgetapi');
  21. expect(screen.queryByText('Remote quota error')).not.toBeInTheDocument();
  22. rerender(<AiDetectionModal printerName="X1 Carbon" detection={{ class: 'safe', frame_count: 1, print_quality: 10, error: null, error_code: null }} lastError={null} onClose={vi.fn()} />);
  23. expect(screen.queryByText('Usage limit reached.')).not.toBeInTheDocument();
  24. expect(screen.queryByRole('link', { name: /set up billing/i })).not.toBeInTheDocument();
  25. expect(screen.getByText('10/10')).toBeInTheDocument();
  26. });
  27. it('uses the global reason and code together when this printer has no error', async () => {
  28. render(<AiDetectionModal printerName="X1 Carbon" lastError="Remote global error" lastErrorCode="OE_FREE_USAGE_LIMIT_REACHED" onClose={vi.fn()} />);
  29. expect(await screen.findByText('Usage limit reached.')).toBeInTheDocument();
  30. expect(screen.getByRole('link', { name: 'Set up billing to continue' })).toBeInTheDocument();
  31. expect(screen.queryByText('Remote global error')).not.toBeInTheDocument();
  32. });
  33. it('does not attach another printer’s usage-limit code to this printer’s camera error', async () => {
  34. render(<AiDetectionModal
  35. printerName="X1 Carbon"
  36. detection={{ ...limitDetection, error: 'Camera unavailable', error_code: null }}
  37. lastError="Another printer reached its usage limit"
  38. lastErrorCode="OE_FREE_USAGE_LIMIT_REACHED"
  39. onClose={vi.fn()}
  40. />);
  41. expect(await screen.findByText('Camera unavailable')).toBeInTheDocument();
  42. expect(screen.queryByText('Usage limit reached.')).not.toBeInTheDocument();
  43. expect(screen.queryByRole('link', { name: /set up billing/i })).not.toBeInTheDocument();
  44. });
  45. it('does not infer a usage-limit error from unstructured text', async () => {
  46. render(<AiDetectionModal printerName="X1 Carbon" lastError="OE_FREE_USAGE_LIMIT_REACHED" onClose={vi.fn()} />);
  47. expect(await screen.findByText('OE_FREE_USAGE_LIMIT_REACHED')).toBeInTheDocument();
  48. expect(screen.queryByRole('link', { name: /set up billing/i })).not.toBeInTheDocument();
  49. });
  50. it.each([
  51. [[], false],
  52. [['settings:read'], true],
  53. ])('respects settings:read permission for quota details and the billing setup link (%j)', async (permissions, canRead) => {
  54. setAuthToken('test-token', 'session');
  55. server.use(
  56. http.get('*/api/v1/auth/status', () => HttpResponse.json({ auth_enabled: true, requires_setup: false })),
  57. http.get('*/api/v1/auth/me', () => HttpResponse.json({ id: 2, username: 'viewer', is_admin: false, permissions })),
  58. );
  59. render(<AiDetectionModal printerName="X1 Carbon" detection={limitDetection} lastError={null} onClose={vi.fn()} />);
  60. if (canRead) {
  61. expect(await screen.findByText('Usage limit reached.')).toBeInTheDocument();
  62. expect(screen.getByRole('link', { name: /set up billing/i })).toBeInTheDocument();
  63. } else {
  64. await waitFor(() => expect(screen.queryByText('Usage limit reached.')).not.toBeInTheDocument());
  65. expect(screen.queryByRole('link', { name: /set up billing/i })).not.toBeInTheDocument();
  66. }
  67. expect(screen.getByText('Not checking')).toBeInTheDocument();
  68. });
  69. });