Files
javadandCursor b93ecf1691 Initial commit of the Kamidso API.
Keep source, config, and deploy files. Leave runtime data, uploads, and logs out of git.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-10 13:43:09 +03:30

181 lines
5.8 KiB
Python

import pytest
from kamidso.contracts.report import validate_report
from kamidso.contracts.user import CurrentUser
from kamidso.repositories.store import RepositoryStore
from kamidso.resources.reports import ReportService, bind_report_service
@pytest.mark.asyncio
async def test_report_service_create_and_get():
store = RepositoryStore()
service = ReportService(store)
user = CurrentUser(
id="usr_1",
email="a@b.c",
name="A",
role="user",
workspace_id="ws_1",
)
spec = validate_report(
{
"version": 2,
"title": "فروش",
"blocks": [{"type": "text", "content": "خلاصه"}],
}
)
doc = await service.create(user, spec, conversation_id="conv_1")
assert doc["_id"].startswith("rpt_")
got = await service.get_report(user, doc["_id"])
assert got["title"] == "فروش"
assert got["report_spec"]["blocks"][0]["type"] == "text"
public = ReportService.to_public(got)
assert public["id"] == doc["_id"]
assert public["report_spec"]["title"] == "فروش"
@pytest.mark.asyncio
async def test_report_autosave_from_conversation():
store = RepositoryStore()
service = ReportService(store)
bind_report_service(service)
await store.create_conversation(
{
"_id": "conv_auto",
"workspace_id": "ws_auto",
"created_by": "usr_auto",
"title": "chat",
}
)
spec = validate_report(
{
"version": 2,
"title": "Auto",
"blocks": [{"type": "kpi", "label": "A", "value": 1}],
}
)
saved = await service.autosave_from_tool(spec, conversation_id="conv_auto")
assert saved is not None
assert saved["workspace_id"] == "ws_auto"
assert saved["_id"].startswith("rpt_")
bind_report_service(None)
@pytest.mark.asyncio
async def test_report_interpreter_flow_without_engine_import():
"""Mirror report_interpreter validate + autosave path without loading engine tools."""
import json
store = RepositoryStore()
service = ReportService(store)
bind_report_service(service)
await store.create_conversation(
{
"_id": "conv_tool",
"workspace_id": "ws_tool",
"created_by": "usr_tool",
}
)
validated = validate_report(
{
"version": 2,
"title": "از ابزار",
"datasets": {
"m": [{"month": "A", "sales": 1, "profit": 2}],
},
"blocks": [
{
"type": "chart",
"chartType": "line",
"dataset": "m",
"x": "month",
"series": [
{"field": "sales", "label": "فروش"},
{"field": "profit", "label": "سود"},
],
}
],
}
)
saved = await service.autosave_from_tool(
validated,
workspace_id="ws_tool",
user_id="usr_tool",
conversation_id="conv_tool",
)
assert saved is not None
validated["report_id"] = saved["_id"]
chunks = [
{"output_type": "text", "content": f"report_id={validated['report_id']}"},
{"output_type": "report", "content": validated},
]
payload = json.loads(json.dumps({"chunks": chunks}, ensure_ascii=False))
report_chunk = next(c for c in payload["chunks"] if c["output_type"] == "report")
assert report_chunk["content"]["version"] == 2
assert report_chunk["content"]["report_id"].startswith("rpt_")
assert len(report_chunk["content"]["blocks"][0]["series"]) == 2
bind_report_service(None)
@pytest.mark.asyncio
async def test_shared_report_omits_workspace_and_conversation():
store = RepositoryStore()
service = ReportService(store)
user = CurrentUser(
id="usr_1",
email="a@b.c",
name="A",
role="user",
workspace_id="ws_1",
)
spec = validate_report(
{
"version": 2,
"title": "فروش",
"blocks": [{"type": "text", "content": "خلاصه"}],
}
)
doc = await service.create(user, spec, conversation_id="conv_secret")
shared = await service.get_shared_report(doc["_id"])
public = ReportService.to_share_public(shared)
assert public["id"] == doc["_id"]
assert public["title"] == "فروش"
assert "conversation_id" not in public
assert "created_by" not in public
assert public["report_spec"]["blocks"][0]["content"] == "خلاصه"
await service.update_report(user, doc["_id"], status="archived")
with pytest.raises(KeyError):
await service.get_shared_report(doc["_id"])
@pytest.mark.asyncio
async def test_html_share_is_public_and_reused():
store = RepositoryStore()
service = ReportService(store)
user = CurrentUser(
id="usr_1",
email="a@b.c",
name="A",
role="user",
workspace_id="ws_1",
)
html = "<html dir='rtl' lang='fa'><head><title>فروش</title></head><body><h1>فروش</h1></body></html>"
first = await service.create_html_share(user, html)
second = await service.create_html_share(user, html, title="عنوان دیگر")
assert first["_id"] == second["_id"]
assert first["title"] == "فروش"
assert "conversation_id" not in first or first.get("conversation_id") is None
shared = await service.get_shared_report(first["_id"])
public = ReportService.to_share_public(shared)
assert public["kind"] == "html"
assert public["html"] == html.strip()
assert public["title"] == "فروش"
assert "workspace_id" not in public
assert "created_by" not in public
assert "html" not in public["report_spec"]
with pytest.raises(ValueError):
await service.create_html_share(user, " ")