"""Preferences must never be written outside the test scratch directory. The installed app reads ``apps/autocal/preference.json`` at startup. A test that builds a window and closes it saves preferences through ``closeEvent``, so a test that forgets to redirect the path rewrites the operator's real settings — which is exactly what happened: the finger screen started up pointing at a scratch bundle from a previous run and reported it as missing. ``conftest._isolate_preference_file`` is the net. These tests pin it, because a fixture that silently stopped applying would look like nothing at all until the app was next launched by hand. """ from __future__ import annotations from pathlib import Path import pytest APP_ROOT = Path(__file__).resolve().parents[1] INSTALLED = APP_ROOT / "preference.json" @pytest.mark.parametrize("stored", [{"calibrated": True}, {"zero_mm": 12.5, "calibrated": True}]) def test_loading_incomplete_press_calibration_does_not_invent_measurements(stored): import json from orisys_autocal import preferences from orisys_autocal.motion.pose_move import PressAxis Path(preferences.path()).write_text(json.dumps({"press_axis": stored}), encoding="utf-8") loaded = preferences.load_preferences() assert PressAxis.from_settings(loaded["press_axis"]).target_for(20) is None def test_the_preference_path_is_redirected_under_the_scratch_root(): from orisys_autocal.preferences import path resolved = Path(path()).resolve() scratch = (APP_ROOT / "outputs" / "_test_scratch").resolve() assert resolved != INSTALLED.resolve() assert scratch in resolved.parents, resolved def test_saving_preferences_leaves_the_installed_file_alone(): from orisys_autocal import preferences as prefs_mod before = INSTALLED.read_bytes() if INSTALLED.is_file() else None prefs = prefs_mod.default_preferences() prefs["finger_bundle_path"] = str(APP_ROOT / "outputs" / "_test_scratch" / "gone") written = Path(prefs_mod.save_preferences(prefs)).resolve() assert written != INSTALLED.resolve() assert written.is_file(), "the save did not reach the redirected file either" after = INSTALLED.read_bytes() if INSTALLED.is_file() else None assert after == before, "a test rewrote the installed preference.json" def test_a_window_that_closes_still_lands_in_the_scratch_directory(qt_app): """The failure mode itself: construct, close, check where it wrote.""" from orisys_autocal import preferences as prefs_mod from orisys_autocal.ui.window import AutoCalMainWindow before = INSTALLED.read_bytes() if INSTALLED.is_file() else None prefs = prefs_mod.default_preferences() prefs["finger_bundle_path"] = str(APP_ROOT / "outputs" / "_test_scratch" / "gone") window = AutoCalMainWindow(prefs=prefs, auto_load_bundle=False) try: window.poller.shutdown() window.close() finally: window.poller.shutdown() after = INSTALLED.read_bytes() if INSTALLED.is_file() else None assert after == before, "closing a test window rewrote the installed preferences" def test_a_stored_recording_block_without_the_newer_keys_gets_each_default(): """The upgrade path for the recording preference, through the same net. A stored ``recording`` block replaces the whole default block, exactly like ``safety_limits``: a codec or the lossless flag added later would otherwise read as absent and the recorder would be configured from a hole. """ import json from orisys_app_shared.paths import preference_path from orisys_autocal.preferences import load_preferences from orisys_autocal.recording_options import RecordingOptions, default_options path = preference_path() path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps({"recording": {"video": False}}), encoding="utf-8") options = default_options(load_preferences()) assert options == RecordingOptions(video=False) assert options.codec == "mp4v" assert options.lossless_frames is False