fix(api): bound claim wire fields end to end

This commit is contained in:
QiuSW
2026-08-05 01:25:23 +08:00
parent 57a5b2e91c
commit 7ea1c5349f
17 changed files with 514 additions and 98 deletions
+89
View File
@@ -193,6 +193,88 @@ func TestClaimRollsBackEveryBusinessMutationOnLateFailure(t *testing.T) {
}
}
func TestClaimRejectsOutOfBoundsCandidatesWithoutBusinessMutation(t *testing.T) {
mutations := map[string]func(*testing.T, *sql.DB){
"invalid utf8 title": func(t *testing.T, database *sql.DB) {
execClaimSQL(t, database, `UPDATE tasks SET title=? WHERE id=?`, string([]byte{0xff}), testTaskA)
},
"overlong title": func(t *testing.T, database *sql.DB) {
execClaimSQL(t, database, `UPDATE tasks SET title=? WHERE id=?`, strings.Repeat("😀", 121), testTaskA)
},
"overlong goods id": func(t *testing.T, database *sql.DB) {
value := strings.Repeat("1", 33)
execClaimSQL(t, database, `UPDATE tasks SET goods_id=? WHERE id=?`, value, testTaskA)
execClaimSQL(t, database, `UPDATE order_authorizations SET goods_id=? WHERE id=?`, value, testAuthA)
},
"overlong color": func(t *testing.T, database *sql.DB) {
value := strings.Repeat("色", 81)
execClaimSQL(t, database, `UPDATE tasks SET sku_color=? WHERE id=?`, value, testTaskA)
execClaimSQL(t, database, `UPDATE order_authorizations SET sku_color=? WHERE id=?`, value, testAuthA)
},
"overlong size": func(t *testing.T, database *sql.DB) {
value := strings.Repeat("码", 81)
execClaimSQL(t, database, `UPDATE tasks SET sku_size=? WHERE id=?`, value, testTaskA)
execClaimSQL(t, database, `UPDATE order_authorizations SET sku_size=? WHERE id=?`, value, testAuthA)
},
"overlong money": func(t *testing.T, database *sql.DB) {
value := strings.Repeat("1", 30) + ".00"
execClaimSQL(t, database, `UPDATE tasks SET max_total_price=? WHERE id=?`, value, testTaskA)
execClaimSQL(t, database, `UPDATE order_authorizations SET total_price_cap=? WHERE id=?`, value, testAuthA)
},
}
for name, mutate := range mutations {
t.Run(name, func(t *testing.T) {
database := openClaimTestDatabase(t)
insertDevice(t, database, testDeviceA, []byte("device-a"))
insertCandidate(t, database, testTaskA, testAuthA, testNow, testNow.Add(time.Minute), true)
mutate(t, database)
store := mustStore(t, database, bytes.Repeat([]byte{0x32}, 32), 30*time.Second)
store.now = func() time.Time { return testNow }
if _, found, err := store.ClaimNext(context.Background(), testDeviceA, ClaimCommand{SessionID: testSessionA, ClaimRequestID: testClaimRequestA}); err == nil || found {
t.Fatalf("ClaimNext = found %v, err %v; want closed failure", found, err)
}
assertClaimState(t, database, 0, "PENDING", "ACTIVE")
})
}
}
func TestClaimReplayRevalidatesImmutableResponseSnapshot(t *testing.T) {
mutations := map[string]func(*testing.T, *sql.DB){
"title": func(t *testing.T, database *sql.DB) {
execClaimSQL(t, database, `UPDATE purchase_attempt_claims SET task_title=? WHERE task_id=?`, strings.Repeat("😀", 121), testTaskA)
},
"goods id": func(t *testing.T, database *sql.DB) {
execClaimSQL(t, database, `UPDATE purchase_attempt_claims SET goods_id=? WHERE task_id=?`, strings.Repeat("1", 33), testTaskA)
},
"color": func(t *testing.T, database *sql.DB) {
execClaimSQL(t, database, `UPDATE purchase_attempt_claims SET sku_color=? WHERE task_id=?`, strings.Repeat("色", 81), testTaskA)
},
"size": func(t *testing.T, database *sql.DB) {
execClaimSQL(t, database, `UPDATE purchase_attempt_claims SET sku_size=? WHERE task_id=?`, strings.Repeat("码", 81), testTaskA)
},
"money": func(t *testing.T, database *sql.DB) {
execClaimSQL(t, database, `UPDATE purchase_attempt_claims SET total_price_cap=? WHERE task_id=?`, strings.Repeat("1", 30)+".00", testTaskA)
},
}
for name, mutate := range mutations {
t.Run(name, func(t *testing.T) {
database := openClaimTestDatabase(t)
insertDevice(t, database, testDeviceA, []byte("device-a"))
insertCandidate(t, database, testTaskA, testAuthA, testNow, testNow.Add(time.Minute), true)
store := mustStore(t, database, bytes.Repeat([]byte{0x34}, 32), 30*time.Second)
store.now = func() time.Time { return testNow }
command := ClaimCommand{SessionID: testSessionA, ClaimRequestID: testClaimRequestA}
if _, found, err := store.ClaimNext(context.Background(), testDeviceA, command); err != nil || !found {
t.Fatalf("initial ClaimNext = found %v, err %v", found, err)
}
mutate(t, database)
if _, found, err := store.ClaimNext(context.Background(), testDeviceA, command); err == nil || found {
t.Fatalf("replay = found %v, err %v; want invalid snapshot", found, err)
}
})
}
}
func TestClaimEligibilityStableOrderAndConcurrentUniqueness(t *testing.T) {
database := openClaimTestDatabase(t)
insertDevice(t, database, testDeviceA, []byte("device-a"))
@@ -849,6 +931,13 @@ func insertCandidate(t *testing.T, database *sql.DB, taskID, authorizationID str
}
}
func execClaimSQL(t *testing.T, database *sql.DB, statement string, arguments ...any) {
t.Helper()
if _, err := database.Exec(statement, arguments...); err != nil {
t.Fatalf("execute claim test SQL: %v", err)
}
}
func assertClaimState(t *testing.T, database *sql.DB, wantClaims int, wantTaskStatus, wantAuthorizationStatus string) {
t.Helper()
var count int