test_archive_print_plate.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. """The archive records which plate of a multi-plate file was printed.
  2. A print Bambuddy did not dispatch names its plate only in the gcode path the
  3. printer reports; a print Bambuddy did dispatch passes the plate explicitly,
  4. while the path may name none (some firmware reports the .3mf name there).
  5. """
  6. import zipfile
  7. import pytest
  8. from backend.app.core.config import settings
  9. from backend.app.models.printer import Printer
  10. from backend.app.services import archive as archive_module
  11. from backend.app.services.archive import ArchiveService
  12. def _three_mf(path, plates):
  13. with zipfile.ZipFile(path, "w") as zf:
  14. zf.writestr("3D/3dmodel.model", "<model/>")
  15. for n in plates:
  16. zf.writestr(f"Metadata/plate_{n}.gcode", "; gcode\n")
  17. return path
  18. @pytest.fixture
  19. def dirs(tmp_path, monkeypatch):
  20. monkeypatch.setattr(settings, "base_dir", tmp_path)
  21. monkeypatch.setattr(settings, "archive_dir", tmp_path / "archive")
  22. return tmp_path
  23. @pytest.fixture
  24. async def printer_id(db_session):
  25. row = Printer(name="X1C-1", ip_address="192.168.0.11", access_code="1234", serial_number="PLATETEST")
  26. db_session.add(row)
  27. await db_session.commit()
  28. return row.id
  29. @pytest.fixture
  30. def parsed_plates(monkeypatch):
  31. seen: list = []
  32. original = archive_module.ThreeMFParser
  33. class _Recording(original):
  34. def __init__(self, file_path, plate_number=None):
  35. seen.append(plate_number)
  36. super().__init__(file_path, plate_number=plate_number)
  37. monkeypatch.setattr(archive_module, "ThreeMFParser", _Recording)
  38. return seen
  39. @pytest.mark.asyncio
  40. async def test_plate_from_the_gcode_path_is_stored(db_session, dirs, printer_id):
  41. source = _three_mf(dirs / "multi.3mf", [1, 2, 3])
  42. archive = await ArchiveService(db_session).archive_print(
  43. printer_id, source, print_data={"filename": "/data/Metadata/plate_3.gcode"}
  44. )
  45. assert archive.plate_id == 3
  46. @pytest.mark.asyncio
  47. async def test_a_plate_the_file_does_not_have_is_not_stored(db_session, dirs, printer_id):
  48. source = _three_mf(dirs / "x_plate_2.gcode.3mf", [1])
  49. archive = await ArchiveService(db_session).archive_print(
  50. printer_id, source, print_data={"filename": "x_plate_2.gcode.3mf"}
  51. )
  52. assert archive.plate_id is None
  53. @pytest.mark.asyncio
  54. async def test_the_given_plate_wins_over_the_path(db_session, dirs, printer_id, parsed_plates):
  55. """The dispatcher knows the plate; the path can be stale (#1166)."""
  56. source = _three_mf(dirs / "multi.3mf", [1, 2, 3])
  57. archive = await ArchiveService(db_session).archive_print(
  58. printer_id, source, print_data={"filename": "/data/Metadata/plate_3.gcode"}, plate_id=2
  59. )
  60. assert archive.plate_id == 2
  61. assert parsed_plates == [2]
  62. @pytest.mark.asyncio
  63. async def test_the_given_plate_is_parsed_when_the_path_names_none(db_session, dirs, printer_id, parsed_plates):
  64. source = _three_mf(dirs / "multi.3mf", [1, 2, 3])
  65. await ArchiveService(db_session).archive_print(printer_id, source, print_data={"filename": "multi.3mf"}, plate_id=3)
  66. assert parsed_plates == [3]