commit e3f3ba04dd40dab2eea6b2c6380a8cf4b198044e
parent b25b49b1e65c7cce38814e04ddc36ac08c9a55ff
Author: Christian Grothoff <grothoff@gnunet.org>
Date: Thu, 29 Jan 2026 18:02:38 +0900
add test case
Diffstat:
1 file changed, 205 insertions(+), 0 deletions(-)
diff --git a/src/util/test_validators.c b/src/util/test_validators.c
@@ -0,0 +1,205 @@
+/*
+ This file is part of TALER
+ (C) 2026 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file util/test_validators.c
+ * @brief Tests for validators.
+ * @author Christian Grothoff (ivan@avalos.me)
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include "taler_merchant_util.h"
+
+static bool
+check_email (void)
+{
+ struct
+ {
+ const char *email;
+ bool expected;
+ } tests[] = {
+ /* Valid emails */
+ {"user@example.com", true},
+ {"john.doe@example.co.uk", true},
+ {"alice+tag@domain.org", true},
+ {"test_underscore@test.example", true},
+ {"user!special@example.com", true},
+ {"first.last@sub.domain.example.com", true},
+ {"\"john doe\"@example.com", true},
+ {"\"very.unusual.@.unusual.com\"@example.com", true},
+ {"user@192.168.1.1", true},
+ {"user@[192.168.1.1]", true},
+ {"user@[IPv6:2001:db8::1]", true},
+ {"user@[IPv6::1]", true},
+ {"a@b.c", true},
+ {"test+123@test-domain.org", true},
+ {"_test@example.com", true},
+ {"1234567890@example.com", true},
+
+ /* Invalid emails */
+ {"", false},
+ {"plainaddress", false},
+ {"@example.com", false},
+ {"user@", false},
+ {"user name@example.com", false},
+ {"user@domain", false}, /* No TLD - debatable, but common validation */
+ {"user..name@example.com", false},
+ {".user@example.com", false},
+ {"user.@example.com", false},
+ {"user@.example.com", false},
+ {"user@example.com.", false},
+ {"user@-example.com", false},
+ {"user@example-.com", false},
+ {"user@@example.com", false},
+ {"user@exam ple.com", false},
+ {"user@[256.256.256.256]", false},
+ {"user@[IPv6:zzzz::1]", false},
+ };
+
+ unsigned int num_tests = sizeof (tests) / sizeof (tests[0]);
+ unsigned int passed = 0;
+ unsigned int failed = 0;
+
+ for (unsigned int i = 0; i < num_tests; i++)
+ {
+ bool result = TALER_MERCHANT_email_valid (tests[i].email);
+ bool success = (result == tests[i].expected);
+
+ if (success)
+ {
+ passed++;
+ continue;
+ }
+ failed++;
+ fprintf (stderr,
+ "FAIL: \"%s\" -> %s (expected %s)\n",
+ tests[i].email ? tests[i].email : "(NULL)",
+ result ? "VALID" : "INVALID",
+ tests[i].expected ? "VALID" : "INVALID");
+ }
+ return (failed > 0) ? 1 : 0;
+}
+
+
+static bool
+check_phone (void)
+{
+ struct
+ {
+ const char *phone;
+ const char *expected_normalized;
+ bool allow_letters;
+ } tests[] = {
+ /* Valid phone numbers with +CC - digits only */
+ {"+1-202-555-0173", "+12025550173", false},
+ {"+1 202 555 0173", "+12025550173", false},
+ {"+1 (202) 555-0173", "+12025550173", false},
+ {"+33142685300", "+33142685300", false},
+ {"+33 1 42 68 53 00", "+33142685300", false},
+ {"+44 20 7946 0958", "+442079460958", false},
+ {"+44.20.7946.0958", "+442079460958", false},
+ {"+49-30-12345678", "+493012345678", false},
+ {"+886 2 2345 6789", "+886223456789", false},
+ {"+1-800-555-0123", "+18005550123", false},
+ {"+81-3-1234-5678", "+81312345678", false},
+ {"+39 06 6994 0255", "+390669940255", false},
+ {"+34-91-577-3200", "+34915773200", false},
+ {"+46 8 123456", "+468123456", false},
+ {"+1(555)1234567", "+15551234567", false},
+ {"+1-555-1234567", "+15551234567", false},
+ {"+358 9 1234567", "+35891234567", false},
+ {"+1 202-555.0173", "+12025550173", false},
+ {"+7 495 123-45-67", "+74951234567", false},
+
+ /* Valid phone numbers with letters (allow_letters=true) */
+ {"+1-800-CALL-NOW", "+18002255669", true},
+ {"+1-800-FLOWERS", "+18003569377", true},
+ {"+1-888-PIZZA", "+188874992", true},
+ {"+1 800 CALL NOW", "+18002255669", true},
+ {"+44-HELLO-WORLD", "+444355696753", true},
+ {"+1-555-ABCDEFGH", "+155522233344", true},
+
+ /* Letters should fail when allow_letters=false */
+ {"+1-800-CALL-NOW", NULL, false},
+ {"+1-800-FLOWERS", NULL, false},
+
+ /* Invalid phone numbers */
+ {NULL, NULL, false},
+ {"", NULL, false},
+ {"202-555-0173", NULL, false}, /* Missing + */
+ {"1-202-555-0173", NULL, false}, /* Missing + */
+ {"+1", NULL, false}, /* Only country code */
+ {"+1 abc def ghij", NULL, false}, /* Invalid format */
+ {"1-800-555-0123", NULL, false}, /* No plus sign */
+ {"++1-202-555-0173", NULL, false}, /* Double plus */
+ {"+1--202-555-0173", NULL, false}, /* Double hyphen */
+ {"+12025550173 ", NULL, false}, /* Trailing space */
+ {" +12025550173", NULL, false}, /* Leading space */
+ {"+1 (555", NULL, false}, /* Unclosed parenthesis */
+ {"+1 555)", NULL, false}, /* Unmatched closing paren */
+ {"+1-555-", NULL, false}, /* Trailing hyphen */
+ {"+1-555-01a3", NULL, false}, /* Lowercase letter without allow_letters */
+ {"+1 (202", NULL, false}, /* Unmatched paren */
+ };
+
+ unsigned int num_tests = sizeof (tests) / sizeof (tests[0]);
+ unsigned int passed = 0;
+ unsigned int failed = 0;
+
+ for (unsigned int i = 0; i < num_tests; i++)
+ {
+ char *result = TALER_MERCHANT_phone_valid (tests[i].phone,
+ tests[i].allow_letters);
+ bool success;
+
+ if (NULL == tests[i].expected_normalized)
+ {
+ success = (NULL == result);
+ }
+ else
+ {
+ success = (NULL != result &&
+ 0 == strcmp (result,
+ tests[i].expected_normalized));
+ }
+ if (success)
+ {
+ passed++;
+ }
+ else
+ {
+ failed++;
+ fprintf (stderr,
+ "FAIL: (`%s' (letters=%s) -> `%s'",
+ tests[i].phone,
+ tests[i].allow_letters ? "true" : "false",
+ result);
+ }
+ GNUNET_free (result);
+ }
+ return (failed > 0) ? 1 : 0;
+}
+
+
+int
+main (void)
+{
+ if (! check_email ())
+ return 1;
+ if (! check_phone ())
+ return 1;
+ return 0;
+}