testing_api_cmd_get_products.c (6164B)
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 "platform.h" 25 #include <taler/taler_exchange_service.h> 26 #include <taler/taler_testing_lib.h> 27 #include "taler_merchant_service.h" 28 #include "taler_merchant_testing_lib.h" 29 30 31 /** 32 * State of a "GET products" CMD. 33 */ 34 struct GetProductsState 35 { 36 37 /** 38 * Handle for a "GET product" request. 39 */ 40 struct TALER_MERCHANT_ProductsGetHandle *igh; 41 42 /** 43 * The interpreter state. 44 */ 45 struct TALER_TESTING_Interpreter *is; 46 47 /** 48 * Base URL of the merchant serving the request. 49 */ 50 const char *merchant_url; 51 52 /** 53 * Expected HTTP response code. 54 */ 55 unsigned int http_status; 56 57 /** 58 * The list of product references. 59 */ 60 const char **products; 61 62 /** 63 * Length of @e products. 64 */ 65 unsigned int products_length; 66 67 }; 68 69 70 /** 71 * Callback for a GET /products operation. 72 * 73 * @param cls closure for this function 74 * @param gpr response details 75 */ 76 static void 77 get_products_cb (void *cls, 78 const struct TALER_MERCHANT_GetProductsResponse *gpr) 79 { 80 struct GetProductsState *gis = cls; 81 const struct TALER_MERCHANT_HttpResponse *hr = &gpr->hr; 82 83 gis->igh = NULL; 84 if (gis->http_status != hr->http_status) 85 { 86 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 87 "Unexpected response code %u (%d) to command %s\n", 88 hr->http_status, 89 (int) hr->ec, 90 TALER_TESTING_interpreter_get_current_label (gis->is)); 91 TALER_TESTING_interpreter_fail (gis->is); 92 return; 93 } 94 switch (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_InventoryEntry *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 hr->http_status, 151 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_products_get ( 174 TALER_TESTING_interpreter_get_context (is), 175 gis->merchant_url, 176 &get_products_cb, 177 gis); 178 GNUNET_assert (NULL != gis->igh); 179 } 180 181 182 /** 183 * Free the state of a "GET product" CMD, and possibly 184 * cancel a pending operation thereof. 185 * 186 * @param cls closure. 187 * @param cmd command being run. 188 */ 189 static void 190 get_products_cleanup (void *cls, 191 const struct TALER_TESTING_Command *cmd) 192 { 193 struct GetProductsState *gis = cls; 194 195 if (NULL != gis->igh) 196 { 197 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 198 "GET /products operation did not complete\n"); 199 TALER_MERCHANT_products_get_cancel (gis->igh); 200 } 201 GNUNET_array_grow (gis->products, 202 gis->products_length, 203 0); 204 GNUNET_free (gis); 205 } 206 207 208 struct TALER_TESTING_Command 209 TALER_TESTING_cmd_merchant_get_products (const char *label, 210 const char *merchant_url, 211 unsigned int http_status, 212 ...) 213 { 214 struct GetProductsState *gis; 215 216 gis = GNUNET_new (struct GetProductsState); 217 gis->merchant_url = merchant_url; 218 gis->http_status = http_status; 219 { 220 const char *clabel; 221 va_list ap; 222 223 va_start (ap, http_status); 224 while (NULL != (clabel = va_arg (ap, const char *))) 225 { 226 GNUNET_array_append (gis->products, 227 gis->products_length, 228 clabel); 229 } 230 va_end (ap); 231 } 232 { 233 struct TALER_TESTING_Command cmd = { 234 .cls = gis, 235 .label = label, 236 .run = &get_products_run, 237 .cleanup = &get_products_cleanup 238 }; 239 240 return cmd; 241 } 242 } 243 244 245 /* end of testing_api_cmd_get_products.c */