package auth import "testing" func TestHashPassword(t *testing.T) { t.Run("hash never equals the plaintext", func(t *testing.T) { pw := "secret123" hash, err := HashPassword(pw) if err != nil { t.Fatalf("HashPassword returned error: %v", err) } if hash == pw { t.Fatal("expected hash to differ from plaintext") } }) t.Run("hashing the same password twice yields two different hashes", func(t *testing.T) { pw := "secret123" h1, err := HashPassword(pw) if err != nil { t.Fatalf("HashPassword returned error: %v", err) } h2, err := HashPassword(pw) if err != nil { t.Fatalf("HashPassword returned error: %v", err) } if h1 == h2 { t.Fatal("expected two different hashes for the same password (salting)") } }) t.Run("the hash verifies against the original password", func(t *testing.T) { pw := "secret123" hash, err := HashPassword(pw) if err != nil { t.Fatalf("HashPassword returned error: %v", err) } if !CheckPassword(pw, hash) { t.Fatal("expected CheckPassword to succeed against its own hash") } }) } func TestCheckPassword(t *testing.T) { pw := "secret123" hash, err := HashPassword(pw) if err != nil { t.Fatalf("HashPassword returned error: %v", err) } tests := []struct { name string password string hash string want bool }{ {"correct password returns true", pw, hash, true}, {"wrong password returns false", "wrongpass", hash, false}, {"empty password returns false", "", hash, false}, {"garbage non-bcrypt hash returns false without panicking", pw, "this-is-not-a-bcrypt-hash", false}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { defer func() { if r := recover(); r != nil { t.Fatalf("CheckPassword panicked: %v", r) } }() got := CheckPassword(tc.password, tc.hash) if got != tc.want { t.Fatalf("CheckPassword(%q, hash) = %v, want %v", tc.password, got, tc.want) } }) } }