from __future__ import annotations from pathlib import Path import pytest from yovision_brain.config import ConfigError, parse_input_config def valid_config() -> dict[str, object]: return { "schema": "brain.internal.input/v1", "logical_device_id": "synthetic-camera-01", "profile": {"id": "main", "width": 4, "height": 3, "fps": 5}, "source": {"kind": "synthetic", "seed": 17, "frame_count": 3}, "areas": [{"id": "danger-yard", "points": [[0.1, 0.1], [0.9, 0.1], [0.5, 0.8]]}], "directional_lines": [ { "id": "gate-line", "start": [0.2, 0.5], "end": [0.8, 0.5], "trigger_direction": "left_to_right", } ], } def test_parse_versioned_internal_config() -> None: parsed = parse_input_config(valid_config()) assert parsed.schema == "brain.internal.input/v1" assert parsed.logical_device_id == "synthetic-camera-01" assert parsed.profile.width == 4 assert parsed.areas[0].rule_id == "danger-yard" assert parsed.directional_lines[0].trigger_direction == "left_to_right" def test_relative_local_path_is_bound_to_explicit_base(tmp_path: Path) -> None: raw = valid_config() raw["source"] = {"kind": "local_file", "path": "fixture.bin", "chunk_size": 8} parsed = parse_input_config(raw, base_dir=tmp_path) assert parsed.source.path == tmp_path / "fixture.bin" @pytest.mark.parametrize( ("change", "message"), [ ({"schema": "shared.source/v1"}, "schema must be"), ({"logical_device_id": ""}, "logical_device_id"), ({"source": {"kind": "synthetic", "seed": 1, "frame_count": 0}}, "frame_count"), ({"password": "must-not-be-accepted"}, "credential field"), ], ) def test_invalid_or_secret_config_is_rejected(change: dict[str, object], message: str) -> None: raw = valid_config() raw.update(change) with pytest.raises(ConfigError, match=message): parse_input_config(raw) def test_coordinates_and_rule_ids_are_validated() -> None: raw = valid_config() raw["areas"] = [{"id": "same", "points": [[0, 0], [2, 0], [0, 1]]}] with pytest.raises(ConfigError, match="normalized"): parse_input_config(raw) raw = valid_config() raw["areas"] = [{"id": "same", "points": [[0, 0], [1, 0], [0, 1]]}] raw["directional_lines"] = [ {"id": "same", "start": [0, 0], "end": [1, 1], "trigger_direction": "left_to_right"} ] with pytest.raises(ConfigError, match="unique"): parse_input_config(raw)