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