feat: 书库导入导出/图片变体/书籍搜索/小组件运行时等
新增: - 书库导入导出(library_import/library_export)及测试 - 图片变体生成(image_variants)与响应式图片(responsiveImage) - 书籍搜索(bookSearch)+ BookSearch/LibrarySearchGrid 组件 - 小组件运行时(widgetRuntime)与静态检查(widgetLint) - 上传缓存中间件(upload_cache)与字体 CSS 提取脚本 其它: - 后端 handlers/services 全量调整 - 前端页面、组件、库函数与配置更新
This commit is contained in:
@@ -250,8 +250,7 @@ func TestAdminMediaLibraryAttachSources(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatal("comment image missing")
|
||||
}
|
||||
if cimg.SourceURL != fmt.Sprintf("/post/%d#comment-", post.ID) &&
|
||||
!strings.HasPrefix(cimg.SourceURL, fmt.Sprintf("/post/%d#comment-", post.ID)) {
|
||||
if cimg.SourceURL != fmt.Sprintf("/post/%d#comment-1", post.ID) {
|
||||
t.Fatalf("comment source url wrong: %+v", cimg)
|
||||
}
|
||||
if !strings.Contains(cimg.SourceLabel, "下的评论") {
|
||||
@@ -259,6 +258,63 @@ func TestAdminMediaLibraryAttachSources(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdminMediaLibraryBookCategory(t *testing.T) {
|
||||
s, dir := newMediaLibraryService(t)
|
||||
|
||||
// 书籍封面(本地磁盘)与正文插图(远程对象),另有一张普通帖子插图
|
||||
writeMediaFile(t, dir, "images/cover.webp", []byte("fake-webp-bytes"))
|
||||
|
||||
if err := s.db.Create(&model.User{Username: "alice", Nickname: "爱丽丝"}).Error; err != nil {
|
||||
t.Fatalf("create user: %v", err)
|
||||
}
|
||||
var alice model.User
|
||||
if err := s.db.Where("username = ?", "alice").First(&alice).Error; err != nil {
|
||||
t.Fatalf("load user: %v", err)
|
||||
}
|
||||
created := time.Date(2026, 9, 1, 10, 0, 0, 0, time.UTC)
|
||||
mkAtt := func(source, url string) {
|
||||
if err := s.db.Create(&model.Attachment{
|
||||
UserID: alice.ID, Kind: model.AttachmentKindImage, Source: source,
|
||||
URL: url, MIME: "image/webp", Size: 100, Width: 10, Height: 10,
|
||||
CreatedAt: created,
|
||||
}).Error; err != nil {
|
||||
t.Fatalf("create attachment %s: %v", source, err)
|
||||
}
|
||||
}
|
||||
mkAtt(model.AttachmentSourceLibraryCover, "/uploads/images/cover.webp")
|
||||
mkAtt(model.AttachmentSourceLibraryContent, "/api/media/book-content")
|
||||
mkAtt(model.AttachmentSourcePost, "/api/media/post-image")
|
||||
|
||||
items, counts, err := s.AdminMediaLibrary()
|
||||
if err != nil {
|
||||
t.Fatalf("AdminMediaLibrary: %v", err)
|
||||
}
|
||||
byURL := map[string]MediaLibraryItem{}
|
||||
for _, it := range items {
|
||||
byURL[it.URL] = it
|
||||
}
|
||||
|
||||
// 封面(磁盘)与正文插图(远程)都归“书籍”
|
||||
for _, u := range []string{"/uploads/images/cover.webp", "/api/media/book-content"} {
|
||||
it, ok := byURL[u]
|
||||
if !ok {
|
||||
t.Fatalf("%s missing", u)
|
||||
}
|
||||
if it.Category != "book" || it.CategoryName != "书籍" {
|
||||
t.Fatalf("%s should be book category, got %q/%q", u, it.Category, it.CategoryName)
|
||||
}
|
||||
}
|
||||
|
||||
// 普通帖子插图仍归 image
|
||||
if post := byURL["/api/media/post-image"]; post.Category != "image" {
|
||||
t.Fatalf("post image should stay image category, got %q", post.Category)
|
||||
}
|
||||
|
||||
if counts["book"] != 2 || counts["image"] != 1 {
|
||||
t.Fatalf("counts wrong: %v", counts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMediaThumb(t *testing.T) {
|
||||
s, dir := newMediaLibraryService(t)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user