134 lines
5.1 KiB
Python
134 lines
5.1 KiB
Python
|
|
import urllib.request
|
|
import json
|
|
import time
|
|
|
|
with open("G:/erp/.test_token") as f:
|
|
token = f.read().strip()
|
|
|
|
base = "http://localhost:3000"
|
|
|
|
def api(method, path, data=None, tok=None):
|
|
url = base + path
|
|
headers = {"Content-Type": "application/json"}
|
|
if tok:
|
|
headers["Authorization"] = f"Bearer {tok}"
|
|
body = json.dumps(data).encode("utf-8") if data else None
|
|
req = urllib.request.Request(url, data=body, headers=headers, method=method)
|
|
start = int(time.time()*1000)
|
|
try:
|
|
with urllib.request.urlopen(req) as resp:
|
|
elapsed = int(time.time()*1000) - start
|
|
return resp.status, json.loads(resp.read().decode("utf-8")), elapsed
|
|
except urllib.error.HTTPError as e:
|
|
elapsed = int(time.time()*1000) - start
|
|
try:
|
|
rbody = json.loads(e.read().decode("utf-8"))
|
|
except:
|
|
rbody = {"raw": str(e)}
|
|
return e.code, rbody, elapsed
|
|
|
|
results = []
|
|
|
|
def log(test_id, name, code, ms, details):
|
|
status = "PASS" if (200 <= code < 300) or (code == 400) or (code == 404) or (code == 409) else "FAIL"
|
|
print(f" [{status}] {name}: HTTP {code}, {ms}ms - {details[:100]}")
|
|
results.append((test_id, name, status, code, ms, details))
|
|
|
|
print("=" * 60)
|
|
print("Part 2: User Management Endpoints")
|
|
print("=" * 60)
|
|
|
|
# 2.1 GET /users
|
|
code, body, ms = api("GET", "/api/v1/users", tok=token)
|
|
data = body.get("data", {})
|
|
items = data.get("items", [])
|
|
log("2.1", "GET /users - list", code, ms, f"total={data.get("total")}, items={len(items)}, success={body.get("success")}")
|
|
|
|
# 2.2 GET /users with pagination
|
|
code, body, ms = api("GET", "/api/v1/users?page=1&page_size=1", tok=token)
|
|
data = body.get("data", {})
|
|
log("2.2", "GET /users?page=1&page_size=1", code, ms, f"total={data.get("total")}, page={data.get("page")}, page_size={data.get("page_size")}, items={len(data.get("items",[]))}")
|
|
|
|
# 2.3 POST /users - create
|
|
code, body, ms = api("POST", "/api/v1/users", {
|
|
"username": "test_user_api",
|
|
"password": "Test@2026!",
|
|
"display_name": "API Test User",
|
|
"email": "test@api.com",
|
|
"phone": "13800138000"
|
|
}, tok=token)
|
|
ud = body.get("data", {})
|
|
test_user_id = ud.get("id", "") if ud else ""
|
|
log("2.3", "POST /users - create", code, ms, f"id={test_user_id}, username={ud.get("username")}, status={ud.get("status")}, pw_in_resp={"password" in ud}" if ud else f"FAIL: {body}")
|
|
|
|
if test_user_id:
|
|
with open("G:/erp/.test_user_id", "w") as f:
|
|
f.write(test_user_id)
|
|
|
|
# 2.4 duplicate username
|
|
code, body, ms = api("POST", "/api/v1/users", {
|
|
"username": "test_user_api",
|
|
"password": "Test@2026!",
|
|
"display_name": "Duplicate User"
|
|
}, tok=token)
|
|
log("2.4", "POST /users - duplicate username", code, ms, f"Expected 400/409, got {code}: {json.dumps(body, ensure_ascii=False)[:100]}")
|
|
|
|
# 2.5 missing fields
|
|
code, body, ms = api("POST", "/api/v1/users", {
|
|
"display_name": "No username"
|
|
}, tok=token)
|
|
log("2.5", "POST /users - missing fields", code, ms, f"code={code}")
|
|
|
|
# 2.6 short password
|
|
code, body, ms = api("POST", "/api/v1/users", {
|
|
"username": "short_pwd_user",
|
|
"password": "12",
|
|
"display_name": "Short Pwd"
|
|
}, tok=token)
|
|
log("2.6", "POST /users - short password", code, ms, f"code={code}, body={json.dumps(body, ensure_ascii=False)[:100]}")
|
|
|
|
if test_user_id:
|
|
# 2.7 GET single user
|
|
code, body, ms = api("GET", f"/api/v1/users/{test_user_id}", tok=token)
|
|
ud = body.get("data", {})
|
|
log("2.7", "GET /users/{id}", code, ms, f"found={ud.get("id")==test_user_id}, pw_in_resp={"password" in ud}, status={ud.get("status")}" if ud else f"body={body}")
|
|
|
|
# 2.8 GET invalid UUID
|
|
code, body, ms = api("GET", "/api/v1/users/00000000-0000-0000-0000-000000000000", tok=token)
|
|
log("2.8", "GET /users/invalid-uuid", code, ms, f"code={code}")
|
|
|
|
# 2.9 PUT - normal update
|
|
code, body, ms = api("PUT", f"/api/v1/users/{test_user_id}", {
|
|
"display_name": "Updated User",
|
|
"email": "updated@api.com",
|
|
"version": 1
|
|
}, tok=token)
|
|
ud = body.get("data", {})
|
|
log("2.9", "PUT /users/{id} - update", code, ms, f"display_name={ud.get("display_name")}, email={ud.get("email")}, version={ud.get("version")}" if ud else f"body={body}")
|
|
|
|
# 2.10 PUT - optimistic lock conflict
|
|
code, body, ms = api("PUT", f"/api/v1/users/{test_user_id}", {
|
|
"display_name": "Conflict",
|
|
"version": 999
|
|
}, tok=token)
|
|
log("2.10", "PUT /users/{id} - version conflict", code, ms, f"code={code}, body={json.dumps(body, ensure_ascii=False)[:100]}")
|
|
|
|
# 2.11 assign roles
|
|
code_r, body_r, _ = api("GET", "/api/v1/roles", tok=token)
|
|
roles = body_r.get("data", {}).get("items", [])
|
|
if roles:
|
|
admin_role_id = roles[0]["id"]
|
|
code, body, ms = api("POST", f"/api/v1/users/{test_user_id}/roles", {"role_ids": [admin_role_id]}, tok=token)
|
|
log("2.11", "POST /users/{id}/roles", code, ms, f"code={code}")
|
|
else:
|
|
log("2.11", "POST /users/{id}/roles", 0, 0, "SKIP: no roles found")
|
|
|
|
print("
|
|
" + "=" * 60)
|
|
print("Part 2 Summary")
|
|
print("=" * 60)
|
|
passed = sum(1 for r in results if r[2]=="PASS")
|
|
failed = sum(1 for r in results if r[2]=="FAIL")
|
|
print(f"Passed: {passed}, Failed: {failed}, Total: {len(results)}")
|