fix(api): bound claim wire fields end to end
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user