mirror of
https://github.com/wneessen/apg-go.git
synced 2024-11-24 23:00:50 +01:00
Implement additional tests for password generation functionality
In this commit, several new tests have been introduced into random_test.go. These include cases for generating pronounceable passwords, testing minimum requirement conditions, and checking different password algorithms. This provides more comprehensive testing coverage and confirms the expected functionality of password generator methods.
This commit is contained in:
parent
8cb702c932
commit
90ff88de41
1 changed files with 181 additions and 1 deletions
182
random_test.go
182
random_test.go
|
@ -3,6 +3,8 @@ package apg
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -251,7 +253,6 @@ func TestGetPasswordLength(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Act and assert for each test case
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.Name, func(t *testing.T) {
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
generator.config.FixedLength = tc.ConfigFixedLength
|
generator.config.FixedLength = tc.ConfigFixedLength
|
||||||
|
@ -298,6 +299,185 @@ func TestGenerateCoinFlip(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGeneratePronouncable(t *testing.T) {
|
||||||
|
config := NewConfig()
|
||||||
|
generator := New(config)
|
||||||
|
foundSylables := 0
|
||||||
|
for range 100 {
|
||||||
|
res, err := generator.generatePronouncable()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("generatePronouncable() failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, syl := range KoremutakeSyllables {
|
||||||
|
if strings.Contains(res, syl) {
|
||||||
|
foundSylables++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if foundSylables < 100 {
|
||||||
|
t.Errorf("generatePronouncable() failed, expected at least 1 sylable, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckMinimumRequirements(t *testing.T) {
|
||||||
|
config := NewConfig()
|
||||||
|
generator := New(config)
|
||||||
|
testCases := []struct {
|
||||||
|
Name string
|
||||||
|
Password string
|
||||||
|
ConfigMinLowerCase int64
|
||||||
|
ConfigMinNumeric int64
|
||||||
|
ConfigMinSpecial int64
|
||||||
|
ConfigMinUpperCase int64
|
||||||
|
ExpectedResult bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "Meets all requirements",
|
||||||
|
Password: "Th1sIsA$trongP@ssword",
|
||||||
|
ConfigMinLowerCase: 2,
|
||||||
|
ConfigMinNumeric: 1,
|
||||||
|
ConfigMinSpecial: 1,
|
||||||
|
ConfigMinUpperCase: 1,
|
||||||
|
ExpectedResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Missing lowercase",
|
||||||
|
Password: "THISIS@STRONGPASSWORD",
|
||||||
|
ConfigMinLowerCase: 2,
|
||||||
|
ConfigMinNumeric: 1,
|
||||||
|
ConfigMinSpecial: 1,
|
||||||
|
ConfigMinUpperCase: 1,
|
||||||
|
ExpectedResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Missing numeric",
|
||||||
|
Password: "ThisIsA$trongPassword",
|
||||||
|
ConfigMinLowerCase: 2,
|
||||||
|
ConfigMinNumeric: 1,
|
||||||
|
ConfigMinSpecial: 1,
|
||||||
|
ConfigMinUpperCase: 1,
|
||||||
|
ExpectedResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Missing special",
|
||||||
|
Password: "ThisIsALowercaseNumericPassword",
|
||||||
|
ConfigMinLowerCase: 2,
|
||||||
|
ConfigMinNumeric: 1,
|
||||||
|
ConfigMinSpecial: 1,
|
||||||
|
ConfigMinUpperCase: 1,
|
||||||
|
ExpectedResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Missing uppercase",
|
||||||
|
Password: "thisisanumericspecialpassword",
|
||||||
|
ConfigMinLowerCase: 2,
|
||||||
|
ConfigMinNumeric: 1,
|
||||||
|
ConfigMinSpecial: 1,
|
||||||
|
ConfigMinUpperCase: 1,
|
||||||
|
ExpectedResult: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Bare minimum",
|
||||||
|
Password: "a1!",
|
||||||
|
ConfigMinLowerCase: 1,
|
||||||
|
ConfigMinNumeric: 1,
|
||||||
|
ConfigMinSpecial: 1,
|
||||||
|
ConfigMinUpperCase: 0,
|
||||||
|
ExpectedResult: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Empty password",
|
||||||
|
Password: "",
|
||||||
|
ConfigMinLowerCase: 1,
|
||||||
|
ConfigMinNumeric: 1,
|
||||||
|
ConfigMinSpecial: 1,
|
||||||
|
ConfigMinUpperCase: 1,
|
||||||
|
ExpectedResult: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
|
generator.config.MinLowerCase = tc.ConfigMinLowerCase
|
||||||
|
generator.config.MinNumeric = tc.ConfigMinNumeric
|
||||||
|
generator.config.MinSpecial = tc.ConfigMinSpecial
|
||||||
|
generator.config.MinUpperCase = tc.ConfigMinUpperCase
|
||||||
|
result := generator.checkMinimumRequirements(tc.Password)
|
||||||
|
if result != tc.ExpectedResult {
|
||||||
|
t.Errorf("Expected result %v, got %v", tc.ExpectedResult, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateRandom(t *testing.T) {
|
||||||
|
config := NewConfig(WithAlgorithm(AlgoRandom), WithNumberPass(1),
|
||||||
|
WithMinLength(1), WithMaxLength(1))
|
||||||
|
config.MinNumeric = 1
|
||||||
|
generator := New(config)
|
||||||
|
pw, err := generator.generateRandom()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("generateRandom() failed: %s", err)
|
||||||
|
}
|
||||||
|
if len(pw) > 1 {
|
||||||
|
t.Errorf("expected password with length 1 but got: %d", len(pw))
|
||||||
|
}
|
||||||
|
n, err := strconv.Atoi(pw)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected password to be a number but got an error: %s", err)
|
||||||
|
}
|
||||||
|
if n < 0 || n > 9 {
|
||||||
|
t.Errorf("expected password to be a number between 0 and 9, got: %d", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerate(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
algorithm Algorithm
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Pronouncable",
|
||||||
|
algorithm: AlgoPronouncable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "CoinFlip",
|
||||||
|
algorithm: AlgoCoinFlip,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Random",
|
||||||
|
algorithm: AlgoRandom,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Unsupported",
|
||||||
|
algorithm: AlgoUnsupported,
|
||||||
|
expectedErr: fmt.Errorf("unsupported algorithm"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
config := NewConfig(WithAlgorithm(tt.algorithm))
|
||||||
|
g := New(config)
|
||||||
|
_, err := g.Generate()
|
||||||
|
if tt.expectedErr != nil {
|
||||||
|
if err == nil || err.Error() != tt.expectedErr.Error() {
|
||||||
|
t.Errorf("Expected error: %s, got: %s", tt.expectedErr, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkGenerator_CoinFlip(b *testing.B) {
|
func BenchmarkGenerator_CoinFlip(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
g := New(NewConfig())
|
g := New(NewConfig())
|
||||||
|
|
Loading…
Reference in a new issue