package parser_test import ( "backend/parser" "backend/utils" "fmt" "testing" "time" ) func TestParseDettaglio(t *testing.T) { tests := []struct { input string wantDisp *string wantPerm *[]int wantPers *[]string }{ { input: "disp:01/10 perm:3-6 persone:single", wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp: perm: persone:", wantDisp: nil, wantPerm: nil, wantPers: nil, }, { input: "disp: perm:3-6 persone:single", // disp missing wantDisp: nil, wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm: persone:single", // perm missing wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: nil, wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:3-6 persone:", // persone missing wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: nil, }, { input: "disp: perm: persone:", // all fields missing wantDisp: nil, wantPerm: nil, wantPers: nil, }, { input: "disp:bad_date perm:3-6 persone:single", // invalid date wantDisp: nil, wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:abc-6 persone:single", // non-numeric perm wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:3- persone:single", // trailing delimiter in perm wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:-6 persone:single", // leading delimiter in perm wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:3-6 persone:single/", // trailing delimiter in persone wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:3-6 persone:/single", // leading delimiter in persone wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:3-6 persone:single//coppia", // double delimiter in persone wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single", "coppia"}), }, { input: "perm:3-6 persone:single", // disp missing wantDisp: nil, wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:3-6", // persone missing wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: nil, }, { input: "disp:01/10 perm: persone:", // perm empty wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: nil, wantPers: nil, }, { input: "", // completely empty string wantDisp: nil, wantPerm: nil, wantPers: nil, }, { input: "disp: 01/10 perm: 3-6 persone: single ", wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "persone:single perm:3-6 disp:01/10", wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:3--6 persone:single", wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10\tperm:3-6\tpersone:single", wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10 perm:3-6 persone:single/coppia!", wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single", "coppia!"}), }, { input: "disp:01/10 disp:02/11 perm:3-6 persone:single", wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), // Only first disp: is parsed wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, { input: "disp:01/10perm:3-6persone:single", wantDisp: utils.Ptr(fmt.Sprintf("01/10/%d", time.Now().Year())), wantPerm: utils.Ptr([]int{3, 6}), wantPers: utils.Ptr([]string{"single"}), }, } for _, tt := range tests { disp_time, perm_arr, persone_arr, _ := parser.ParseDettaglio(tt.input) //Handle *string comparison, including nil if tt.wantDisp != nil { if disp_time == nil { t.Errorf("disp_time: got nil, want %v, input: %v", *tt.wantDisp, tt.input) } else if *disp_time != *tt.wantDisp { t.Errorf("disp_time: got %v, want %v, input: %v", *disp_time, *tt.wantDisp, tt.input) } } else if disp_time != nil { t.Errorf("disp_time: got %v, want nil, input: %v", *disp_time, tt.input) } // Handle *[]int comparison, including nil if tt.wantPerm != nil { if perm_arr == nil || len(*perm_arr) != len(*tt.wantPerm) { t.Errorf("perm_arr: got %v, want %v, input: %v", perm_arr, *tt.wantPerm, tt.input) } else { for i := range *perm_arr { if (*perm_arr)[i] != (*tt.wantPerm)[i] { t.Errorf("perm_arr[%d]: got %v, want %v, input: %v", i, (*perm_arr)[i], (*tt.wantPerm)[i], tt.input) } } } } else if perm_arr != nil && len(*perm_arr) != 0 { t.Errorf("perm_arr: got %v, want nil, input: %v", perm_arr, tt.input) } // Handle *[]string comparison, including nil if tt.wantPers != nil { if persone_arr == nil || len(*persone_arr) != len(*tt.wantPers) { t.Errorf("persone_arr: got %v, want %v, input: %v", persone_arr, *tt.wantPers, tt.input) } else { for i := range *persone_arr { if (*persone_arr)[i] != (*tt.wantPers)[i] { t.Errorf("persone_arr[%d]: got %v, want %v, input: %v", i, (*persone_arr)[i], (*tt.wantPers)[i], tt.input) } } } } else if persone_arr != nil && len(*persone_arr) != 0 { t.Errorf("persone_arr: got %v, want nil, input: %v", persone_arr, tt.input) } } } func TestParseConsegna(t *testing.T) { tests := []struct { input *string wantConsegna *int }{ // Test all Italian month names { input: utils.Ptr("Gennaio"), wantConsegna: utils.Ptr(1), }, { input: utils.Ptr("Febbraio"), wantConsegna: utils.Ptr(2), }, { input: utils.Ptr("Marzo"), wantConsegna: utils.Ptr(3), }, { input: utils.Ptr("Aprile"), wantConsegna: utils.Ptr(4), }, { input: utils.Ptr("Maggio"), wantConsegna: utils.Ptr(5), }, { input: utils.Ptr("Giugno"), wantConsegna: utils.Ptr(6), }, { input: utils.Ptr("Luglio"), wantConsegna: utils.Ptr(7), }, { input: utils.Ptr("Agosto"), wantConsegna: utils.Ptr(8), }, { input: utils.Ptr("Settembre"), wantConsegna: utils.Ptr(9), }, { input: utils.Ptr("Ottobre"), wantConsegna: utils.Ptr(10), }, { input: utils.Ptr("Novembre"), wantConsegna: utils.Ptr(11), }, { input: utils.Ptr("Dicembre"), wantConsegna: utils.Ptr(12), }, // Test "Libero" (should return current month) { input: utils.Ptr("Libero"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, // Test nil input { input: nil, wantConsegna: nil, }, // Test empty string { input: utils.Ptr(""), wantConsegna: utils.Ptr(int(time.Now().Month())), }, // Test lowercase (should return current month as default) { input: utils.Ptr("gennaio"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, // Test with spaces { input: utils.Ptr("Gennaio "), wantConsegna: utils.Ptr(int(time.Now().Month())), }, { input: utils.Ptr(" Gennaio"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, // Test with special characters { input: utils.Ptr("Gennaio!"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, // Test abbreviated forms { input: utils.Ptr("Gen"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, { input: utils.Ptr("Feb"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, // Test English month names { input: utils.Ptr("January"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, // Test numeric strings { input: utils.Ptr("1"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, // Test mixed cases { input: utils.Ptr("GEnNaIo"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, // Test completely unrelated strings { input: utils.Ptr("NotAMonth"), wantConsegna: utils.Ptr(int(time.Now().Month())), }, } for _, tt := range tests { gotConsegna := parser.ParseConsegna(tt.input) if tt.wantConsegna != nil { if gotConsegna == nil { t.Errorf("got nil, want %v, input: %v", *tt.wantConsegna, tt.input) } else if *gotConsegna != *tt.wantConsegna { t.Errorf("got %v, want %v, input: %v", *gotConsegna, *tt.wantConsegna, tt.input) } } else if gotConsegna != nil { t.Errorf("got %v, want nil, input: %v", *gotConsegna, tt.input) } } } func TestParsePrezzo(t *testing.T) { tests := []struct { input *string want int }{ {input: utils.Ptr("100"), want: 10000}, {input: utils.Ptr("€ 100"), want: 10000}, {input: utils.Ptr("100€"), want: 10000}, {input: utils.Ptr("€100"), want: 10000}, {input: utils.Ptr("100 €"), want: 10000}, {input: utils.Ptr("€ 100,50"), want: 10050}, {input: utils.Ptr("100,50€"), want: 10050}, {input: utils.Ptr("€100,50"), want: 10050}, {input: utils.Ptr("100,50 €"), want: 10050}, {input: utils.Ptr("€ 1.000"), want: 100000}, {input: utils.Ptr("1.000€"), want: 100000}, {input: utils.Ptr("€1.000"), want: 100000}, {input: utils.Ptr("1.000 €"), want: 100000}, {input: utils.Ptr("€ 1.000,50"), want: 100050}, {input: utils.Ptr("1.000,50€"), want: 100050}, {input: utils.Ptr("€1.000,50"), want: 100050}, {input: utils.Ptr("1.000,50 €"), want: 100050}, } for _, tt := range tests { got := parser.ParsePrezzo(tt.input) if got != tt.want { inputStr := "" if tt.input != nil { inputStr = *tt.input } t.Errorf("got %v, want %v, input: %v", got, tt.want, inputStr) } } } func TestProcessTipologia(t *testing.T) { tests := []struct { t1, t2 *string want *string }{ {t1: utils.Ptr("V"), want: utils.Ptr("Vendita")}, {t1: utils.Ptr("I"), want: utils.Ptr("Cessione")}, {t1: utils.Ptr("A"), t2: utils.Ptr("Residenziale"), want: utils.Ptr("Transitorio")}, {t1: utils.Ptr("A"), t2: utils.Ptr("Turistico"), want: utils.Ptr("Transitorio")}, {t1: utils.Ptr("A"), t2: utils.Ptr("Stanza"), want: utils.Ptr("Transitorio")}, {t1: utils.Ptr("A"), t2: nil, want: utils.Ptr("Stabile")}, {t1: nil, want: utils.Ptr("Errore")}, // Unknown t1 value {t1: utils.Ptr("X"), want: utils.Ptr("Errore")}, // Lowercase t1 value {t1: utils.Ptr("v"), want: utils.Ptr("Errore")}, // t1 is empty string {t1: utils.Ptr(""), want: utils.Ptr("Errore")}, // t2 is empty string with t1 == "A" {t1: utils.Ptr("A"), t2: utils.Ptr(""), want: utils.Ptr("Stabile")}, // t2 is unknown value with t1 == "A" {t1: utils.Ptr("A"), t2: utils.Ptr("Commerciale"), want: utils.Ptr("Stabile")}, // t2 is lowercase valid value with t1 == "A" {t1: utils.Ptr("A"), t2: utils.Ptr("residenziale"), want: utils.Ptr("Transitorio")}, // t2 is uppercase valid value with t1 == "A" {t1: utils.Ptr("A"), t2: utils.Ptr("RESIDENZIALE"), want: utils.Ptr("Transitorio")}, // t2 is "Stanza" with extra spaces {t1: utils.Ptr("A"), t2: utils.Ptr(" Stanza "), want: utils.Ptr("Transitorio")}, } for _, tt := range tests { got := parser.ParseTipologia(tt.t1, tt.t2) if got == nil || *got != *tt.want { t.Errorf("got %v, want %v, input t1: %v, t2: %v", *got, *tt.want, *tt.t1, *tt.t2) } } } 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) } } } }