feat: 安全回写档口入库码并支持核验恢复 (#234)

This commit is contained in:
chengma
2026-08-15 09:10:10 +08:00
parent 15ebda23e3
commit 2778eed29f
11 changed files with 782 additions and 4 deletions
+79
View File
@@ -431,6 +431,85 @@ func TestClient_DetailListByStock_超过100个id报错(t *testing.T) {
}
}
func TestClient_InnerCodeWrite_参数和路径正确且只发送一次(t *testing.T) {
var requests atomic.Int32
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requests.Add(1)
w.Header().Set("Content-Type", "application/json")
switch r.URL.Path {
case "/am/stock/detail/deleteInnerCode":
if r.URL.Query().Get("detailId") != "22" {
t.Errorf("delete query=%v", r.URL.Query())
}
case "/am/stock/detail/updateDetailCode":
query := r.URL.Query()
if query.Get("t") != "0" || query.Get("id") != "11" || query.Get("detailId") != "22" || query.Get("code") != "DK-001" {
t.Errorf("update query=%v", query)
}
default:
t.Errorf("意外路径 %s", r.URL.Path)
}
io.WriteString(w, `{"status":true,"msg":"成功","data":null}`)
}))
defer server.Close()
client, err := New(server.URL)
if err != nil {
t.Fatal(err)
}
if err := client.DeleteInnerCode(context.Background(), 22); err != nil {
t.Fatal(err)
}
if err := client.UpdateDetailCode(context.Background(), 11, 22, " DK-001 "); err != nil {
t.Fatal(err)
}
if requests.Load() != 2 {
t.Fatalf("每个写动作只能发一次请求,实际总请求 %d", requests.Load())
}
}
func TestClient_InnerCodeWrite_未知结果与明确业务失败分开(t *testing.T) {
for _, tc := range []struct {
name string
status int
body string
wantUnknown bool
}{
{"服务端故障", http.StatusInternalServerError, `oops`, true},
{"成功响应损坏", http.StatusOK, `not-json`, true},
{"明确业务失败", http.StatusOK, `{"status":false,"msg":"已打单数据不能清除","code":1}`, false},
} {
t.Run(tc.name, func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(tc.status)
io.WriteString(w, tc.body)
}))
defer server.Close()
client, _ := New(server.URL)
err := client.DeleteInnerCode(context.Background(), 22)
if err == nil || errors.Is(err, ErrWriteResultUnknown) != tc.wantUnknown {
t.Fatalf("err=%v unknown=%v want=%v", err, errors.Is(err, ErrWriteResultUnknown), tc.wantUnknown)
}
})
}
}
func TestClient_UpdateDetailCode_本地校验失败不发送请求(t *testing.T) {
var requests atomic.Int32
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requests.Add(1)
}))
defer server.Close()
client, _ := New(server.URL)
for _, code := range []string{"", "bad\ncode", strings.Repeat("长", 129)} {
if err := client.UpdateDetailCode(context.Background(), 1, 2, code); err == nil {
t.Errorf("code=%q 应被拒绝", code)
}
}
if requests.Load() != 0 {
t.Fatalf("本地校验失败不应发请求,实际 %d", requests.Load())
}
}
// ── 业务失败但不是登录问题 ──────────────────────────────
func TestClient_业务失败但不是登录问题时返回普通错误(t *testing.T) {