fix(printers): Clear-Plate button delayed 30s–5min after print completes (#939 follow-up)

PR #939 added the awaiting_plate_clear gate but stored it on
  PrinterManager, not on PrinterState. printer_state_to_dict() — which
  builds every WebSocket printer_status payload — never emitted the flag,
  so the frontend's WS merge preserved the stale false value. The only
  path that surfaced true was the 30s HTTP fallback poll, and incoming WS
  ticks kept bumping React Query's dataUpdatedAt, pushing the refetch out
  further on chatty printers.

  Emit awaiting_plate_clear from printer_state_to_dict by reading
  printer_manager.is_awaiting_plate_clear(printer_id) directly; returns
  False when no id is passed. No frontend change needed — the existing WS
  merge carries the flag end-to-end and the button now appears the instant
  the printer transitions to FINISH.

  Regression tests assert the WS dict always contains the key and surfaces
  True when the manager has the flag set for that printer_id.

  Affects every printer (A1/H2D/X1C) equally — transport-agnostic path.
This commit is contained in:
maziggy
2026-04-21 18:10:02 +02:00
parent 597d961b0c
commit 4e86e8cb16
3 changed files with 25 additions and 0 deletions
@@ -966,6 +966,26 @@ class TestPrinterStateToDict:
assert tray["drying_temp"] == 55
assert tray["drying_time"] == 240
def test_awaiting_plate_clear_defaults_false(self, mock_state):
"""Without a printer_id, awaiting_plate_clear is False (no lookup possible)."""
result = printer_state_to_dict(mock_state)
assert result["awaiting_plate_clear"] is False
def test_awaiting_plate_clear_surfaced_when_set(self, mock_state):
"""With printer_id, awaiting_plate_clear reflects PrinterManager state.
Regression: PR #939 left this flag off the WebSocket payload, so the
"Clear Plate" button only appeared after the 30 s REST fallback poll.
"""
from backend.app.services.printer_manager import printer_manager
printer_manager.set_awaiting_plate_clear(12345, True)
try:
result = printer_state_to_dict(mock_state, printer_id=12345)
assert result["awaiting_plate_clear"] is True
finally:
printer_manager.set_awaiting_plate_clear(12345, False)
class TestStatusKeyDryingDedup:
"""Regression tests for WebSocket dedup including drying fields.