package mall import ( "context" "errors" "testing" "git.118im.com/im_team/olons_server/internal/store" ) type fakeRepository struct { items []store.ManualProduct detail *store.ManualProduct } func (f *fakeRepository) ManualProducts(context.Context, int64, int64, int, int) (*store.ManualProductPage, error) { return &store.ManualProductPage{Items: f.items, Total: int64(len(f.items))}, nil } func (f *fakeRepository) ManualProduct(context.Context, int64, int64) (*store.ManualProduct, error) { return f.detail, nil } func TestProductsMapsSafeCard(t *testing.T) { service := New(&fakeRepository{items: []store.ManualProduct{{ID: 4, ProductNo: "DEMO-P-03", CategoryID: 2, CategoryCode: "DAILY", CategoryName: "日用", Name: "体验商品", ShopName: "平台", PriceAmount: 12900, Currency: "CNY", CoverURL: "https://example.com/cover.png", DetailHTML: "

标题

内容

", ClaimedCount: 2, IsRecommended: true, StartAt: "2026-10-01T00:00:00Z", EndAt: "2026-10-31T00:00:00Z"}}}) result, err := service.Products(context.Background(), 0, 0, 1, 20) if err != nil { t.Fatal(err) } if len(result.Items) != 1 || result.Items[0].CoverURL == "" || result.Items[0].Summary != "标题 内容" || !result.Items[0].IsLimited || result.Items[0].EndAt == "" || len(result.Items[0].AvailableActions) != 1 || result.Items[0].AvailableActions[0] != "contact_support" { t.Fatalf("unexpected product: %#v", result.Items) } } func TestProductRejectsUnsafeCoverAndReturnsPlainText(t *testing.T) { service := New(&fakeRepository{detail: &store.ManualProduct{ID: 4, Name: "商品", CoverURL: "javascript:alert(1)", DetailHTML: "

安全说明

"}}) result, err := service.Product(context.Background(), 0, 4) if err != nil { t.Fatal(err) } if result.CoverURL != "" || result.DetailText != "安全说明" { t.Fatalf("unexpected detail: %#v", result) } } func TestProductsValidatesPagination(t *testing.T) { service := New(&fakeRepository{}) if _, err := service.Products(context.Background(), 0, 0, -1, 20); !errors.Is(err, ErrPageInvalid) { t.Fatalf("expected page error, got %v", err) } if _, err := service.Products(context.Background(), 0, -1, 1, 20); !errors.Is(err, ErrCategoryIDInvalid) { t.Fatalf("expected category error, got %v", err) } }