2026-05-19 19:50:50 +08:00

75 lines
2.0 KiB
Go

package prizepool
import (
"context"
"errors"
"testing"
)
func TestPickAvailableSkipsUnavailableItems(t *testing.T) {
counter := UserIssueCounterFunc(func(_ context.Context, itemID int64, userID int64) (int64, error) {
if itemID == 4 && userID == 1001 {
return 1, nil
}
return 0, nil
})
picker := Picker{RandomIntn: func(max int) (int, error) {
if max != 7 {
t.Fatalf("max = %d, want 7", max)
}
return 6, nil
}}
picked, err := picker.PickAvailable(context.Background(), []Item{
{ID: 1, Enabled: false, Weight: 100},
{ID: 2, Enabled: true, Weight: 0},
{ID: 3, Enabled: true, Weight: 5, TotalLimit: 10, IssuedCount: 10},
{ID: 4, Enabled: true, Weight: 8, UserLimit: 1},
{ID: 5, Enabled: true, Weight: 7},
}, 1001, counter)
if err != nil {
t.Fatalf("PickAvailable() error = %v", err)
}
if picked.Item.ID != 5 || picked.Index != 4 {
t.Fatalf("picked = %+v, want item 5 at original index 4", picked)
}
}
func TestPickAvailableNoAvailableItem(t *testing.T) {
_, err := Picker{}.PickAvailable(context.Background(), []Item{
{ID: 1, Enabled: true, Weight: 1, TotalLimit: 1, IssuedCount: 1},
}, 1001, nil)
if !errors.Is(err, ErrNoAvailableItem) {
t.Fatalf("error = %v, want ErrNoAvailableItem", err)
}
}
func TestPickAvailableRequiresCounterForUserLimit(t *testing.T) {
_, err := Picker{}.PickAvailable(context.Background(), []Item{
{ID: 1, Enabled: true, Weight: 1, UserLimit: 1},
}, 1001, nil)
if !errors.Is(err, ErrUserIssueCounterRequired) {
t.Fatalf("error = %v, want ErrUserIssueCounterRequired", err)
}
}
func TestPickWeightedUsesWeights(t *testing.T) {
picker := Picker{RandomIntn: func(max int) (int, error) {
if max != 10 {
t.Fatalf("max = %d, want 10", max)
}
return 3, nil
}}
picked, err := picker.PickWeighted([]PickResult{
{Item: Item{ID: 1, Enabled: true, Weight: 3}, Index: 0},
{Item: Item{ID: 2, Enabled: true, Weight: 7}, Index: 1},
})
if err != nil {
t.Fatalf("PickWeighted() error = %v", err)
}
if picked.Item.ID != 2 {
t.Fatalf("picked item = %d, want 2", picked.Item.ID)
}
}