package validation_test import ( "fmt" "time" "github.com/juanatsap/cv-site/internal/validation" ) // Example_basicValidation demonstrates basic usage of the struct tag validator func Example_basicValidation() { req := &validation.ContactFormRequest{ Name: "John Smith", Email: "john@example.com", Company: "Acme Corp", Subject: "Inquiry about services", Message: "I would like to know more about your services.", Honeypot: "", Timestamp: time.Now().Unix() - 10, // 10 seconds ago } err := validation.ValidateContactFormV2(req) if err != nil { fmt.Println("Validation failed:", err) return } fmt.Println("Validation successful!") // Output: Validation successful! } // Example_validationErrors demonstrates error handling func Example_validationErrors() { req := &validation.ContactFormRequest{ Name: "", // Empty - will fail required Email: "invalid-email", Subject: "Test", Message: "Test message", Timestamp: time.Now().Unix() - 10, // Valid timestamp } err := validation.ValidateContactFormV2(req) if err != nil { if verrs, ok := err.(validation.ValidationErrors); ok { fmt.Printf("Found %d validation errors:\n", len(verrs)) for _, e := range verrs { fmt.Printf("- %s: %s\n", e.Field, e.Message) } } } // Output: // Found 2 validation errors: // - name: name is required // - email: Invalid email address format } // Example_trimTransform demonstrates automatic trimming func Example_trimTransform() { req := &validation.ContactFormRequest{ Name: " John Smith ", Email: " john@example.com ", Subject: " Test ", Message: " Test message ", Timestamp: time.Now().Unix() - 10, } err := validation.ValidateContactFormV2(req) if err != nil { fmt.Println("Error:", err) return } fmt.Printf("Name: '%s'\n", req.Name) fmt.Printf("Email: '%s'\n", req.Email) fmt.Printf("Subject: '%s'\n", req.Subject) fmt.Printf("Message: '%s'\n", req.Message) // Output: // Name: 'John Smith' // Email: 'john@example.com' // Subject: 'Test' // Message: 'Test message' } // Example_securityValidation demonstrates security features func Example_securityValidation() { // Email injection attempt via subject field req := &validation.ContactFormRequest{ Name: "John Smith", Email: "test@example.com", Subject: "Test\nBcc: attacker@evil.com", Message: "Test", Timestamp: time.Now().Unix() - 10, } err := validation.ValidateContactFormV2(req) if err != nil { if verrs, ok := err.(validation.ValidationErrors); ok { for _, e := range verrs { if e.Tag == "no_injection" { fmt.Printf("Security violation detected: %s\n", e.Message) break } } } } // Output: Security violation detected: subject contains invalid characters (possible injection attempt) } // Example_botDetection demonstrates honeypot and timing validation func Example_botDetection() { // Bot filled honeypot field req1 := &validation.ContactFormRequest{ Name: "Bot", Email: "bot@example.com", Subject: "Spam", Message: "Spam message", Honeypot: "http://evil.com", } err1 := validation.ValidateContactFormV2(req1) if err1 != nil { if verrs, ok := err1.(validation.ValidationErrors); ok { if honeypotErr := verrs.GetFieldError("website"); honeypotErr != nil { fmt.Println("Bot detected via honeypot:", honeypotErr.Message) } } } // Bot submitted too quickly req2 := &validation.ContactFormRequest{ Name: "John", Email: "john@example.com", Subject: "Test", Message: "Test", Timestamp: time.Now().Unix(), // Just now (< 2 seconds) } err2 := validation.ValidateContactFormV2(req2) if err2 != nil { if verrs, ok := err2.(validation.ValidationErrors); ok { if timingErr := verrs.GetFieldError("timestamp"); timingErr != nil { fmt.Println("Bot detected via timing:", timingErr.Message) } } } // Output: // Bot detected via honeypot: Bot detected // Bot detected via timing: Form submitted too quickly (bot detected) } // Example_internationalNames demonstrates UTF-8 support func Example_internationalNames() { names := []struct { name string valid bool }{ {"José María", true}, // Spanish {"François Dubois", true}, // French {"Müller", true}, // German {"Anne-Marie", true}, // Hyphenated {"O'Connor", true}, // Apostrophe {"John123", false}, // Numbers (invalid) {"John@Smith", false}, // Special chars (invalid) } for _, tc := range names { req := &validation.ContactFormRequest{ Name: tc.name, Email: "test@example.com", Subject: "Test", Message: "Test", Timestamp: time.Now().Unix() - 10, } err := validation.ValidateContactFormV2(req) isValid := err == nil || !containsPatternError(err, "name") if isValid == tc.valid { fmt.Printf("'%s': %v ✓\n", tc.name, tc.valid) } else { fmt.Printf("'%s': unexpected result\n", tc.name) } } // Output: // 'José María': true ✓ // 'François Dubois': true ✓ // 'Müller': true ✓ // 'Anne-Marie': true ✓ // 'O'Connor': true ✓ // 'John123': false ✓ // 'John@Smith': false ✓ } // Example_multipleErrors demonstrates handling multiple validation errors func Example_multipleErrors() { req := &validation.ContactFormRequest{ Name: "", // Required Email: "invalid", // Invalid format Subject: "", // Required Message: "", // Required Timestamp: time.Now().Unix() - 10, } err := validation.ValidateContactFormV2(req) if err != nil { if verrs, ok := err.(validation.ValidationErrors); ok { fmt.Printf("Total errors: %d\n", len(verrs)) // Get errors by field fields := []string{"name", "email", "subject", "message"} for _, field := range fields { if fieldErr := verrs.GetFieldError(field); fieldErr != nil { fmt.Printf("- %s: %s (tag: %s)\n", fieldErr.Field, fieldErr.Message, fieldErr.Tag) } } } } // Output: // Total errors: 4 // - name: name is required (tag: required) // - email: Invalid email address format (tag: email) // - subject: subject is required (tag: required) // - message: message is required (tag: required) } // Helper function for example func containsPatternError(err error, field string) bool { if err == nil { return false } verrs, ok := err.(validation.ValidationErrors) if !ok { return false } for _, e := range verrs { if e.Field == field && e.Tag == "pattern" { return true } } return false }