//go:build integration // 集成测试:公开仓储方法必须读视图(读不到 pending),后台方法必须读基表(读得到 pending)。 package repository import ( "context" "errors" "strconv" "testing" "fashionapi/internal/dto" "fashionapi/internal/model" ) // TestPublicReadHidesUnpublishedRunway 走秀公开列表/详情/图片看不到 pending;后台 GetForEdit 看得到。 func TestPublicReadHidesUnpublishedRunway(t *testing.T) { db := testDB(t) applyMigration(t, db, "2026-09-22-01-single-table-publish.sql") ctx := context.Background() repo := NewArticleRepository(db) const year = 1997 id := seedRunway(t, db, model.StatusPending, year) idStr := strconv.FormatUint(uint64(id), 10) if _, err := repo.FindByID(ctx, idStr); !errors.Is(err, ErrNotFound) { t.Fatalf("pending 走秀详情应 ErrNotFound,实际 %v", err) } imgs, err := repo.ListImages(ctx, idStr) if err != nil { t.Fatalf("ListImages 出错: %v", err) } if len(imgs) != 0 { t.Fatalf("pending 走秀的图片不应公开,实际 %d 张", len(imgs)) } _, total, err := repo.List(ctx, dto.ArticleQuery{Year: year, Size: 20}) if err != nil { t.Fatalf("List 出错: %v", err) } if total != 0 { t.Fatalf("pending 走秀不应出现在公开列表,实际 total=%d", total) } // 后台读基表:必须能看到这条待审记录与其图片,否则审核页是空的。 rw, baseImgs, err := repo.GetForEdit(ctx, id) if err != nil { t.Fatalf("后台 GetForEdit 应读到 pending 行: %v", err) } if rw == nil || len(baseImgs) == 0 { t.Fatalf("后台应读到 pending 行与其图片,实际 rw=%v imgs=%d", rw != nil, len(baseImgs)) } // 置为已发布后,公开侧才可见。 if err := db.Model(&model.BrandRunway{}).Where("id = ?", id).Update("status", model.StatusPublished).Error; err != nil { t.Fatalf("置为已发布失败: %v", err) } if _, err := repo.FindByID(ctx, idStr); err != nil { t.Fatalf("已发布走秀详情应可读: %v", err) } _, total, err = repo.List(ctx, dto.ArticleQuery{Year: year, Size: 20}) if err != nil { t.Fatalf("List 出错: %v", err) } if total != 1 { t.Fatalf("已发布走秀应出现在公开列表,实际 total=%d", total) } } // TestPublicReadHidesUnpublishedStreet 街拍公开列表/详情/图片看不到 pending;后台 GetForEdit 看得到。 func TestPublicReadHidesUnpublishedStreet(t *testing.T) { db := testDB(t) applyMigration(t, db, "2026-09-22-01-single-table-publish.sql") ctx := context.Background() repo := NewStreetSnapRepository(db) const year = 1996 id := seedStreetSnap(t, db, model.StatusPending, year) idStr := strconv.FormatUint(uint64(id), 10) if _, err := repo.FindByID(ctx, idStr); !errors.Is(err, ErrNotFound) { t.Fatalf("pending 街拍详情应 ErrNotFound,实际 %v", err) } imgs, err := repo.ListImages(ctx, idStr) if err != nil { t.Fatalf("ListImages 出错: %v", err) } if len(imgs) != 0 { t.Fatalf("pending 街拍的图片不应公开,实际 %d 张", len(imgs)) } _, total, err := repo.List(ctx, dto.StreetSnapQuery{City: "ViewTestCity", Size: 20}) if err != nil { t.Fatalf("List 出错: %v", err) } if total != 0 { t.Fatalf("pending 街拍不应出现在公开列表,实际 total=%d", total) } snap, baseImgs, err := repo.GetForEdit(ctx, id) if err != nil { t.Fatalf("后台 GetForEdit 应读到 pending 行: %v", err) } if snap == nil || len(baseImgs) == 0 { t.Fatalf("后台应读到 pending 行与其图片,实际 snap=%v imgs=%d", snap != nil, len(baseImgs)) } // 后台列表 ListAdmin 读基表:必须能看到这条待审记录,否则审核员无从下手。 _, adminTotal, err := repo.ListAdmin(ctx, dto.StreetSnapQuery{City: "ViewTestCity", Size: 20}) if err != nil { t.Fatalf("ListAdmin 出错: %v", err) } if adminTotal != 1 { t.Fatalf("后台列表应看到 pending 街拍,实际 total=%d", adminTotal) } if err := db.Model(&model.StreetSnap{}).Where("id = ?", id).Update("status", model.StatusPublished).Error; err != nil { t.Fatalf("置为已发布失败: %v", err) } _, total, err = repo.List(ctx, dto.StreetSnapQuery{City: "ViewTestCity", Size: 20}) if err != nil { t.Fatalf("List 出错: %v", err) } if total != 1 { t.Fatalf("已发布街拍应出现在公开列表,实际 total=%d", total) } }