Files
cleveragents-core/robot/helper_project_cli.py
T
Jeffrey Phillips Freeman 4dc05051dd
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
CI / security (push) Waiting to run
CI / quality (push) Waiting to run
CI / unit_tests (push) Waiting to run
CI / integration_tests (push) Waiting to run
CI / coverage (push) Blocked by required conditions
CI / build (push) Waiting to run
CI / docker (push) Blocked by required conditions
CI / lint (pull_request) Failing after 13s
CI / typecheck (pull_request) Successful in 28s
CI / coverage (pull_request) Has been skipped
CI / security (pull_request) Successful in 25s
CI / quality (pull_request) Successful in 16s
CI / integration_tests (pull_request) Successful in 5m16s
CI / build (pull_request) Successful in 17s
CI / unit_tests (pull_request) Successful in 15m34s
CI / docker (pull_request) Has been skipped
feat(cli): add project commands (core)
2026-02-16 23:56:55 -05:00

185 lines
5.0 KiB
Python

"""Helper script for project CLI Robot Framework integration tests.
Usage: python robot/helper_project_cli.py <test-name>
"""
from __future__ import annotations
import sys
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from cleveragents.application.services.resource_registry_service import (
ResourceRegistryService,
)
from cleveragents.domain.models.core.project import (
NamespacedProject,
parse_namespaced_name,
)
from cleveragents.infrastructure.database.models import Base
from cleveragents.infrastructure.database.repositories import (
NamespacedProjectRepository,
ProjectResourceLinkRepository,
)
def _setup_db() -> tuple[
NamespacedProjectRepository,
ProjectResourceLinkRepository,
ResourceRegistryService,
]:
"""Create an in-memory SQLite DB and return repos + service."""
engine = create_engine("sqlite:///:memory:", echo=False)
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine, expire_on_commit=False)()
class _NoClose:
def __init__(self, s: object) -> None:
object.__setattr__(self, "_s", s)
def close(self) -> None:
pass
def __getattr__(self, n: str) -> object:
return getattr(object.__getattribute__(self, "_s"), n)
wrapper = _NoClose(session)
def factory() -> object:
return wrapper
proj_repo = NamespacedProjectRepository(session_factory=factory)
link_repo = ProjectResourceLinkRepository(session_factory=factory)
svc = ResourceRegistryService(session_factory=factory)
svc.bootstrap_builtin_types()
return proj_repo, link_repo, svc
def test_project_crud() -> None:
"""Create, list, show, delete a project."""
proj_repo, _link_repo, _svc = _setup_db()
# Create
parsed = parse_namespaced_name("my-project")
proj = NamespacedProject(
name=parsed.name,
namespace=parsed.namespace,
description="Robot test project",
)
proj_repo.create(proj)
# List
projects = proj_repo.list_projects()
if len(projects) != 1:
raise AssertionError(f"Expected 1 project, got {len(projects)}")
# Show
fetched = proj_repo.get("local/my-project")
if fetched.namespaced_name != "local/my-project":
raise AssertionError(f"Name mismatch: {fetched.namespaced_name}")
# Delete
deleted = proj_repo.delete("local/my-project")
if not deleted:
raise AssertionError("Delete returned False")
projects_after = proj_repo.list_projects()
if len(projects_after) != 0:
raise AssertionError(f"Expected 0 projects, got {len(projects_after)}")
print("project-crud-ok")
def test_link_lifecycle() -> None:
"""Create project, link resource, unlink, delete."""
proj_repo, link_repo, svc = _setup_db()
# Create project
parsed = parse_namespaced_name("link-test")
proj = NamespacedProject(
name=parsed.name,
namespace=parsed.namespace,
description="Link test",
)
proj_repo.create(proj)
# Register resource
res = svc.register_resource(
type_name="git-checkout",
name="local/test-repo",
location="/tmp/test",
description="Test repo",
)
# Link
link = link_repo.create_link(
project_name="local/link-test",
resource_id=res.resource_id,
)
# Verify link
links = link_repo.list_links("local/link-test")
if len(links) != 1:
raise AssertionError(f"Expected 1 link, got {len(links)}")
# Unlink
link_repo.remove_link(str(link.link_id))
links_after = link_repo.list_links("local/link-test")
if len(links_after) != 0:
raise AssertionError(f"Expected 0 links, got {len(links_after)}")
# Delete project
proj_repo.delete("local/link-test")
print("link-lifecycle-ok")
def test_spec_dict() -> None:
"""Verify _project_spec_dict output keys."""
from cleveragents.cli.commands.project import _project_spec_dict
proj_repo, _link_repo, _svc = _setup_db()
parsed = parse_namespaced_name("dict-test")
proj = NamespacedProject(
name=parsed.name,
namespace=parsed.namespace,
description="Dict test",
)
proj_repo.create(proj)
fetched = proj_repo.get("local/dict-test")
data = _project_spec_dict(fetched)
expected_keys = {
"namespaced_name",
"namespace",
"name",
"description",
"linked_resources",
"created_at",
"updated_at",
}
if set(data.keys()) != expected_keys:
raise AssertionError(f"Key mismatch: {set(data.keys())} != {expected_keys}")
print("spec-dict-ok")
TESTS = {
"project-crud": test_project_crud,
"link-lifecycle": test_link_lifecycle,
"spec-dict": test_spec_dict,
}
if __name__ == "__main__":
if len(sys.argv) < 2 or sys.argv[1] not in TESTS:
print(f"Usage: {sys.argv[0]} <{'|'.join(TESTS)}>", file=sys.stderr)
sys.exit(2)
try:
TESTS[sys.argv[1]]()
except Exception as exc:
print(f"FAIL: {exc}", file=sys.stderr)
sys.exit(1)