package main import ( "crypto/rand" "encoding/binary" mrand "math/rand" "testing" ) // TestEncodeDecodeBase62RoundTrip verifies encodeBase62/decodeBase62 are inverse. func TestEncodeDecodeBase62RoundTrip(t *testing.T) { mrand.Seed(42) for i := 0; i < 1000; i++ { // Random 64-bit value v := mrand.Uint64() s := encodeBase62(v) dec, ok := decodeBase62(s) if !ok { t.Fatalf("decodeBase62 failed for %d encoded=%s", v, s) } if dec != v { t.Fatalf("round trip mismatch: have %d got %d (encoded=%s)", v, dec, s) } } // Explicit zero test if s := encodeBase62(0); s != "0" { t.Fatalf("expected encodeBase62(0) == \"0\", got %q", s) } if v, ok := decodeBase62("0"); !ok || v != 0 { t.Fatalf("decodeBase62(0) unexpected result v=%d ok=%v", v, ok) } } // TestNewCartIDUniqueness generates a number of IDs and checks for duplicates. func TestNewCartIDUniqueness(t *testing.T) { const n = 10000 seen := make(map[string]struct{}, n) for i := 0; i < n; i++ { id, err := NewCartID() if err != nil { t.Fatalf("NewCartID error: %v", err) } s := id.String() if _, exists := seen[s]; exists { t.Fatalf("duplicate CartID generated: %s", s) } seen[s] = struct{}{} if id.IsZero() { t.Fatalf("NewCartID returned zero value") } } } // TestParseCartIDValidation tests parsing of valid and invalid base62 strings. func TestParseCartIDValidation(t *testing.T) { id, err := NewCartID() if err != nil { t.Fatalf("NewCartID error: %v", err) } parsed, ok := ParseCartID(id.String()) if !ok { t.Fatalf("ParseCartID failed for valid id %s", id) } if parsed.raw != id.raw { t.Fatalf("parsed raw mismatch: %d vs %d", parsed.raw, id.raw) } if _, ok := ParseCartID(""); ok { t.Fatalf("expected empty string to be invalid") } // Invalid char ('-') if _, ok := ParseCartID("abc-123"); ok { t.Fatalf("expected invalid chars to fail parse") } // Overly long ( >16 ) if _, ok := ParseCartID("1234567890abcdefg"); ok { t.Fatalf("expected overly long string to fail parse") } } // TestFallbackDeterminism ensures fallback hashing is deterministic. func TestFallbackDeterminism(t *testing.T) { inputs := []string{ "legacy-cart-1", "legacy-cart-2", "UPPER_lower_123", "🚀unicode", // unicode bytes (will hash byte sequence) } for _, in := range inputs { a := FallbackFromString(in) b := FallbackFromString(in) if a.raw != b.raw || a.String() != b.String() { t.Fatalf("fallback mismatch for %q: %+v vs %+v", in, a, b) } } // Distinct inputs should almost always differ; sample check a := FallbackFromString("distinct-A") b := FallbackFromString("distinct-B") if a.raw == b.raw { t.Fatalf("unexpected identical fallback hashes for distinct inputs") } } // TestCanonicalizeIncomingBehavior covers main control flow branches. func TestCanonicalizeIncomingBehavior(t *testing.T) { // Empty => new id id1, generated, err := CanonicalizeIncoming("") if err != nil || !generated || id1.IsZero() { t.Fatalf("CanonicalizeIncoming empty failed: id=%v gen=%v err=%v", id1, generated, err) } // Valid base62 => parse; no generation id2, gen2, err := CanonicalizeIncoming(id1.String()) if err != nil || gen2 || id2.raw != id1.raw { t.Fatalf("CanonicalizeIncoming parse mismatch: id2=%v gen2=%v err=%v", id2, gen2, err) } // Legacy-like random containing invalid chars -> fallback fallbackInput := "legacy\x00\x00padding" id3, gen3, err := CanonicalizeIncoming(fallbackInput) if err != nil || gen3 { t.Fatalf("CanonicalizeIncoming fallback unexpected: id3=%v gen3=%v err=%v", id3, gen3, err) } // Deterministic fallback id4, _, _ := CanonicalizeIncoming(fallbackInput) if id3.raw != id4.raw { t.Fatalf("fallback canonicalization not deterministic") } } // TestUpgradeLegacyCartId ensures mapping of old CartId is stable. func TestUpgradeLegacyCartId(t *testing.T) { var legacy CartId copy(legacy[:], []byte("legacy-123456789")) // 15 bytes + padding up1 := UpgradeLegacyCartId(legacy) up2 := UpgradeLegacyCartId(legacy) if up1.raw != up2.raw { t.Fatalf("UpgradeLegacyCartId not deterministic: %v vs %v", up1, up2) } if up1.String() != up2.String() { t.Fatalf("UpgradeLegacyCartId string mismatch: %s vs %s", up1, up2) } } // BenchmarkNewCartID gives a rough idea of generation cost. func BenchmarkNewCartID(b *testing.B) { for i := 0; i < b.N; i++ { if _, err := NewCartID(); err != nil { b.Fatalf("error: %v", err) } } } // BenchmarkEncodeBase62 measures encode speed in isolation. func BenchmarkEncodeBase62(b *testing.B) { // Random sample of values samples := make([]uint64, 1024) for i := range samples { var buf [8]byte if _, err := rand.Read(buf[:]); err != nil { b.Fatalf("rand: %v", err) } samples[i] = binary.BigEndian.Uint64(buf[:]) } b.ResetTimer() var sink string for i := 0; i < b.N; i++ { sink = encodeBase62(samples[i%len(samples)]) } _ = sink } // BenchmarkDecodeBase62 measures decode speed. func BenchmarkDecodeBase62(b *testing.B) { // Pre-encode encoded := make([]string, 1024) for i := range encoded { encoded[i] = encodeBase62(uint64(i)<<32 | uint64(i)) } b.ResetTimer() var sum uint64 for i := 0; i < b.N; i++ { v, ok := decodeBase62(encoded[i%len(encoded)]) if !ok { b.Fatalf("decode failed") } sum ^= v } _ = sum } // Removed TestLookupNDeterminism (ring-based ownership deprecated) // Removed TestRingFingerprintChanges (ring-based ownership deprecated) // Removed TestRingDiffHosts (ring-based ownership deprecated) // TestRingLookupConsistency ensures direct Lookup and LookupID are aligned. // Removed TestRingLookupConsistency (ring-based ownership deprecated)