Files
StarlightRadio/test_write.py
T
Xiao-no-love 5d5d5cce19 v2.2+v2.3: 前端增强与 UI 去 AI 味重构
v2.2 前端增强:
- 站内 HLS 收听页 (#pageLive),hls.js 本地化 vendor/hls.min.js
- 设置页 (缓存/配置/日志)
- 上传进度百分比 (XHR upload.onprogress)
- 资源列表排序 (时间/热度/名称 ×升降)
- 面板正在播放实时化 (接 playlist-update/song-finished,删死监听)
- 死代码清理 + forgetSong 内存泄漏修复 + CORS 非法头移除
- start.cmd 托管启动脚本 (set "VAR=val" 避免尾部空格)

v2.3 UI 去 AI 味 (依据 ibelick/ui-skills baseline-ui):
- 频道管理+切换合并为单一入口 #btnStreamMgr.channel-btn
  (删除 header 的 #streamSelect 下拉,弹窗内统一切换/删除/新建)
- 清除全部 CSS 渐变与 glow: 橙红 #ff5f6d→#ffc371、紫 #8b5cf6、
  径向光晕、缓存条渐变 → 全部改为 accent/token 纯色
- live 区、modal 区硬编码色统一归 CSS 变量 token

测试: api 16/16, e2e 17/17, write 5/5 全绿
2026-09-24 21:55:23 +08:00

90 lines
3.4 KiB
Python

import urllib.request, urllib.error, http.cookiejar, json, sys, os, io, uuid
BASE = "http://127.0.0.1:3000"
cj = http.cookiejar.CookieJar()
op = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
def call(path, method="GET", data=None):
body = json.dumps(data).encode() if data is not None else None
req = urllib.request.Request(BASE + path, data=body, method=method)
if body: req.add_header("Content-Type", "application/json")
try:
r = op.open(req, timeout=30)
return r.status, r.read()
except urllib.error.HTTPError as e:
return e.code, e.read()
results = []
def check(name, cond, extra=""):
results.append((name, cond)); print(("PASS" if cond else "FAIL"), name, extra)
# 登录
call("/api/auth/login", "POST", {"password": "test123"})
# ---------- 读基线资源数 ----------
st, body0 = call("/api/resources")
BASE_N = len(json.loads(body0)["list"])
print(" 基线资源数:", BASE_N)
# ---------- 导入测试 ----------
tmp_file = r"F:\music_online\demo\tmp\test_import.mp3"
boundary = "----test" + uuid.uuid4().hex
with open(tmp_file, "rb") as f:
audio_data = f.read()
title = "测试导入歌"
artist = "测试作者"
parts = []
def add_field(name, value):
parts.append(("--" + boundary + "\r\n").encode())
parts.append(('Content-Disposition: form-data; name="%s"\r\n\r\n' % name).encode())
parts.append((value + "\r\n").encode())
def add_file(name, filename, content):
parts.append(("--" + boundary + "\r\n").encode())
parts.append(('Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (name, filename)).encode())
parts.append(("Content-Type: audio/mpeg\r\n\r\n").encode())
parts.append(content)
parts.append(b"\r\n")
add_field("title", title)
add_field("artist", artist)
add_file("audio", "测试导入歌.mp3", audio_data)
parts.append(("--" + boundary + "--\r\n").encode())
body = b"".join(parts)
req = urllib.request.Request(BASE + "/api/music/import", data=body, method="POST")
req.add_header("Content-Type", "multipart/form-data; boundary=" + boundary)
try:
r = op.open(req, timeout=60)
d = json.loads(r.read())
check("导入音频", r.status == 200 and d.get("ok"), str(d)[:120])
imported_file = d.get("file")
print(" 导入文件名:", imported_file)
print(" 元数据:", json.dumps(d.get("song", {}), ensure_ascii=False)[:200])
except urllib.error.HTTPError as e:
check("导入音频", False, f"HTTP {e.code}: {e.read()[:200]}")
imported_file = None
# 确认资源数增加
st, body = call("/api/resources")
d = json.loads(body)
check(f"资源数变为{BASE_N+1}", len(d["list"]) == BASE_N + 1, f"{len(d['list'])}")
# ---------- 删除测试 ----------
if imported_file:
st, body = call("/api/music/delete", "POST", {"file": imported_file})
d = json.loads(body)
check("删除音频", st == 200 and d.get("ok"), str(d)[:120])
# 确认文件没了
fp = os.path.join(r"F:\music_online\demo\audio", imported_file)
check("音频文件已删", not os.path.exists(fp))
# 确认资源数恢复
st, body = call("/api/resources")
d = json.loads(body)
check(f"资源数恢复为{BASE_N}", len(d["list"]) == BASE_N, f"{len(d['list'])}")
else:
check("删除音频", False, "无导入文件")
print("\n=== 汇总:", sum(1 for _,c in results if c), "/", len(results), "通过 ===")
sys.exit(0 if all(c for _,c in results) else 1)