Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YZ4DskSRKsSiheQonFtQvx
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/wangjia/jiu/backend/internal/model"
|
||||
"github.com/wangjia/jiu/backend/testutil"
|
||||
)
|
||||
|
||||
func setupPublicRouter(db *gorm.DB) *gin.Engine {
|
||||
h := NewPublicHandler(db)
|
||||
r := gin.New()
|
||||
r.Use(gin.Recovery())
|
||||
r.GET("/api/v1/public/shops/:shop_code/products", h.ListShopProducts)
|
||||
return r
|
||||
}
|
||||
|
||||
// 给商品补 public_id(CreateTestProduct 默认不设)
|
||||
func setPublicID(db *gorm.DB, productID uint64, pub string) {
|
||||
require := func(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
require(db.Model(&model.Product{}).Where("id = ?", productID).Update("public_id", pub).Error)
|
||||
}
|
||||
|
||||
func addInventory(db *gorm.DB, shopID, warehouseID, productID uint64, qty float64) {
|
||||
wid := warehouseID
|
||||
pid := productID
|
||||
if err := db.Create(&model.Inventory{
|
||||
ShopID: shopID,
|
||||
WarehouseID: &wid,
|
||||
ProductID: &pid,
|
||||
Quantity: qty,
|
||||
}).Error; err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicHandler_ListShopProducts_InStockOnly(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
shop := testutil.CreateTestShop(db, "PUB001")
|
||||
wh := testutil.CreateTestWarehouse(db, shop.ID, "仓")
|
||||
r := setupPublicRouter(db)
|
||||
|
||||
// A:有库存 5 → 应出现,quantity=5
|
||||
pa := testutil.CreateTestProduct(db, shop.ID, "茅台A")
|
||||
setPublicID(db, pa.ID, "pub-a")
|
||||
addInventory(db, shop.ID, wh.ID, pa.ID, 5)
|
||||
|
||||
// B:有 public_id 但无库存 → 不出现
|
||||
pb := testutil.CreateTestProduct(db, shop.ID, "五粮液B")
|
||||
setPublicID(db, pb.ID, "pub-b")
|
||||
|
||||
// C:两条库存 3+2 → 出现,quantity=5
|
||||
pc := testutil.CreateTestProduct(db, shop.ID, "汾酒C")
|
||||
setPublicID(db, pc.ID, "pub-c")
|
||||
addInventory(db, shop.ID, wh.ID, pc.ID, 3)
|
||||
addInventory(db, shop.ID, wh.ID, pc.ID, 2)
|
||||
|
||||
// D:有库存但无 public_id → 不出现
|
||||
pd := testutil.CreateTestProduct(db, shop.ID, "无公开D")
|
||||
addInventory(db, shop.ID, wh.ID, pd.ID, 9)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/api/v1/public/shops/PUB001/products", nil)
|
||||
r.ServeHTTP(w, req)
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
|
||||
// 只 A、C 两个有库存 + 有 public_id
|
||||
assert.Equal(t, float64(2), resp["total"])
|
||||
data := resp["data"].([]interface{})
|
||||
require.Len(t, data, 2)
|
||||
|
||||
byName := map[string]map[string]interface{}{}
|
||||
for _, it := range data {
|
||||
m := it.(map[string]interface{})
|
||||
byName[m["name"].(string)] = m
|
||||
}
|
||||
|
||||
require.Contains(t, byName, "茅台A")
|
||||
require.Contains(t, byName, "汾酒C")
|
||||
assert.NotContains(t, byName, "五粮液B") // 无库存
|
||||
assert.NotContains(t, byName, "无公开D") // 无 public_id
|
||||
|
||||
// 数量正确(C 聚合 3+2=5)
|
||||
assert.Equal(t, float64(5), byName["茅台A"]["quantity"])
|
||||
assert.Equal(t, float64(5), byName["汾酒C"]["quantity"])
|
||||
// 带上了序列号 code
|
||||
assert.Equal(t, "P-茅台A", byName["茅台A"]["code"])
|
||||
}
|
||||
|
||||
func TestPublicHandler_ListShopProducts_Isolation(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
shopA := testutil.CreateTestShop(db, "PUBA")
|
||||
shopB := testutil.CreateTestShop(db, "PUBB")
|
||||
whB := testutil.CreateTestWarehouse(db, shopB.ID, "仓B")
|
||||
r := setupPublicRouter(db)
|
||||
|
||||
// B 店有个有库存商品
|
||||
pb := testutil.CreateTestProduct(db, shopB.ID, "他店商品")
|
||||
setPublicID(db, pb.ID, "pub-x")
|
||||
addInventory(db, shopB.ID, whB.ID, pb.ID, 7)
|
||||
|
||||
// 查 A 店:看不到 B 店商品
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/api/v1/public/shops/"+shopA.Code+"/products", nil)
|
||||
r.ServeHTTP(w, req)
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Equal(t, float64(0), resp["total"])
|
||||
}
|
||||
Reference in New Issue
Block a user