forked from baron/baron-sso
129 lines
3.4 KiB
Go
129 lines
3.4 KiB
Go
package utils
|
|
|
|
import (
|
|
"baron-sso-backend/internal/domain"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestValidatePasswordWithPolicy(t *testing.T) {
|
|
policy := &domain.PasswordPolicy{
|
|
MinLength: 8,
|
|
Lowercase: true,
|
|
Uppercase: true,
|
|
Number: true,
|
|
NonAlphanumeric: true,
|
|
MinCharacterTypes: 3,
|
|
}
|
|
|
|
t.Run("Valid Password", func(t *testing.T) {
|
|
err := ValidatePasswordWithPolicy(policy, "Pass1234!")
|
|
assert.NoError(t, err)
|
|
})
|
|
|
|
t.Run("Nil Policy", func(t *testing.T) {
|
|
err := ValidatePasswordWithPolicy(nil, "")
|
|
assert.NoError(t, err)
|
|
})
|
|
|
|
t.Run("Too Short", func(t *testing.T) {
|
|
err := ValidatePasswordWithPolicy(policy, "P123!")
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "최소 8자")
|
|
})
|
|
|
|
t.Run("Missing Lowercase", func(t *testing.T) {
|
|
err := ValidatePasswordWithPolicy(policy, "PASS1234!")
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "소문자")
|
|
})
|
|
|
|
t.Run("Missing Uppercase", func(t *testing.T) {
|
|
err := ValidatePasswordWithPolicy(policy, "pass1234!")
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "대문자")
|
|
})
|
|
|
|
t.Run("Missing Number", func(t *testing.T) {
|
|
err := ValidatePasswordWithPolicy(policy, "Password!")
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "숫자")
|
|
})
|
|
|
|
t.Run("Missing Symbol", func(t *testing.T) {
|
|
err := ValidatePasswordWithPolicy(policy, "Pass1234")
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "특수문자")
|
|
})
|
|
|
|
t.Run("Missing Minimum Character Types", func(t *testing.T) {
|
|
err := ValidatePasswordWithPolicy(&domain.PasswordPolicy{MinLength: 4, MinCharacterTypes: 4}, "abcd")
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "4가지")
|
|
})
|
|
}
|
|
|
|
func TestGeneratePasswordWithPolicy(t *testing.T) {
|
|
policy := &domain.PasswordPolicy{
|
|
MinLength: 16,
|
|
Lowercase: true,
|
|
Uppercase: true,
|
|
Number: true,
|
|
NonAlphanumeric: true,
|
|
}
|
|
|
|
t.Run("Generate and Validate", func(t *testing.T) {
|
|
password, err := GeneratePasswordWithPolicy(policy)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, password, 16)
|
|
|
|
err = ValidatePasswordWithPolicy(policy, password)
|
|
assert.NoError(t, err, "Generated password '%s' does not satisfy policy", password)
|
|
})
|
|
|
|
t.Run("Nil Policy Uses Default Length", func(t *testing.T) {
|
|
password, err := GeneratePasswordWithPolicy(nil)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, password, 12)
|
|
})
|
|
|
|
t.Run("Minimum Character Types Adds Optional Categories", func(t *testing.T) {
|
|
policy := &domain.PasswordPolicy{
|
|
MinLength: 4,
|
|
Lowercase: true,
|
|
MinCharacterTypes: 4,
|
|
}
|
|
|
|
password, err := GeneratePasswordWithPolicy(policy)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, password, 4)
|
|
assert.NoError(t, ValidatePasswordWithPolicy(policy, password))
|
|
})
|
|
|
|
t.Run("Required Categories Raise Short Minimum Length", func(t *testing.T) {
|
|
policy := &domain.PasswordPolicy{
|
|
MinLength: 1,
|
|
Lowercase: true,
|
|
Uppercase: true,
|
|
Number: true,
|
|
NonAlphanumeric: true,
|
|
}
|
|
|
|
password, err := GeneratePasswordWithPolicy(policy)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, password, 4)
|
|
assert.NoError(t, ValidatePasswordWithPolicy(policy, password))
|
|
})
|
|
}
|
|
|
|
func TestPasswordPolicyRandomHelpersRejectInvalidInput(t *testing.T) {
|
|
_, err := randomIndex(0)
|
|
assert.Error(t, err)
|
|
|
|
_, err = randomChar("")
|
|
assert.Error(t, err)
|
|
|
|
assert.NoError(t, shuffleRunes([]rune("a")))
|
|
}
|