fix(backend): JWT config mapstructure tag 修复 + 模型从 hotel 重构为 shop
- 修复 JWTConfig 缺少 mapstructure tag 导致 access_expire_min 解析为 0, token 签发即过期,所有 API 请求返回 401 - 全部 config struct 补齐 mapstructure tag(secret/dsn/hmac_secret 等) - 模型层从 hotel/HotelID 统一重命名为 shop/ShopID - 删除旧 migrations(001-004),新增 001_init 综合迁移文件 - 更新 schema.sql、testutil、handler/service/model 相关引用 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,9 +14,9 @@ import (
|
||||
|
||||
func TestProductHandler_CRUD(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
hotel := testutil.CreateTestHotel(db, "PROD001")
|
||||
user := testutil.CreateTestUser(db, hotel.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, hotel.ID, "admin")
|
||||
shop := testutil.CreateTestShop(db, "PROD001")
|
||||
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, shop.ID, "admin")
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
// 1. Create
|
||||
@@ -66,14 +66,14 @@ func TestProductHandler_HotelIsolation(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
|
||||
// 酒店 A
|
||||
hotelA := testutil.CreateTestHotel(db, "ISOL_A")
|
||||
userA := testutil.CreateTestUser(db, hotelA.ID, "adminA", "pass", "admin")
|
||||
tokenA := getAuthToken(userA.ID, hotelA.ID, "admin")
|
||||
shopA := testutil.CreateTestShop(db, "ISOL_A")
|
||||
userA := testutil.CreateTestUser(db, shopA.ID, "adminA", "pass", "admin")
|
||||
tokenA := getAuthToken(userA.ID, shopA.ID, "admin")
|
||||
|
||||
// 酒店 B
|
||||
hotelB := testutil.CreateTestHotel(db, "ISOL_B")
|
||||
userB := testutil.CreateTestUser(db, hotelB.ID, "adminB", "pass", "admin")
|
||||
tokenB := getAuthToken(userB.ID, hotelB.ID, "admin")
|
||||
shopB := testutil.CreateTestShop(db, "ISOL_B")
|
||||
userB := testutil.CreateTestUser(db, shopB.ID, "adminB", "pass", "admin")
|
||||
tokenB := getAuthToken(userB.ID, shopB.ID, "admin")
|
||||
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
@@ -128,9 +128,9 @@ func TestProductHandler_NoAuth(t *testing.T) {
|
||||
|
||||
func TestProductHandler_List_Pagination(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
hotel := testutil.CreateTestHotel(db, "PROD002")
|
||||
user := testutil.CreateTestUser(db, hotel.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, hotel.ID, "admin")
|
||||
shop := testutil.CreateTestShop(db, "PROD002")
|
||||
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, shop.ID, "admin")
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
// 创建 5 个商品
|
||||
@@ -152,9 +152,9 @@ func TestProductHandler_List_Pagination(t *testing.T) {
|
||||
|
||||
func TestProductHandler_UpdateNotFound(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
hotel := testutil.CreateTestHotel(db, "PROD003")
|
||||
user := testutil.CreateTestUser(db, hotel.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, hotel.ID, "admin")
|
||||
shop := testutil.CreateTestShop(db, "PROD003")
|
||||
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, shop.ID, "admin")
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
w := makeRequest(r, "PUT", "/api/v1/products/99999", token, map[string]interface{}{
|
||||
@@ -165,35 +165,35 @@ func TestProductHandler_UpdateNotFound(t *testing.T) {
|
||||
|
||||
func TestProductHandler_DeleteNotFound(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
hotel := testutil.CreateTestHotel(db, "PROD004")
|
||||
user := testutil.CreateTestUser(db, hotel.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, hotel.ID, "admin")
|
||||
shop := testutil.CreateTestShop(db, "PROD004")
|
||||
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, shop.ID, "admin")
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
w := makeRequest(r, "DELETE", "/api/v1/products/99999", token, nil)
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestProductHandler_Create_HotelIDFromToken(t *testing.T) {
|
||||
func TestProductHandler_Create_ShopIDFromToken(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
hotel := testutil.CreateTestHotel(db, "PROD005")
|
||||
user := testutil.CreateTestUser(db, hotel.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, hotel.ID, "admin")
|
||||
shop := testutil.CreateTestShop(db, "PROD005")
|
||||
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
|
||||
token := getAuthToken(user.ID, shop.ID, "admin")
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
// 尝试在请求体中传入不同的 hotel_id
|
||||
// 尝试在请求体中传入不同的 shop_id
|
||||
w := makeRequest(r, "POST", "/api/v1/products", token, map[string]interface{}{
|
||||
"name": "Test Product",
|
||||
"hotel_id": 9999, // 尝试注入其他酒店 ID
|
||||
"unit": "个",
|
||||
"name": "Test Product",
|
||||
"shop_id": 9999, // 尝试注入其他门店 ID
|
||||
"unit": "个",
|
||||
})
|
||||
require.Equal(t, http.StatusCreated, w.Code)
|
||||
resp := parseResponse(w)
|
||||
data := resp["data"].(map[string]interface{})
|
||||
|
||||
// hotel_id 应该是从 token 中获取的,而不是请求体中的
|
||||
createdHotelID := uint64(data["hotel_id"].(float64))
|
||||
assert.Equal(t, hotel.ID, createdHotelID)
|
||||
// shop_id 应该是从 token 中获取的,而不是请求体中的
|
||||
createdShopID := uint64(data["shop_id"].(float64))
|
||||
assert.Equal(t, shop.ID, createdShopID)
|
||||
|
||||
// 反序列化验证
|
||||
dataBytes, _ := json.Marshal(data)
|
||||
|
||||
Reference in New Issue
Block a user