blob: 4ed83d41d09991c7ba20caaaad20cca57a86e8a6 [file] [log] [blame]
Philip Zeyliger59789952025-06-28 20:02:23 -07001package skabandclient
2
3import (
4 "testing"
5)
6
7// TestValidateSessionID_Roundtrip tests that all session IDs generated by NewSessionID
8// pass validation by ValidateSessionID
9func TestValidateSessionID_Roundtrip(t *testing.T) {
10 // Test multiple generated session IDs to ensure consistent behavior
11 for i := range 1000 {
12 sessionID := NewSessionID()
13 if !ValidateSessionID(sessionID) {
14 t.Errorf("Generated session ID %q failed validation (iteration %d)", sessionID, i)
15 }
16 }
17}
18
19// TestValidateSessionID_ValidCases tests various valid session ID formats
20func TestValidateSessionID_ValidCases(t *testing.T) {
21 tests := []struct {
22 name string
23 sessionID string
24 want bool
25 }{
26 {"uppercase letters", "ABCD-EFGH-JKMN-PQRS", true},
27 {"lowercase letters", "abcd-efgh-jkmn-pqrs", true},
28 {"mixed case", "AbCd-EfGh-JkMn-PqRs", true},
29 {"with numbers", "123A-5678-9BCD-EF0H", true},
30 {"all numbers", "1234-5678-9012-3456", true},
31 {"boundary chars lower", "0000-0000-0000-0000", true},
32 {"boundary chars upper A-H", "ABCD-EFGH-ABCD-EFGH", true},
33 {"boundary chars J-N", "JKMN-JKMN-JKMN-JKMN", true},
34 {"boundary chars P-Z", "PQRS-TUVW-XYZ0-1234", true},
35 }
36
37 for _, tt := range tests {
38 t.Run(tt.name, func(t *testing.T) {
39 got := ValidateSessionID(tt.sessionID)
40 if got != tt.want {
41 t.Errorf("ValidateSessionID(%q) = %v, want %v", tt.sessionID, got, tt.want)
42 }
43 })
44 }
45}
46
47// TestValidateSessionID_InvalidCases tests various invalid session ID formats
48func TestValidateSessionID_InvalidCases(t *testing.T) {
49 tests := []struct {
50 name string
51 sessionID string
52 want bool
53 }{
54 {"empty string", "", false},
55 {"too short", "ABC-DEF-GHI-JKL", false},
56 {"too long", "ABCDE-EFGH-JKMN-PQRS", false},
57 {"missing dashes", "ABCDEFGHJKMNPQRS", false},
58 {"wrong dash positions", "AB-CD-EFGH-JKMNPQRS", false},
59 {"invalid chars I", "ABCI-EFGH-JKMN-PQRS", false},
60 {"invalid chars O", "ABCO-EFGH-JKMN-PQRS", false},
61 {"invalid chars lowercase i", "ABCi-EFGH-JKMN-PQRS", false},
62 {"invalid chars lowercase o", "ABCo-EFGH-JKMN-PQRS", false},
63 {"special characters", "ABC!-EFGH-JKMN-PQRS", false},
64 {"spaces", "ABC -EFGH-JKMN-PQRS", false},
65 {"extra dashes", "ABCD--EFGH-JKMN-PQRS", false},
66 {"underscore instead of dash", "ABCD_EFGH_JKMN_PQRS", false},
67 }
68
69 for _, tt := range tests {
70 t.Run(tt.name, func(t *testing.T) {
71 got := ValidateSessionID(tt.sessionID)
72 if got != tt.want {
73 t.Errorf("ValidateSessionID(%q) = %v, want %v", tt.sessionID, got, tt.want)
74 }
75 })
76 }
77}
78
79// TestNewSessionID_Format tests that NewSessionID generates properly formatted IDs
80func TestNewSessionID_Format(t *testing.T) {
81 // Generate multiple session IDs and verify they all have the correct format
82 for range 100 {
83 sessionID := NewSessionID()
84
85 // Check length
86 if len(sessionID) != 19 { // xxxx-xxxx-xxxx-xxxx = 19 characters
87 t.Errorf("Generated session ID %q has wrong length %d, expected 19", sessionID, len(sessionID))
88 }
89
90 // Check dash positions
91 if sessionID[4] != '-' || sessionID[9] != '-' || sessionID[14] != '-' {
92 t.Errorf("Generated session ID %q has wrong dash positions", sessionID)
93 }
94
95 // Should pass validation
96 if !ValidateSessionID(sessionID) {
97 t.Errorf("Generated session ID %q failed validation", sessionID)
98 }
99 }
100}
101
102// TestNewSessionID_Uniqueness tests that NewSessionID generates unique IDs
103func TestNewSessionID_Uniqueness(t *testing.T) {
104 seen := make(map[string]bool)
105 count := 10000
106
107 for range count {
108 sessionID := NewSessionID()
109 if seen[sessionID] {
110 t.Errorf("Duplicate session ID generated: %q", sessionID)
111 }
112 seen[sessionID] = true
113 }
114
115 if len(seen) != count {
116 t.Errorf("Expected %d unique session IDs, got %d", count, len(seen))
117 }
118}