from pathlib import Path import pytest from pydantic import ValidationError from modelforge_api.domain.contracts import ProjectManifest from modelforge_api.services.manifest_registry import PROJECT_ROOT, ManifestRegistry def test_repository_manifests_are_valid_and_model_independent() -> None: registry = ManifestRegistry(PROJECT_ROOT / "config") assert len(registry.capabilities()) >= 6 assert len(registry.projects()) == 3 assert len(registry.benchmarks()) == 2 assert registry.policies().security.trust_remote_code is False for project in registry.projects(): for binding in project.bindings.values(): assert "model" not in binding.model_fields_set def test_project_referencing_missing_contract_is_rejected(tmp_path: Path) -> None: (tmp_path / "capabilities").mkdir() (tmp_path / "projects").mkdir() (tmp_path / "models").mkdir() (tmp_path / "projects" / "broken.yaml").write_text( "project:\n id: broken\n name: Broken\n description: broken\nbindings:\n rag.missing:\n contract_version: 1\n channel: stable\n priority: production\n", encoding="utf-8", ) with pytest.raises(ValueError, match="missing capability"): ManifestRegistry(tmp_path).projects() def test_duplicate_project_manifest_identity_is_rejected(tmp_path: Path) -> None: (tmp_path / "capabilities").mkdir() projects = tmp_path / "projects" projects.mkdir() (projects / "first.yaml").write_text( "project:\n id: shared\n name: First\n description: First declaration\nbindings: {}\n", encoding="utf-8", ) (projects / "second.yaml").write_text( "project:\n id: shared\n name: Second\n description: Conflicting declaration\nbindings: {}\n", encoding="utf-8", ) with pytest.raises(ValueError, match="duplicate project manifest identity"): ManifestRegistry(tmp_path).projects() def test_project_manifest_rejects_secret_bearing_extra_fields() -> None: payload = { "project": { "id": "local-consumer", "name": "Local Consumer", "description": "A non-secret project contract.", "service_token": "placeholder-only", }, "bindings": {}, } with pytest.raises(ValidationError): ProjectManifest.model_validate(payload)