bambuddy/backend/tests/unit/test_printer_schema.py
maziggy 01787eb1e6 fix(printers): normalize serial numbers + diagnose connect-but-no-reports (#1465)
Reporter's H2C connected over MQTT+TLS but every status field stayed
  unknown. Root cause was layer-8: the MQTT broker is the printer, it
  authenticates on the access code and SUBACKs any topic string, so a
  wrong or mis-cased serial connects fine and silently receives nothing
  (the report topic device/<serial>/report is case-sensitive; Bambu
  serials are uppercase). Bambuddy stored and used the serial verbatim.

  - schemas/printer.py: field_validator strip()+upper()s serial_number on
    create, rejects blank-after-strip. The subscribed topic now always
    matches the printer's correctly-cased one.
  - bambu_mqtt.py: count report-topic messages per connection; when a
    stale reconnect fires with zero reports received, log a one-shot
    hint pointing at the serial number instead of looping silently.
2026-05-21 08:30:17 +02:00

42 lines
1.2 KiB
Python

"""Serial-number normalization on the printer schema (#1465).
Bambu serial numbers are uppercase alphanumeric and the MQTT report topic
``device/<serial>/report`` is case-sensitive. A serial entered in the wrong
case connects and subscribes without error but never receives a message, so
the schema normalizes it on input.
"""
import pytest
from pydantic import ValidationError
from backend.app.schemas.printer import PrinterCreate
def _make(serial: str) -> PrinterCreate:
return PrinterCreate(
name="Test Printer",
serial_number=serial,
ip_address="192.168.1.50",
access_code="12345678",
)
def test_serial_number_uppercased():
assert _make("01p00a3b1234567").serial_number == "01P00A3B1234567"
def test_serial_number_whitespace_stripped():
assert _make(" 01P00A3B1234567 ").serial_number == "01P00A3B1234567"
def test_serial_number_stripped_and_uppercased():
assert _make(" 31b8c0ca1234567 ").serial_number == "31B8C0CA1234567"
def test_already_normalized_serial_unchanged():
assert _make("31B8C0CA1234567").serial_number == "31B8C0CA1234567"
def test_blank_serial_number_rejected():
with pytest.raises(ValidationError):
_make(" ")