fix(growth): harden deterministic report evidence
This commit is contained in:
@@ -74,13 +74,25 @@ func TestDetectRisksRequiresTwentyPercentDropAndBaselineSize(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectRisksCoalescesAdjacentDaysAndRanksDeepestFirst(t *testing.T) {
|
||||
forecast := Forecast{Confidence: ConfidenceHigh, Points: []ForecastPoint{
|
||||
{Date: date("2026-07-01"), BaselineSessions: 200, BaselineAmountRial: 1_000, PaidSessions: Range{P50: 150}, PaidAmountRial: Range{P50: 750}},
|
||||
{Date: date("2026-07-02"), BaselineSessions: 200, BaselineAmountRial: 1_000, PaidSessions: Range{P50: 100}, PaidAmountRial: Range{P50: 500}},
|
||||
{Date: date("2026-07-04"), BaselineSessions: 200, BaselineAmountRial: 1_000, PaidSessions: Range{P50: 120}, PaidAmountRial: Range{P50: 600}},
|
||||
}}
|
||||
risks := DetectRisks(forecast, 3)
|
||||
if len(risks) != 2 || risks[0].Date != date("2026-07-01") || risks[0].EndDate != date("2026-07-02") || risks[0].SessionDeclineBPS != 5_000 {
|
||||
t.Fatalf("unexpected ranked/coalesced risks: %+v", risks)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvaluatePeerAppliesPrivacyThresholdAndEqualMerchantWeight(t *testing.T) {
|
||||
peers := make([]PeerMerchantValue, 10)
|
||||
for i := range peers {
|
||||
peers[i] = PeerMerchantValue{PaidSessions: int64(i + 1), SessionCount: 100}
|
||||
}
|
||||
result := EvaluatePeer(PeerInput{MerchantPaidSessions: 8, Peers: peers})
|
||||
if result.State != PeerReady || result.MedianPaidSessions != 5 || result.PercentileBPS != 8_000 {
|
||||
if result.State != PeerReady || result.MedianPaidSessions != 5 || result.PercentileBPS != 7_500 {
|
||||
t.Fatalf("unexpected peer result: %+v", result)
|
||||
}
|
||||
suppressed := EvaluatePeer(PeerInput{TerminalScoped: true, Peers: peers})
|
||||
@@ -90,7 +102,7 @@ func TestEvaluatePeerAppliesPrivacyThresholdAndEqualMerchantWeight(t *testing.T)
|
||||
}
|
||||
|
||||
func TestFingerprintIsStableAndVersionSensitive(t *testing.T) {
|
||||
input := FingerprintInput{MerchantID: 7, DatasetWatermark: "run-1", ForecastStart: date("2026-07-01"), HorizonDays: 90, CatalogVersion: "1", AnalyticsVersion: "1", PromptVersion: "1", SchemaVersion: "1", Model: "mini"}
|
||||
input := FingerprintInput{MerchantID: 7, DatasetWatermark: "run-1", ForecastStart: date("2026-07-01"), HorizonDays: 90, CatalogVersion: "1", AnalyticsVersion: "1", PromptVersion: "1", SchemaVersion: "1", Model: "mini", ModelConfigVersion: "cfg-1"}
|
||||
a := Fingerprint(input)
|
||||
b := Fingerprint(input)
|
||||
input.Model = "other"
|
||||
@@ -99,6 +111,26 @@ func TestFingerprintIsStableAndVersionSensitive(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPeerPercentileUsesMidRankForTies(t *testing.T) {
|
||||
peers := make([]PeerMerchantValue, 10)
|
||||
for index := range peers {
|
||||
peers[index] = PeerMerchantValue{PaidSessions: 50, SessionCount: 100}
|
||||
}
|
||||
result := EvaluatePeer(PeerInput{MerchantPaidSessions: 50, Peers: peers})
|
||||
if result.PercentileBPS != 5_000 {
|
||||
t.Fatalf("all-tie percentile = %d, want 5000", result.PercentileBPS)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFingerprintIncludesModelConfigurationPolicy(t *testing.T) {
|
||||
input := FingerprintInput{MerchantID: 7, ForecastStart: date("2026-07-01"), HorizonDays: 90, Model: "mini", ModelConfigVersion: "cfg-1"}
|
||||
first := Fingerprint(input)
|
||||
input.ModelConfigVersion = "cfg-2"
|
||||
if first == Fingerprint(input) {
|
||||
t.Fatal("model configuration policy must invalidate fingerprint")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTehranRefreshBoundary(t *testing.T) {
|
||||
last := time.Date(2026, 8, 20, 20, 31, 0, 0, time.UTC) // 00:01 Tehran on Aug 21.
|
||||
next := NextRefreshAt(last)
|
||||
|
||||
Reference in New Issue
Block a user