package admin import ( "context" "errors" "testing" "oneblog/internal/model" "oneblog/internal/store" ) func TestAttachLinkCard(t *testing.T) { old := linkFetch t.Cleanup(func() { linkFetch = old }) t.Run("长文不动", func(t *testing.T) { called := false linkFetch = func(context.Context, string) (*model.LinkCard, error) { called = true return nil, nil } in := &model.PostInput{Kind: model.KindLong, ContentMd: "看 https://a.cn"} attachLinkCard(context.Background(), in, nil) if in.LinkCard != nil || called { t.Fatalf("长文不该抓取,card=%+v called=%v", in.LinkCard, called) } }) t.Run("没链接则清空", func(t *testing.T) { linkFetch = func(context.Context, string) (*model.LinkCard, error) { t.Fatal("没链接不该抓") return nil, nil } in := &model.PostInput{Kind: model.KindShort, ContentMd: "纯文本一句"} attachLinkCard(context.Background(), in, &model.LinkCard{URL: "https://old.cn", Title: "旧"}) if in.LinkCard == nil || !in.LinkCard.Empty() { t.Fatalf("应传空卡片清掉旧的,got %+v", in.LinkCard) } }) t.Run("链接未变则沿用不重抓", func(t *testing.T) { linkFetch = func(context.Context, string) (*model.LinkCard, error) { t.Fatal("同一个链接不该重复抓") return nil, nil } cur := &model.LinkCard{URL: "https://a.cn", Title: "已抓过"} in := &model.PostInput{Kind: model.KindShort, ContentMd: "看 https://a.cn"} attachLinkCard(context.Background(), in, cur) if in.LinkCard != cur { t.Fatalf("应沿用旧卡片,got %+v", in.LinkCard) } }) t.Run("新链接则抓取", func(t *testing.T) { var gotURL string linkFetch = func(_ context.Context, u string) (*model.LinkCard, error) { gotURL = u return &model.LinkCard{URL: u, Title: "新卡片"}, nil } in := &model.PostInput{Kind: model.KindShort, ContentMd: "换成 https://b.cn/x。"} attachLinkCard(context.Background(), in, &model.LinkCard{URL: "https://a.cn", Title: "旧"}) if gotURL != "https://b.cn/x" { t.Fatalf("结尾标点没剪掉: %q", gotURL) } if in.LinkCard == nil || in.LinkCard.Title != "新卡片" { t.Fatalf("card=%+v", in.LinkCard) } }) t.Run("抓取失败则清空", func(t *testing.T) { linkFetch = func(context.Context, string) (*model.LinkCard, error) { return nil, errors.New("timeout") } in := &model.PostInput{Kind: model.KindShort, ContentMd: "https://slow.cn"} attachLinkCard(context.Background(), in, &model.LinkCard{URL: "https://a.cn", Title: "旧"}) if in.LinkCard == nil || !in.LinkCard.Empty() { t.Fatalf("失败应清空,got %+v", in.LinkCard) } }) } func TestLinkCardRoundTrip(t *testing.T) { a, _ := newTestAPI(t) card := &model.LinkCard{URL: "https://example.cn/x", Title: "示例标题", Desc: "描述", Site: "example", Image: "https://cdn/i.png"} p, err := a.Store.Create(model.PostInput{Kind: model.KindShort, ContentMd: "看 https://example.cn/x", Status: model.StatusPublished, LinkCard: card}) if err != nil { t.Fatal(err) } if p.LinkCard == nil || p.LinkCard.Title != "示例标题" || p.LinkCard.Image != "https://cdn/i.png" { t.Fatalf("创建后没读回卡片: %+v", p.LinkCard) } // 列表接口也要带上(时间线靠它渲染) page, err := a.Store.List(store.ListOptions{Page: 1, Size: 10}) if err != nil { t.Fatal(err) } if len(page.Items) != 1 || page.Items[0].LinkCard == nil { t.Fatalf("列表未带卡片: %+v", page.Items) } // 空卡片 = 清空 if _, err := a.Store.Update(p.ID, model.PostInput{LinkCard: &model.LinkCard{}}); err != nil { t.Fatal(err) } got, err := a.Store.Get(p.ID) if err != nil { t.Fatal(err) } if got.LinkCard != nil { t.Fatalf("应已清空,got %+v", got.LinkCard) } }