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