99 lines
4.3 KiB
Python
99 lines
4.3 KiB
Python
"""业务链条「管理员隐藏」目录开关测试。
|
||
|
||
覆盖(对齐 agents 的 hidden 语义):
|
||
- store:``hidden`` 随 update 持久化,create 缺省 False;
|
||
- 普通列表(mine / public / pending)一律排除 hidden —— 含 owner 自己的
|
||
「我的链条」与管理员的普通视图(选链弹窗路径,不带 admin_view);
|
||
- 管理视图(``include_hidden=True`` + admin)不排除,并可按 ``hidden``
|
||
筛选「只看隐藏 / 只看显示中」;非管理员的 ``include_hidden`` 一律忽略;
|
||
- 单条读取(get_chain)不过滤:owner / 公共链条的已配置使用路径不受影响。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import pytest
|
||
|
||
from test_roundtable_chain_review import _SEATS, _make_repo
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_hidden_flag_roundtrip():
|
||
repo, engine = await _make_repo()
|
||
try:
|
||
row = await repo.create_chain("u1", {"id": "c1", "title": "链", "seats": _SEATS})
|
||
assert row["hidden"] is False
|
||
|
||
updated = await repo.update_chain("c1", "u1", hidden=True)
|
||
assert updated is not None and updated["hidden"] is True
|
||
|
||
updated = await repo.update_chain("c1", "u1", hidden=False)
|
||
assert updated is not None and updated["hidden"] is False
|
||
finally:
|
||
await engine.dispose()
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_hidden_chain_vanishes_from_all_normal_listings():
|
||
repo, engine = await _make_repo()
|
||
try:
|
||
await repo.create_chain("u1", {"id": "c1", "title": "被隐藏的公共链", "seats": _SEATS})
|
||
await repo.create_chain("u1", {"id": "c2", "title": "普通链", "seats": _SEATS})
|
||
await repo.update_chain("c1", "u1", is_public=True)
|
||
await repo.update_chain("c2", "u1", is_public=True)
|
||
await repo.update_chain("c1", "u1", hidden=True)
|
||
|
||
# owner 的「我的链条」:c1 消失(隐藏对本人也生效)。
|
||
rows = await repo.list_chains("u1", scope="mine")
|
||
assert {r["id"] for r in rows} == {"c2"}
|
||
|
||
# 公共列表:任何账号都看不到 c1。
|
||
rows = await repo.list_chains("u2", scope="public")
|
||
assert {r["id"] for r in rows} == {"c2"}
|
||
|
||
# 管理员的普通视图(选链弹窗路径,无 admin_view):同样排除。
|
||
rows = await repo.list_chains("admin", scope="all", is_admin=True)
|
||
assert {r["id"] for r in rows} == {"c2"}
|
||
|
||
# 非管理员传 include_hidden 也绝不越权看到隐藏链条。
|
||
rows = await repo.list_chains("u1", scope="mine", is_admin=False, include_hidden=True)
|
||
assert {r["id"] for r in rows} == {"c2"}
|
||
|
||
# 单条读取不受影响(隐藏不是禁用:业务映射 / 研讨快照继续可用)。
|
||
assert await repo.get_chain("c1", "u1") is not None
|
||
assert await repo.get_chain("c1", "u2") is not None # 公共链条他人可读
|
||
finally:
|
||
await engine.dispose()
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_admin_view_lists_and_filters_hidden():
|
||
repo, engine = await _make_repo()
|
||
try:
|
||
await repo.create_chain("u1", {"id": "c1", "title": "被隐藏", "seats": _SEATS})
|
||
await repo.create_chain("u1", {"id": "c2", "title": "显示中", "seats": _SEATS})
|
||
await repo.update_chain("c1", "u1", hidden=True)
|
||
|
||
# 管理视图:默认(hidden=None)全部可见(含隐藏)。
|
||
rows = await repo.list_chains("admin", scope="all", is_admin=True, include_hidden=True)
|
||
assert {r["id"] for r in rows} == {"c1", "c2"}
|
||
|
||
# 只看隐藏 / 只看显示中。
|
||
rows = await repo.list_chains(
|
||
"admin", scope="all", is_admin=True, include_hidden=True, hidden=True
|
||
)
|
||
assert {r["id"] for r in rows} == {"c1"}
|
||
rows = await repo.list_chains(
|
||
"admin", scope="all", is_admin=True, include_hidden=True, hidden=False
|
||
)
|
||
assert {r["id"] for r in rows} == {"c2"}
|
||
|
||
# 管理视图 + 非 admin → include_hidden 失效(普通视图,排除隐藏)。
|
||
rows = await repo.list_chains("u1", scope="mine", is_admin=False, include_hidden=True)
|
||
assert {r["id"] for r in rows} == {"c2"}
|
||
|
||
# 取消隐藏回到普通列表。
|
||
await repo.update_chain("c1", "u1", hidden=False)
|
||
rows = await repo.list_chains("u1", scope="mine")
|
||
assert {r["id"] for r in rows} == {"c1", "c2"}
|
||
finally:
|
||
await engine.dispose()
|