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

Generated by: LCOV version 2.0-1