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) } }