isPrinterCurrentlyDispatchable.test.ts 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /**
  2. * Tests for the shared "would ASAP mean now" predicate (#2849).
  3. *
  4. * Every print goes through the queue, so this is not "can we print at all" —
  5. * it is whether a queue item aimed at this printer starts immediately or
  6. * waits. The PrintModal uses it to promise a later start; the printer card
  7. * uses it to decide whether a dropped file says "Drop to print" or "Drop to
  8. * queue". They share it so the card cannot promise one thing and the modal
  9. * immediately contradict it.
  10. */
  11. import { describe, it, expect } from 'vitest';
  12. import type { PrinterStatus } from '../../api/client';
  13. import { isPrinterCurrentlyDispatchable } from '../../utils/printer';
  14. const status = (over: Partial<PrinterStatus> = {}): PrinterStatus =>
  15. ({ connected: true, state: 'IDLE', ...over }) as PrinterStatus;
  16. describe('isPrinterCurrentlyDispatchable', () => {
  17. it('accepts the states that can take a print right now', () => {
  18. for (const state of ['IDLE', 'FINISH', 'FAILED']) {
  19. expect(isPrinterCurrentlyDispatchable(status({ state }))).toBe(true);
  20. }
  21. });
  22. it('rejects a printer that is mid-print', () => {
  23. // The #2849 case: the drop is still allowed, it just queues.
  24. expect(isPrinterCurrentlyDispatchable(status({ state: 'RUNNING' }))).toBe(false);
  25. expect(isPrinterCurrentlyDispatchable(status({ state: 'PAUSE' }))).toBe(false);
  26. expect(isPrinterCurrentlyDispatchable(status({ state: 'PREPARE' }))).toBe(false);
  27. });
  28. it('rejects a disconnected printer whatever its last known state', () => {
  29. expect(isPrinterCurrentlyDispatchable(status({ connected: false, state: 'IDLE' }))).toBe(false);
  30. });
  31. it('rejects a printer still awaiting plate clear', () => {
  32. // FINISH alone would pass; the plate is physically in the way.
  33. expect(isPrinterCurrentlyDispatchable(status({ state: 'FINISH', awaiting_plate_clear: true }))).toBe(false);
  34. });
  35. it('rejects a printer whose AMS is drying', () => {
  36. expect(
  37. isPrinterCurrentlyDispatchable(status({ ams: [{ dry_time: 240 }] as PrinterStatus['ams'] }))
  38. ).toBe(false);
  39. });
  40. it('ignores a parked drying timer, which never ends on its own (#2896)', () => {
  41. expect(
  42. isPrinterCurrentlyDispatchable(
  43. status({ ams: [{ dry_time: 720, dry_countdown_stalled: true }] as PrinterStatus['ams'] })
  44. )
  45. ).toBe(true);
  46. // One unit really drying still holds the printer back.
  47. expect(
  48. isPrinterCurrentlyDispatchable(
  49. status({
  50. ams: [
  51. { dry_time: 720, dry_countdown_stalled: true },
  52. { dry_time: 240, dry_countdown_stalled: false },
  53. ] as PrinterStatus['ams'],
  54. })
  55. )
  56. ).toBe(false);
  57. });
  58. it('ignores an AMS that is loaded but not drying', () => {
  59. expect(
  60. isPrinterCurrentlyDispatchable(status({ ams: [{ dry_time: 0 }] as PrinterStatus['ams'] }))
  61. ).toBe(true);
  62. });
  63. it('treats an unknown or missing status as not dispatchable', () => {
  64. expect(isPrinterCurrentlyDispatchable(undefined)).toBe(false);
  65. expect(isPrinterCurrentlyDispatchable(status({ state: undefined }))).toBe(false);
  66. });
  67. });