LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_get_unit.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.9 % 103 73
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_unit.c
      21              :  * @brief command to test GET /private/units/$ID
      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/$ID command.
      33              :  */
      34              : struct GetUnitState
      35              : {
      36              :   /**
      37              :    * In-flight request handle.
      38              :    */
      39              :   struct TALER_MERCHANT_UnitGetHandle *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              :    * Unit identifier to fetch.
      53              :    */
      54              :   const char *unit_id;
      55              : 
      56              :   /**
      57              :    * Expected HTTP status.
      58              :    */
      59              :   unsigned int http_status;
      60              : 
      61              :   /**
      62              :    * Optional command label providing expected traits.
      63              :    */
      64              :   const char *reference;
      65              : };
      66              : 
      67              : 
      68              : /**
      69              :  * Compare response @a entry with traits from @a ref_cmd.
      70              :  */
      71              : static bool
      72            4 : unit_matches_reference (const struct TALER_MERCHANT_UnitEntry *entry,
      73              :                         const struct TALER_TESTING_Command *ref_cmd)
      74              : {
      75              :   const char *unit_id;
      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              :                 "Unit trait resolution failed for reference `%s'\n",
      83              :                 ref_cmd->label);
      84            0 :     return false;
      85              :   }
      86            4 :   if (0 != strcmp (entry->unit,
      87              :                    unit_id))
      88              :   {
      89            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
      90              :                 "Unit mismatch: expected id %s got %s\n",
      91              :                 unit_id,
      92              :                 entry->unit);
      93            0 :     return false;
      94              :   }
      95              : 
      96              :   {
      97            4 :     const char *unit_name_long = NULL;
      98              : 
      99            4 :     if (GNUNET_OK ==
     100            4 :         TALER_TESTING_get_trait_unit_name_long (ref_cmd,
     101              :                                                 &unit_name_long))
     102              :     {
     103            4 :       if ( (NULL != unit_name_long) &&
     104            4 :            (0 != strcmp (entry->unit_name_long,
     105              :                          unit_name_long)) )
     106              :       {
     107            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     108              :                     "Unit %s mismatch: expected long label '%s' got '%s'\n",
     109              :                     entry->unit,
     110              :                     unit_name_long,
     111              :                     entry->unit_name_long);
     112            0 :         return false;
     113              :       }
     114              :     }
     115              :   }
     116              :   {
     117            4 :     const char *unit_name_short = NULL;
     118              : 
     119            4 :     if (GNUNET_OK ==
     120            4 :         TALER_TESTING_get_trait_unit_name_short (ref_cmd,
     121              :                                                  &unit_name_short))
     122              :     {
     123            4 :       if ( (NULL != unit_name_short) &&
     124            4 :            (0 != strcmp (entry->unit_name_short,
     125              :                          unit_name_short)) )
     126              :       {
     127            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     128              :                     "Unit %s mismatch: expected short label '%s' got '%s'\n",
     129              :                     entry->unit,
     130              :                     unit_name_short,
     131              :                     entry->unit_name_short);
     132            0 :         return false;
     133              :       }
     134              :     }
     135              :   }
     136              :   {
     137            4 :     const bool *unit_allow_fraction = NULL;
     138              : 
     139            4 :     if (GNUNET_OK ==
     140            4 :         TALER_TESTING_get_trait_unit_allow_fraction (ref_cmd,
     141              :                                                      &unit_allow_fraction))
     142              :     {
     143            4 :       if ( (NULL != unit_allow_fraction) &&
     144            4 :            (*unit_allow_fraction != entry->unit_allow_fraction) )
     145              :       {
     146            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     147              :                     "Unit %s mismatch: expected allow_fraction %d got %d\n",
     148              :                     entry->unit,
     149              :                     (int) *unit_allow_fraction,
     150              :                     (int) entry->unit_allow_fraction);
     151            0 :         return false;
     152              :       }
     153              :     }
     154              :   }
     155              :   {
     156            4 :     const uint32_t *unit_precision_level = NULL;
     157              : 
     158            4 :     if (GNUNET_OK ==
     159            4 :         TALER_TESTING_get_trait_unit_precision_level (ref_cmd,
     160              :                                                       &unit_precision_level))
     161              :     {
     162            4 :       if ( (NULL != unit_precision_level) &&
     163            4 :            (*unit_precision_level != entry->unit_precision_level) )
     164              :       {
     165            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     166              :                     "Unit %s mismatch: expected precision %u got %u\n",
     167              :                     entry->unit,
     168              :                     (unsigned int) *unit_precision_level,
     169              :                     (unsigned int) entry->unit_precision_level);
     170            0 :         return false;
     171              :       }
     172              :     }
     173              :   }
     174              :   {
     175            4 :     const bool *unit_active = NULL;
     176              : 
     177            4 :     if (GNUNET_OK ==
     178            4 :         TALER_TESTING_get_trait_unit_active (ref_cmd,
     179              :                                              &unit_active))
     180              :     {
     181            4 :       if ( (NULL != unit_active) &&
     182            4 :            (*unit_active != entry->unit_active) )
     183              :       {
     184            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     185              :                     "Unit %s mismatch: expected active flag %d got %d\n",
     186              :                     entry->unit,
     187              :                     (int) *unit_active,
     188              :                     (int) entry->unit_active);
     189            0 :         return false;
     190              :       }
     191              :     }
     192              :   }
     193              :   {
     194            4 :     const json_t *unit_name_long_i18n = NULL;
     195              : 
     196            4 :     if (GNUNET_OK ==
     197            4 :         TALER_TESTING_get_trait_unit_name_long_i18n (ref_cmd,
     198              :                                                      &unit_name_long_i18n))
     199              :     {
     200            4 :       if ( (NULL != unit_name_long_i18n) &&
     201            8 :            ( (NULL == entry->unit_name_long_i18n) ||
     202            4 :              (1 != json_equal (unit_name_long_i18n,
     203            4 :                                entry->unit_name_long_i18n)) ) )
     204              :       {
     205            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     206              :                     "Unit %s mismatch: long_i18n differs\n",
     207              :                     entry->unit);
     208            0 :         return false;
     209              :       }
     210              :     }
     211              :   }
     212              :   {
     213            4 :     const json_t *unit_name_short_i18n = NULL;
     214              : 
     215            4 :     if (GNUNET_OK ==
     216            4 :         TALER_TESTING_get_trait_unit_name_short_i18n (ref_cmd,
     217              :                                                       &unit_name_short_i18n))
     218              :     {
     219            4 :       if ( (NULL != unit_name_short_i18n) &&
     220            8 :            ( (NULL == entry->unit_name_short_i18n) ||
     221            4 :              (1 != json_equal (unit_name_short_i18n,
     222            4 :                                entry->unit_name_short_i18n)) ) )
     223              :       {
     224            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     225              :                     "Unit %s mismatch: short_i18n differs\n",
     226              :                     entry->unit);
     227            0 :         return false;
     228              :       }
     229              :     }
     230              :   }
     231            4 :   return true;
     232              : }
     233              : 
     234              : 
     235              : /**
     236              :  * Completion callback.
     237              :  */
     238              : static void
     239            6 : get_unit_cb (void *cls,
     240              :              const struct TALER_MERCHANT_UnitGetResponse *ugr)
     241              : {
     242            6 :   struct GetUnitState *gug = cls;
     243              : 
     244            6 :   gug->ugh = NULL;
     245            6 :   if (gug->http_status != ugr->hr.http_status)
     246              :   {
     247            0 :     TALER_TESTING_unexpected_status_with_body (gug->is,
     248              :                                                ugr->hr.http_status,
     249              :                                                gug->http_status,
     250              :                                                ugr->hr.reply);
     251            0 :     return;
     252              :   }
     253            6 :   if ( (MHD_HTTP_OK == ugr->hr.http_status) &&
     254            4 :        (NULL != gug->reference) )
     255              :   {
     256              :     const struct TALER_TESTING_Command *ref_cmd;
     257              : 
     258            4 :     ref_cmd = TALER_TESTING_interpreter_lookup_command (gug->is,
     259              :                                                         gug->reference);
     260            4 :     if (NULL == ref_cmd)
     261              :     {
     262            0 :       GNUNET_break (0);
     263            0 :       TALER_TESTING_interpreter_fail (gug->is);
     264            0 :       return;
     265              :     }
     266            4 :     if (! unit_matches_reference (&ugr->details.ok.unit,
     267              :                                   ref_cmd))
     268              :     {
     269            0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     270              :                   "GET /private/units/%s response does not match expectation from `%s'\n",
     271              :                   gug->unit_id,
     272              :                   gug->reference);
     273            0 :       TALER_TESTING_interpreter_fail (gug->is);
     274            0 :       return;
     275              :     }
     276              :   }
     277            6 :   TALER_TESTING_interpreter_next (gug->is);
     278              : }
     279              : 
     280              : 
     281              : /**
     282              :  * Issue GET request.
     283              :  */
     284              : static void
     285            6 : get_unit_run (void *cls,
     286              :               const struct TALER_TESTING_Command *cmd,
     287              :               struct TALER_TESTING_Interpreter *is)
     288              : {
     289            6 :   struct GetUnitState *gug = cls;
     290              : 
     291            6 :   gug->is = is;
     292            6 :   gug->ugh = TALER_MERCHANT_unit_get (
     293              :     TALER_TESTING_interpreter_get_context (is),
     294              :     gug->merchant_url,
     295              :     gug->unit_id,
     296              :     &get_unit_cb,
     297              :     gug);
     298            6 :   if (NULL == gug->ugh)
     299              :   {
     300            0 :     GNUNET_break (0);
     301            0 :     TALER_TESTING_interpreter_fail (is);
     302              :   }
     303            6 : }
     304              : 
     305              : 
     306              : /**
     307              :  * Cleanup.
     308              :  */
     309              : static void
     310            6 : get_unit_cleanup (void *cls,
     311              :                   const struct TALER_TESTING_Command *cmd)
     312              : {
     313            6 :   struct GetUnitState *gug = cls;
     314              : 
     315            6 :   if (NULL != gug->ugh)
     316              :   {
     317            0 :     TALER_MERCHANT_unit_get_cancel (gug->ugh);
     318            0 :     gug->ugh = NULL;
     319              :   }
     320            6 :   GNUNET_free (gug);
     321            6 : }
     322              : 
     323              : 
     324              : struct TALER_TESTING_Command
     325            6 : TALER_TESTING_cmd_merchant_get_unit (const char *label,
     326              :                                      const char *merchant_url,
     327              :                                      const char *unit_id,
     328              :                                      unsigned int http_status,
     329              :                                      const char *reference)
     330              : {
     331              :   struct GetUnitState *gug;
     332              : 
     333            6 :   gug = GNUNET_new (struct GetUnitState);
     334            6 :   gug->merchant_url = merchant_url;
     335            6 :   gug->unit_id = unit_id;
     336            6 :   gug->http_status = http_status;
     337            6 :   gug->reference = reference;
     338              : 
     339              :   {
     340            6 :     struct TALER_TESTING_Command cmd = {
     341              :       .cls = gug,
     342              :       .label = label,
     343              :       .run = &get_unit_run,
     344              :       .cleanup = &get_unit_cleanup
     345              :     };
     346              : 
     347            6 :     return cmd;
     348              :   }
     349              : }
     350              : 
     351              : 
     352              : /* end of testing_api_cmd_get_unit.c */
        

Generated by: LCOV version 2.0-1