| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- """The tray-change log has to leave the process.
- ``PrinterState.tray_change_log`` is what the usage tracker splits filament
- weight on when AMS filament backup swaps in a fresh spool mid-print. It lived
- only in memory, so a restart during a long print erased the segment boundaries
- and the whole job got charged to the tray that finished it. The client now
- reports every appended entry so main.py can persist it.
- """
- import pytest
- from backend.app.services.bambu_mqtt import BambuMQTTClient
- def _tray_msg(tray_now: int):
- """A partial AMS update carrying only tray_now, as P-series and H2D send."""
- return {"print": {"ams": {"tray_now": str(tray_now)}}}
- class TestTrayChangeCallback:
- @pytest.fixture
- def mqtt_client(self):
- client = BambuMQTTClient(
- ip_address="192.168.1.100",
- serial_number="TEST123",
- access_code="12345678",
- )
- client._was_running = True
- client._completion_triggered = False
- return client
- def test_every_logged_change_is_reported(self, mqtt_client):
- seen: list[tuple[int, int]] = []
- mqtt_client.on_tray_change = lambda tray, layer: seen.append((tray, layer))
- mqtt_client.state.layer_num = 0
- mqtt_client._process_message(_tray_msg(2))
- mqtt_client.state.layer_num = 670
- mqtt_client._process_message(_tray_msg(254))
- mqtt_client.state.layer_num = 675
- mqtt_client._process_message(_tray_msg(3))
- assert seen == [(2, 0), (254, 670), (3, 675)]
- assert mqtt_client.state.tray_change_log == [(2, 0), (254, 670), (3, 675)]
- def test_repeat_of_the_same_tray_is_not_reported(self, mqtt_client):
- """The printer republishes tray_now on every push; only transitions
- are segment boundaries."""
- seen: list[tuple[int, int]] = []
- mqtt_client.on_tray_change = lambda tray, layer: seen.append((tray, layer))
- mqtt_client._process_message(_tray_msg(2))
- mqtt_client.state.layer_num = 40
- mqtt_client._process_message(_tray_msg(2))
- assert seen == [(2, 0)]
- def test_no_callback_outside_a_running_print(self, mqtt_client):
- seen: list[tuple[int, int]] = []
- mqtt_client.on_tray_change = lambda tray, layer: seen.append((tray, layer))
- mqtt_client._was_running = False
- mqtt_client._process_message(_tray_msg(2))
- assert seen == []
- assert mqtt_client.state.tray_change_log == []
- def test_missing_callback_does_not_break_logging(self, mqtt_client):
- """The callback is optional — the in-memory log still has to work."""
- mqtt_client.on_tray_change = None
- mqtt_client._process_message(_tray_msg(2))
- assert mqtt_client.state.tray_change_log == [(2, 0)]
|