package playletser import ( "encoding/json" "reflect" "testing" ) func TestSeoInfo_UnmarshalJSON_SwaggerShape(t *testing.T) { raw := []byte(`{ "title":"灵气复苏,我成为了万古医圣", "keywords":["灵气复苏,我成为了万古医圣","职场"], "description":"灵气复苏,我成为了万古医圣", "canonicalUrl":"/detail/example-show" }`) var seo SeoInfo if err := json.Unmarshal(raw, &seo); err != nil { t.Fatalf("unmarshal: %v", err) } if seo.Title != "灵气复苏,我成为了万古医圣" { t.Fatalf("title=%q", seo.Title) } if seo.Description != "灵气复苏,我成为了万古医圣" { t.Fatalf("description=%q", seo.Description) } if seo.CanonicalURL != "/detail/example-show" { t.Fatalf("canonicalUrl=%q", seo.CanonicalURL) } want := []string{"灵气复苏,我成为了万古医圣", "职场"} if !reflect.DeepEqual(seo.Keywords, want) { t.Fatalf("keywords=%v", seo.Keywords) } } func TestSeoInfo_UnmarshalJSON_AliasesAndStringKeywords(t *testing.T) { raw := []byte(`{ "webTitle":"镇龙", "webDescription":"短剧简介", "keyworld":"镇龙,玄幻", "canonical":"/detail/example-show" }`) var seo SeoInfo if err := json.Unmarshal(raw, &seo); err != nil { t.Fatalf("unmarshal: %v", err) } if seo.Title != "镇龙" || seo.Description != "短剧简介" { t.Fatalf("got title=%q desc=%q", seo.Title, seo.Description) } if seo.CanonicalURL != "/detail/example-show" { t.Fatalf("canonicalUrl=%q", seo.CanonicalURL) } want := []string{"镇龙", "玄幻"} if !reflect.DeepEqual(seo.Keywords, want) { t.Fatalf("keywords=%v", seo.Keywords) } } func TestAPIEnvelope_UnmarshalJSON_ObjectData(t *testing.T) { raw := []byte(`{"code":200,"msg":"ok","data":{"id":10741,"title":"都市逍遥神医","seoInfo":""}}`) var env APIEnvelope[PlayletInfoResp] if err := json.Unmarshal(raw, &env); err != nil { t.Fatalf("unmarshal: %v", err) } if env.Code != 200 || env.Data.ID != 10741 || env.Data.Title != "都市逍遥神医" { t.Fatalf("env=%+v data=%+v", env, env.Data) } } func TestAPIEnvelope_UnmarshalJSON_StringEncodedData(t *testing.T) { raw := []byte(`{"code":200,"msg":"ok","data":"{\"id\":10741,\"title\":\"都市逍遥神医\",\"seoInfo\":\"\"}"}`) var env APIEnvelope[PlayletInfoResp] if err := json.Unmarshal(raw, &env); err != nil { t.Fatalf("unmarshal: %v", err) } if env.Data.ID != 10741 || env.Data.Title != "都市逍遥神医" { t.Fatalf("data=%+v", env.Data) } } func TestAPIEnvelope_UnmarshalJSON_EmptyStringData(t *testing.T) { raw := []byte(`{"code":200,"msg":"ok","data":""}`) var env APIEnvelope[PlayletInfoResp] if err := json.Unmarshal(raw, &env); err != nil { t.Fatalf("unmarshal: %v", err) } if env.Data.ID != 0 { t.Fatalf("data=%+v", env.Data) } } func TestPlayletInfoResp_SeoInfoEmptyString(t *testing.T) { raw := []byte(`{"id":10741,"title":"都市逍遥神医","seoInfo":""}`) var info PlayletInfoResp if err := json.Unmarshal(raw, &info); err != nil { t.Fatalf("unmarshal: %v", err) } if info.ID != 10741 || info.Title != "都市逍遥神医" { t.Fatalf("info=%+v", info) } if info.SeoInfo.Title != "" { t.Fatalf("seoInfo=%+v", info.SeoInfo) } } func TestPlayletInfoResp_KeepsSeoInfo(t *testing.T) { raw := []byte(`{"id":10619,"slug":"example-show","title":"剧名","seoInfo":{"title":"SEO标题","description":"SEO描述","keywords":["a","b"],"canonicalUrl":"/detail/example-show"}}`) var info PlayletInfoResp if err := json.Unmarshal(raw, &info); err != nil { t.Fatalf("unmarshal: %v", err) } if info.SeoInfo.Title != "SEO标题" || info.SeoInfo.CanonicalURL != "/detail/example-show" { t.Fatalf("seoInfo=%+v", info.SeoInfo) } } func TestPlayletChapterInfoResp_KeepsSeoInfo(t *testing.T) { raw := []byte(`{"id":12743,"playletId":10619,"currentEpisode":1,"title":"1","seoInfo":{"title":"剧名 1","description":"剧名","keywords":["剧名","短剧"],"canonicalUrl":"/play/example-show/12743"}}`) var info PlayletChapterInfoResp if err := json.Unmarshal(raw, &info); err != nil { t.Fatalf("unmarshal: %v", err) } if info.SeoInfo.Title != "剧名 1" || info.SeoInfo.CanonicalURL != "/play/example-show/12743" { t.Fatalf("seoInfo=%+v", info.SeoInfo) } } func TestResolvePlayPageSEO_PrefersChapter(t *testing.T) { chapter := &PlayletChapterInfoResp{ CurrentEpisode: 1, SeoInfo: SeoInfo{ Title: "章节标题", Description: "章节描述", Keywords: []string{"章节"}, CanonicalURL: "/play/example-show/2", }, } playlet := &PlayletInfoResp{ Title: "短剧名", SeoInfo: SeoInfo{ Title: "短剧SEO", Description: "短剧描述", Keywords: []string{"短剧"}, CanonicalURL: "/detail/example-show", }, } seo := ResolvePlayPageSEO(chapter, playlet) if seo.Title != "章节标题" || seo.CanonicalURL != "/play/example-show/2" { t.Fatalf("seo=%+v", seo) } if !reflect.DeepEqual(seo.Keywords, []string{"章节"}) { t.Fatalf("keywords=%v", seo.Keywords) } } func TestResolvePlayPageTitle_UsesChapterSeoTitle(t *testing.T) { chapter := &PlayletChapterInfoResp{ CurrentEpisode: 1, SeoInfo: SeoInfo{Title: "灵气复苏,我成为了万古医圣 1"}, } playlet := &PlayletInfoResp{Title: "灵气复苏,我成为了万古医圣"} if got := ResolvePlayPageTitle(chapter, playlet); got != "灵气复苏,我成为了万古医圣 1" { t.Fatalf("title=%q", got) } }