77 lines
3.3 KiB
Go
77 lines
3.3 KiB
Go
package peercomparison
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func pointer(value float64) *float64 { return &value }
|
|
|
|
func TestCalculateAppliesPrivacyThresholdsAndExcludesActiveMerchant(t *testing.T) {
|
|
merchants := make([]MerchantValues, 0, 11)
|
|
merchants = append(merchants, MerchantValues{MerchantID: 70, SessionCount: 900, Values: [8]*float64{pointer(0)}})
|
|
for i := int64(1); i <= 10; i++ {
|
|
merchants = append(merchants, MerchantValues{MerchantID: i, SessionCount: 100, Values: [8]*float64{pointer(float64(i))}})
|
|
}
|
|
result := Calculate(70, false, merchants)
|
|
if result.State != StateReady || result.EligiblePeerCount != 10 || result.CombinedPeerSessions != 1000 {
|
|
t.Fatalf("unexpected ready result: %+v", result)
|
|
}
|
|
if result.Metrics[0].MerchantPerformancePercentile != "0.00" {
|
|
t.Fatalf("active merchant must be ranked below all peers: %+v", result.Metrics[0])
|
|
}
|
|
suppressed := Calculate(70, true, merchants)
|
|
if suppressed.State != StateSuppressed || suppressed.Reason != "TERMINAL_SCOPE_UNSUPPORTED" {
|
|
t.Fatalf("unexpected terminal result: %+v", suppressed)
|
|
}
|
|
insufficient := Calculate(70, false, merchants[:10])
|
|
if insufficient.State != StateSuppressed || insufficient.Reason != "INSUFFICIENT_COHORT" {
|
|
t.Fatalf("unexpected insufficient result: %+v", insufficient)
|
|
}
|
|
}
|
|
|
|
func TestCalculateUsesDirectionAwareMidRankAndStableMetricOrder(t *testing.T) {
|
|
merchants := make([]MerchantValues, 0, 11)
|
|
merchants = append(merchants, MerchantValues{MerchantID: 70, SessionCount: 1, Values: [8]*float64{pointer(5), pointer(5), pointer(5), pointer(5), pointer(5), pointer(5), pointer(5), pointer(5)}})
|
|
for i := int64(1); i <= 10; i++ {
|
|
value := float64(i)
|
|
merchants = append(merchants, MerchantValues{MerchantID: i, SessionCount: 100, Values: [8]*float64{pointer(value), pointer(value), pointer(value), pointer(value), pointer(value), pointer(value), pointer(value), pointer(value)}})
|
|
}
|
|
result := Calculate(70, false, merchants)
|
|
if len(result.Metrics) != 8 || result.Metrics[0].MetricID != "payment_success_rate" || result.Metrics[7].MetricID != "paid_fee_rate" {
|
|
t.Fatalf("unexpected metric order: %+v", result.Metrics)
|
|
}
|
|
if result.Metrics[0].MerchantPerformancePercentile != "45.00" {
|
|
t.Fatalf("higher-is-better midrank = %s, want 45.00", result.Metrics[0].MerchantPerformancePercentile)
|
|
}
|
|
if result.Metrics[3].MerchantPerformancePercentile != "55.00" || result.Metrics[3].Direction != "LOWER_IS_BETTER" {
|
|
t.Fatalf("lower-is-better direction/percentile = %+v", result.Metrics[3])
|
|
}
|
|
}
|
|
|
|
func TestCalculateKeepsPeerIdentitiesOutOfSerializedResult(t *testing.T) {
|
|
merchants := []MerchantValues{{MerchantID: 987654321, Values: [8]*float64{pointer(5)}}}
|
|
for i := int64(1); i <= 10; i++ {
|
|
merchants = append(merchants, MerchantValues{
|
|
MerchantID: 1000 + i,
|
|
SessionCount: 100,
|
|
Values: [8]*float64{pointer(5)},
|
|
})
|
|
}
|
|
result := Calculate(987654321, false, merchants)
|
|
encoded, err := json.Marshal(result)
|
|
if err != nil {
|
|
t.Fatalf("marshal result: %v", err)
|
|
}
|
|
text := string(encoded)
|
|
for _, forbidden := range []string{"merchantId", "987654321", "1001"} {
|
|
if strings.Contains(text, forbidden) {
|
|
t.Fatalf("serialized peer result exposed %q: %s", forbidden, text)
|
|
}
|
|
}
|
|
if result.Metrics[0].MerchantPerformancePercentile != "50.00" {
|
|
t.Fatalf("all-tie percentile = %s, want 50.00", result.Metrics[0].MerchantPerformancePercentile)
|
|
}
|
|
}
|