blob: 4ed83d41d09991c7ba20caaaad20cca57a86e8a6 [file] [log] [blame]
package skabandclient
import (
"testing"
)
// TestValidateSessionID_Roundtrip tests that all session IDs generated by NewSessionID
// pass validation by ValidateSessionID
func TestValidateSessionID_Roundtrip(t *testing.T) {
// Test multiple generated session IDs to ensure consistent behavior
for i := range 1000 {
sessionID := NewSessionID()
if !ValidateSessionID(sessionID) {
t.Errorf("Generated session ID %q failed validation (iteration %d)", sessionID, i)
}
}
}
// TestValidateSessionID_ValidCases tests various valid session ID formats
func TestValidateSessionID_ValidCases(t *testing.T) {
tests := []struct {
name string
sessionID string
want bool
}{
{"uppercase letters", "ABCD-EFGH-JKMN-PQRS", true},
{"lowercase letters", "abcd-efgh-jkmn-pqrs", true},
{"mixed case", "AbCd-EfGh-JkMn-PqRs", true},
{"with numbers", "123A-5678-9BCD-EF0H", true},
{"all numbers", "1234-5678-9012-3456", true},
{"boundary chars lower", "0000-0000-0000-0000", true},
{"boundary chars upper A-H", "ABCD-EFGH-ABCD-EFGH", true},
{"boundary chars J-N", "JKMN-JKMN-JKMN-JKMN", true},
{"boundary chars P-Z", "PQRS-TUVW-XYZ0-1234", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ValidateSessionID(tt.sessionID)
if got != tt.want {
t.Errorf("ValidateSessionID(%q) = %v, want %v", tt.sessionID, got, tt.want)
}
})
}
}
// TestValidateSessionID_InvalidCases tests various invalid session ID formats
func TestValidateSessionID_InvalidCases(t *testing.T) {
tests := []struct {
name string
sessionID string
want bool
}{
{"empty string", "", false},
{"too short", "ABC-DEF-GHI-JKL", false},
{"too long", "ABCDE-EFGH-JKMN-PQRS", false},
{"missing dashes", "ABCDEFGHJKMNPQRS", false},
{"wrong dash positions", "AB-CD-EFGH-JKMNPQRS", false},
{"invalid chars I", "ABCI-EFGH-JKMN-PQRS", false},
{"invalid chars O", "ABCO-EFGH-JKMN-PQRS", false},
{"invalid chars lowercase i", "ABCi-EFGH-JKMN-PQRS", false},
{"invalid chars lowercase o", "ABCo-EFGH-JKMN-PQRS", false},
{"special characters", "ABC!-EFGH-JKMN-PQRS", false},
{"spaces", "ABC -EFGH-JKMN-PQRS", false},
{"extra dashes", "ABCD--EFGH-JKMN-PQRS", false},
{"underscore instead of dash", "ABCD_EFGH_JKMN_PQRS", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ValidateSessionID(tt.sessionID)
if got != tt.want {
t.Errorf("ValidateSessionID(%q) = %v, want %v", tt.sessionID, got, tt.want)
}
})
}
}
// TestNewSessionID_Format tests that NewSessionID generates properly formatted IDs
func TestNewSessionID_Format(t *testing.T) {
// Generate multiple session IDs and verify they all have the correct format
for range 100 {
sessionID := NewSessionID()
// Check length
if len(sessionID) != 19 { // xxxx-xxxx-xxxx-xxxx = 19 characters
t.Errorf("Generated session ID %q has wrong length %d, expected 19", sessionID, len(sessionID))
}
// Check dash positions
if sessionID[4] != '-' || sessionID[9] != '-' || sessionID[14] != '-' {
t.Errorf("Generated session ID %q has wrong dash positions", sessionID)
}
// Should pass validation
if !ValidateSessionID(sessionID) {
t.Errorf("Generated session ID %q failed validation", sessionID)
}
}
}
// TestNewSessionID_Uniqueness tests that NewSessionID generates unique IDs
func TestNewSessionID_Uniqueness(t *testing.T) {
seen := make(map[string]bool)
count := 10000
for range count {
sessionID := NewSessionID()
if seen[sessionID] {
t.Errorf("Duplicate session ID generated: %q", sessionID)
}
seen[sessionID] = true
}
if len(seen) != count {
t.Errorf("Expected %d unique session IDs, got %d", count, len(seen))
}
}