Files
jiu/backend/internal/handler/testhelper_test.go
T
wangjia 08f9e20010
Deploy Server / release-deploy-server (push) Successful in 1m30s
chore: release server-v1.0.76
修复编辑入库单草稿后合计金额被清零(Update 漏累加 total)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YZ4DskSRKsSiheQonFtQvx
2026-06-22 20:15:38 +08:00

147 lines
4.2 KiB
Go

package handler
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"github.com/wangjia/jiu/backend/internal/middleware"
"github.com/wangjia/jiu/backend/internal/service"
"github.com/wangjia/jiu/backend/testutil"
)
// setupProtectedRouter 创建带 JWT 中间件的测试路由
func setupProtectedRouter(db *gorm.DB) *gin.Engine {
stockSvc := service.NewStockService(db)
licenseSvc := service.NewLicenseService(db)
productH := NewProductHandler(db)
stockInH := NewStockInHandler(db, stockSvc)
stockOutH := NewStockOutHandler(db, stockSvc)
inventoryH := NewInventoryHandler(db)
warehouseH := NewWarehouseHandler(db)
partnerH := NewPartnerHandler(db)
licenseH := NewLicenseHandler(licenseSvc)
r := gin.New()
r.Use(gin.Recovery())
api := r.Group("/api/v1")
api.Use(middleware.JWT(db))
// 商品路由
products := api.Group("/products")
products.GET("", productH.List)
products.POST("", productH.Create)
products.PUT("/:id", productH.Update)
products.DELETE("/:id", productH.Delete)
// 仓库路由
warehouses := api.Group("/warehouses")
warehouses.GET("", warehouseH.List)
warehouses.POST("", warehouseH.Create)
warehouses.PUT("/:id", warehouseH.Update)
warehouses.DELETE("/:id", warehouseH.Delete)
// 往来单位路由
partners := api.Group("/partners")
partners.GET("", partnerH.List)
partners.POST("", partnerH.Create)
partners.PUT("/:id", partnerH.Update)
partners.DELETE("/:id", partnerH.Delete)
// 入库路由
stockIn := api.Group("/stock-in")
stockIn.GET("/orders", stockInH.List)
stockIn.GET("/orders/:id", stockInH.Get)
stockIn.POST("/orders", stockInH.Create)
stockIn.PUT("/orders/:id", stockInH.Update)
stockIn.PUT("/orders/:id/submit", stockInH.Submit)
stockIn.PUT("/orders/:id/approve", stockInH.Approve)
stockIn.PUT("/orders/:id/reject", stockInH.Reject)
stockIn.PUT("/orders/:id/withdraw", stockInH.Withdraw)
stockIn.POST("/orders/:id/return", stockInH.Return)
// 出库路由
stockOut := api.Group("/stock-out")
stockOut.GET("/orders", stockOutH.List)
stockOut.GET("/orders/:id", stockOutH.Get)
stockOut.POST("/orders", stockOutH.Create)
stockOut.PUT("/orders/:id", stockOutH.Update)
stockOut.PUT("/orders/:id/submit", stockOutH.Submit)
stockOut.PUT("/orders/:id/approve", stockOutH.Approve)
stockOut.PUT("/orders/:id/reject", stockOutH.Reject)
stockOut.PUT("/orders/:id/withdraw", stockOutH.Withdraw)
stockOut.POST("/orders/:id/return", stockOutH.Return)
// 库存路由
inv := api.Group("/inventory")
inv.GET("", inventoryH.List)
inv.GET("/logs", inventoryH.Logs)
inv.POST("/checks", inventoryH.CreateCheck)
inv.GET("/checks/:id", inventoryH.GetCheck)
// 许可证路由
license := api.Group("/license")
license.POST("/activate", licenseH.Activate)
license.GET("/verify", licenseH.Verify)
license.POST("/deactivate", licenseH.Deactivate)
return r
}
// makeRequest 发起带认证的请求
func makeRequest(r *gin.Engine, method, path, token string, body interface{}) *httptest.ResponseRecorder {
var bodyBytes []byte
if body != nil {
bodyBytes, _ = json.Marshal(body)
}
w := httptest.NewRecorder()
req, _ := http.NewRequest(method, path, bytes.NewBuffer(bodyBytes))
req.Header.Set("Content-Type", "application/json")
if token != "" {
req.Header.Set("Authorization", "Bearer "+token)
}
r.ServeHTTP(w, req)
return w
}
// parseResponse 解析 JSON 响应
func parseResponse(w *httptest.ResponseRecorder) map[string]interface{} {
var resp map[string]interface{}
json.Unmarshal(w.Body.Bytes(), &resp)
return resp
}
// getAuthToken 为测试用户获取 token
func getAuthToken(userID, shopID uint64, role string) string {
return testutil.GetAuthToken(userID, shopID, role)
}
// extractID 从响应 data 中提取 id
func extractID(w *httptest.ResponseRecorder) uint64 {
resp := parseResponse(w)
if data, ok := resp["data"].(map[string]interface{}); ok {
if id, ok := data["id"].(float64); ok {
return uint64(id)
}
}
return 0
}
// jsonBody 快速构建 JSON body
func jsonBody(kv ...interface{}) map[string]interface{} {
m := map[string]interface{}{}
for i := 0; i+1 < len(kv); i += 2 {
key := fmt.Sprintf("%v", kv[i])
m[key] = kv[i+1]
}
return m
}