package service import ( "testing" "fashionapi/internal/model" "fashionapi/internal/pkg/imgurl" ) // TestGroupSnapImages 验证主副图分组与「副图的副图」上浮归并。 // // 5 张图:A 主,B 副(挂 A);C 主;D 副(挂 C);E 副(挂 B → 应上浮归并到 A) // // 期望 2 组:第 0 组 = A + [B, E],第 1 组 = C + [D]。 func TestGroupSnapImages(t *testing.T) { s := &streetSnapService{img: imgurl.New("", "", "")} imgs := []model.StreetSnapImage{ {ID: 1, Image: "A", Name: "A", IsDetail: 0, ParentImageID: 0}, {ID: 2, Image: "B", Name: "B", IsDetail: 1, ParentImageID: 1}, {ID: 3, Image: "C", Name: "C", IsDetail: 0, ParentImageID: 0}, {ID: 4, Image: "D", Name: "D", IsDetail: 1, ParentImageID: 3}, {ID: 5, Image: "E", Name: "E", IsDetail: 1, ParentImageID: 2}, // 2 是副图 → 上浮到 A } flat, groups := s.groupSnapImages(imgs) if len(flat) != 5 { t.Fatalf("flat 应 5 张,实际 %d", len(flat)) } if len(groups) != 2 { t.Fatalf("groups 应为 2 组,实际 %d", len(groups)) } g0 := groups[0] if g0.Image.Name != "A" { t.Fatalf("第 0 组主图应为 A,实际 %s", g0.Image.Name) } if len(g0.Details) != 2 { t.Fatalf("第 0 组副图应为 2 张,实际 %d", len(g0.Details)) } if g0.Details[0].Name != "B" || g0.Details[1].Name != "E" { t.Fatalf("第 0 组副图顺序应为 [B, E],实际 %s, %s", g0.Details[0].Name, g0.Details[1].Name) } g1 := groups[1] if g1.Image.Name != "C" { t.Fatalf("第 1 组主图应为 C,实际 %s", g1.Image.Name) } if len(g1.Details) != 1 || g1.Details[0].Name != "D" { t.Fatalf("第 1 组副图应为 [D],实际 %d 张", len(g1.Details)) } } // TestGroupSnapImagesOrphan 父引用指向失效行(不存在)时,该图按主图渲染,不丢图。 func TestGroupSnapImagesOrphan(t *testing.T) { s := &streetSnapService{img: imgurl.New("", "", "")} imgs := []model.StreetSnapImage{ {ID: 1, Image: "A", Name: "A", IsDetail: 1, ParentImageID: 99}, // 父 99 不存在 {ID: 2, Image: "B", Name: "B", IsDetail: 0, ParentImageID: 0}, } flat, groups := s.groupSnapImages(imgs) if len(flat) != 2 || len(groups) != 2 { t.Fatalf("孤儿副图应自成主图:flat=%d groups=%d", len(flat), len(groups)) } if groups[0].Image.Name != "A" || len(groups[0].Details) != 0 { t.Fatalf("A 应作为主图且无副图,实际 %s details=%d", groups[0].Image.Name, len(groups[0].Details)) } }