merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_get_unit.c (9464B)


      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 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   if (GNUNET_OK !=
     78       TALER_TESTING_get_trait_unit_id (ref_cmd,
     79                                        &unit_id))
     80   {
     81     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     82                 "Unit trait resolution failed for reference `%s'\n",
     83                 ref_cmd->label);
     84     return false;
     85   }
     86   if (0 != strcmp (entry->unit,
     87                    unit_id))
     88   {
     89     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     90                 "Unit mismatch: expected id %s got %s\n",
     91                 unit_id,
     92                 entry->unit);
     93     return false;
     94   }
     95 
     96   {
     97     const char *unit_name_long = NULL;
     98 
     99     if (GNUNET_OK ==
    100         TALER_TESTING_get_trait_unit_name_long (ref_cmd,
    101                                                 &unit_name_long))
    102     {
    103       if ( (NULL != unit_name_long) &&
    104            (0 != strcmp (entry->unit_name_long,
    105                          unit_name_long)) )
    106       {
    107         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         return false;
    113       }
    114     }
    115   }
    116   {
    117     const char *unit_name_short = NULL;
    118 
    119     if (GNUNET_OK ==
    120         TALER_TESTING_get_trait_unit_name_short (ref_cmd,
    121                                                  &unit_name_short))
    122     {
    123       if ( (NULL != unit_name_short) &&
    124            (0 != strcmp (entry->unit_name_short,
    125                          unit_name_short)) )
    126       {
    127         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         return false;
    133       }
    134     }
    135   }
    136   {
    137     const bool *unit_allow_fraction = NULL;
    138 
    139     if (GNUNET_OK ==
    140         TALER_TESTING_get_trait_unit_allow_fraction (ref_cmd,
    141                                                      &unit_allow_fraction))
    142     {
    143       if ( (NULL != unit_allow_fraction) &&
    144            (*unit_allow_fraction != entry->unit_allow_fraction) )
    145       {
    146         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         return false;
    152       }
    153     }
    154   }
    155   {
    156     const uint32_t *unit_precision_level = NULL;
    157 
    158     if (GNUNET_OK ==
    159         TALER_TESTING_get_trait_unit_precision_level (ref_cmd,
    160                                                       &unit_precision_level))
    161     {
    162       if ( (NULL != unit_precision_level) &&
    163            (*unit_precision_level != entry->unit_precision_level) )
    164       {
    165         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         return false;
    171       }
    172     }
    173   }
    174   {
    175     const bool *unit_active = NULL;
    176 
    177     if (GNUNET_OK ==
    178         TALER_TESTING_get_trait_unit_active (ref_cmd,
    179                                              &unit_active))
    180     {
    181       if ( (NULL != unit_active) &&
    182            (*unit_active != entry->unit_active) )
    183       {
    184         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         return false;
    190       }
    191     }
    192   }
    193   {
    194     const json_t *unit_name_long_i18n = NULL;
    195 
    196     if (GNUNET_OK ==
    197         TALER_TESTING_get_trait_unit_name_long_i18n (ref_cmd,
    198                                                      &unit_name_long_i18n))
    199     {
    200       if ( (NULL != unit_name_long_i18n) &&
    201            ( (NULL == entry->unit_name_long_i18n) ||
    202              (1 != json_equal (unit_name_long_i18n,
    203                                entry->unit_name_long_i18n)) ) )
    204       {
    205         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    206                     "Unit %s mismatch: long_i18n differs\n",
    207                     entry->unit);
    208         return false;
    209       }
    210     }
    211   }
    212   {
    213     const json_t *unit_name_short_i18n = NULL;
    214 
    215     if (GNUNET_OK ==
    216         TALER_TESTING_get_trait_unit_name_short_i18n (ref_cmd,
    217                                                       &unit_name_short_i18n))
    218     {
    219       if ( (NULL != unit_name_short_i18n) &&
    220            ( (NULL == entry->unit_name_short_i18n) ||
    221              (1 != json_equal (unit_name_short_i18n,
    222                                entry->unit_name_short_i18n)) ) )
    223       {
    224         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    225                     "Unit %s mismatch: short_i18n differs\n",
    226                     entry->unit);
    227         return false;
    228       }
    229     }
    230   }
    231   return true;
    232 }
    233 
    234 
    235 /**
    236  * Completion callback.
    237  */
    238 static void
    239 get_unit_cb (void *cls,
    240              const struct TALER_MERCHANT_UnitGetResponse *ugr)
    241 {
    242   struct GetUnitState *gug = cls;
    243 
    244   gug->ugh = NULL;
    245   if (gug->http_status != ugr->hr.http_status)
    246   {
    247     TALER_TESTING_unexpected_status_with_body (gug->is,
    248                                                ugr->hr.http_status,
    249                                                gug->http_status,
    250                                                ugr->hr.reply);
    251     return;
    252   }
    253   if ( (MHD_HTTP_OK == ugr->hr.http_status) &&
    254        (NULL != gug->reference) )
    255   {
    256     const struct TALER_TESTING_Command *ref_cmd;
    257 
    258     ref_cmd = TALER_TESTING_interpreter_lookup_command (gug->is,
    259                                                         gug->reference);
    260     if (NULL == ref_cmd)
    261     {
    262       GNUNET_break (0);
    263       TALER_TESTING_interpreter_fail (gug->is);
    264       return;
    265     }
    266     if (! unit_matches_reference (&ugr->details.ok.unit,
    267                                   ref_cmd))
    268     {
    269       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       TALER_TESTING_interpreter_fail (gug->is);
    274       return;
    275     }
    276   }
    277   TALER_TESTING_interpreter_next (gug->is);
    278 }
    279 
    280 
    281 /**
    282  * Issue GET request.
    283  */
    284 static void
    285 get_unit_run (void *cls,
    286               const struct TALER_TESTING_Command *cmd,
    287               struct TALER_TESTING_Interpreter *is)
    288 {
    289   struct GetUnitState *gug = cls;
    290 
    291   gug->is = is;
    292   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   if (NULL == gug->ugh)
    299   {
    300     GNUNET_break (0);
    301     TALER_TESTING_interpreter_fail (is);
    302   }
    303 }
    304 
    305 
    306 /**
    307  * Cleanup.
    308  */
    309 static void
    310 get_unit_cleanup (void *cls,
    311                   const struct TALER_TESTING_Command *cmd)
    312 {
    313   struct GetUnitState *gug = cls;
    314 
    315   if (NULL != gug->ugh)
    316   {
    317     TALER_MERCHANT_unit_get_cancel (gug->ugh);
    318     gug->ugh = NULL;
    319   }
    320   GNUNET_free (gug);
    321 }
    322 
    323 
    324 struct TALER_TESTING_Command
    325 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   gug = GNUNET_new (struct GetUnitState);
    334   gug->merchant_url = merchant_url;
    335   gug->unit_id = unit_id;
    336   gug->http_status = http_status;
    337   gug->reference = reference;
    338 
    339   {
    340     struct TALER_TESTING_Command cmd = {
    341       .cls = gug,
    342       .label = label,
    343       .run = &get_unit_run,
    344       .cleanup = &get_unit_cleanup
    345     };
    346 
    347     return cmd;
    348   }
    349 }
    350 
    351 
    352 /* end of testing_api_cmd_get_unit.c */