Files
base/plugins/waitlist/referral_credit_test.go
zeekayandHanzo Dev 5954991bc3 a referral is counted whatever it is worth
creditReferrer incremented referralCount in memory and left the save to award(),
which touches the record only for a non-zero award. So under POINTS_REFERRAL=0 —
a real configuration, meaning track who invited whom and pay nothing for it,
reachable because envInt parses "0" and returns it — the increment was silently
discarded. Not merely lost: the joiner's referredBy IS saved a few lines above,
so the two sides of one referral disagreed, and the referrer's dashboard showed
none of the people it had actually brought in.

The count and the points are two facts, so each is now written by whoever owns
it. award()'s own return value still gates the increment, so a referral already
credited under the same dedupKey is not counted twice.

The test that found it comes back from feat/waitlist-plugin, where it had sat
unmerged since the plugin itself landed — restored against main's shapes (typed
responses are gone; entryView returns a map, so the test declares the fields it
depends on) and extended to prove the referral is PAID, not just counted, since
rank is computed from points and a referral nobody is paid for moves no one.

Shown failing first: paid passed, unpaid failed on exactly the discarded count.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-23 23:28:50 -07:00

48 lines
1.5 KiB
Go

// Copyright (C) 2020-2026, Hanzo AI Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package waitlist
import "testing"
// A referral is COUNTED whatever it is worth. The count and the points are two
// facts: an operator may run POINTS_REFERRAL=0 to track who invited whom while
// paying nothing for it, and the count must still move.
//
// It did not. creditReferrer incremented referralCount in memory and left the
// save to award(), which skips it for a zero-point award — so the increment was
// discarded while the joiner's own referredBy was written, leaving the two
// sides of one referral disagreeing.
func TestReferralIsCountedEvenWhenItPaysNothing(t *testing.T) {
for _, tc := range []struct {
name string
pts int
}{
{"paid", 10},
{"unpaid", 0},
} {
t.Run(tc.name, func(t *testing.T) {
cfg := Config{Enabled: true, DefaultSlugs: []string{"launch"}, JoinRateLimit: -1}
cfg.Points.Referral = tc.pts
srv := newWaitlistServerWith(t, cfg)
a := join(t, srv, "[email protected]", "")
join(t, srv, "[email protected]", a.RefCode)
got := status(t, srv, "[email protected]")
if got.ReferralCount != 1 {
t.Fatalf("referralCount = %d, want 1 (referral worth %d points)", got.ReferralCount, tc.pts)
}
if got.Points != tc.pts {
t.Fatalf("points = %d, want %d", got.Points, tc.pts)
}
// The joiner's side must agree: it records who referred it.
b := status(t, srv, "[email protected]")
if b.ReferralCount != 0 {
t.Fatalf("joiner referralCount = %d, want 0", b.ReferralCount)
}
})
}
}