test_design_settings_plates.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. """The plates endpoints must surface the designer's changed settings (#2622).
  2. Parsing is covered in ``unit/test_design_settings.py``. What is asserted here is
  3. the wiring: SliceModal reads ``design_overrides`` off the plates response, so a
  4. correct parser that never reaches the payload is a feature that silently does
  5. nothing.
  6. """
  7. import json
  8. import zipfile
  9. from pathlib import Path
  10. import pytest
  11. from httpx import AsyncClient
  12. def _designed_3mf(path: Path, *, with_deviations: bool = True) -> None:
  13. """A Bambu-style project 3MF, optionally carrying designer deviations."""
  14. config = {
  15. "print_settings_id": "0.20mm Standard @BBL A1",
  16. "printer_settings_id": "Bambu Lab A1 0.4 nozzle",
  17. "filament_settings_id": ["Bambu PLA Basic @BBL A1"],
  18. "wall_loops": "5",
  19. "outer_wall_speed": "200",
  20. "machine_start_gcode": "G28 ; designer printer",
  21. "different_settings_to_system": (
  22. ["wall_loops;outer_wall_speed", "", "machine_start_gcode"] if with_deviations else ["", "", ""]
  23. ),
  24. }
  25. with zipfile.ZipFile(path, "w", zipfile.ZIP_DEFLATED) as zf:
  26. zf.writestr("Metadata/plate_1.gcode", "G0\n")
  27. zf.writestr("Metadata/project_settings.config", json.dumps(config))
  28. @pytest.fixture
  29. def _patch_base_dir(monkeypatch, tmp_path):
  30. from backend.app.core.config import settings
  31. monkeypatch.setattr(settings, "base_dir", tmp_path)
  32. return tmp_path
  33. class TestArchivePlatesDesignOverrides:
  34. @pytest.mark.asyncio
  35. @pytest.mark.integration
  36. async def test_returns_the_process_deviations_with_classification(
  37. self, async_client: AsyncClient, archive_factory, printer_factory, _patch_base_dir
  38. ):
  39. _designed_3mf(_patch_base_dir / "designed.3mf")
  40. printer = await printer_factory()
  41. archive = await archive_factory(printer.id, filename="designed.3mf", file_path="designed.3mf")
  42. response = await async_client.get(f"/api/v1/archives/{archive.id}/plates")
  43. assert response.status_code == 200
  44. overrides = response.json()["design_overrides"]
  45. assert [o["key"] for o in overrides] == ["outer_wall_speed", "wall_loops"]
  46. by_key = {o["key"]: o for o in overrides}
  47. assert by_key["wall_loops"] == {
  48. "key": "wall_loops",
  49. "value": "5",
  50. "printer_coupled": False,
  51. "preset_defining": False,
  52. }
  53. assert by_key["outer_wall_speed"]["printer_coupled"] is True
  54. # The printer slot must never leak into the process list.
  55. assert "machine_start_gcode" not in by_key
  56. @pytest.mark.asyncio
  57. @pytest.mark.integration
  58. async def test_empty_for_a_file_that_changes_nothing(
  59. self, async_client: AsyncClient, archive_factory, printer_factory, _patch_base_dir
  60. ):
  61. _designed_3mf(_patch_base_dir / "stock.3mf", with_deviations=False)
  62. printer = await printer_factory()
  63. archive = await archive_factory(printer.id, filename="stock.3mf", file_path="stock.3mf")
  64. response = await async_client.get(f"/api/v1/archives/{archive.id}/plates")
  65. assert response.status_code == 200
  66. assert response.json()["design_overrides"] == []
  67. class TestLibraryPlatesDesignOverrides:
  68. @pytest.mark.asyncio
  69. @pytest.mark.integration
  70. async def test_returns_the_process_deviations(self, async_client: AsyncClient, db_session, tmp_path):
  71. from backend.app.models.library import LibraryFile
  72. path = tmp_path / "designed.3mf"
  73. _designed_3mf(path)
  74. lib_file = LibraryFile(
  75. filename="designed.3mf",
  76. file_path=str(path),
  77. file_type="3mf",
  78. file_size=path.stat().st_size,
  79. )
  80. db_session.add(lib_file)
  81. await db_session.commit()
  82. await db_session.refresh(lib_file)
  83. response = await async_client.get(f"/api/v1/library/files/{lib_file.id}/plates")
  84. assert response.status_code == 200
  85. assert [o["key"] for o in response.json()["design_overrides"]] == ["outer_wall_speed", "wall_loops"]