testing_api_cmd_post_tokenfamilies.c (7943B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2024 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 /** 21 * @file src/testing/testing_api_cmd_post_tokenfamilies.c 22 * @brief command to run POST /tokenfamilies 23 * @author Christian Blättler 24 */ 25 #include "platform.h" 26 struct PostTokenFamiliesState; 27 #define TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE struct PostTokenFamiliesState 28 #include <gnunet/gnunet_time_lib.h> 29 #include <taler/taler_exchange_service.h> 30 #include <taler/taler_testing_lib.h> 31 #include "taler/taler_merchant_service.h" 32 #include "taler/taler_merchant_testing_lib.h" 33 #include <taler/merchant/post-private-tokenfamilies.h> 34 35 36 /** 37 * State of a "POST /tokenfamilies" CMD. 38 */ 39 struct PostTokenFamiliesState 40 { 41 42 /** 43 * Expected status code. 44 */ 45 unsigned int http_status; 46 47 /** 48 * Handle for a "POST /tokenfamilies" request. 49 */ 50 struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *handle; 51 52 /** 53 * The interpreter state. 54 */ 55 struct TALER_TESTING_Interpreter *is; 56 57 /** 58 * Base URL of the merchant serving the request. 59 */ 60 const char *merchant_url; 61 62 /** 63 * Slug of the token family. 64 */ 65 const char *slug; 66 67 /** 68 * Name of the token family. 69 */ 70 const char *name; 71 72 /** 73 * Description of the token family. 74 */ 75 const char *description; 76 77 /** 78 * Map from IETF BCP 47 language tags to localized descriptions. 79 */ 80 json_t *description_i18n; 81 82 /** 83 * Start of the validity period. 84 */ 85 struct GNUNET_TIME_Timestamp valid_after; 86 87 /** 88 * End of the validity period. 89 */ 90 struct GNUNET_TIME_Timestamp valid_before; 91 92 /** 93 * Validity duation of issued tokens of this family. 94 */ 95 struct GNUNET_TIME_Relative duration; 96 97 /** 98 * Rounding duation of token family. 99 */ 100 struct GNUNET_TIME_Relative rounding; 101 102 /** 103 * Kind of the token family. "subscription" or "discount". 104 */ 105 const char *kind; 106 }; 107 108 109 /** 110 * Callback for a POST /tokenfamilies operation. 111 * 112 * @param cls closure for this function 113 * @param tfr response being processed 114 */ 115 static void 116 post_tokenfamilies_cb (struct PostTokenFamiliesState *state, 117 const struct 118 TALER_MERCHANT_PostPrivateTokenfamiliesResponse *tfr) 119 { 120 121 state->handle = NULL; 122 if (state->http_status != tfr->hr.http_status) 123 { 124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 125 "Unexpected response code %u (%d) to command %s\n", 126 tfr->hr.http_status, 127 (int) tfr->hr.ec, 128 TALER_TESTING_interpreter_get_current_label (state->is)); 129 TALER_TESTING_interpreter_fail (state->is); 130 return; 131 } 132 switch (tfr->hr.http_status) 133 { 134 case MHD_HTTP_NO_CONTENT: 135 break; 136 case MHD_HTTP_UNAUTHORIZED: 137 break; 138 case MHD_HTTP_FORBIDDEN: 139 break; 140 case MHD_HTTP_NOT_FOUND: 141 break; 142 default: 143 GNUNET_break (0); 144 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 145 "Unhandled HTTP status %u for POST /tokenfamilies.\n", 146 tfr->hr.http_status); 147 } 148 TALER_TESTING_interpreter_next (state->is); 149 } 150 151 152 /** 153 * Run the "POST /tokenfamilies" CMD. 154 * 155 * 156 * @param cls closure. 157 * @param cmd command being run now. 158 * @param is interpreter state. 159 */ 160 static void 161 post_tokenfamilies_run (void *cls, 162 const struct TALER_TESTING_Command *cmd, 163 struct TALER_TESTING_Interpreter *is) 164 { 165 struct PostTokenFamiliesState *state = cls; 166 167 state->is = is; 168 state->handle = TALER_MERCHANT_post_private_tokenfamilies_create ( 169 TALER_TESTING_interpreter_get_context (is), 170 state->merchant_url, 171 state->slug, 172 state->name, 173 state->description, 174 state->valid_after, 175 state->valid_before, 176 state->duration, 177 state->rounding, 178 GNUNET_TIME_UNIT_ZERO, /* start_offset */ 179 state->kind); 180 if (NULL != state->description_i18n) 181 { 182 TALER_MERCHANT_post_private_tokenfamilies_set_options ( 183 state->handle, 184 TALER_MERCHANT_post_private_tokenfamilies_option_description_i18n ( 185 state->description_i18n)); 186 } 187 { 188 enum TALER_ErrorCode ec; 189 190 ec = TALER_MERCHANT_post_private_tokenfamilies_start ( 191 state->handle, 192 &post_tokenfamilies_cb, 193 state); 194 GNUNET_assert (TALER_EC_NONE == ec); 195 } 196 } 197 198 199 /** 200 * Offers information from the "POST /tokenfamilies" CMD state to other 201 * commands. 202 * 203 * @param cls closure 204 * @param[out] ret result (could be anything) 205 * @param trait name of the trait 206 * @param index index number of the object to extract. 207 * @return #GNUNET_OK on success 208 */ 209 static enum GNUNET_GenericReturnValue 210 post_tokenfamilies_traits (void *cls, 211 const void **ret, 212 const char *trait, 213 unsigned int index) 214 { 215 struct PostTokenFamiliesState *state = cls; 216 struct TALER_TESTING_Trait traits[] = { 217 TALER_TESTING_make_trait_token_family_slug (state->slug), 218 TALER_TESTING_make_trait_timestamp (0, 219 &state->valid_after), 220 TALER_TESTING_make_trait_timestamp (1, 221 &state->valid_before), 222 TALER_TESTING_make_trait_token_family_duration (&state->duration), 223 TALER_TESTING_make_trait_token_family_kind (state->kind), 224 TALER_TESTING_trait_end () 225 }; 226 227 return TALER_TESTING_get_trait (traits, 228 ret, 229 trait, 230 index); 231 } 232 233 234 /** 235 * Free the state of a "POST /tokenfamilies" CMD, and possibly 236 * cancel a pending operation thereof. 237 * 238 * @param cls closure. 239 * @param cmd command being run. 240 */ 241 static void 242 post_tokenfamilies_cleanup (void *cls, 243 const struct TALER_TESTING_Command *cmd) 244 { 245 struct PostTokenFamiliesState *state = cls; 246 247 if (NULL != state->handle) 248 { 249 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 250 "POST /tokenfamilies operation did not complete\n"); 251 TALER_MERCHANT_post_private_tokenfamilies_cancel (state->handle); 252 } 253 json_decref (state->description_i18n); 254 GNUNET_free (state); 255 } 256 257 258 struct TALER_TESTING_Command 259 TALER_TESTING_cmd_merchant_post_tokenfamilies ( 260 const char *label, 261 const char *merchant_url, 262 unsigned int http_status, 263 const char *slug, 264 const char *name, 265 const char *description, 266 json_t *description_i18n, 267 struct GNUNET_TIME_Timestamp valid_after, 268 struct GNUNET_TIME_Timestamp valid_before, 269 struct GNUNET_TIME_Relative duration, 270 struct GNUNET_TIME_Relative rounding, 271 const char *kind) /* "subscription" or "discount" */ 272 { 273 struct PostTokenFamiliesState *state; 274 275 GNUNET_assert ((NULL == description_i18n) || 276 json_is_object (description_i18n)); 277 state = GNUNET_new (struct PostTokenFamiliesState); 278 state->merchant_url = merchant_url; 279 state->http_status = http_status; 280 state->slug = slug; 281 state->name = name; 282 state->description = description; 283 state->description_i18n = description_i18n; /* ownership taken */ 284 state->valid_after = valid_after; 285 state->valid_before = valid_before; 286 state->duration = duration; 287 state->rounding = rounding; 288 state->kind = kind; 289 { 290 struct TALER_TESTING_Command cmd = { 291 .cls = state, 292 .label = label, 293 .run = &post_tokenfamilies_run, 294 .cleanup = &post_tokenfamilies_cleanup, 295 .traits = &post_tokenfamilies_traits 296 }; 297 298 return cmd; 299 } 300 }