SettingsPagePauseWarning.test.tsx 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * How long before a slicer pause the "Pause Coming Up" notification goes out
  3. * (#2984): a setting next to the bed-cooled threshold, saved as whole minutes
  4. * within what the server accepts.
  5. */
  6. import { describe, it, expect, beforeEach, vi } from 'vitest';
  7. import { fireEvent, screen, waitFor } from '@testing-library/react';
  8. import { render } from '../utils';
  9. import { SettingsPage } from '../../pages/SettingsPage';
  10. import { http, HttpResponse } from 'msw';
  11. import { server } from '../mocks/server';
  12. import { setAuthToken } from '../../api/client';
  13. const settings = {
  14. auto_archive: true,
  15. currency: 'USD',
  16. time_format: 'system',
  17. date_format: 'system',
  18. check_updates: false,
  19. check_printer_firmware: false,
  20. bed_cooled_threshold: 35,
  21. pause_warning_minutes: 5,
  22. // Set, so the page has no detected address of its own to save with any edit.
  23. external_url: window.location.origin,
  24. };
  25. let saved: Array<Record<string, unknown>>;
  26. beforeEach(() => {
  27. window.history.replaceState({}, '', '/?tab=notifications');
  28. vi.mocked(localStorage.getItem).mockReset();
  29. setAuthToken(null);
  30. saved = [];
  31. server.use(
  32. http.get('/api/v1/settings/', () => HttpResponse.json(settings)),
  33. http.put('/api/v1/settings/', async ({ request }) => {
  34. const body = (await request.json()) as Record<string, unknown>;
  35. saved.push(body);
  36. return HttpResponse.json({ ...settings, ...body });
  37. }),
  38. http.get('/api/v1/printers/', () => HttpResponse.json([])),
  39. http.get('/api/v1/notifications/', () => HttpResponse.json([])),
  40. http.get('/api/v1/auth/status', () => HttpResponse.json({ auth_enabled: false, requires_setup: false })),
  41. );
  42. });
  43. async function field() {
  44. const input = (await screen.findByLabelText('Pause Heads-Up')) as HTMLInputElement;
  45. // Let the loaded settings land first; a change before that is overwritten.
  46. await new Promise(resolve => setTimeout(resolve, 200));
  47. return input;
  48. }
  49. describe('SettingsPage - pause heads-up minutes (#2984)', () => {
  50. it('shows the saved value, and saves nothing unchanged', async () => {
  51. render(<SettingsPage />);
  52. expect((await field()).value).toBe('5');
  53. await new Promise(resolve => setTimeout(resolve, 1000));
  54. expect(saved).toEqual([]);
  55. });
  56. it('saves a changed value', async () => {
  57. render(<SettingsPage />);
  58. fireEvent.change(await field(), { target: { value: '15' } });
  59. await waitFor(() => expect(saved.at(-1)?.pause_warning_minutes).toBe(15), { timeout: 3000 });
  60. });
  61. it('saves an out-of-range value within 1-120', async () => {
  62. render(<SettingsPage />);
  63. fireEvent.change(await field(), { target: { value: '500' } });
  64. await waitFor(() => expect(saved.at(-1)?.pause_warning_minutes).toBe(120), { timeout: 3000 });
  65. });
  66. it('saves an out-of-range value once, and shows what was saved on leaving the field', async () => {
  67. render(<SettingsPage />);
  68. const input = await field();
  69. fireEvent.change(input, { target: { value: '500' } });
  70. await waitFor(() => expect(saved).toHaveLength(1), { timeout: 3000 });
  71. // The server holds 120 now; 500 in the field must not read as a change
  72. // still to save, or the page saves it again and again.
  73. await new Promise(resolve => setTimeout(resolve, 1500));
  74. expect(saved).toHaveLength(1);
  75. fireEvent.blur(input);
  76. expect(input.value).toBe('120');
  77. });
  78. it('an emptied field is the default: nothing to save, and it shows 5 on leaving', async () => {
  79. render(<SettingsPage />);
  80. const input = await field();
  81. fireEvent.change(input, { target: { value: '' } });
  82. await new Promise(resolve => setTimeout(resolve, 1000));
  83. expect(saved).toEqual([]);
  84. fireEvent.blur(input);
  85. expect(input.value).toBe('5');
  86. });
  87. });