LCOV - code coverage report
Current view: top level - util - test_validators.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.4 % 43 32
Test Date: 2026-04-12 12:58:13 Functions: 100.0 % 3 3

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   (C) 2026 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify it under the
       6              :   terms of the GNU General Public License as published by the Free Software
       7              :   Foundation; either version 3, or (at your option) any later version.
       8              : 
       9              :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10              :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11              :   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12              : 
      13              :   You should have received a copy of the GNU General Public License along with
      14              :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15              : */
      16              : 
      17              : /**
      18              :  * @file util/test_validators.c
      19              :  * @brief Tests for validators.
      20              :  * @author Christian Grothoff (ivan@avalos.me)
      21              :  */
      22              : #include "taler/platform.h"
      23              : #include <gnunet/gnunet_util_lib.h>
      24              : #include "taler/taler_merchant_util.h"
      25              : 
      26              : static bool
      27            1 : check_email (void)
      28              : {
      29              :   struct
      30              :   {
      31              :     const char *email;
      32              :     bool expected;
      33            1 :   } tests[] = {
      34              :     /* Valid emails */
      35              :     {"user@example.com", true},
      36              :     {"john.doe@example.co.uk", true},
      37              :     {"alice+tag@domain.org", true},
      38              :     {"test_underscore@test.example", true},
      39              :     {"user!special@example.com", true},
      40              :     {"first.last@sub.domain.example.com", true},
      41              :     {"\"john doe\"@example.com", true},
      42              :     {"\"very.unusual.@.unusual.com\"@example.com", true},
      43              :     {"user@192.168.1.1", true},
      44              :     {"user@[192.168.1.1]", true},
      45              :     {"user@[IPv6:2001:db8::1]", true},
      46              :     {"user@[IPv6::1]", true},
      47              :     {"a@b.c", true},
      48              :     {"test+123@test-domain.org", true},
      49              :     {"_test@example.com", true},
      50              :     {"1234567890@example.com", true},
      51              : 
      52              :     /* Invalid emails */
      53              :     {"", false},
      54              :     {"plainaddress", false},
      55              :     {"@example.com", false},
      56              :     {"user@", false},
      57              :     {"user name@example.com", false},
      58              :     {"user@domain", false},  /* No TLD - debatable, but common validation */
      59              :     {"user..name@example.com", false},
      60              :     {".user@example.com", false},
      61              :     {"user.@example.com", false},
      62              :     {"user@.example.com", false},
      63              :     {"user@example.com.", false},
      64              :     {"user@-example.com", false},
      65              :     {"user@example-.com", false},
      66              :     {"user@@example.com", false},
      67              :     {"user@exam ple.com", false},
      68              :     {"user@[256.256.256.256]", false},
      69              :     {"user@[IPv6:zzzz::1]", false},
      70              :   };
      71              : 
      72            1 :   unsigned int num_tests = sizeof (tests) / sizeof (tests[0]);
      73            1 :   unsigned int passed = 0;
      74            1 :   unsigned int failed = 0;
      75              : 
      76           34 :   for (unsigned int i = 0; i < num_tests; i++)
      77              :   {
      78           33 :     bool result = TALER_MERCHANT_email_valid (tests[i].email);
      79           33 :     bool success = (result == tests[i].expected);
      80              : 
      81           33 :     if (success)
      82              :     {
      83           33 :       passed++;
      84           33 :       continue;
      85              :     }
      86            0 :     failed++;
      87            0 :     fprintf (stderr,
      88              :              "FAIL: \"%s\" -> %s (expected %s)\n",
      89            0 :              tests[i].email ? tests[i].email : "(NULL)",
      90              :              result ? "VALID" : "INVALID",
      91            0 :              tests[i].expected ? "VALID" : "INVALID");
      92              :   }
      93            1 :   return (failed > 0) ? 1 : 0;
      94              : }
      95              : 
      96              : 
      97              : static bool
      98            1 : check_phone (void)
      99              : {
     100              :   struct
     101              :   {
     102              :     const char *phone;
     103              :     const char *expected_normalized;
     104              :     bool allow_letters;
     105            1 :   } tests[] = {
     106              :     /* Valid phone numbers with +CC - digits only */
     107              :     {"+1-202-555-0173", "+12025550173", false},
     108              :     {"+1 202 555 0173", "+12025550173", false},
     109              :     {"+1 (202) 555-0173", "+12025550173", false},
     110              :     {"+33142685300", "+33142685300", false},
     111              :     {"+33 1 42 68 53 00", "+33142685300", false},
     112              :     {"+44 20 7946 0958", "+442079460958", false},
     113              :     {"+44.20.7946.0958", "+442079460958", false},
     114              :     {"+49-30-12345678", "+493012345678", false},
     115              :     {"+886 2 2345 6789", "+886223456789", false},
     116              :     {"+1-800-555-0123", "+18005550123", false},
     117              :     {"+81-3-1234-5678", "+81312345678", false},
     118              :     {"+39 06 6994 0255", "+390669940255", false},
     119              :     {"+34-91-577-3200", "+34915773200", false},
     120              :     {"+46 8 123456", "+468123456", false},
     121              :     {"+1(555)1234567", "+15551234567", false},
     122              :     {"+1-555-1234567", "+15551234567", false},
     123              :     {"+358 9 1234567", "+35891234567", false},
     124              :     {"+1 202-555.0173", "+12025550173", false},
     125              :     {"+7 495 123-45-67", "+74951234567", false},
     126              : 
     127              :     /* Valid phone numbers with letters (allow_letters=true) */
     128              :     {"+1-800-CALL-NOW", "+18002255669", true},
     129              :     {"+1-800-FLOWERS", "+18003569377", true},
     130              :     {"+1-888-PIZZA", "+188874992", true},
     131              :     {"+1 800 CALL NOW", "+18002255669", true},
     132              :     {"+44-HELLO-WORLD", "+444355696753", true},
     133              :     {"+1-555-ABCDEFGH", "+155522233344", true},
     134              : 
     135              :     /* Letters should fail when allow_letters=false */
     136              :     {"+1-800-CALL-NOW", NULL, false},
     137              :     {"+1-800-FLOWERS", NULL, false},
     138              : 
     139              :     /* Invalid phone numbers */
     140              :     {"", NULL, false},
     141              :     {"202-555-0173", NULL, false},          /* Missing + */
     142              :     {"1-202-555-0173", NULL, false},        /* Missing + */
     143              :     {"+1", NULL, false},                    /* Only country code */
     144              :     {"+1 abc def ghij", NULL, false},       /* Invalid format */
     145              :     {"1-800-555-0123", NULL, false},        /* No plus sign */
     146              :     {"++1-202-555-0173", NULL, false},      /* Double plus */
     147              :     {"+1--202-555-0173", NULL, false},      /* Double hyphen */
     148              :     {"+12025550173 ", NULL, false},         /* Trailing space */
     149              :     {" +12025550173", NULL, false},         /* Leading space */
     150              :     {"+1 (555", NULL, false},               /* Unclosed parenthesis */
     151              :     {"+1 555)", NULL, false},               /* Unmatched closing paren */
     152              :     {"+1-555-", NULL, false},               /* Trailing hyphen */
     153              :     {"+1-555-01a3", NULL, false},           /* Lowercase letter without allow_letters */
     154              :     {"+1 (202", NULL, false},               /* Unmatched paren */
     155              :   };
     156              : 
     157            1 :   unsigned int num_tests = sizeof (tests) / sizeof (tests[0]);
     158            1 :   unsigned int passed = 0;
     159            1 :   unsigned int failed = 0;
     160              : 
     161           43 :   for (unsigned int i = 0; i < num_tests; i++)
     162              :   {
     163           42 :     char *result = TALER_MERCHANT_phone_validate_normalize (tests[i].phone,
     164           42 :                                                             tests[i].allow_letters);
     165              :     bool success;
     166              : 
     167           42 :     if (NULL == tests[i].expected_normalized)
     168              :     {
     169           17 :       success = (NULL == result);
     170              :     }
     171              :     else
     172              :     {
     173           50 :       success = (NULL != result &&
     174           25 :                  0 == strcmp (result,
     175              :                               tests[i].expected_normalized));
     176              :     }
     177           42 :     if (success)
     178              :     {
     179           42 :       passed++;
     180              :     }
     181              :     else
     182              :     {
     183            0 :       failed++;
     184            0 :       fprintf (stderr,
     185              :                "FAIL: (`%s' (letters=%s) -> `%s'",
     186              :                tests[i].phone,
     187            0 :                tests[i].allow_letters ? "true" : "false",
     188              :                result);
     189              :     }
     190           42 :     GNUNET_free (result);
     191              :   }
     192            1 :   return (failed > 0) ? 1 : 0;
     193              : }
     194              : 
     195              : 
     196              : int
     197            1 : main (void)
     198              : {
     199            1 :   if (check_email ())
     200              :   {
     201            0 :     fprintf (stderr,
     202              :              "email failed\n");
     203            0 :     return 1;
     204              :   }
     205            1 :   if (check_phone ())
     206              :   {
     207            0 :     fprintf (stderr,
     208              :              "phone failed\n");
     209            0 :     return 1;
     210              :   }
     211            1 :   return 0;
     212              : }
        

Generated by: LCOV version 2.0-1