mirror of
https://github.com/MemeMeow-Studio/MemeMeow.git
synced 2026-10-19 23:20:02 +08:00
e88513e0e7
Add the 0004 PostgreSQL collection schema, scope-bound ORM repository, and CRUD/member API. Extend the Vue workbench with collection navigation, selection, creation, renaming, deletion, and member removal while keeping stable meme IDs and image storage untouched.\n\n新增 0004 PostgreSQL 合集 schema、scope-bound ORM repository 及 CRUD/成员 API;扩展 Vue 工作台支持合集导航、选择、创建、重命名、删除和移除成员,并保持稳定 meme_id 与图片存储不变。
38 lines
1.3 KiB
Python
38 lines
1.3 KiB
Python
"""合集 API 路由和请求模型的静态契约测试。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from api import CollectionItemsRequest, CollectionRequest, app
|
|
|
|
|
|
def test_collection_routes_are_scoped_resource_endpoints() -> None:
|
|
"""公共入口只暴露 CRUD 和成员维护,不接受资源包导入导出。"""
|
|
routes = {(route.path, method) for route in app.routes for method in getattr(route, "methods", set())}
|
|
expected = {
|
|
("/collections", "GET"),
|
|
("/collections", "POST"),
|
|
("/collections/{collection_id}", "GET"),
|
|
("/collections/{collection_id}", "PATCH"),
|
|
("/collections/{collection_id}", "DELETE"),
|
|
("/collections/{collection_id}/items", "POST"),
|
|
("/collections/{collection_id}/items/{meme_id}", "DELETE"),
|
|
}
|
|
assert expected <= routes
|
|
|
|
|
|
def test_collection_requests_reject_scope_and_empty_members() -> None:
|
|
"""客户端不能覆盖 scope,成员数组必须非空。"""
|
|
assert CollectionRequest(name=" 工作 ").name == " 工作 "
|
|
try:
|
|
CollectionRequest(name="工作", scope_id="other")
|
|
except Exception:
|
|
pass
|
|
else:
|
|
raise AssertionError("scope_id must be rejected")
|
|
try:
|
|
CollectionItemsRequest(meme_ids=[])
|
|
except Exception:
|
|
pass
|
|
else:
|
|
raise AssertionError("empty meme_ids must be rejected")
|