merchant

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

testing_api_cmd_get_unit.c (9630B)


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