package handler import ( "fmt" "net/http" "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/middleware" "github.com/wangjia/jiu/backend/internal/model" "github.com/wangjia/jiu/backend/internal/service" "github.com/wangjia/jiu/backend/testutil" ) // setupPayRouter 独立路由:仅挂 payH.Purchases(仓里暂无 pay handler 测试先例, // 不复用 setupProtectedRouter 以免污染其他测试的路由表;判权写法与 Purchase/Cancel 同构)。 func setupPayRouter(db *gorm.DB) *gin.Engine { payH := NewPayHandler(service.NewPayService(db, "http://pay.invalid", "test-secret", "")) r := gin.New() r.Use(gin.Recovery()) api := r.Group("/api/v1") api.Use(middleware.JWT(db)) api.GET("/license/purchases", payH.Purchases) return r } func seedPurchase(t *testing.T, db *gorm.DB, shopID, userID uint64, otn, status string, amountMinor int64) { t.Helper() require.NoError(t, db.Create(&model.LicensePurchase{ ShopID: shopID, UserID: userID, ProductBizCode: "monthly_standard", AmountMinor: amountMinor, Currency: "CNY", OutTradeNo: otn, Status: status, }).Error) } func TestPayHandler_Purchases_OperatorForbidden(t *testing.T) { db := testutil.SetupTestDB() shop := testutil.CreateTestShop(db, "PHDL01") op := testutil.CreateTestUser(db, shop.ID, "op1", "pass", "operator") token := getAuthToken(op.ID, shop.ID, "operator") r := setupPayRouter(db) w := makeRequest(r, "GET", "/api/v1/license/purchases", token, nil) assert.Equal(t, http.StatusForbidden, w.Code) } func TestPayHandler_Purchases_ReadonlyForbidden(t *testing.T) { db := testutil.SetupTestDB() shop := testutil.CreateTestShop(db, "PHDL02") ro := testutil.CreateTestUser(db, shop.ID, "ro1", "pass", "readonly") token := getAuthToken(ro.ID, shop.ID, "readonly") r := setupPayRouter(db) w := makeRequest(r, "GET", "/api/v1/license/purchases", token, nil) assert.Equal(t, http.StatusForbidden, w.Code) } func TestPayHandler_Purchases_AdminOK(t *testing.T) { db := testutil.SetupTestDB() shop := testutil.CreateTestShop(db, "PHDL03") admin := testutil.CreateTestUser(db, shop.ID, "admin1", "pass", "admin") token := getAuthToken(admin.ID, shop.ID, "admin") seedPurchase(t, db, shop.ID, admin.ID, "phdl-1", "paid", 29900) seedPurchase(t, db, shop.ID, admin.ID, "phdl-2", "pending", 29900) r := setupPayRouter(db) w := makeRequest(r, "GET", "/api/v1/license/purchases", token, nil) assert.Equal(t, http.StatusOK, w.Code) resp := parseResponse(w) data, ok := resp["data"].(map[string]interface{}) require.True(t, ok, "响应应含 data") assert.EqualValues(t, 2, data["total"]) summary, ok := data["summary"].(map[string]interface{}) require.True(t, ok) assert.EqualValues(t, 1, summary["paid_count"]) assert.EqualValues(t, 1, summary["pending_count"]) assert.EqualValues(t, 2, summary["total_count"]) } func TestPayHandler_Purchases_SuperadminOK(t *testing.T) { db := testutil.SetupTestDB() shop := testutil.CreateTestShop(db, "PHDL04") sa := testutil.CreateTestUser(db, shop.ID, "sa1", "pass", "superadmin") token := getAuthToken(sa.ID, shop.ID, "superadmin") r := setupPayRouter(db) w := makeRequest(r, "GET", "/api/v1/license/purchases", token, nil) assert.Equal(t, http.StatusOK, w.Code) } func TestPayHandler_Purchases_InvalidStatusBadRequest(t *testing.T) { db := testutil.SetupTestDB() shop := testutil.CreateTestShop(db, "PHDL05") admin := testutil.CreateTestUser(db, shop.ID, "admin2", "pass", "admin") token := getAuthToken(admin.ID, shop.ID, "admin") r := setupPayRouter(db) w := makeRequest(r, "GET", "/api/v1/license/purchases?status=bogus", token, nil) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestPayHandler_Purchases_PageSizeClamped(t *testing.T) { db := testutil.SetupTestDB() shop := testutil.CreateTestShop(db, "PHDL06") admin := testutil.CreateTestUser(db, shop.ID, "admin3", "pass", "admin") token := getAuthToken(admin.ID, shop.ID, "admin") for i := 0; i < 3; i++ { seedPurchase(t, db, shop.ID, admin.ID, fmt.Sprintf("phdl6-%d", i), "paid", 100) } r := setupPayRouter(db) // page_size 请求 500,服务端应上限 clamp 到 100(不报错,正常 200) w := makeRequest(r, "GET", "/api/v1/license/purchases?page_size=500", token, nil) assert.Equal(t, http.StatusOK, w.Code) }