feat(cli): add resource commands (core)
CI / lint (pull_request) Successful in 15s
CI / typecheck (pull_request) Successful in 28s
CI / security (pull_request) Successful in 23s
CI / quality (pull_request) Successful in 15s
CI / integration_tests (pull_request) Successful in 5m11s
CI / build (pull_request) Successful in 16s
CI / unit_tests (pull_request) Successful in 14m31s
CI / docker (pull_request) Successful in 40s
CI / coverage (pull_request) Successful in 8m18s
CI / lint (push) Successful in 13s
CI / typecheck (push) Successful in 28s
CI / security (push) Successful in 23s
CI / quality (push) Successful in 16s
CI / integration_tests (push) Successful in 4m58s
CI / build (push) Successful in 15s
CI / unit_tests (push) Successful in 15m30s
CI / coverage (push) Has been cancelled
CI / docker (push) Has been cancelled
CI / lint (pull_request) Successful in 15s
CI / typecheck (pull_request) Successful in 28s
CI / security (pull_request) Successful in 23s
CI / quality (pull_request) Successful in 15s
CI / integration_tests (pull_request) Successful in 5m11s
CI / build (pull_request) Successful in 16s
CI / unit_tests (pull_request) Successful in 14m31s
CI / docker (pull_request) Successful in 40s
CI / coverage (pull_request) Successful in 8m18s
CI / lint (push) Successful in 13s
CI / typecheck (push) Successful in 28s
CI / security (push) Successful in 23s
CI / quality (push) Successful in 16s
CI / integration_tests (push) Successful in 4m58s
CI / build (push) Successful in 15s
CI / unit_tests (push) Successful in 15m30s
CI / coverage (push) Has been cancelled
CI / docker (push) Has been cancelled
This commit was merged in pull request #71.
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
"""Helper for project repository Robot integration tests.
|
||||
|
||||
Tests NamespacedProjectRepository and ProjectResourceLinkRepository
|
||||
with an in-memory SQLite database.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from sqlalchemy import create_engine, event, text
|
||||
from sqlalchemy.orm import Session, sessionmaker
|
||||
|
||||
from cleveragents.domain.models.core.project import NamespacedProject
|
||||
from cleveragents.infrastructure.database.models import (
|
||||
Base,
|
||||
NamespacedProjectModel, # noqa: F401
|
||||
ProjectResourceLinkModel, # noqa: F401
|
||||
ResourceModel,
|
||||
ResourceTypeModel,
|
||||
)
|
||||
from cleveragents.infrastructure.database.repositories import (
|
||||
DuplicateLinkError,
|
||||
NamespacedProjectRepository,
|
||||
ProjectNotFoundError,
|
||||
ProjectResourceLinkRepository,
|
||||
)
|
||||
|
||||
|
||||
def _now_iso() -> str:
|
||||
return datetime.now(tz=UTC).isoformat()
|
||||
|
||||
|
||||
def _set_sqlite_pragma(dbapi_conn: object, _connection_record: object) -> None:
|
||||
cursor = dbapi_conn.cursor() # type: ignore[union-attr]
|
||||
cursor.execute("PRAGMA foreign_keys = ON")
|
||||
cursor.close()
|
||||
|
||||
|
||||
def _create_db() -> tuple[sessionmaker[Session], object]:
|
||||
engine = create_engine("sqlite:///:memory:")
|
||||
event.listen(engine, "connect", _set_sqlite_pragma)
|
||||
with engine.connect() as conn:
|
||||
conn.execute(text("PRAGMA foreign_keys = ON"))
|
||||
conn.commit()
|
||||
Base.metadata.create_all(engine)
|
||||
sf = sessionmaker(bind=engine)
|
||||
return sf, engine
|
||||
|
||||
|
||||
def _setup_resource_type(session: Session) -> None:
|
||||
rt = ResourceTypeModel()
|
||||
rt.name = "builtin/git-checkout" # type: ignore[assignment]
|
||||
rt.namespace = "builtin" # type: ignore[assignment]
|
||||
rt.resource_kind = "physical" # type: ignore[assignment]
|
||||
rt.user_addable = True # type: ignore[assignment]
|
||||
rt.created_at = _now_iso() # type: ignore[assignment]
|
||||
rt.updated_at = _now_iso() # type: ignore[assignment]
|
||||
session.add(rt)
|
||||
session.commit()
|
||||
|
||||
|
||||
def _create_resource(session: Session, resource_id: str) -> None:
|
||||
r = ResourceModel()
|
||||
r.resource_id = resource_id # type: ignore[assignment]
|
||||
r.type_name = "builtin/git-checkout" # type: ignore[assignment]
|
||||
r.resource_kind = "physical" # type: ignore[assignment]
|
||||
r.created_at = _now_iso() # type: ignore[assignment]
|
||||
r.updated_at = _now_iso() # type: ignore[assignment]
|
||||
session.add(r)
|
||||
session.commit()
|
||||
|
||||
|
||||
def test_project_crud() -> None:
|
||||
"""Test project create, get, list, update, delete."""
|
||||
sf, _engine = _create_db()
|
||||
session = sf()
|
||||
_setup_resource_type(session)
|
||||
|
||||
repo = NamespacedProjectRepository(session_factory=sf)
|
||||
|
||||
# Create
|
||||
project = NamespacedProject(name="test-proj", namespace="local")
|
||||
repo.create(project)
|
||||
session.commit()
|
||||
|
||||
# Get
|
||||
fetched = repo.get("local/test-proj")
|
||||
assert fetched.name == "test-proj"
|
||||
assert fetched.namespace == "local"
|
||||
|
||||
# List
|
||||
projects = repo.list_projects()
|
||||
assert len(projects) == 1
|
||||
|
||||
# Update
|
||||
updated = fetched.model_copy(update={"description": "Updated"})
|
||||
repo.update(updated)
|
||||
session.commit()
|
||||
re_fetched = repo.get("local/test-proj")
|
||||
assert re_fetched.description == "Updated"
|
||||
|
||||
# Delete
|
||||
deleted = repo.delete("local/test-proj")
|
||||
session.commit()
|
||||
assert deleted is True
|
||||
|
||||
# Verify gone
|
||||
try:
|
||||
repo.get("local/test-proj")
|
||||
raise AssertionError("Expected ProjectNotFoundError")
|
||||
except ProjectNotFoundError:
|
||||
pass
|
||||
|
||||
print("project-crud-ok")
|
||||
|
||||
|
||||
def test_link_crud() -> None:
|
||||
"""Test link create, list, get, remove, alias uniqueness."""
|
||||
sf, _engine = _create_db()
|
||||
session = sf()
|
||||
_setup_resource_type(session)
|
||||
|
||||
project_repo = NamespacedProjectRepository(session_factory=sf)
|
||||
link_repo = ProjectResourceLinkRepository(session_factory=sf)
|
||||
|
||||
# Create project
|
||||
project = NamespacedProject(name="link-proj", namespace="local")
|
||||
project_repo.create(project)
|
||||
session.commit()
|
||||
|
||||
# Create resources
|
||||
_create_resource(session, "00000000000000000000000001")
|
||||
_create_resource(session, "00000000000000000000000002")
|
||||
|
||||
# Create links
|
||||
link1 = link_repo.create_link(
|
||||
project_name="local/link-proj",
|
||||
resource_id="00000000000000000000000001",
|
||||
alias="repo-a",
|
||||
)
|
||||
session.commit()
|
||||
assert link1.link_id is not None
|
||||
assert len(str(link1.link_id)) == 26
|
||||
|
||||
link_repo.create_link(
|
||||
project_name="local/link-proj",
|
||||
resource_id="00000000000000000000000002",
|
||||
alias="repo-b",
|
||||
)
|
||||
session.commit()
|
||||
|
||||
# List
|
||||
links = link_repo.list_links("local/link-proj")
|
||||
assert len(links) == 2
|
||||
|
||||
# Get
|
||||
fetched = link_repo.get_link(str(link1.link_id))
|
||||
assert fetched is not None
|
||||
|
||||
# Duplicate alias
|
||||
try:
|
||||
_create_resource(session, "00000000000000000000000003")
|
||||
link_repo.create_link(
|
||||
project_name="local/link-proj",
|
||||
resource_id="00000000000000000000000003",
|
||||
alias="repo-a",
|
||||
)
|
||||
raise AssertionError("Expected DuplicateLinkError")
|
||||
except DuplicateLinkError:
|
||||
pass
|
||||
|
||||
# Remove
|
||||
removed = link_repo.remove_link(str(link1.link_id))
|
||||
session.commit()
|
||||
assert removed is True
|
||||
|
||||
# Verify removed
|
||||
remaining = link_repo.list_links("local/link-proj")
|
||||
assert len(remaining) == 1
|
||||
|
||||
print("link-crud-ok")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_name = sys.argv[1] if len(sys.argv) > 1 else "project-crud"
|
||||
if test_name == "project-crud":
|
||||
test_project_crud()
|
||||
elif test_name == "link-crud":
|
||||
test_link_crud()
|
||||
else:
|
||||
print(f"Unknown test: {test_name}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user