forked from sagnik/Project_Velocity
134 lines
4.6 KiB
Python
134 lines
4.6 KiB
Python
"""
|
|
test_canvas_service.py — Unit tests for CanvasService (demo mode in-memory store).
|
|
"""
|
|
import asyncio
|
|
import pytest
|
|
import sys
|
|
import os
|
|
|
|
# Ensure backend is on path
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
|
|
|
|
from oracle.canvas_service import CanvasService
|
|
|
|
TENANT = "tenant_test_001"
|
|
ACTOR = "user_test_001"
|
|
|
|
|
|
def run(coro):
|
|
return asyncio.get_event_loop().run_until_complete(coro)
|
|
|
|
|
|
@pytest.fixture
|
|
def svc():
|
|
"""Fresh CanvasService instance with empty demo store per test."""
|
|
from oracle import canvas_service as _mod
|
|
_mod._DEMO_PAGES.clear()
|
|
_mod._DEMO_REVISIONS.clear()
|
|
_mod._DEMO_COMPONENTS.clear()
|
|
return CanvasService()
|
|
|
|
|
|
def test_create_page(svc):
|
|
page = run(svc.create_page(tenant_id=TENANT, owner_id=ACTOR, title="Test Canvas"))
|
|
assert page["tenantId"] == TENANT
|
|
assert page["ownerId"] == ACTOR
|
|
assert page["title"] == "Test Canvas"
|
|
assert page["headRevision"] == 0
|
|
assert page["pageType"] == "main"
|
|
assert page["branchName"] == "main"
|
|
|
|
|
|
def test_get_page_not_found(svc):
|
|
result = run(svc.get_page("nonexistent_id", TENANT))
|
|
assert result is None
|
|
|
|
|
|
def test_get_page_returns_page(svc):
|
|
page = run(svc.create_page(tenant_id=TENANT, owner_id=ACTOR))
|
|
retrieved = run(svc.get_page(page["pageId"], TENANT))
|
|
assert retrieved is not None
|
|
assert retrieved["pageId"] == page["pageId"]
|
|
|
|
|
|
def test_commit_revision_advances_head(svc):
|
|
page = run(svc.create_page(tenant_id=TENANT, owner_id=ACTOR))
|
|
comps = [{"componentId": "cmp_001", "type": "barChart", "title": "Test"}]
|
|
rev = run(svc.commit_revision(
|
|
page_id=page["pageId"],
|
|
tenant_id=TENANT,
|
|
actor_id=ACTOR,
|
|
commit_kind="prompt",
|
|
commit_summary="Test prompt",
|
|
components=comps,
|
|
idempotency_key="ikey_001",
|
|
))
|
|
assert rev["revisionNumber"] == 1
|
|
updated = run(svc.get_page(page["pageId"], TENANT))
|
|
assert updated["headRevision"] == 1
|
|
assert len(updated["components"]) == 1
|
|
|
|
|
|
def test_idempotency_key_prevents_double_commit(svc):
|
|
page = run(svc.create_page(tenant_id=TENANT, owner_id=ACTOR))
|
|
comps = [{"componentId": "cmp_001", "type": "barChart", "title": "Test"}]
|
|
rev1 = run(svc.commit_revision(
|
|
page_id=page["pageId"], tenant_id=TENANT, actor_id=ACTOR,
|
|
commit_kind="prompt", commit_summary="First", components=comps,
|
|
idempotency_key="ikey_idempotent",
|
|
))
|
|
rev2 = run(svc.commit_revision(
|
|
page_id=page["pageId"], tenant_id=TENANT, actor_id=ACTOR,
|
|
commit_kind="prompt", commit_summary="Duplicate", components=comps,
|
|
idempotency_key="ikey_idempotent",
|
|
))
|
|
assert rev1["revisionId"] == rev2["revisionId"]
|
|
# Head should still be 1
|
|
updated = run(svc.get_page(page["pageId"], TENANT))
|
|
assert updated["headRevision"] == 1
|
|
|
|
|
|
def test_rollback_creates_new_revision(svc):
|
|
page = run(svc.create_page(tenant_id=TENANT, owner_id=ACTOR))
|
|
comps_v1 = [{"componentId": "cmp_v1", "type": "barChart", "title": "V1"}]
|
|
comps_v2 = [{"componentId": "cmp_v2", "type": "lineChart", "title": "V2"}]
|
|
|
|
run(svc.commit_revision(
|
|
page_id=page["pageId"], tenant_id=TENANT, actor_id=ACTOR,
|
|
commit_kind="prompt", commit_summary="V1", components=comps_v1, idempotency_key="key_v1",
|
|
))
|
|
run(svc.commit_revision(
|
|
page_id=page["pageId"], tenant_id=TENANT, actor_id=ACTOR,
|
|
commit_kind="prompt", commit_summary="V2", components=comps_v2, idempotency_key="key_v2",
|
|
))
|
|
|
|
# Rollback to revision 1
|
|
rollback_rev = run(svc.rollback(
|
|
page_id=page["pageId"], tenant_id=TENANT, actor_id=ACTOR,
|
|
target_revision=1, idempotency_key="key_rollback",
|
|
))
|
|
assert rollback_rev["revisionNumber"] == 3
|
|
assert rollback_rev["commitKind"] == "rollback"
|
|
|
|
revisions = run(svc.list_revisions(page["pageId"], TENANT))
|
|
assert len(revisions) == 3 # 3 revisions total
|
|
|
|
|
|
def test_list_revisions_returns_newest_first(svc):
|
|
page = run(svc.create_page(tenant_id=TENANT, owner_id=ACTOR))
|
|
for i in range(3):
|
|
run(svc.commit_revision(
|
|
page_id=page["pageId"], tenant_id=TENANT, actor_id=ACTOR,
|
|
commit_kind="prompt", commit_summary=f"Rev {i+1}",
|
|
components=[], idempotency_key=f"key_{i}",
|
|
))
|
|
revisions = run(svc.list_revisions(page["pageId"], TENANT))
|
|
assert revisions[0]["revisionNumber"] > revisions[-1]["revisionNumber"]
|
|
|
|
|
|
def test_tenant_isolation(svc):
|
|
page = run(svc.create_page(tenant_id=TENANT, owner_id=ACTOR))
|
|
# Different tenant cannot access the page
|
|
result = run(svc.get_page(page["pageId"], "tenant_different_999"))
|
|
assert result is None
|