from __future__ import annotations from pathlib import Path import pytest from infra_controller.discovery import InfraMetadata def _write(path: Path, content: str) -> Path: path.write_text(content, encoding="utf-8") return path def test_infra_metadata_toml_valid(tmp_path: Path) -> None: p = _write( tmp_path / ".infra.toml", """ project = "my-app" [requires] services = ["grafana", "prometheus"] """.lstrip(), ) md = InfraMetadata.from_file(p) assert md.project == "my-app" assert md.requires["services"] == ["grafana", "prometheus"] def test_infra_metadata_yaml_valid_uses_dir_name_when_project_missing(tmp_path: Path) -> None: proj_dir = tmp_path / "some-app" proj_dir.mkdir() p = _write( proj_dir / ".infra.yml", """ requires: services: grafana """.lstrip(), ) md = InfraMetadata.from_file(p) assert md.project == "some-app" assert md.requires["services"] == "grafana" def test_infra_metadata_invalid_top_level(tmp_path: Path) -> None: p = _write(tmp_path / ".infra.yml", "- not-a-mapping\n") with pytest.raises(ValueError, match=r"expected mapping"): InfraMetadata.from_file(p) def test_infra_metadata_invalid_project(tmp_path: Path) -> None: p = _write( tmp_path / ".infra.toml", """ project = "bad name" [requires] services = "grafana" """.lstrip(), ) with pytest.raises(ValueError, match=r"Invalid 'project'"): InfraMetadata.from_file(p) def test_infra_metadata_invalid_requires_type(tmp_path: Path) -> None: p = _write( tmp_path / ".infra.yml", """ project: app requires: not-a-mapping """.lstrip(), ) with pytest.raises(ValueError, match=r"Invalid 'requires'"): InfraMetadata.from_file(p) @pytest.mark.parametrize( "services", [ "[]", "[\"\"]", "[1]", ], ) def test_infra_metadata_invalid_requires_services_list(tmp_path: Path, services: str) -> None: p = _write( tmp_path / ".infra.toml", ( "project = \"app\"\n\n" "[requires]\n" f"services = {services}\n" ), ) with pytest.raises(ValueError, match=r"requires\.services"): InfraMetadata.from_file(p) def test_infra_metadata_invalid_requires_services_type(tmp_path: Path) -> None: p = _write( tmp_path / ".infra.yml", """ project: app requires: services: 123 """.lstrip(), ) with pytest.raises(ValueError, match=r"requires\.services"): InfraMetadata.from_file(p)