package flags import ( "testing" "github.com/google/uuid" ) // nilStore returns enabled for everything — handy for hot paths where // the store isn't wired (tests, init). func TestNilStoreAllows(t *testing.T) { var s *Store if !s.Enabled("anything", uuid.New()) { t.Fatal("nil *Store must report Enabled=true so absent infra never disables behaviour") } } // Unknown keys default to enabled — the safe default for "we just // added a gate; ship code first, write the row later if needed". func TestUnknownKeyDefaultsOn(t *testing.T) { s := New(nil, nil) if !s.Enabled("never_seeded", uuid.New()) { t.Errorf("unknown key should be enabled by default") } } func TestExplicitlyDisabledKey(t *testing.T) { s := New(nil, nil) s.flags["kill"] = Flag{Key: "kill", Enabled: false, PercentRollout: 100} if s.Enabled("kill", uuid.New()) { t.Errorf("disabled flag must be off regardless of percent") } } func TestPercentRolloutZeroDisablesForUsers(t *testing.T) { s := New(nil, nil) s.flags["k"] = Flag{Key: "k", Enabled: true, PercentRollout: 0} if s.Enabled("k", uuid.New()) { t.Errorf("0%% rollout should be off for any user") } } // Stable bucketing — same (key, user) must always return the same // decision so a user doesn't flap on and off across requests. func TestPercentBucketIsStable(t *testing.T) { s := New(nil, nil) s.flags["k"] = Flag{Key: "k", Enabled: true, PercentRollout: 50} u := uuid.New() first := s.Enabled("k", u) for i := 0; i < 20; i++ { if s.Enabled("k", u) != first { t.Fatalf("flag decision for user %v flapped on iteration %d", u, i) } } } // Anonymous callers (uuid.Nil) skip percent-rollout splits — they're // treated as the public path. Otherwise a 25%-rollout flag would 75% // of the time refuse anonymous traffic, which is the wrong default // for a public endpoint. func TestAnonymousIsAlwaysOn(t *testing.T) { s := New(nil, nil) s.flags["k"] = Flag{Key: "k", Enabled: true, PercentRollout: 1} if !s.Enabled("k", uuid.Nil) { t.Errorf("uuid.Nil subject should be Enabled=true for partial rollouts") } }