package passwords import ( "errors" "slices" "strings" "testing" ) func TestGenerateRespectsProfileRequirements(t *testing.T) { t.Parallel() profile := Profile{ Name: "strong", Length: 24, Lowercase: true, Uppercase: true, Digits: true, Symbols: true, MinLowercase: 2, MinUppercase: 2, MinDigits: 2, MinSymbols: 2, ExcludeSimilar: true, } password, err := Generate(profile) if err != nil { t.Fatalf("Generate() error = %v", err) } if len(password) != 24 { t.Fatalf("len(password) = %d, want 24", len(password)) } if countFromSet(password, lowercaseChars) < 2 { t.Fatalf("lowercase count in %q is too small", password) } if countFromSet(password, uppercaseChars) < 2 { t.Fatalf("uppercase count in %q is too small", password) } if countFromSet(password, digitChars) < 2 { t.Fatalf("digit count in %q is too small", password) } if countFromSet(password, symbolChars) < 2 { t.Fatalf("symbol count in %q is too small", password) } if strings.ContainsAny(password, "O0Il1") { t.Fatalf("password %q contains excluded similar characters", password) } } func TestGenerateRejectsImpossibleProfiles(t *testing.T) { t.Parallel() _, err := Generate(Profile{ Name: "bad", Length: 6, Lowercase: true, Uppercase: true, Digits: true, Symbols: true, MinLowercase: 2, MinUppercase: 2, MinDigits: 2, MinSymbols: 2, }) if err == nil { t.Fatal("Generate() error = nil, want impossible profile error") } } func TestProfileSetReturnsNamedProfiles(t *testing.T) { t.Parallel() set := DefaultProfiles() profile, ok := set["strong"] if !ok { t.Fatalf("DefaultProfiles()[\"strong\"] missing") } if profile.Length < 20 || !profile.Symbols { t.Fatalf("strong profile = %#v, want a strong reusable profile", profile) } } func TestDefaultProfileNamesReturnsSortedNames(t *testing.T) { t.Parallel() got := DefaultProfileNames() want := []string{"memorable", "strong"} if !slices.Equal(got, want) { t.Fatalf("DefaultProfileNames() = %v, want %v", got, want) } } func TestLookupDefaultProfileResolvesKnownProfilesAndRejectsUnknownNames(t *testing.T) { t.Parallel() profile, err := LookupDefaultProfile(" strong ") if err != nil { t.Fatalf("LookupDefaultProfile(\" strong \") error = %v", err) } if profile.Name != "strong" { t.Fatalf("LookupDefaultProfile(\" strong \").Name = %q, want %q", profile.Name, "strong") } _, err = LookupDefaultProfile("invalid") if !errors.Is(err, ErrUnknownProfile) { t.Fatalf("LookupDefaultProfile(\"invalid\") error = %v, want ErrUnknownProfile", err) } } func countFromSet(password, chars string) int { count := 0 for _, r := range password { if strings.ContainsRune(chars, r) { count++ } } return count }