完成错误测试用例
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
"""
|
||||
项目 API 测试(依据 API 文档 3–7 节)
|
||||
TDD:先写失败用例,再实现路由
|
||||
"""
|
||||
|
||||
|
||||
def _auth_header(token: str) -> dict:
|
||||
return {"Authorization": f"Bearer {token}"}
|
||||
|
||||
|
||||
# ---------- POST /api/projects/list ----------
|
||||
|
||||
|
||||
def test_list_without_token_returns_401(client):
|
||||
"""项目列表无 token 时返回 401"""
|
||||
r = client.post("/api/projects/list", json={})
|
||||
assert r.status_code == 401
|
||||
|
||||
|
||||
def test_list_with_token_returns_200_with_list_total_page_page_size(client):
|
||||
"""有 token 时返回 200 且包含 list、total、page、pageSize"""
|
||||
r = client.post(
|
||||
"/api/projects/list",
|
||||
headers=_auth_header("valid-token"),
|
||||
json={"page": 1, "pageSize": 20},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert "list" in body
|
||||
assert isinstance(body["list"], list)
|
||||
assert "total" in body
|
||||
assert "page" in body
|
||||
assert "pageSize" in body
|
||||
|
||||
|
||||
def test_list_empty_result_has_empty_list_and_total_zero(client):
|
||||
"""无数据时 list 为空数组且 total 为 0"""
|
||||
r = client.post(
|
||||
"/api/projects/list",
|
||||
headers=_auth_header("valid-token"),
|
||||
json={},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert r.json()["list"] == []
|
||||
assert r.json()["total"] == 0
|
||||
|
||||
|
||||
# ---------- POST /api/projects/detail ----------
|
||||
|
||||
|
||||
def test_detail_without_token_returns_401(client):
|
||||
"""项目详情无 token 时返回 401"""
|
||||
r = client.post("/api/projects/detail", json={"id": "any-id"})
|
||||
assert r.status_code == 401
|
||||
|
||||
|
||||
def test_detail_existing_project_returns_200_with_full_fields(client):
|
||||
"""存在项目时返回 200 且包含 id、contract、costControl、receivable、payable、other、createdAt、updatedAt"""
|
||||
create_r = client.post(
|
||||
"/api/projects/create",
|
||||
headers=_auth_header("market-token"),
|
||||
json={"contract": {"contractCode": "HT001", "projectName": "测试项目"}},
|
||||
)
|
||||
assert create_r.status_code == 201
|
||||
pid = create_r.json()["id"]
|
||||
r = client.post(
|
||||
"/api/projects/detail",
|
||||
headers=_auth_header("valid-token"),
|
||||
json={"id": pid},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert "id" in body
|
||||
assert "contract" in body
|
||||
assert "costControl" in body
|
||||
assert "receivable" in body
|
||||
assert "payable" in body
|
||||
assert "other" in body
|
||||
assert "createdAt" in body
|
||||
assert "updatedAt" in body
|
||||
|
||||
|
||||
def test_detail_nonexistent_project_returns_404_with_code_and_message(client):
|
||||
"""不存在项目时返回 404 且包含 code 和 message"""
|
||||
r = client.post(
|
||||
"/api/projects/detail",
|
||||
headers=_auth_header("valid-token"),
|
||||
json={"id": "non-existent-id"},
|
||||
)
|
||||
assert r.status_code == 404
|
||||
body = r.json()
|
||||
assert body.get("code") == 404
|
||||
assert "message" in body
|
||||
|
||||
|
||||
# ---------- POST /api/projects/create ----------
|
||||
|
||||
|
||||
def test_create_without_token_returns_401(client):
|
||||
"""新建项目无 token 时返回 401"""
|
||||
r = client.post(
|
||||
"/api/projects/create",
|
||||
json={"contract": {"contractCode": "HT001", "projectName": "测试项目"}},
|
||||
)
|
||||
assert r.status_code == 401
|
||||
|
||||
|
||||
def test_create_non_market_role_returns_403(client):
|
||||
"""非市场部角色返回 403"""
|
||||
r = client.post(
|
||||
"/api/projects/create",
|
||||
headers=_auth_header("engineer-token"),
|
||||
json={"contract": {"contractCode": "HT001", "projectName": "测试项目"}},
|
||||
)
|
||||
assert r.status_code == 403
|
||||
assert r.json().get("code") == 403
|
||||
|
||||
|
||||
def test_create_market_with_contract_code_and_name_returns_201_with_id_and_message(client):
|
||||
"""市场部且合同编号与项目名称齐全时返回 201 且包含 id 和 message"""
|
||||
r = client.post(
|
||||
"/api/projects/create",
|
||||
headers=_auth_header("market-token"),
|
||||
json={"contract": {"contractCode": "HT001", "projectName": "测试项目"}},
|
||||
)
|
||||
assert r.status_code == 201
|
||||
body = r.json()
|
||||
assert "id" in body
|
||||
assert body.get("message") == "创建成功"
|
||||
|
||||
|
||||
def test_create_missing_contract_code_returns_400(client):
|
||||
"""缺少合同编号时返回 400"""
|
||||
r = client.post(
|
||||
"/api/projects/create",
|
||||
headers=_auth_header("market-token"),
|
||||
json={"contract": {"projectName": "测试项目"}},
|
||||
)
|
||||
assert r.status_code == 400
|
||||
assert r.json().get("code") == 400
|
||||
|
||||
|
||||
def test_create_missing_project_name_returns_400(client):
|
||||
"""缺少项目名称时返回 400"""
|
||||
r = client.post(
|
||||
"/api/projects/create",
|
||||
headers=_auth_header("market-token"),
|
||||
json={"contract": {"contractCode": "HT001"}},
|
||||
)
|
||||
assert r.status_code == 400
|
||||
assert r.json().get("code") == 400
|
||||
|
||||
|
||||
# ---------- POST /api/projects/update ----------
|
||||
|
||||
|
||||
def test_update_without_token_returns_401(client):
|
||||
"""更新项目无 token 时返回 401"""
|
||||
r = client.post("/api/projects/update", json={"id": "any-id"})
|
||||
assert r.status_code == 401
|
||||
|
||||
|
||||
def test_update_existing_project_returns_200_with_id_and_save_success_message(client):
|
||||
"""存在项目时返回 200 且包含 id 和 message「保存成功」"""
|
||||
create_r = client.post(
|
||||
"/api/projects/create",
|
||||
headers=_auth_header("market-token"),
|
||||
json={"contract": {"contractCode": "HT002", "projectName": "测试项目2"}},
|
||||
)
|
||||
assert create_r.status_code == 201
|
||||
pid = create_r.json()["id"]
|
||||
r = client.post(
|
||||
"/api/projects/update",
|
||||
headers=_auth_header("valid-token"),
|
||||
json={"id": pid, "contract": {"projectName": "新名称"}},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert "id" in body
|
||||
assert body.get("message") == "保存成功"
|
||||
|
||||
|
||||
def test_update_nonexistent_project_returns_404(client):
|
||||
"""不存在项目时返回 404"""
|
||||
r = client.post(
|
||||
"/api/projects/update",
|
||||
headers=_auth_header("valid-token"),
|
||||
json={"id": "non-existent-id"},
|
||||
)
|
||||
assert r.status_code == 404
|
||||
assert r.json().get("code") == 404
|
||||
|
||||
|
||||
# ---------- POST /api/projects/logs ----------
|
||||
|
||||
|
||||
def test_logs_without_token_returns_401(client):
|
||||
"""操作日志无 token 时返回 401"""
|
||||
r = client.post("/api/projects/logs", json={"id": "any-id"})
|
||||
assert r.status_code == 401
|
||||
|
||||
|
||||
def test_logs_with_token_returns_200_with_list_total_page_page_size(client):
|
||||
"""有 token 时返回 200 且包含 list、total、page、pageSize"""
|
||||
create_r = client.post(
|
||||
"/api/projects/create",
|
||||
headers=_auth_header("market-token"),
|
||||
json={"contract": {"contractCode": "HT003", "projectName": "测试项目3"}},
|
||||
)
|
||||
assert create_r.status_code == 201
|
||||
pid = create_r.json()["id"]
|
||||
r = client.post(
|
||||
"/api/projects/logs",
|
||||
headers=_auth_header("valid-token"),
|
||||
json={"id": pid},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert "list" in body
|
||||
assert isinstance(body["list"], list)
|
||||
assert "total" in body
|
||||
assert "page" in body
|
||||
assert "pageSize" in body
|
||||
|
||||
|
||||
def test_logs_nonexistent_project_returns_404(client):
|
||||
"""不存在项目时返回 404"""
|
||||
r = client.post(
|
||||
"/api/projects/logs",
|
||||
headers=_auth_header("valid-token"),
|
||||
json={"id": "non-existent-id"},
|
||||
)
|
||||
assert r.status_code == 404
|
||||
assert r.json().get("code") == 404
|
||||
Reference in New Issue
Block a user