LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_get_units.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 72.9 % 118 86
Test Date: 2025-12-10 19:49:57 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2025 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify
       6              :   it under the terms of the GNU General Public License as
       7              :   published by the Free Software Foundation; either version 3, or
       8              :   (at your option) any later version.
       9              : 
      10              :   TALER is distributed in the hope that it will be useful, but
      11              :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12              :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13              :   GNU General Public License for more details.
      14              : 
      15              :   You should have received a copy of the GNU General Public
      16              :   License along with TALER; see the file COPYING.  If not, see
      17              :   <http://www.gnu.org/licenses/>
      18              : */
      19              : /**
      20              :  * @file testing_api_cmd_get_units.c
      21              :  * @brief command to test GET /private/units
      22              :  * @author Bohdan Potuzhnyi
      23              :  */
      24              : #include "platform.h"
      25              : #include <jansson.h>
      26              : #include <taler/taler_testing_lib.h>
      27              : #include "taler_merchant_service.h"
      28              : #include "taler_merchant_testing_lib.h"
      29              : 
      30              : 
      31              : /**
      32              :  * State for a GET /private/units command.
      33              :  */
      34              : struct GetUnitsState
      35              : {
      36              :   /**
      37              :    * In-flight request handle.
      38              :    */
      39              :   struct TALER_MERCHANT_UnitsGetHandle *ugh;
      40              : 
      41              :   /**
      42              :    * Interpreter context.
      43              :    */
      44              :   struct TALER_TESTING_Interpreter *is;
      45              : 
      46              :   /**
      47              :    * Merchant backend base URL.
      48              :    */
      49              :   const char *merchant_url;
      50              : 
      51              :   /**
      52              :    * Expected HTTP status.
      53              :    */
      54              :   unsigned int http_status;
      55              : 
      56              :   /**
      57              :    * Expected references that must appear in the listing.
      58              :    */
      59              :   const char **references;
      60              : 
      61              :   /**
      62              :    * Length of @e references.
      63              :    */
      64              :   unsigned int references_length;
      65              : };
      66              : 
      67              : 
      68              : /**
      69              :  * Verify that @a entry matches the traits from @a ref_cmd.
      70              :  */
      71              : static enum GNUNET_GenericReturnValue
      72            4 : check_unit_matches (const struct TALER_MERCHANT_UnitEntry *entry,
      73              :                     const struct TALER_TESTING_Command *ref_cmd)
      74              : {
      75            4 :   const char *unit_id = NULL;
      76              : 
      77            4 :   if (GNUNET_OK !=
      78            4 :       TALER_TESTING_get_trait_unit_id (ref_cmd,
      79              :                                        &unit_id))
      80              :   {
      81            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
      82              :                 "Internal error: command `%s' lacks unit_id trait\n",
      83              :                 ref_cmd->label);
      84            0 :     return GNUNET_SYSERR;
      85              :   }
      86            4 :   if (0 != strcmp (entry->unit,
      87              :                    unit_id))
      88            0 :     return GNUNET_NO;
      89              : 
      90              :   {
      91            4 :     const char *unit_name_long = NULL;
      92              : 
      93            4 :     if (GNUNET_OK ==
      94            4 :         TALER_TESTING_get_trait_unit_name_long (ref_cmd,
      95              :                                                 &unit_name_long))
      96              :     {
      97            4 :       if ( (NULL != unit_name_long) &&
      98            4 :            (0 != strcmp (entry->unit_name_long,
      99              :                          unit_name_long)) )
     100            0 :         return GNUNET_SYSERR;
     101              :     }
     102              :   }
     103              :   {
     104            4 :     const char *unit_name_short = NULL;
     105              : 
     106            4 :     if (GNUNET_OK ==
     107            4 :         TALER_TESTING_get_trait_unit_name_short (ref_cmd,
     108              :                                                  &unit_name_short))
     109              :     {
     110            4 :       if ( (NULL != unit_name_short) &&
     111            4 :            (0 != strcmp (entry->unit_name_short,
     112              :                          unit_name_short)) )
     113            0 :         return GNUNET_SYSERR;
     114              :     }
     115              :   }
     116              :   {
     117            4 :     const bool *unit_allow_fraction = NULL;
     118              : 
     119            4 :     if (GNUNET_OK ==
     120            4 :         TALER_TESTING_get_trait_unit_allow_fraction (ref_cmd,
     121              :                                                      &unit_allow_fraction))
     122              :     {
     123            4 :       if ( (NULL != unit_allow_fraction) &&
     124            4 :            (*unit_allow_fraction != entry->unit_allow_fraction) )
     125              :       {
     126            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     127              :                     "Unit %s mismatch: expected allow_fraction %d got %d\n",
     128              :                     entry->unit,
     129              :                     (int) *unit_allow_fraction,
     130              :                     (int) entry->unit_allow_fraction);
     131            0 :         return GNUNET_SYSERR;
     132              :       }
     133              :     }
     134              :   }
     135              :   {
     136            4 :     const uint32_t *unit_precision_level = NULL;
     137              : 
     138            4 :     if (GNUNET_OK ==
     139            4 :         TALER_TESTING_get_trait_unit_precision_level (ref_cmd,
     140              :                                                       &unit_precision_level))
     141              :     {
     142            4 :       if ( (NULL != unit_precision_level) &&
     143            4 :            (*unit_precision_level != entry->unit_precision_level) )
     144              :       {
     145            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     146              :                     "Unit %s mismatch: expected precision %u got %u\n",
     147              :                     entry->unit,
     148              :                     (unsigned int) *unit_precision_level,
     149              :                     (unsigned int) entry->unit_precision_level);
     150            0 :         return GNUNET_SYSERR;
     151              :       }
     152              :     }
     153              :   }
     154              :   {
     155            4 :     const bool *unit_active = NULL;
     156              : 
     157            4 :     if (GNUNET_OK ==
     158            4 :         TALER_TESTING_get_trait_unit_active (ref_cmd,
     159              :                                              &unit_active))
     160              :     {
     161            4 :       if ( (NULL != unit_active) &&
     162            4 :            (*unit_active != entry->unit_active) )
     163              :       {
     164            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     165              :                     "Unit %s mismatch: expected active %d got %d\n",
     166              :                     entry->unit,
     167              :                     (int) *unit_active,
     168              :                     (int) entry->unit_active);
     169            0 :         return GNUNET_SYSERR;
     170              :       }
     171              :     }
     172              :   }
     173              :   {
     174            4 :     const json_t *unit_name_long_i18n = NULL;
     175              : 
     176            4 :     if (GNUNET_OK ==
     177            4 :         TALER_TESTING_get_trait_unit_name_long_i18n (ref_cmd,
     178              :                                                      &unit_name_long_i18n))
     179              :     {
     180            4 :       if ( (NULL != unit_name_long_i18n) &&
     181            8 :            ( (NULL == entry->unit_name_long_i18n) ||
     182            4 :              (1 != json_equal (unit_name_long_i18n,
     183            4 :                                entry->unit_name_long_i18n)) ) )
     184              :       {
     185            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     186              :                     "Unit %s mismatch: long_i18n differs\n",
     187              :                     entry->unit);
     188            0 :         return GNUNET_SYSERR;
     189              :       }
     190              :     }
     191              :   }
     192              :   {
     193            4 :     const json_t *unit_name_short_i18n = NULL;
     194              : 
     195            4 :     if (GNUNET_OK ==
     196            4 :         TALER_TESTING_get_trait_unit_name_short_i18n (ref_cmd,
     197              :                                                       &unit_name_short_i18n))
     198              :     {
     199            4 :       if ( (NULL != unit_name_short_i18n) &&
     200            8 :            ( (NULL == entry->unit_name_short_i18n) ||
     201            4 :              (1 != json_equal (unit_name_short_i18n,
     202            4 :                                entry->unit_name_short_i18n)) ) )
     203              :       {
     204            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     205              :                     "Unit %s mismatch: short_i18n differs\n",
     206              :                     entry->unit);
     207            0 :         return GNUNET_SYSERR;
     208              :       }
     209              :     }
     210              :   }
     211            4 :   return GNUNET_OK;
     212              : }
     213              : 
     214              : 
     215              : /**
     216              :  * Completion callback for GET /private/units.
     217              :  */
     218              : static void
     219            4 : get_units_cb (void *cls,
     220              :               const struct TALER_MERCHANT_UnitsGetResponse *ugr)
     221              : {
     222            4 :   struct GetUnitsState *gus = cls;
     223              : 
     224            4 :   gus->ugh = NULL;
     225            4 :   if (gus->http_status != ugr->hr.http_status)
     226              :   {
     227            0 :     TALER_TESTING_unexpected_status_with_body (gus->is,
     228              :                                                ugr->hr.http_status,
     229              :                                                gus->http_status,
     230              :                                                ugr->hr.reply);
     231            0 :     return;
     232              :   }
     233            4 :   if (MHD_HTTP_OK == ugr->hr.http_status)
     234              :   {
     235            8 :     for (unsigned int i = 0; i < gus->references_length; ++i)
     236              :     {
     237            4 :       const char *label = gus->references[i];
     238              :       const struct TALER_TESTING_Command *ref_cmd;
     239            4 :       enum GNUNET_GenericReturnValue match = GNUNET_NO;
     240              : 
     241            4 :       ref_cmd = TALER_TESTING_interpreter_lookup_command (gus->is,
     242              :                                                           label);
     243            4 :       if (NULL == ref_cmd)
     244              :       {
     245            0 :         GNUNET_break (0);
     246            0 :         TALER_TESTING_interpreter_fail (gus->is);
     247            0 :         return;
     248              :       }
     249            4 :       for (unsigned int j = 0;
     250            4 :            j < ugr->details.ok.units_length;
     251            0 :            ++j)
     252              :       {
     253            4 :         match = check_unit_matches (&ugr->details.ok.units[j],
     254              :                                     ref_cmd);
     255            4 :         if (GNUNET_SYSERR == match)
     256            0 :           break;
     257            4 :         if (GNUNET_OK == match)
     258            4 :           break;
     259              :       }
     260            4 :       if (GNUNET_SYSERR == match)
     261              :       {
     262            0 :         GNUNET_break (0);
     263            0 :         TALER_TESTING_interpreter_fail (gus->is);
     264            0 :         return;
     265              :       }
     266            4 :       if (GNUNET_OK != match)
     267              :       {
     268            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     269              :                     "Unit referenced by `%s' not found in GET /private/units response\n",
     270              :                     label);
     271            0 :         TALER_TESTING_interpreter_fail (gus->is);
     272            0 :         return;
     273              :       }
     274              :     }
     275              :   }
     276            4 :   TALER_TESTING_interpreter_next (gus->is);
     277              : }
     278              : 
     279              : 
     280              : /**
     281              :  * Issue the GET request.
     282              :  */
     283              : static void
     284            4 : get_units_run (void *cls,
     285              :                const struct TALER_TESTING_Command *cmd,
     286              :                struct TALER_TESTING_Interpreter *is)
     287              : {
     288            4 :   struct GetUnitsState *gus = cls;
     289              : 
     290            4 :   gus->is = is;
     291            4 :   gus->ugh = TALER_MERCHANT_units_get (
     292              :     TALER_TESTING_interpreter_get_context (is),
     293              :     gus->merchant_url,
     294              :     &get_units_cb,
     295              :     gus);
     296            4 :   if (NULL == gus->ugh)
     297              :   {
     298            0 :     GNUNET_break (0);
     299            0 :     TALER_TESTING_interpreter_fail (is);
     300              :   }
     301            4 : }
     302              : 
     303              : 
     304              : /**
     305              :  * Cleanup.
     306              :  */
     307              : static void
     308            4 : get_units_cleanup (void *cls,
     309              :                    const struct TALER_TESTING_Command *cmd)
     310              : {
     311            4 :   struct GetUnitsState *gus = cls;
     312              : 
     313            4 :   if (NULL != gus->ugh)
     314              :   {
     315            0 :     TALER_MERCHANT_units_get_cancel (gus->ugh);
     316            0 :     gus->ugh = NULL;
     317              :   }
     318            4 :   GNUNET_array_grow (gus->references,
     319              :                      gus->references_length,
     320              :                      0);
     321            4 :   GNUNET_free (gus);
     322            4 : }
     323              : 
     324              : 
     325              : struct TALER_TESTING_Command
     326            4 : TALER_TESTING_cmd_merchant_get_units (const char *label,
     327              :                                       const char *merchant_url,
     328              :                                       unsigned int http_status,
     329              :                                       ...)
     330              : {
     331              :   struct GetUnitsState *gus;
     332              :   va_list ap;
     333              :   const char *ref;
     334              : 
     335            4 :   gus = GNUNET_new (struct GetUnitsState);
     336            4 :   gus->merchant_url = merchant_url;
     337            4 :   gus->http_status = http_status;
     338              : 
     339            4 :   va_start (ap, http_status);
     340            8 :   while (NULL != (ref = va_arg (ap, const char *)))
     341              :   {
     342            4 :     GNUNET_array_append (gus->references,
     343              :                          gus->references_length,
     344              :                          ref);
     345              :   }
     346            4 :   va_end (ap);
     347              : 
     348              :   {
     349            4 :     struct TALER_TESTING_Command cmd = {
     350              :       .cls = gus,
     351              :       .label = label,
     352              :       .run = &get_units_run,
     353              :       .cleanup = &get_units_cleanup
     354              :     };
     355              : 
     356            4 :     return cmd;
     357              :   }
     358              : }
     359              : 
     360              : 
     361              : /* end of testing_api_cmd_get_units.c */
        

Generated by: LCOV version 2.0-1