package auth import ( "testing" ) func TestHashPassword_ProducesVerifiableHash(t *testing.T) { hash, err := HashPassword("secret") if err != nil { t.Fatalf("HashPassword returned error: %v", err) } if hash == "" { t.Fatal("HashPassword returned empty string") } if !VerifyPassword("secret", hash) { t.Error("VerifyPassword returned false for correct password") } } func TestHashPassword_TwoCallsProduceDifferentHashes(t *testing.T) { h1, err1 := HashPassword("secret") h2, err2 := HashPassword("secret") if err1 != nil || err2 != nil { t.Fatalf("HashPassword error: %v / %v", err1, err2) } // Different salts → different hashes if h1 == h2 { t.Error("expected distinct hashes for same password (due to random salt), got identical") } } func TestVerifyPassword_WrongPassword(t *testing.T) { hash, err := HashPassword("correct") if err != nil { t.Fatalf("HashPassword error: %v", err) } if VerifyPassword("wrong", hash) { t.Error("VerifyPassword returned true for wrong password") } } func TestVerifyPassword_EmptyPassword(t *testing.T) { hash, err := HashPassword("notempty") if err != nil { t.Fatalf("HashPassword error: %v", err) } if VerifyPassword("", hash) { t.Error("VerifyPassword returned true for empty password against non-empty hash") } } func TestVerifyPassword_MalformedHash(t *testing.T) { cases := []string{ "", "notahash", "$wrongalgo$aabb$ccdd", "$argon2id$nothex$ccdd", "$argon2id$aabb$nothex", } for _, h := range cases { if VerifyPassword("secret", h) { t.Errorf("VerifyPassword should return false for malformed hash %q", h) } } }