package validation import ( "strings" "testing" "git.techease.ru/Smart-search/smart-search-back/pkg/errors" "github.com/stretchr/testify/assert" ) func TestValidateEmail(t *testing.T) { tests := []struct { name string email string wantErr bool wantCode string }{ {"valid email", "test@example.com", false, ""}, {"valid with subdomain", "test@sub.example.com", false, ""}, {"valid with plus", "test+tag@example.com", false, ""}, {"valid with dots", "test.name@example.com", false, ""}, {"empty", "", true, errors.ValidationInvalidEmail}, {"no at sign", "testexample.com", true, errors.ValidationInvalidEmail}, {"no domain", "test@", true, errors.ValidationInvalidEmail}, {"no local part", "@example.com", true, errors.ValidationInvalidEmail}, {"double dots in domain", "test@example..com", true, errors.ValidationInvalidEmail}, {"too long", strings.Repeat("a", 255) + "@example.com", true, errors.ValidationInvalidEmail}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateEmail(tt.email) if tt.wantErr { assert.Error(t, err) if appErr, ok := err.(*errors.AppError); ok { assert.Equal(t, tt.wantCode, appErr.Code) } } else { assert.NoError(t, err) } }) } } func TestValidatePassword(t *testing.T) { tests := []struct { name string password string wantErr bool wantCode string }{ {"valid password", "Abcd1234", false, ""}, {"valid with special chars", "Abcd1234!", false, ""}, {"empty", "", true, errors.ValidationInvalidPassword}, {"too short", "Ab1", true, errors.ValidationInvalidPassword}, {"no uppercase", "abcd1234", true, errors.ValidationInvalidPassword}, {"no lowercase", "ABCD1234", true, errors.ValidationInvalidPassword}, {"no digit", "Abcdefgh", true, errors.ValidationInvalidPassword}, {"only digits", "12345678", true, errors.ValidationInvalidPassword}, {"only lowercase", "abcdefgh", true, errors.ValidationInvalidPassword}, {"only uppercase", "ABCDEFGH", true, errors.ValidationInvalidPassword}, {"too long", strings.Repeat("Aa1", 50), true, errors.ValidationInvalidPassword}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidatePassword(tt.password) if tt.wantErr { assert.Error(t, err) if appErr, ok := err.(*errors.AppError); ok { assert.Equal(t, tt.wantCode, appErr.Code) } } else { assert.NoError(t, err) } }) } } func TestValidatePhone(t *testing.T) { tests := []struct { name string phone string wantErr bool wantCode string }{ {"valid international", "+1234567890", false, ""}, {"valid with country code", "+79123456789", false, ""}, {"valid without plus", "1234567890", false, ""}, {"empty", "", true, errors.ValidationInvalidPhone}, {"too short", "123", true, errors.ValidationInvalidPhone}, {"letters", "abcdefgh", true, errors.ValidationInvalidPhone}, {"too long", "+123456789012345678901", true, errors.ValidationInvalidPhone}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidatePhone(tt.phone) if tt.wantErr { assert.Error(t, err) if appErr, ok := err.(*errors.AppError); ok { assert.Equal(t, tt.wantCode, appErr.Code) } } else { assert.NoError(t, err) } }) } } func TestValidateName(t *testing.T) { tests := []struct { name string value string wantErr bool wantCode string }{ {"valid name", "John Doe", false, ""}, {"valid cyrillic", "Иван Иванов", false, ""}, {"empty", "", true, errors.ValidationInvalidName}, {"only whitespace", " ", true, errors.ValidationInvalidName}, {"too long", strings.Repeat("a", 101), true, errors.ValidationInvalidName}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateName(tt.value) if tt.wantErr { assert.Error(t, err) if appErr, ok := err.(*errors.AppError); ok { assert.Equal(t, tt.wantCode, appErr.Code) } } else { assert.NoError(t, err) } }) } } func TestValidateRequestTxt(t *testing.T) { tests := []struct { name string txt string wantErr bool wantCode string }{ {"valid short", "Test request", false, ""}, {"empty is valid", "", false, ""}, {"max length", strings.Repeat("a", MaxRequestTxtLen), false, ""}, {"too long", strings.Repeat("a", MaxRequestTxtLen+1), true, errors.ValidationRequestTooLong}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateRequestTxt(tt.txt) if tt.wantErr { assert.Error(t, err) if appErr, ok := err.(*errors.AppError); ok { assert.Equal(t, tt.wantCode, appErr.Code) } } else { assert.NoError(t, err) } }) } } func TestValidateFileSize(t *testing.T) { tests := []struct { name string size int wantErr bool wantCode string }{ {"zero", 0, false, ""}, {"small file", 1024, false, ""}, {"max size", MaxFileSizeBytes, false, ""}, {"too large", MaxFileSizeBytes + 1, true, errors.ValidationFileTooLarge}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateFileSize(tt.size) if tt.wantErr { assert.Error(t, err) if appErr, ok := err.(*errors.AppError); ok { assert.Equal(t, tt.wantCode, appErr.Code) } } else { assert.NoError(t, err) } }) } } func TestValidateRegistration(t *testing.T) { tests := []struct { name string email string password string userName string phone string wantErr bool }{ {"valid", "test@example.com", "Abcd1234", "John Doe", "+1234567890", false}, {"invalid email", "invalid", "Abcd1234", "John Doe", "+1234567890", true}, {"invalid password", "test@example.com", "weak", "John Doe", "+1234567890", true}, {"invalid name", "test@example.com", "Abcd1234", "", "+1234567890", true}, {"invalid phone", "test@example.com", "Abcd1234", "John Doe", "abc", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateRegistration(tt.email, tt.password, tt.userName, tt.phone) if tt.wantErr { assert.Error(t, err) } else { assert.NoError(t, err) } }) } }