"""Tests for web UI project registry (#427).""" import json import sys import tempfile import unittest from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from starlette.testclient import TestClient from webui.app import create_app from webui.project_registry import ( default_registry_path, load_registry, project_to_dict, ) class TestProjectRegistryLoader(unittest.TestCase): def test_default_registry_loads_gitea_tools(self): registry = load_registry() self.assertEqual(registry.version, 1) self.assertEqual(len(registry.projects), 1) project = registry.projects[0] self.assertEqual(project.id, "gitea-tools") self.assertEqual(project.repo_name, "Gitea-Tools") self.assertEqual(project.gitea_owner, "Scaled-Tech-Consulting") self.assertEqual(project.remote_host, "https://gitea.prgs.cc") self.assertEqual(project.profiles["author"], "prgs-author") self.assertEqual(project.profiles["reviewer"], "prgs-reviewer") self.assertEqual(project.profiles["reconciler"], "prgs-reconciler") self.assertIn("skill", project.workflow_paths) self.assertGreaterEqual(len(project.onboarding_checklist), 4) def test_registry_rejects_credential_keys(self): payload = { "version": 1, "projects": [ { "id": "bad", "repo_name": "Bad", "gitea_owner": "Org", "remote_host": "https://gitea.example.invalid", "default_branch": "main", "local_checkout_path": ".", "profiles": { "author": "a", "reviewer": "r", "reconciler": "c", }, "workflow_paths": {"skill": "skills/x.md"}, "api_token": "secret", } ], } with tempfile.NamedTemporaryFile("w", suffix=".json", delete=False) as handle: json.dump(payload, handle) path = Path(handle.name) try: with self.assertRaises(ValueError): load_registry(path) finally: path.unlink(missing_ok=True) def test_default_registry_path_points_at_packaged_data(self): path = default_registry_path() self.assertTrue(path.name == "projects.registry.json") self.assertTrue(path.parent.name == "data") class TestProjectRegistryRoutes(unittest.TestCase): def setUp(self): self.client = TestClient(create_app()) def test_projects_page_lists_gitea_tools(self): response = self.client.get("/projects") self.assertEqual(response.status_code, 200) self.assertIn("Gitea-Tools", response.text) self.assertIn("Scaled-Tech-Consulting", response.text) self.assertIn("prgs-author", response.text) self.assertNotIn("child issue", response.text.lower()) def test_project_detail_renders_checklist(self): response = self.client.get("/projects/gitea-tools") self.assertEqual(response.status_code, 200) self.assertIn("Onboarding checklist", response.text) self.assertIn("Configure execution profiles", response.text) self.assertIn("branches/", response.text) def test_project_detail_404(self): response = self.client.get("/projects/unknown-repo") self.assertEqual(response.status_code, 404) def test_api_projects_json(self): response = self.client.get("/api/projects") self.assertEqual(response.status_code, 200) data = response.json() self.assertEqual(data["version"], 1) self.assertEqual(len(data["projects"]), 1) self.assertEqual(data["projects"][0]["id"], "gitea-tools") self.assertIn("onboarding_checklist", data["projects"][0]) def test_project_to_dict_is_json_safe(self): registry = load_registry() encoded = json.dumps(project_to_dict(registry.projects[0])) self.assertIn("gitea-tools", encoded) if __name__ == "__main__": unittest.main()