package libs import ( "strings" "testing" ) func TestMd5(t *testing.T) { tests := []struct { input string expected string }{ {"hello", "5d41402abc4b2a76b9719d911017c592"}, {"123456", "e10adc3949ba59abbe56e057f20f883e"}, {"", "d41d8cd98f00b204e9800998ecf8427e"}, } for _, tt := range tests { result := Md5([]byte(tt.input)) if result != tt.expected { t.Errorf("Md5(%q) = %q, want %q", tt.input, result, tt.expected) } } } func TestHashPassword(t *testing.T) { password := "test123" hash, salt := HashPassword(password) if hash == "" { t.Error("HashPassword() returned empty hash") } if salt == "" { t.Error("HashPassword() returned empty salt") } if !strings.HasPrefix(hash, "$sha256$") { t.Errorf("HashPassword() hash %q does not have $sha256$ prefix", hash) } // Verify the hash can be verified if !VerifyPassword(password, hash, salt) { t.Error("VerifyPassword() failed for freshly generated hash") } // Wrong password should fail if VerifyPassword("wrong", hash, salt) { t.Error("VerifyPassword() should fail for wrong password") } } func TestVerifyPassword_NewFormat(t *testing.T) { hash, salt := HashPassword("mypassword") if !VerifyPassword("mypassword", hash, salt) { t.Error("VerifyPassword should verify $sha256$ format") } if VerifyPassword("notmypassword", hash, salt) { t.Error("VerifyPassword should reject wrong password for $sha256$ format") } } func TestVerifyPassword_OldFormat(t *testing.T) { // Old format: MD5(password + salt) oldHash := Md5([]byte("oldpass" + "abcd")) if !VerifyPassword("oldpass", oldHash, "abcd") { t.Error("VerifyPassword should verify old MD5 format") } if VerifyPassword("wrongpass", oldHash, "abcd") { t.Error("VerifyPassword should reject wrong password for old MD5 format") } } func TestVerifyPassword_MalformedHash(t *testing.T) { // Malformed $sha256$ hash (only 2 parts instead of 4) malformed := "$sha256$toofew" if VerifyPassword("anything", malformed, "salt") { t.Error("VerifyPassword should reject malformed hash") } } func TestPassword(t *testing.T) { // Default password when empty pwd, salt := Password(0, "") if pwd == "" || salt == "" { t.Error("Password() with empty input should return non-empty hash/salt") } if !strings.HasPrefix(pwd, "$sha256$") { t.Errorf("Password() hash should have $sha256$ prefix, got %q", pwd) } // Custom password pwd2, salt2 := Password(0, "custompass") if pwd2 == "" || salt2 == "" { t.Error("Password() with custom password should return non-empty hash/salt") } if !VerifyPassword("custompass", pwd2, salt2) { t.Error("Password() hash should verify with original password") } } func TestSha256Hex(t *testing.T) { tests := []struct { input string expected string }{ {"hello", "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"}, {"", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}, } for _, tt := range tests { result := Sha256Hex([]byte(tt.input)) if result != tt.expected { t.Errorf("Sha256Hex(%q) = %q, want %q", tt.input, result, tt.expected) } } } func FuzzVerifyPassword(f *testing.F) { f.Add("password123", "$sha256$salt1234$ab12cd34ef56", "salt1234") f.Add("abc", "5d41402abc4b2a76b9719d911017c592", "salt") f.Fuzz(func(t *testing.T, password, hash, salt string) { // Should not panic with any input _ = VerifyPassword(password, hash, salt) }) }