refactor(repo): conform structure to AGENTS.md (web->frontend, internal/api->cmd/webui/{api,handlers}, docs/README+CHANGELOGs, module .gitignores, drop stray library/ and committed debug bins)
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package handlers_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func adminToken(t *testing.T, h http.Handler) string {
|
||||
t.Helper()
|
||||
return loginAs(t, h, "alice", testPW)
|
||||
}
|
||||
|
||||
func TestUserCRUD(t *testing.T) {
|
||||
_, _, h, _ := setupAPI(t)
|
||||
tok := adminToken(t, h)
|
||||
w := do(h, "POST", "/api/users", tok, map[string]string{"username": "carol", "password": "pw123456", "role": "member"})
|
||||
if w.Code != 201 {
|
||||
t.Fatalf("create %d %s", w.Code, w.Body)
|
||||
}
|
||||
w = do(h, "GET", "/api/users", tok, nil)
|
||||
var users []map[string]any
|
||||
json.Unmarshal(w.Body.Bytes(), &users)
|
||||
if len(users) != 3 {
|
||||
t.Fatalf("list want 3 got %d: %s", len(users), w.Body)
|
||||
}
|
||||
carolID := findID(users, "carol")
|
||||
// 重名 → 409
|
||||
w = do(h, "POST", "/api/users", tok, map[string]string{"username": "carol", "password": "pw123456", "role": "member"})
|
||||
if w.Code != 409 {
|
||||
t.Fatalf("dup want 409 got %d", w.Code)
|
||||
}
|
||||
// 弱密码 → 400
|
||||
w = do(h, "POST", "/api/users", tok, map[string]string{"username": "dave", "password": "1", "role": "member"})
|
||||
if w.Code != 400 {
|
||||
t.Fatalf("weak want 400 got %d", w.Code)
|
||||
}
|
||||
// 不能删自己:先 me 拿 id
|
||||
w = do(h, "GET", "/api/auth/me", tok, nil)
|
||||
var me map[string]any
|
||||
json.Unmarshal(w.Body.Bytes(), &me)
|
||||
w = do(h, "DELETE", "/api/users/"+itoa(me["id"]), tok, nil)
|
||||
if w.Code != 400 {
|
||||
t.Fatalf("self-delete want 400 got %d %s", w.Code, w.Body)
|
||||
}
|
||||
// 删 carol → 204,再删 → 404
|
||||
w = do(h, "DELETE", "/api/users/"+itoa(carolID), tok, nil)
|
||||
if w.Code != 204 {
|
||||
t.Fatalf("delete %d %s", w.Code, w.Body)
|
||||
}
|
||||
w = do(h, "DELETE", "/api/users/"+itoa(carolID), tok, nil)
|
||||
if w.Code != 404 {
|
||||
t.Fatalf("redelete want 404 got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadRoleRejected(t *testing.T) {
|
||||
_, _, h, _ := setupAPI(t)
|
||||
tok := adminToken(t, h)
|
||||
w := do(h, "POST", "/api/users", tok, map[string]string{"username": "e", "password": "pw123456", "role": "god"})
|
||||
if w.Code != 400 {
|
||||
t.Fatalf("bad role want 400 got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func findID(rows []map[string]any, name string) float64 {
|
||||
for _, r := range rows {
|
||||
if r["username"] == name {
|
||||
return r["id"].(float64)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func itoa(v any) string {
|
||||
if i, ok := v.(int64); ok {
|
||||
return strconv.FormatInt(i, 10) // DB 行里的 id (如 store.Library.ID)
|
||||
}
|
||||
return strconv.FormatFloat(v.(float64), 'f', 0, 64) // json.Unmarshal 出来的数字
|
||||
}
|
||||
Reference in New Issue
Block a user