feat: implement email parsing and validation in parser package

This commit is contained in:
Marco Pedone 2025-09-03 10:02:04 +02:00
parent 08333b80b2
commit ae6fb3a27b
3 changed files with 152 additions and 1 deletions

View file

@ -262,7 +262,8 @@ func processLocatore(tmp *typesdefs.AnnuncioParsed, annuncio *typesdefs.Annuncio
if annuncio.Clienti == nil || annuncio.Clienti.Cliente == nil { if annuncio.Clienti == nil || annuncio.Clienti.Cliente == nil {
return return
} }
tmp.Email = annuncio.Clienti.Cliente.Email1
tmp.Email = parser.ParseEmail(annuncio.Clienti.Cliente.Email1)
var number string var number string
for _, tel := range []*string{annuncio.Clienti.Cliente.Tel1, annuncio.Clienti.Cliente.Tel2, annuncio.Clienti.Cliente.Tel3} { for _, tel := range []*string{annuncio.Clienti.Cliente.Tel1, annuncio.Clienti.Cliente.Tel2, annuncio.Clienti.Cliente.Tel3} {

View file

@ -188,3 +188,89 @@ func ParseTipologia(t1, t2 *string) (tipo *string) {
return utils.Ptr("Errore") 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
}

View file

@ -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)
}
}
}
}