kb-demo / backend /tests /test_helpful.py
RayLi-Git
fix: 檔案移至根目錄 + 套用示範 README
a7cd101
Raw
History Blame Contribute Delete
5 kB
"""§50.3.3 有用按鈕 endpoint 測試。"""
from __future__ import annotations
import pytest
from fastapi.testclient import TestClient
from app.auth.passwords import hash_password
from app.db import _utcnow, get_conn
from app.main import app
PWD = "TestPw123!"
@pytest.fixture()
def client():
return TestClient(app)
def _mkuser(name, role="user", dept="業務部"):
c = get_conn()
c.execute(
"INSERT INTO users (username, email, password_hash, role, department, "
"created_at, is_active) VALUES (?,?,?,?,?,?,1)",
(name, f"{name}@x.tw", hash_password(PWD), role, dept, _utcnow()),
)
return c.execute("SELECT id FROM users WHERE username=?", (name,)).fetchone()["id"]
def _mkdoc(author_id, vis="public", dept="業務部"):
now = _utcnow()
cur = get_conn().execute(
"INSERT INTO documents (title, category, tags, summary, body, author_id, "
"owner_department, visibility, allowed_departments, access_list, status, "
"created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,'[]','[]','active',?,?)",
("t", "知識/筆記", "[]", "s", "b", author_id, dept, vis, now, now),
)
return cur.lastrowid
def _login(c, u):
return c.post("/api/auth/login", json={"username": u, "password": PWD}).json()["access_token"]
def _auth(t):
return {"Authorization": f"Bearer {t}"}
def test_toggle_helpful_on(client):
a = _mkuser("author")
did = _mkdoc(a)
u = _mkuser("voter")
tok = _login(client, "voter")
r = client.post(f"/api/documents/{did}/helpful", headers=_auth(tok))
assert r.status_code == 200
j = r.json()
assert j["helpful"] is True
assert j["count"] == 1
def test_toggle_helpful_off(client):
a = _mkuser("author")
did = _mkdoc(a)
_mkuser("voter")
tok = _login(client, "voter")
client.post(f"/api/documents/{did}/helpful", headers=_auth(tok))
r = client.post(f"/api/documents/{did}/helpful", headers=_auth(tok)) # 再點取消
j = r.json()
assert j["helpful"] is False
assert j["count"] == 0
def test_helpful_count_multi_user(client):
a = _mkuser("author")
did = _mkdoc(a)
for name in ("v1", "v2", "v3"):
_mkuser(name)
tok = _login(client, name)
client.post(f"/api/documents/{did}/helpful", headers=_auth(tok))
cnt = get_conn().execute("SELECT helpful_count FROM documents WHERE id=?", (did,)).fetchone()["helpful_count"]
assert cnt == 3
def test_get_helpful_status(client):
a = _mkuser("author")
did = _mkdoc(a)
_mkuser("voter")
tok = _login(client, "voter")
# 未投
r1 = client.get(f"/api/documents/{did}/helpful", headers=_auth(tok))
assert r1.json()["helpful"] is False
# 投了
client.post(f"/api/documents/{did}/helpful", headers=_auth(tok))
r2 = client.get(f"/api/documents/{did}/helpful", headers=_auth(tok))
assert r2.json()["helpful"] is True
assert r2.json()["count"] == 1
def test_helpful_404_missing_doc(client):
_mkuser("voter")
tok = _login(client, "voter")
r = client.post("/api/documents/99999/helpful", headers=_auth(tok))
assert r.status_code == 404
def test_helpful_respects_visibility(client):
a = _mkuser("author", dept="業務部")
did = _mkdoc(a, vis="department", dept="業務部")
_mkuser("outsider", dept="研發部")
tok = _login(client, "outsider")
r = client.post(f"/api/documents/{did}/helpful", headers=_auth(tok))
assert r.status_code == 404 # 跨部門看不到 → 不能投
def test_helpful_unauth(client):
a = _mkuser("author")
did = _mkdoc(a)
r = client.post(f"/api/documents/{did}/helpful")
assert r.status_code in (401, 403)
# ============ helpful_count 不 drift(巡檢 #helpful)============
def test_helpful_count_always_equals_vote_rows(client):
"""stored helpful_count 永遠 == COUNT(helpful_votes),且 toggle 冪等不漂移。"""
aid = _mkuser("a1", "admin")
_mkuser("u1", "user")
_mkuser("u2", "user")
did = _mkdoc(aid, "public", "業務部")
def _stored_vs_real():
c = get_conn()
stored = c.execute("SELECT helpful_count FROM documents WHERE id=?", (did,)).fetchone()["helpful_count"]
real = c.execute("SELECT COUNT(*) AS n FROM helpful_votes WHERE document_id=?", (did,)).fetchone()["n"]
return stored, real
t1 = _login(client, "u1"); t2 = _login(client, "u2")
client.post(f"/api/documents/{did}/helpful", headers=_auth(t1)) # u1 讚
client.post(f"/api/documents/{did}/helpful", headers=_auth(t2)) # u2 讚
s, r = _stored_vs_real(); assert s == r == 2
# u1 重複按(toggle off)
client.post(f"/api/documents/{did}/helpful", headers=_auth(t1))
s, r = _stored_vs_real(); assert s == r == 1
# u1 再按回(toggle on)
last = client.post(f"/api/documents/{did}/helpful", headers=_auth(t1)).json()
s, r = _stored_vs_real(); assert s == r == 2
assert last["count"] == 2 and last["helpful"] is True