testing_api_cmd_get_products.c (6548B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2020-2023 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_get_products.c 21 * @brief command to test GET /products 22 * @author Christian Grothoff 23 */ 24 #include "platform.h" 25 struct GetProductsState; 26 #define TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE struct GetProductsState 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/merchant/get-private-products.h> 32 33 34 /** 35 * State of a "GET products" CMD. 36 */ 37 struct GetProductsState 38 { 39 40 /** 41 * Handle for a "GET product" request. 42 */ 43 struct TALER_MERCHANT_GetPrivateProductsHandle *igh; 44 45 /** 46 * The interpreter state. 47 */ 48 struct TALER_TESTING_Interpreter *is; 49 50 /** 51 * Base URL of the merchant serving the request. 52 */ 53 const char *merchant_url; 54 55 /** 56 * Expected HTTP response code. 57 */ 58 unsigned int http_status; 59 60 /** 61 * The list of product references. 62 */ 63 const char **products; 64 65 /** 66 * Length of @e products. 67 */ 68 unsigned int products_length; 69 70 }; 71 72 73 /** 74 * Callback for a GET /products operation. 75 * 76 * @param cls closure for this function 77 * @param gpr response details 78 */ 79 static void 80 get_products_cb (struct GetProductsState *gis, 81 const struct TALER_MERCHANT_GetPrivateProductsResponse *gpr) 82 { 83 84 gis->igh = NULL; 85 if (gis->http_status != gpr->hr.http_status) 86 { 87 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 88 "Unexpected response code %u (%d) to command %s\n", 89 gpr->hr.http_status, 90 (int) gpr->hr.ec, 91 TALER_TESTING_interpreter_get_current_label (gis->is)); 92 TALER_TESTING_interpreter_fail (gis->is); 93 return; 94 } 95 switch (gpr->hr.http_status) 96 { 97 case MHD_HTTP_OK: 98 { 99 unsigned int products_length 100 = gpr->details.ok.products_length; 101 const struct TALER_MERCHANT_GetPrivateProductsInventoryEntry *products 102 = gpr->details.ok.products; 103 104 if (products_length != gis->products_length) 105 { 106 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 107 "Length of products found does not match\n"); 108 TALER_TESTING_interpreter_fail (gis->is); 109 return; 110 } 111 for (unsigned int i = 0; i < gis->products_length; ++i) 112 { 113 const struct TALER_TESTING_Command *product_cmd; 114 115 product_cmd = TALER_TESTING_interpreter_lookup_command ( 116 gis->is, 117 gis->products[i]); 118 119 { 120 const char *product_id; 121 122 if (GNUNET_OK != 123 TALER_TESTING_get_trait_product_id (product_cmd, 124 &product_id)) 125 { 126 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 127 "Could not fetch product id\n"); 128 TALER_TESTING_interpreter_fail (gis->is); 129 return; 130 } 131 if (0 != strcmp (products[i].product_id, 132 product_id)) 133 { 134 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 135 "Product id does not match\n"); 136 TALER_TESTING_interpreter_fail (gis->is); 137 return; 138 } 139 } 140 } 141 } 142 break; 143 case MHD_HTTP_UNAUTHORIZED: 144 break; 145 case MHD_HTTP_NOT_FOUND: 146 /* instance does not exist */ 147 break; 148 default: 149 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 150 "Unhandled HTTP status %u (%d).\n", 151 gpr->hr.http_status, 152 gpr->hr.ec); 153 } 154 TALER_TESTING_interpreter_next (gis->is); 155 } 156 157 158 /** 159 * Run the "GET /products" CMD. 160 * 161 * 162 * @param cls closure. 163 * @param cmd command being run now. 164 * @param is interpreter state. 165 */ 166 static void 167 get_products_run (void *cls, 168 const struct TALER_TESTING_Command *cmd, 169 struct TALER_TESTING_Interpreter *is) 170 { 171 struct GetProductsState *gis = cls; 172 173 gis->is = is; 174 gis->igh = TALER_MERCHANT_get_private_products_create ( 175 TALER_TESTING_interpreter_get_context (is), 176 gis->merchant_url); 177 { 178 enum TALER_ErrorCode ec; 179 180 ec = TALER_MERCHANT_get_private_products_start (gis->igh, 181 &get_products_cb, 182 gis); 183 GNUNET_assert (TALER_EC_NONE == ec); 184 } 185 } 186 187 188 /** 189 * Free the state of a "GET product" CMD, and possibly 190 * cancel a pending operation thereof. 191 * 192 * @param cls closure. 193 * @param cmd command being run. 194 */ 195 static void 196 get_products_cleanup (void *cls, 197 const struct TALER_TESTING_Command *cmd) 198 { 199 struct GetProductsState *gis = cls; 200 201 if (NULL != gis->igh) 202 { 203 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 204 "GET /products operation did not complete\n"); 205 TALER_MERCHANT_get_private_products_cancel (gis->igh); 206 } 207 GNUNET_array_grow (gis->products, 208 gis->products_length, 209 0); 210 GNUNET_free (gis); 211 } 212 213 214 struct TALER_TESTING_Command 215 TALER_TESTING_cmd_merchant_get_products (const char *label, 216 const char *merchant_url, 217 unsigned int http_status, 218 ...) 219 { 220 struct GetProductsState *gis; 221 222 gis = GNUNET_new (struct GetProductsState); 223 gis->merchant_url = merchant_url; 224 gis->http_status = http_status; 225 { 226 const char *clabel; 227 va_list ap; 228 229 va_start (ap, http_status); 230 while (NULL != (clabel = va_arg (ap, const char *))) 231 { 232 GNUNET_array_append (gis->products, 233 gis->products_length, 234 clabel); 235 } 236 va_end (ap); 237 } 238 { 239 struct TALER_TESTING_Command cmd = { 240 .cls = gis, 241 .label = label, 242 .run = &get_products_run, 243 .cleanup = &get_products_cleanup 244 }; 245 246 return cmd; 247 } 248 } 249 250 251 /* end of testing_api_cmd_get_products.c */