Refactor component terminology to programs in config and manifest
- Updated the terminology from "components" to "programs" across the codebase, including in config loading, saving, and manifest specifications. - Introduced a new `stacks.py` file to handle lifecycle actions for development stacks, implementing handlers for Python and React Vite stacks. - Adjusted tests to reflect the new program structure and ensure proper functionality. - Revised documentation to align with the new terminology and structure, ensuring clarity on the purpose and configuration of programs, services, and jobs.
This commit is contained in:
@@ -71,6 +71,169 @@ class TestComponentDetail:
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
class TestServicesList:
|
||||
"""GET /services endpoint tests."""
|
||||
|
||||
def test_returns_deployed_services(self, client: TestClient) -> None:
|
||||
"""Returns deployed services from registry."""
|
||||
response = client.get("/services")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
names = [s["id"] for s in data]
|
||||
assert "test-svc" in names
|
||||
|
||||
def test_service_has_port_and_health(self, client: TestClient) -> None:
|
||||
"""Service summary includes port and health info."""
|
||||
response = client.get("/services")
|
||||
data = response.json()
|
||||
svc = next(s for s in data if s["id"] == "test-svc")
|
||||
assert svc["port"] == 19000
|
||||
assert svc["health_path"] == "/health"
|
||||
assert svc["proxy_path"] == "/test-svc"
|
||||
assert svc["managed"] is True
|
||||
|
||||
def test_no_schedule_field(self, client: TestClient) -> None:
|
||||
"""ServiceSummary does not have schedule field."""
|
||||
response = client.get("/services")
|
||||
data = response.json()
|
||||
svc = next(s for s in data if s["id"] == "test-svc")
|
||||
assert "schedule" not in svc
|
||||
|
||||
def test_no_installed_field(self, client: TestClient) -> None:
|
||||
"""ServiceSummary does not have installed field."""
|
||||
response = client.get("/services")
|
||||
data = response.json()
|
||||
svc = next(s for s in data if s["id"] == "test-svc")
|
||||
assert "installed" not in svc
|
||||
|
||||
def test_excludes_jobs(self, client: TestClient) -> None:
|
||||
"""Jobs (scheduled items) are not in the services list."""
|
||||
response = client.get("/services")
|
||||
data = response.json()
|
||||
names = [s["id"] for s in data]
|
||||
assert "test-job" not in names
|
||||
|
||||
|
||||
class TestServiceDetail:
|
||||
"""GET /services/{name} endpoint tests."""
|
||||
|
||||
def test_get_service(self, client: TestClient) -> None:
|
||||
"""Returns detailed info for a service."""
|
||||
response = client.get("/services/test-svc")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["id"] == "test-svc"
|
||||
assert "manifest" in data
|
||||
assert data["manifest"]["runner"] == "python"
|
||||
|
||||
def test_not_found(self, client: TestClient) -> None:
|
||||
"""Returns 404 for unknown service."""
|
||||
response = client.get("/services/nonexistent")
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
class TestJobsList:
|
||||
"""GET /jobs endpoint tests."""
|
||||
|
||||
def test_returns_jobs(self, client: TestClient) -> None:
|
||||
"""Returns jobs from castle.yaml."""
|
||||
response = client.get("/jobs")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
names = [j["id"] for j in data]
|
||||
assert "test-job" in names
|
||||
|
||||
def test_job_has_schedule(self, client: TestClient) -> None:
|
||||
"""Job summary includes schedule."""
|
||||
response = client.get("/jobs")
|
||||
data = response.json()
|
||||
job = next(j for j in data if j["id"] == "test-job")
|
||||
assert job["schedule"] == "0 2 * * *"
|
||||
|
||||
def test_no_port_field(self, client: TestClient) -> None:
|
||||
"""JobSummary does not have port field."""
|
||||
response = client.get("/jobs")
|
||||
data = response.json()
|
||||
job = next(j for j in data if j["id"] == "test-job")
|
||||
assert "port" not in job
|
||||
|
||||
def test_excludes_services(self, client: TestClient) -> None:
|
||||
"""Services (non-scheduled) are not in the jobs list."""
|
||||
response = client.get("/jobs")
|
||||
data = response.json()
|
||||
names = [j["id"] for j in data]
|
||||
assert "test-svc" not in names
|
||||
|
||||
|
||||
class TestJobDetail:
|
||||
"""GET /jobs/{name} endpoint tests."""
|
||||
|
||||
def test_get_job(self, client: TestClient) -> None:
|
||||
"""Returns detailed info for a job."""
|
||||
response = client.get("/jobs/test-job")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["id"] == "test-job"
|
||||
assert "manifest" in data
|
||||
assert data["schedule"] == "0 2 * * *"
|
||||
|
||||
def test_not_found(self, client: TestClient) -> None:
|
||||
"""Returns 404 for unknown job."""
|
||||
response = client.get("/jobs/nonexistent")
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
class TestProgramsList:
|
||||
"""GET /programs endpoint tests."""
|
||||
|
||||
def test_returns_programs(self, client: TestClient) -> None:
|
||||
"""Returns programs from castle.yaml."""
|
||||
response = client.get("/programs")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
names = [p["id"] for p in data]
|
||||
assert "test-tool" in names
|
||||
|
||||
def test_program_has_behavior(self, client: TestClient) -> None:
|
||||
"""Program summary includes behavior."""
|
||||
response = client.get("/programs")
|
||||
data = response.json()
|
||||
tool = next(p for p in data if p["id"] == "test-tool")
|
||||
assert tool["behavior"] == "tool"
|
||||
|
||||
def test_no_port_field(self, client: TestClient) -> None:
|
||||
"""ProgramSummary does not have port field."""
|
||||
response = client.get("/programs")
|
||||
data = response.json()
|
||||
tool = next(p for p in data if p["id"] == "test-tool")
|
||||
assert "port" not in tool
|
||||
|
||||
def test_no_schedule_field(self, client: TestClient) -> None:
|
||||
"""ProgramSummary does not have schedule field."""
|
||||
response = client.get("/programs")
|
||||
data = response.json()
|
||||
tool = next(p for p in data if p["id"] == "test-tool")
|
||||
assert "schedule" not in tool
|
||||
|
||||
|
||||
class TestProgramDetail:
|
||||
"""GET /programs/{name} endpoint tests."""
|
||||
|
||||
def test_get_program(self, client: TestClient) -> None:
|
||||
"""Returns detailed info for a program."""
|
||||
response = client.get("/programs/test-tool")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["id"] == "test-tool"
|
||||
assert "manifest" in data
|
||||
assert data["behavior"] == "tool"
|
||||
|
||||
def test_not_found(self, client: TestClient) -> None:
|
||||
"""Returns 404 for unknown program."""
|
||||
response = client.get("/programs/nonexistent")
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
class TestGateway:
|
||||
"""Gateway info endpoint tests."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user