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 */