mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-06 13:26:38 +08:00
支持按用户保存播放器与弹幕偏好
在 user 记录上新增播放器音量、弹幕开关、透明度、字号、显示区域、合并偏好、自定义弹幕源以及 dandanplay 应用凭据字段,并提供 PUT /danmaku/settings 局部更新接口,带取值校验。 返回脱敏后的完整渲染配置,绝不回传应用密钥,仅在响应中标记密钥是否已配置。 结果缓存键加入用户 ID 与凭据指纹,避免不同用户或凭据串用缓存;旧版实例级设置仅作为未登录与迁移期的回退。
This commit is contained in:
@@ -133,3 +133,58 @@ func TestGetDanmakuConfigIncludesPerUserMergePreference(t *testing.T) {
|
||||
t.Fatal("config should reflect the persisted merge preference")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateDanmakuSettingsPersistsAllPlayerPreferences(t *testing.T) {
|
||||
svc := newDanmakuSettingsService(t)
|
||||
|
||||
body := "{\"enabled\":false,\"opacity\":0.6,\"font_size\":32,\"area\":0.7,\"merge_sources\":true,\"volume\":0.35,\"source\":\"https://dm.example/base/\",\"app_id\":\"my-app-id\",\"app_key\":\"my-app-secret\"}"
|
||||
c, w := newDanmakuSettingsContext(t, svc, http.MethodPut, "/danmaku/settings", body, "user-1")
|
||||
updateDanmakuSettingsHandler(svc)(c)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want 200 (body=%s)", w.Code, w.Body.String())
|
||||
}
|
||||
if bytes.Contains(w.Body.Bytes(), []byte("my-app-secret")) {
|
||||
t.Fatal("response must never expose the application secret")
|
||||
}
|
||||
var cfg service.DanmakuRenderConfig
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &cfg); err != nil {
|
||||
t.Fatalf("decode: %v", err)
|
||||
}
|
||||
if cfg.Enabled || cfg.Opacity != "0.6" || cfg.FontSize != "32" || cfg.Area != "0.7" {
|
||||
t.Fatalf("unexpected render config: %+v", cfg)
|
||||
}
|
||||
if !cfg.MergeSources || cfg.Volume != 0.35 {
|
||||
t.Fatalf("unexpected user preferences: %+v", cfg)
|
||||
}
|
||||
if cfg.Source != "https://dm.example/base" || cfg.AppID != "my-app-id" || !cfg.AppKeyConfigured {
|
||||
t.Fatalf("unexpected service config: %+v", cfg)
|
||||
}
|
||||
|
||||
user, err := svc.Repo.User.FindByID(t.Context(), "user-1")
|
||||
if err != nil || user == nil {
|
||||
t.Fatalf("read persisted user: %v", err)
|
||||
}
|
||||
if user.DanmakuAppKey != "my-app-secret" || user.PlayerVolume != 0.35 || user.DanmakuSource != "https://dm.example/base" {
|
||||
t.Fatalf("preferences not persisted: %+v", user)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateDanmakuSettingsRejectsInvalidSource(t *testing.T) {
|
||||
svc := newDanmakuSettingsService(t)
|
||||
|
||||
c, w := newDanmakuSettingsContext(t, svc, http.MethodPut, "/danmaku/settings",
|
||||
`{"source":"ftp://dm.example.com"}`, "user-1")
|
||||
updateDanmakuSettingsHandler(svc)(c)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("status = %d, want 400 (body=%s)", w.Code, w.Body.String())
|
||||
}
|
||||
user, err := svc.Repo.User.FindByID(t.Context(), "user-1")
|
||||
if err != nil || user == nil {
|
||||
t.Fatalf("read user: %v", err)
|
||||
}
|
||||
if user.DanmakuSource != "" {
|
||||
t.Fatalf("invalid source was persisted: %q", user.DanmakuSource)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user