feat: implement email parsing and validation in parser package
This commit is contained in:
parent
08333b80b2
commit
ae6fb3a27b
3 changed files with 152 additions and 1 deletions
|
|
@ -262,7 +262,8 @@ func processLocatore(tmp *typesdefs.AnnuncioParsed, annuncio *typesdefs.Annuncio
|
|||
if annuncio.Clienti == nil || annuncio.Clienti.Cliente == nil {
|
||||
return
|
||||
}
|
||||
tmp.Email = annuncio.Clienti.Cliente.Email1
|
||||
|
||||
tmp.Email = parser.ParseEmail(annuncio.Clienti.Cliente.Email1)
|
||||
|
||||
var number string
|
||||
for _, tel := range []*string{annuncio.Clienti.Cliente.Tel1, annuncio.Clienti.Cliente.Tel2, annuncio.Clienti.Cliente.Tel3} {
|
||||
|
|
|
|||
|
|
@ -188,3 +188,89 @@ func ParseTipologia(t1, t2 *string) (tipo *string) {
|
|||
return utils.Ptr("Errore")
|
||||
|
||||
}
|
||||
|
||||
func ParseEmail(input *string) *string {
|
||||
if input == nil {
|
||||
return nil
|
||||
}
|
||||
email := strings.TrimLeft(*input, " ")
|
||||
if email == "" {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(email, " ")
|
||||
if len(parts) > 0 {
|
||||
email = parts[0]
|
||||
}
|
||||
email = strings.TrimSpace(email)
|
||||
if email == "" {
|
||||
return nil
|
||||
}
|
||||
// Basic email validation
|
||||
if !isValidEmail(email) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &email
|
||||
}
|
||||
|
||||
func isValidEmail(email string) bool {
|
||||
// Must contain exactly one @ symbol
|
||||
atCount := strings.Count(email, "@")
|
||||
if atCount != 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Split on @ to get local and domain parts
|
||||
parts := strings.Split(email, "@")
|
||||
if len(parts) != 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
local := parts[0]
|
||||
domain := parts[1]
|
||||
|
||||
// Local part cannot be empty
|
||||
if local == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Domain part cannot be empty
|
||||
if domain == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Domain must contain at least one dot
|
||||
if !strings.Contains(domain, ".") {
|
||||
return false
|
||||
}
|
||||
|
||||
// Domain cannot start or end with dot
|
||||
if strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") {
|
||||
return false
|
||||
}
|
||||
|
||||
// Domain cannot have consecutive dots
|
||||
if strings.Contains(domain, "..") {
|
||||
return false
|
||||
}
|
||||
|
||||
// Local part cannot start or end with dot
|
||||
if strings.HasPrefix(local, ".") || strings.HasSuffix(local, ".") {
|
||||
return false
|
||||
}
|
||||
|
||||
// Local part cannot have consecutive dots
|
||||
if strings.Contains(local, "..") {
|
||||
return false
|
||||
}
|
||||
|
||||
// Basic check for valid characters (this is simplified)
|
||||
// In production, you might want to use a proper regex or email validation library
|
||||
for _, char := range email {
|
||||
if char == ' ' || char == '\t' || char == '\n' || char == '\r' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -416,3 +416,67 @@ func TestProcessTipologia(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseEmail(t *testing.T) {
|
||||
tests := []struct {
|
||||
input *string
|
||||
want *string
|
||||
}{
|
||||
{input: utils.Ptr(" test@test.it "), want: utils.Ptr("test@test.it")},
|
||||
{input: utils.Ptr("user@example.com"), want: utils.Ptr("user@example.com")},
|
||||
{input: utils.Ptr("admin@domain.org"), want: utils.Ptr("admin@domain.org")},
|
||||
{input: utils.Ptr("contact@company.co.uk"), want: utils.Ptr("contact@company.co.uk")},
|
||||
{input: utils.Ptr("user.name@example.com"), want: utils.Ptr("user.name@example.com")},
|
||||
{input: utils.Ptr("user+tag@example.com"), want: utils.Ptr("user+tag@example.com")},
|
||||
{input: utils.Ptr("123@example.com"), want: utils.Ptr("123@example.com")},
|
||||
|
||||
// Emails with extra whitespace
|
||||
{input: utils.Ptr(" email@test.com "), want: utils.Ptr("email@test.com")},
|
||||
{input: utils.Ptr("\temail@test.com\t"), want: utils.Ptr("email@test.com")},
|
||||
{input: utils.Ptr("\nemail@test.com\n"), want: utils.Ptr("email@test.com")},
|
||||
|
||||
// Invalid emails (should return nil)
|
||||
{input: utils.Ptr("invalid-email"), want: nil},
|
||||
{input: utils.Ptr("@domain.com"), want: nil},
|
||||
{input: utils.Ptr("user@"), want: nil},
|
||||
{input: utils.Ptr("user@domain"), want: nil},
|
||||
{input: utils.Ptr("user.domain.com"), want: nil},
|
||||
{input: utils.Ptr("user@@domain.com"), want: nil},
|
||||
{input: utils.Ptr(""), want: nil},
|
||||
{input: utils.Ptr(" "), want: nil},
|
||||
{input: nil, want: nil},
|
||||
|
||||
// Edge cases
|
||||
{input: utils.Ptr("a@b.co"), want: utils.Ptr("a@b.co")},
|
||||
{input: utils.Ptr("test@test-domain.com"), want: utils.Ptr("test@test-domain.com")},
|
||||
{input: utils.Ptr("user@sub.domain.com"), want: utils.Ptr("user@sub.domain.com")},
|
||||
{input: utils.Ptr("lui.stra2006@gmail.com - LUIGINA"), want: utils.Ptr("lui.stra2006@gmail.com")},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := parser.ParseEmail(tt.input)
|
||||
if tt.want == nil {
|
||||
if got != nil {
|
||||
|
||||
inputStr := "nil"
|
||||
if tt.input != nil {
|
||||
inputStr = *tt.input
|
||||
}
|
||||
t.Errorf("got %q, want nil, input: %q", *got, inputStr)
|
||||
}
|
||||
} else {
|
||||
if got == nil {
|
||||
inputStr := "nil"
|
||||
if tt.input != nil {
|
||||
inputStr = *tt.input
|
||||
}
|
||||
t.Errorf("got nil, want %q, input: %q", *tt.want, inputStr)
|
||||
} else if *got != *tt.want {
|
||||
inputStr := "nil"
|
||||
if tt.input != nil {
|
||||
inputStr = *tt.input
|
||||
}
|
||||
t.Errorf("got %q, want %q, input: %q", *got, *tt.want, inputStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue