package handler import ( "net/http" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/wangjia/jiu/backend/internal/middleware" "github.com/wangjia/jiu/backend/internal/model" "github.com/wangjia/jiu/backend/testutil" ) func TestFeedbackHandler_SubmitAndList(t *testing.T) { db := testutil.SetupTestDB() require.NoError(t, db.AutoMigrate(&model.Feedback{})) shop := testutil.CreateTestShop(db, "FB001") user := testutil.CreateTestUser(db, shop.ID, "fbuser", "pass", "admin") token := getAuthToken(user.ID, shop.ID, "admin") fh := NewFeedbackHandler(db) r := gin.New() r.Use(gin.Recovery()) api := r.Group("/api/v1") api.Use(middleware.JWT(db)) api.POST("/feedback", fh.Submit) adminG := api.Group("/admin") adminG.Use(middleware.SuperAdminOnly()) adminG.GET("/feedback", fh.List) // 1. 正常提交(文字 + 图片) w := makeRequest(r, "POST", "/api/v1/feedback", token, map[string]interface{}{ "type": "bug", "content": "打印时卡住了", "images": []string{"/images/feedback/1/a.jpg"}, }) require.Equal(t, http.StatusCreated, w.Code) assert.NotZero(t, parseResponse(w)["id"]) // 去规范化字段已写入 var fb model.Feedback require.NoError(t, db.Order("id DESC").First(&fb).Error) assert.Equal(t, "fbuser", fb.Username) assert.Equal(t, "FB001", fb.ShopCode) assert.Equal(t, "new", fb.Status) assert.Equal(t, 1, len(fb.Images)) // 2. 内容与图片都为空 → 400 w = makeRequest(r, "POST", "/api/v1/feedback", token, map[string]interface{}{ "type": "suggestion", }) assert.Equal(t, http.StatusBadRequest, w.Code) // 3. 非法 type → 400 w = makeRequest(r, "POST", "/api/v1/feedback", token, map[string]interface{}{ "type": "other", "content": "x", }) assert.Equal(t, http.StatusBadRequest, w.Code) // 4. 普通管理员访问 admin 列表 → 403 w = makeRequest(r, "GET", "/api/v1/admin/feedback", token, nil) assert.Equal(t, http.StatusForbidden, w.Code) // 5. 超级管理员可列出 superToken := getAuthToken(user.ID, shop.ID, "superadmin") w = makeRequest(r, "GET", "/api/v1/admin/feedback", superToken, nil) require.Equal(t, http.StatusOK, w.Code) assert.GreaterOrEqual(t, parseResponse(w)["total"].(float64), float64(1)) }