package auth import ( "crypto/sha256" "encoding/base64" "strings" "testing" "golang.org/x/crypto/bcrypt" ) func TestMintSessionToken_ReturnsUrlSafeBase64(t *testing.T) { token, err := MintSessionToken() if err != nil { t.Fatalf("MintSessionToken: %v", err) } if len(token) < 40 { t.Errorf("token length = %d, want >= 40 (32B base64 url-safe)", len(token)) } if strings.ContainsAny(token, "+/=") { t.Errorf("token %q contains non-url-safe chars", token) } } func TestHashSessionToken_IsDeterministicSHA256(t *testing.T) { token := "test-token-xyz" want := sha256.Sum256([]byte(token)) got := HashSessionToken(token) if len(got) != sha256.Size { t.Fatalf("hash length = %d, want %d", len(got), sha256.Size) } if base64.StdEncoding.EncodeToString(got) != base64.StdEncoding.EncodeToString(want[:]) { t.Errorf("hash = %x, want %x", got, want) } } func TestVerifyPassword(t *testing.T) { hash, err := bcrypt.GenerateFromPassword([]byte("hunter2"), bcrypt.MinCost) if err != nil { t.Fatalf("GenerateFromPassword: %v", err) } if !VerifyPassword(string(hash), "hunter2") { t.Error("correct password rejected") } if VerifyPassword(string(hash), "wrong") { t.Error("wrong password accepted") } if VerifyPassword("not-a-hash", "hunter2") { t.Error("malformed hash accepted") } }