testing_api_cmd_patch_unit.c (8421B)
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_patch_unit.c 21 * @brief command to test PATCH /private/units/$ID 22 * @author Bohdan Potuzhnyi 23 */ 24 #include "taler/platform.h" 25 #include <taler/taler_testing_lib.h> 26 #include "taler/taler_merchant_service.h" 27 #include "taler/taler_merchant_testing_lib.h" 28 #include <taler/taler-merchant/patch-private-units-UNIT.h> 29 30 31 /** 32 * State for a PATCH /private/units command. 33 */ 34 struct PatchUnitState 35 { 36 /** 37 * In-flight request handle. 38 */ 39 struct TALER_MERCHANT_PatchPrivateUnitHandle *uph; 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. 53 */ 54 const char *unit_id; 55 56 /** 57 * Optional new long label. 58 */ 59 const char *unit_name_long; 60 61 /** 62 * Optional new short label. 63 */ 64 const char *unit_name_short; 65 66 /** 67 * Optional long label translations. 68 */ 69 json_t *unit_name_long_i18n; 70 71 /** 72 * Optional short label translations. 73 */ 74 json_t *unit_name_short_i18n; 75 76 /** 77 * Whether a new fractional flag was provided. 78 */ 79 bool have_unit_allow_fraction; 80 81 /** 82 * New fractional flag value. 83 */ 84 bool unit_allow_fraction; 85 86 /** 87 * Whether a new precision level was provided. 88 */ 89 bool have_unit_precision_level; 90 91 /** 92 * New precision level. 93 */ 94 uint32_t unit_precision_level; 95 96 /** 97 * Whether a new active flag was provided. 98 */ 99 bool have_unit_active; 100 101 /** 102 * New active flag value. 103 */ 104 bool unit_active; 105 106 /** 107 * Expected HTTP status. 108 */ 109 unsigned int http_status; 110 }; 111 112 113 /** 114 * Completion callback for PATCH /private/units. 115 */ 116 static void 117 patch_unit_cb (void *cls, 118 const struct TALER_MERCHANT_PatchPrivateUnitResponse *result) 119 { 120 struct PatchUnitState *pus = cls; 121 const struct TALER_MERCHANT_HttpResponse *hr = &result->hr; 122 123 pus->uph = NULL; 124 if (pus->http_status != hr->http_status) 125 { 126 TALER_TESTING_unexpected_status_with_body (pus->is, 127 hr->http_status, 128 pus->http_status, 129 hr->reply); 130 return; 131 } 132 TALER_TESTING_interpreter_next (pus->is); 133 } 134 135 136 /** 137 * Issue the PATCH request. 138 */ 139 static void 140 patch_unit_run (void *cls, 141 const struct TALER_TESTING_Command *cmd, 142 struct TALER_TESTING_Interpreter *is) 143 { 144 struct PatchUnitState *pus = cls; 145 146 pus->is = is; 147 pus->uph = TALER_MERCHANT_patch_private_unit_create ( 148 TALER_TESTING_interpreter_get_context (is), 149 pus->merchant_url, 150 pus->unit_id); 151 if (NULL == pus->uph) 152 { 153 GNUNET_break (0); 154 TALER_TESTING_interpreter_fail (is); 155 return; 156 } 157 /* Set all optional fields via set_options. 158 We build the options dynamically based on which fields are present. */ 159 { 160 struct TALER_MERCHANT_PatchPrivateUnitOptionValue 161 opts[8]; 162 unsigned int n = 0; 163 164 if (NULL != pus->unit_name_long) 165 opts[n++] = TALER_MERCHANT_patch_private_unit_option_unit_name_long ( 166 pus->unit_name_long); 167 if (NULL != pus->unit_name_short) 168 opts[n++] = TALER_MERCHANT_patch_private_unit_option_unit_name_short ( 169 pus->unit_name_short); 170 if (NULL != pus->unit_name_long_i18n) 171 opts[n++] = 172 TALER_MERCHANT_patch_private_unit_option_unit_name_long_i18n ( 173 pus->unit_name_long_i18n); 174 if (NULL != pus->unit_name_short_i18n) 175 opts[n++] = 176 TALER_MERCHANT_patch_private_unit_option_unit_name_short_i18n ( 177 pus->unit_name_short_i18n); 178 if (pus->have_unit_allow_fraction) 179 opts[n++] = 180 TALER_MERCHANT_patch_private_unit_option_unit_allow_fraction ( 181 pus->unit_allow_fraction); 182 if (pus->have_unit_precision_level) 183 opts[n++] = 184 TALER_MERCHANT_patch_private_unit_option_unit_precision_level ( 185 pus->unit_precision_level); 186 if (pus->have_unit_active) 187 opts[n++] = TALER_MERCHANT_patch_private_unit_option_unit_active ( 188 pus->unit_active); 189 opts[n++] = TALER_MERCHANT_patch_private_unit_option_end_ (); 190 TALER_MERCHANT_patch_private_unit_set_options_ ( 191 pus->uph, 192 n, 193 opts); 194 } 195 { 196 enum TALER_ErrorCode ec; 197 198 ec = TALER_MERCHANT_patch_private_unit_start ( 199 pus->uph, 200 &patch_unit_cb, 201 pus); 202 GNUNET_assert (TALER_EC_NONE == ec); 203 } 204 } 205 206 207 /** 208 * Provide traits to other commands. 209 */ 210 static enum GNUNET_GenericReturnValue 211 patch_unit_traits (void *cls, 212 const void **ret, 213 const char *trait, 214 unsigned int index) 215 { 216 struct PatchUnitState *pus = cls; 217 struct TALER_TESTING_Trait traits[] = { 218 TALER_TESTING_make_trait_unit_id (pus->unit_id), 219 TALER_TESTING_make_trait_unit_name_long (pus->unit_name_long), 220 TALER_TESTING_make_trait_unit_name_short (pus->unit_name_short), 221 TALER_TESTING_make_trait_unit_name_long_i18n (pus->unit_name_long_i18n), 222 TALER_TESTING_make_trait_unit_name_short_i18n (pus->unit_name_short_i18n), 223 TALER_TESTING_make_trait_unit_allow_fraction ( 224 pus->have_unit_allow_fraction 225 ? &pus->unit_allow_fraction 226 : NULL), 227 TALER_TESTING_make_trait_unit_precision_level ( 228 pus->have_unit_precision_level 229 ? &pus->unit_precision_level 230 : NULL), 231 TALER_TESTING_make_trait_unit_active ( 232 pus->have_unit_active 233 ? &pus->unit_active 234 : NULL), 235 TALER_TESTING_trait_end () 236 }; 237 238 return TALER_TESTING_get_trait (traits, 239 ret, 240 trait, 241 index); 242 } 243 244 245 /** 246 * Cleanup. 247 */ 248 static void 249 patch_unit_cleanup (void *cls, 250 const struct TALER_TESTING_Command *cmd) 251 { 252 struct PatchUnitState *pus = cls; 253 254 if (NULL != pus->uph) 255 { 256 TALER_MERCHANT_patch_private_unit_cancel (pus->uph); 257 pus->uph = NULL; 258 } 259 if (NULL != pus->unit_name_long_i18n) 260 json_decref (pus->unit_name_long_i18n); 261 if (NULL != pus->unit_name_short_i18n) 262 json_decref (pus->unit_name_short_i18n); 263 GNUNET_free (pus); 264 } 265 266 267 struct TALER_TESTING_Command 268 TALER_TESTING_cmd_merchant_patch_unit (const char *label, 269 const char *merchant_url, 270 const char *unit_id, 271 const char *unit_name_long, 272 const char *unit_name_short, 273 json_t *unit_name_long_i18n, 274 json_t *unit_name_short_i18n, 275 const bool unit_allow_fraction, 276 const uint32_t unit_precision_level, 277 const bool unit_active, 278 unsigned int http_status) 279 { 280 struct PatchUnitState *pus; 281 282 pus = GNUNET_new (struct PatchUnitState); 283 pus->merchant_url = merchant_url; 284 pus->unit_id = unit_id; 285 pus->unit_name_long = unit_name_long; 286 pus->unit_name_short = unit_name_short; 287 pus->unit_name_long_i18n = unit_name_long_i18n; 288 pus->unit_name_short_i18n = unit_name_short_i18n; 289 pus->unit_allow_fraction = unit_allow_fraction; 290 pus->have_unit_allow_fraction = true; 291 pus->unit_precision_level = unit_precision_level; 292 pus->have_unit_precision_level = true; 293 pus->unit_active = unit_active; 294 pus->have_unit_active = true; 295 pus->http_status = http_status; 296 { 297 struct TALER_TESTING_Command cmd = { 298 .cls = pus, 299 .label = label, 300 .run = &patch_unit_run, 301 .cleanup = &patch_unit_cleanup, 302 .traits = &patch_unit_traits 303 }; 304 305 return cmd; 306 } 307 } 308 309 310 /* end of testing_api_cmd_patch_unit.c */