test: 补酒名搜索拼音/多租户与前端搜索限流用例
- backend: 入库酒名全拼(feitian)+首字母(ftmt)命中、不相关拼音不命中 - backend: 入库酒名反查的多租户隔离(店A搜茅台不串到店B) - client: setKeyword 防抖(350ms内连发取最后一次)+去重(同词不重查) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -487,6 +487,70 @@ func TestStockInHandler_List_FilterByProductName(t *testing.T) {
|
||||
assert.Equal(t, float64(2), parseResponse(w)["total"].(float64))
|
||||
}
|
||||
|
||||
func TestStockInHandler_List_FilterByProductPinyin(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
shop := testutil.CreateTestShop(db, "SI013")
|
||||
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
|
||||
warehouse := testutil.CreateTestWarehouse(db, shop.ID, "Warehouse")
|
||||
token := getAuthToken(user.ID, shop.ID, "admin")
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
// 入库按 product_name 新建独立 product,会自动写入拼音列(name_pinyin/name_initials)
|
||||
w := makeRequest(r, "POST", "/api/v1/stock-in/orders", token, map[string]interface{}{
|
||||
"warehouse_id": warehouse.ID,
|
||||
"order_date": time.Now().Format(time.RFC3339),
|
||||
"items": []map[string]interface{}{{"product_name": "飞天茅台", "quantity": 5.0}},
|
||||
})
|
||||
require.Equal(t, http.StatusCreated, w.Code)
|
||||
|
||||
// 全拼命中(feitianmaotai)
|
||||
w = makeRequest(r, "GET", "/api/v1/stock-in/orders?keyword=feitian", token, nil)
|
||||
assert.Equal(t, float64(1), parseResponse(w)["total"].(float64))
|
||||
|
||||
// 首字母命中(ftmt)
|
||||
w = makeRequest(r, "GET", "/api/v1/stock-in/orders?keyword=ftmt", token, nil)
|
||||
assert.Equal(t, float64(1), parseResponse(w)["total"].(float64))
|
||||
|
||||
// 不相关拼音不命中
|
||||
w = makeRequest(r, "GET", "/api/v1/stock-in/orders?keyword=wuliangye", token, nil)
|
||||
assert.Equal(t, float64(0), parseResponse(w)["total"].(float64))
|
||||
}
|
||||
|
||||
func TestStockInHandler_List_FilterByProductName_TenantIsolation(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
r := setupProtectedRouter(db)
|
||||
|
||||
// 店A、店B 各建一张含「茅台」明细的入库单
|
||||
shopA := testutil.CreateTestShop(db, "SI014A")
|
||||
userA := testutil.CreateTestUser(db, shopA.ID, "adminA", "pass", "admin")
|
||||
whA := testutil.CreateTestWarehouse(db, shopA.ID, "WA")
|
||||
tokenA := getAuthToken(userA.ID, shopA.ID, "admin")
|
||||
|
||||
shopB := testutil.CreateTestShop(db, "SI014B")
|
||||
userB := testutil.CreateTestUser(db, shopB.ID, "adminB", "pass", "admin")
|
||||
whB := testutil.CreateTestWarehouse(db, shopB.ID, "WB")
|
||||
tokenB := getAuthToken(userB.ID, shopB.ID, "admin")
|
||||
|
||||
for _, tc := range []struct {
|
||||
token string
|
||||
wh uint64
|
||||
}{{tokenA, whA.ID}, {tokenB, whB.ID}} {
|
||||
w := makeRequest(r, "POST", "/api/v1/stock-in/orders", tc.token, map[string]interface{}{
|
||||
"warehouse_id": tc.wh,
|
||||
"order_date": time.Now().Format(time.RFC3339),
|
||||
"items": []map[string]interface{}{{"product_name": "飞天茅台", "quantity": 1.0}},
|
||||
})
|
||||
require.Equal(t, http.StatusCreated, w.Code)
|
||||
}
|
||||
|
||||
// 店A 搜茅台只看到自己的 1 单,绝不串到店B
|
||||
w := makeRequest(r, "GET", "/api/v1/stock-in/orders?keyword=茅台", tokenA, nil)
|
||||
assert.Equal(t, float64(1), parseResponse(w)["total"].(float64))
|
||||
|
||||
w = makeRequest(r, "GET", "/api/v1/stock-in/orders?keyword=茅台", tokenB, nil)
|
||||
assert.Equal(t, float64(1), parseResponse(w)["total"].(float64))
|
||||
}
|
||||
|
||||
func TestStockInHandler_List_FilterByStatus(t *testing.T) {
|
||||
db := testutil.SetupTestDB()
|
||||
shop := testutil.CreateTestShop(db, "SI010")
|
||||
|
||||
Reference in New Issue
Block a user