add tui features
Some checks failed
CI / test-build (push) Failing after 2m26s

This commit is contained in:
2025-12-15 01:08:17 +07:00
parent 96a6b5a4cf
commit 507961716e
12 changed files with 2793 additions and 8 deletions

View File

@@ -0,0 +1,278 @@
package validation
import "testing"
func TestValidateZFSName(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"valid pool name", "tank", false},
{"valid dataset name", "tank/data", false},
{"valid nested dataset", "tank/data/subdata", false},
{"valid with underscore", "tank_data", false},
{"valid with dash", "tank-data", false},
{"valid with colon", "tank:data", false},
{"empty name", "", true},
{"starts with dash", "-tank", true},
{"starts with dot", ".tank", true},
{"invalid character @", "tank@data", true},
{"too long", string(make([]byte, 257)), true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateZFSName(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateZFSName(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
})
}
}
func TestValidateUsername(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"valid username", "admin", false},
{"valid with underscore", "admin_user", false},
{"valid with dash", "admin-user", false},
{"valid with dot", "admin.user", false},
{"too short", "ab", true},
{"too long", string(make([]byte, 33)), true},
{"empty", "", true},
{"invalid character", "admin@user", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateUsername(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateUsername(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
})
}
}
func TestValidatePassword(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"valid password", "SecurePass123", false},
{"valid with special chars", "Secure!Pass123", false},
{"too short", "Short1", true},
{"no letter", "12345678", true},
{"no number", "SecurePass", true},
{"empty", "", true},
{"too long", string(make([]byte, 129)), true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidatePassword(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ValidatePassword(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
})
}
}
func TestValidateEmail(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"valid email", "user@example.com", false},
{"valid with subdomain", "user@mail.example.com", false},
{"empty (optional)", "", false},
{"invalid format", "notanemail", true},
{"missing @", "user.example.com", true},
{"missing domain", "user@", true},
{"too long", string(make([]byte, 255)), true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateEmail(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateEmail(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
})
}
}
func TestValidateShareName(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"valid share name", "data-share", false},
{"valid with underscore", "data_share", false},
{"reserved name CON", "CON", true},
{"reserved name COM1", "COM1", true},
{"too long", string(make([]byte, 81)), true},
{"empty", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateShareName(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateShareName(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
})
}
}
func TestValidateIQN(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"valid IQN", "iqn.2024-12.com.atlas:target1", false},
{"invalid format", "iqn.2024-12", true},
{"missing iqn prefix", "2024-12.com.atlas:target1", true},
{"invalid date format", "iqn.2024-1.com.atlas:target1", true},
{"empty", "", true},
{"too long", string(make([]byte, 224)), true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateIQN(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateIQN(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
})
}
}
func TestValidateSize(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"valid size bytes", "1024", false},
{"valid size KB", "10K", false},
{"valid size MB", "100M", false},
{"valid size GB", "1G", false},
{"valid size TB", "2T", false},
{"lowercase unit", "1g", false},
{"invalid unit", "10X", true},
{"empty", "", true},
{"no number", "G", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateSize(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateSize(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
})
}
}
func TestValidatePath(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"valid absolute path", "/tank/data", false},
{"valid root path", "/", false},
{"empty (optional)", "", false},
{"relative path", "tank/data", true},
{"path traversal", "/tank/../data", true},
{"double slash", "/tank//data", true},
{"too long", "/" + string(make([]byte, 4096)), true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidatePath(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ValidatePath(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
})
}
}
func TestValidateCIDR(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"valid CIDR", "192.168.1.0/24", false},
{"valid IP", "192.168.1.1", false},
{"wildcard", "*", false},
{"valid hostname", "server.example.com", false},
{"invalid format", "not@a@valid@format", true},
{"empty", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateCIDR(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ValidateCIDR(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
}
})
}
}
func TestSanitizeString(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{"normal string", "hello world", "hello world"},
{"with null byte", "hello\x00world", "helloworld"},
{"with control chars", "hello\x01\x02world", "helloworld"},
{"with whitespace", " hello world ", "hello world"},
{"empty", "", ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := SanitizeString(tt.input)
if result != tt.expected {
t.Errorf("SanitizeString(%q) = %q, want %q", tt.input, result, tt.expected)
}
})
}
}
func TestSanitizePath(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{"normal path", "/tank/data", "/tank/data"},
{"with backslash", "/tank\\data", "/tank/data"},
{"with double slash", "/tank//data", "/tank/data"},
{"with whitespace", " /tank/data ", "/tank/data"},
{"multiple slashes", "/tank///data", "/tank/data"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := SanitizePath(tt.input)
if result != tt.expected {
t.Errorf("SanitizePath(%q) = %q, want %q", tt.input, result, tt.expected)
}
})
}
}