Files
jiu/backend/internal/handler/feedback_test.go
T
wangjia 7a1d8465e5 feat(backend): 意见反馈接口(提交+图片上传+admin列表)
- model/feedback.go: Feedback(多租户 shop_id,images 以 JSON 存)+ StringSlice 类型
- handler/feedback.go: Submit(认证,shop/user 从 JWT,去规范化 username/shop_code)、
  UploadImage(复用 product_image 压缩逻辑,存 /images/feedback/<shop>/)、
  List(SuperAdminOnly,分页过滤)、UpdateStatus(new/handled)
- router 注册 /feedback、/feedback/images、/admin/feedback;main AutoMigrate;schema.sql 加表
- feedback_test 覆盖提交/校验/权限/列表

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 21:31:46 +08:00

73 lines
2.2 KiB
Go

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())
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))
}