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