75 lines
2.6 KiB
Python
75 lines
2.6 KiB
Python
# ============================================================
|
|
# AG-08 workspace golden tests
|
|
# ============================================================
|
|
from __future__ import annotations
|
|
|
|
import copy
|
|
import os
|
|
|
|
from server.state.projects import PERSONAL_PROJECT_ID, ProjectStore
|
|
from server.state.seed import seed_world
|
|
|
|
|
|
def test_workspace_persist_roundtrip(tmp_path):
|
|
path = str(tmp_path / "projects.json")
|
|
store = ProjectStore(path)
|
|
created = store.create_project("pilot-plant")
|
|
pid = created["project"]["id"]
|
|
sid = created["session"]["id"]
|
|
store.replace_messages(sid, [{"role": "user", "text": "run"}, {"role": "assistant", "text": "ok"}])
|
|
|
|
store2 = ProjectStore(path)
|
|
snap = store2.snapshot()
|
|
assert any(p["id"] == pid for p in snap["projects"])
|
|
assert snap["messages"][sid][0]["text"] == "run"
|
|
assert snap["worldKey"] == "default"
|
|
assert os.path.exists(path)
|
|
|
|
|
|
def test_delete_project_does_not_touch_world(tmp_path):
|
|
path = str(tmp_path / "projects.json")
|
|
store = ProjectStore(path)
|
|
world = seed_world()
|
|
world_before = copy.deepcopy(world)
|
|
created = store.create_project("temp-project")
|
|
pid = created["project"]["id"]
|
|
|
|
result = store.delete_project(pid)
|
|
assert result["worldUntouched"] is True
|
|
assert world == world_before
|
|
assert len(world["salesOrders"]) == 7
|
|
assert not any(p["id"] == pid for p in store.snapshot()["projects"])
|
|
|
|
|
|
def test_migrate_local_workspace_replace(tmp_path):
|
|
path = str(tmp_path / "projects.json")
|
|
store = ProjectStore(path)
|
|
local = {
|
|
"projects": [{
|
|
"id": "proj_local1", "name": "migrated", "scopeLabel": "demo",
|
|
"createdAt": "2026-07-22 10:00",
|
|
}],
|
|
"sessions": [{
|
|
"id": "sess_local1", "projectId": "proj_local1", "title": "topic",
|
|
"status": "running", "updatedAt": "2026-07-22 10:00",
|
|
}],
|
|
"files": [],
|
|
"messages": {"sess_local1": [{"role": "user", "text": "hello"}]},
|
|
"activeProjectId": "proj_local1",
|
|
"activeSessionId": "sess_local1",
|
|
"worldKey": "default",
|
|
}
|
|
snap = store.replace_workspace(local)
|
|
assert snap["projects"][0]["name"] == "migrated"
|
|
assert snap["messages"]["sess_local1"][0]["text"] == "hello"
|
|
assert snap["activeSessionId"] == "sess_local1"
|
|
|
|
|
|
def test_personal_scope_cannot_delete(tmp_path):
|
|
store = ProjectStore(str(tmp_path / "p.json"))
|
|
try:
|
|
store.delete_project(PERSONAL_PROJECT_ID)
|
|
assert False, "should raise"
|
|
except ValueError as exc:
|
|
assert "personal" in str(exc).lower() or "不可删除" in str(exc)
|