|
|
@@ -376,6 +376,84 @@ async def test_orca_cloud_unwraps_content():
|
|
|
svc_mock.close.assert_awaited_once()
|
|
|
|
|
|
|
|
|
+@pytest.mark.asyncio
|
|
|
+async def test_orca_cloud_string_lists_become_arrays():
|
|
|
+ """#3380: Orca Cloud returns list options INI-encoded. The sidecar only
|
|
|
+ adds a user printer preset's system parent to ``compatible_printers``
|
|
|
+ when it is an array, so they're forwarded as arrays, parsed the way the
|
|
|
+ slicer would: empty items keep their per-extruder positions. Other
|
|
|
+ options are left alone."""
|
|
|
+ db = MagicMock()
|
|
|
+ user = MagicMock()
|
|
|
+ user.has_permission = MagicMock(return_value=True)
|
|
|
+ svc_mock = MagicMock()
|
|
|
+ svc_mock.get_profile = AsyncMock(
|
|
|
+ return_value={
|
|
|
+ "content": {
|
|
|
+ "compatible_printers": '"Bambu Lab H2D 0.4 nozzle - Skew";"Bambu Lab X1 Carbon 0.4 nozzle"',
|
|
|
+ "compatible_prints": "",
|
|
|
+ "filament_type": "PLA",
|
|
|
+ "default_filament_colour": '"";"#FF0000"',
|
|
|
+ "compatible_printers_condition": '"bad" quote',
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+ svc_mock.close = AsyncMock()
|
|
|
+ with patch.object(preset_resolver, "_build_orca_service", AsyncMock(return_value=svc_mock)):
|
|
|
+ out = await preset_resolver._resolve_orca_cloud(
|
|
|
+ db, user, PresetRef(source="orca_cloud", id="abc"), slot="filament"
|
|
|
+ )
|
|
|
+ payload = json.loads(out)
|
|
|
+ assert payload["compatible_printers"] == ["Bambu Lab H2D 0.4 nozzle - Skew", "Bambu Lab X1 Carbon 0.4 nozzle"]
|
|
|
+ assert payload["compatible_prints"] == ""
|
|
|
+ assert payload["filament_type"] == ["PLA"]
|
|
|
+ assert payload["default_filament_colour"] == ["", "#FF0000"]
|
|
|
+ assert payload["compatible_printers_condition"] == '"bad" quote'
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.asyncio
|
|
|
+async def test_orca_cloud_unparseable_string_list_is_forwarded_as_is():
|
|
|
+ db = MagicMock()
|
|
|
+ user = MagicMock()
|
|
|
+ user.has_permission = MagicMock(return_value=True)
|
|
|
+ svc_mock = MagicMock()
|
|
|
+ svc_mock.get_profile = AsyncMock(return_value={"content": {"compatible_printers": '"X1C" junk'}})
|
|
|
+ svc_mock.close = AsyncMock()
|
|
|
+ with patch.object(preset_resolver, "_build_orca_service", AsyncMock(return_value=svc_mock)):
|
|
|
+ out = await preset_resolver._resolve_orca_cloud(
|
|
|
+ db, user, PresetRef(source="orca_cloud", id="abc"), slot="process"
|
|
|
+ )
|
|
|
+ assert json.loads(out)["compatible_printers"] == '"X1C" junk'
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.asyncio
|
|
|
+async def test_orca_cloud_json_array_lists_are_forwarded_unchanged():
|
|
|
+ """Only a string is INI-parsed: an array that already is one must not be
|
|
|
+ re-read, or its names would merge into one and the slice be refused."""
|
|
|
+ db = MagicMock()
|
|
|
+ user = MagicMock()
|
|
|
+ user.has_permission = MagicMock(return_value=True)
|
|
|
+ svc_mock = MagicMock()
|
|
|
+ svc_mock.get_profile = AsyncMock(
|
|
|
+ return_value={
|
|
|
+ "content": {
|
|
|
+ "compatible_printers": ["X1C 0.4", "H2C 0.4"],
|
|
|
+ "filament_type": ["PLA", "PETG"],
|
|
|
+ "default_filament_colour": ["", "#FF0000"],
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+ svc_mock.close = AsyncMock()
|
|
|
+ with patch.object(preset_resolver, "_build_orca_service", AsyncMock(return_value=svc_mock)):
|
|
|
+ out = await preset_resolver._resolve_orca_cloud(
|
|
|
+ db, user, PresetRef(source="orca_cloud", id="abc"), slot="filament"
|
|
|
+ )
|
|
|
+ payload = json.loads(out)
|
|
|
+ assert payload["compatible_printers"] == ["X1C 0.4", "H2C 0.4"]
|
|
|
+ assert payload["filament_type"] == ["PLA", "PETG"]
|
|
|
+ assert payload["default_filament_colour"] == ["", "#FF0000"]
|
|
|
+
|
|
|
+
|
|
|
@pytest.mark.asyncio
|
|
|
async def test_orca_cloud_auth_error_returns_401():
|
|
|
db = MagicMock()
|