testing_api_cmd_transfer_get.c (11262B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2020, 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/testing_api_cmd_transfer_get.c 22 * @brief Implement the testing CMDs for the /transfer GET operation. 23 * @author Marcello Stanisci 24 */ 25 #include "taler/platform.h" 26 #include "taler/taler_json_lib.h" 27 #include <gnunet/gnunet_curl_lib.h> 28 #include "taler/taler_testing_lib.h" 29 30 /** 31 * State for a "track transfer" CMD. 32 */ 33 struct TrackTransferState 34 { 35 36 /** 37 * Expected amount for the WTID being tracked. 38 */ 39 const char *expected_total_amount; 40 41 /** 42 * Expected fee for this WTID. 43 */ 44 const char *expected_wire_fee; 45 46 /** 47 * Our command. 48 */ 49 const struct TALER_TESTING_Command *cmd; 50 51 /** 52 * Reference to any operation that can provide a WTID. 53 * Will be the WTID to track. 54 */ 55 const char *wtid_reference; 56 57 /** 58 * Reference to any operation that can provide wire details. 59 * Those wire details will then be matched against the credit 60 * bank account of the tracked WTID. This way we can test that 61 * a wire transfer paid back one particular bank account. 62 */ 63 const char *wire_details_reference; 64 65 /** 66 * Reference to any operation that can provide an amount. 67 * This way we can check that the transferred amount matches 68 * our expectations. 69 */ 70 const char *total_amount_reference; 71 72 /** 73 * Handle to a pending "track transfer" operation. 74 */ 75 struct TALER_EXCHANGE_TransfersGetHandle *tth; 76 77 /** 78 * Interpreter state. 79 */ 80 struct TALER_TESTING_Interpreter *is; 81 82 /** 83 * Expected HTTP response code. 84 */ 85 unsigned int expected_response_code; 86 87 }; 88 89 90 /** 91 * Cleanup the state for a "track transfer" CMD, and possibly 92 * cancel a pending operation thereof. 93 * 94 * @param cls closure. 95 * @param cmd the command which is being cleaned up. 96 */ 97 static void 98 track_transfer_cleanup ( 99 void *cls, 100 const struct TALER_TESTING_Command *cmd) 101 { 102 struct TrackTransferState *tts = cls; 103 104 if (NULL != tts->tth) 105 { 106 TALER_TESTING_command_incomplete (tts->is, 107 cmd->label); 108 TALER_EXCHANGE_transfers_get_cancel (tts->tth); 109 tts->tth = NULL; 110 } 111 GNUNET_free (tts); 112 } 113 114 115 /** 116 * Check whether the HTTP response code from a "track transfer" 117 * operation is acceptable, and all other values like total amount, 118 * wire fees and hashed wire details as well. 119 * 120 * @param cls closure. 121 * @param tgr response details 122 */ 123 static void 124 track_transfer_cb ( 125 void *cls, 126 const struct TALER_EXCHANGE_TransfersGetResponse *tgr) 127 { 128 struct TrackTransferState *tts = cls; 129 const struct TALER_EXCHANGE_HttpResponse *hr = &tgr->hr; 130 struct TALER_TESTING_Interpreter *is = tts->is; 131 struct TALER_Amount expected_amount; 132 133 tts->tth = NULL; 134 if (tts->expected_response_code != hr->http_status) 135 { 136 TALER_TESTING_unexpected_status (is, 137 hr->http_status, 138 tts->expected_response_code); 139 return; 140 } 141 142 switch (hr->http_status) 143 { 144 case MHD_HTTP_OK: 145 { 146 const struct TALER_EXCHANGE_TransferData *ta 147 = &tgr->details.ok.td; 148 149 if (NULL == tts->expected_total_amount) 150 { 151 GNUNET_break (0); 152 TALER_TESTING_interpreter_fail (is); 153 return; 154 } 155 if (NULL == tts->expected_wire_fee) 156 { 157 GNUNET_break (0); 158 TALER_TESTING_interpreter_fail (is); 159 return; 160 } 161 162 if (GNUNET_OK != 163 TALER_string_to_amount (tts->expected_total_amount, 164 &expected_amount)) 165 { 166 GNUNET_break (0); 167 TALER_TESTING_interpreter_fail (is); 168 return; 169 } 170 if (0 != TALER_amount_cmp (&ta->total_amount, 171 &expected_amount)) 172 { 173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 174 "Total amount mismatch to command %s - " 175 "%s vs %s\n", 176 tts->cmd->label, 177 TALER_amount_to_string (&ta->total_amount), 178 TALER_amount_to_string (&expected_amount)); 179 json_dumpf (hr->reply, 180 stderr, 181 0); 182 fprintf (stderr, "\n"); 183 TALER_TESTING_interpreter_fail (is); 184 return; 185 } 186 187 if (GNUNET_OK != 188 TALER_string_to_amount (tts->expected_wire_fee, 189 &expected_amount)) 190 { 191 GNUNET_break (0); 192 TALER_TESTING_interpreter_fail (is); 193 return; 194 } 195 196 if (0 != TALER_amount_cmp (&ta->wire_fee, 197 &expected_amount)) 198 { 199 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 200 "Wire fee mismatch to command %s\n", 201 tts->cmd->label); 202 json_dumpf (hr->reply, 203 stderr, 204 0); 205 TALER_TESTING_interpreter_fail (is); 206 return; 207 } 208 209 /** 210 * Optionally checking: (1) wire-details for this transfer 211 * match the ones from a referenced "deposit" operation - 212 * or any operation that could provide wire-details. (2) 213 * Total amount for this transfer matches the one from any 214 * referenced command that could provide one. 215 */ 216 if (NULL != tts->wire_details_reference) 217 { 218 const struct TALER_TESTING_Command *wire_details_cmd; 219 const struct TALER_FullPayto *payto_uri; 220 struct TALER_FullPaytoHashP h_payto; 221 222 wire_details_cmd 223 = TALER_TESTING_interpreter_lookup_command ( 224 is, 225 tts->wire_details_reference); 226 if (NULL == wire_details_cmd) 227 { 228 GNUNET_break (0); 229 TALER_TESTING_interpreter_fail (is); 230 return; 231 } 232 if (GNUNET_OK != 233 TALER_TESTING_get_trait_full_payto_uri (wire_details_cmd, 234 &payto_uri)) 235 { 236 GNUNET_break (0); 237 TALER_TESTING_interpreter_fail (is); 238 return; 239 } 240 TALER_full_payto_hash (*payto_uri, 241 &h_payto); 242 if (0 != GNUNET_memcmp (&h_payto, 243 &ta->h_payto)) 244 { 245 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 246 "Wire hash missmath to command %s\n", 247 tts->cmd->label); 248 json_dumpf (hr->reply, 249 stderr, 250 0); 251 TALER_TESTING_interpreter_fail (is); 252 return; 253 } 254 } 255 if (NULL != tts->total_amount_reference) 256 { 257 const struct TALER_TESTING_Command *total_amount_cmd; 258 const struct TALER_Amount *total_amount_from_reference; 259 260 total_amount_cmd 261 = TALER_TESTING_interpreter_lookup_command (is, 262 tts-> 263 total_amount_reference); 264 if (NULL == total_amount_cmd) 265 { 266 GNUNET_break (0); 267 TALER_TESTING_interpreter_fail (is); 268 return; 269 } 270 if (GNUNET_OK != 271 TALER_TESTING_get_trait_amount (total_amount_cmd, 272 &total_amount_from_reference)) 273 { 274 GNUNET_break (0); 275 TALER_TESTING_interpreter_fail (is); 276 return; 277 } 278 if (0 != TALER_amount_cmp (&ta->total_amount, 279 total_amount_from_reference)) 280 { 281 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 282 "Amount mismatch in command %s\n", 283 tts->cmd->label); 284 json_dumpf (hr->reply, 285 stderr, 286 0); 287 TALER_TESTING_interpreter_fail (is); 288 return; 289 } 290 } 291 break; 292 } /* case OK */ 293 } /* switch on status */ 294 TALER_TESTING_interpreter_next (is); 295 } 296 297 298 /** 299 * Run the command. 300 * 301 * @param cls closure. 302 * @param cmd the command under execution. 303 * @param is the interpreter state. 304 */ 305 static void 306 track_transfer_run ( 307 void *cls, 308 const struct TALER_TESTING_Command *cmd, 309 struct TALER_TESTING_Interpreter *is) 310 { 311 /* looking for a wtid to track .. */ 312 struct TrackTransferState *tts = cls; 313 struct TALER_WireTransferIdentifierRawP wtid; 314 const struct TALER_WireTransferIdentifierRawP *wtid_ptr; 315 316 tts->cmd = cmd; 317 /* If no reference is given, we'll use a all-zeros 318 * WTID */ 319 memset (&wtid, 320 0, 321 sizeof (wtid)); 322 wtid_ptr = &wtid; 323 tts->is = is; 324 if (NULL != tts->wtid_reference) 325 { 326 const struct TALER_TESTING_Command *wtid_cmd; 327 328 wtid_cmd = TALER_TESTING_interpreter_lookup_command (tts->is, 329 tts->wtid_reference); 330 if (NULL == wtid_cmd) 331 { 332 GNUNET_break (0); 333 TALER_TESTING_interpreter_fail (tts->is); 334 return; 335 } 336 337 if (GNUNET_OK != 338 TALER_TESTING_get_trait_wtid (wtid_cmd, 339 &wtid_ptr)) 340 { 341 GNUNET_break (0); 342 TALER_TESTING_interpreter_fail (tts->is); 343 return; 344 } 345 GNUNET_assert (NULL != wtid_ptr); 346 } 347 tts->tth = TALER_EXCHANGE_transfers_get ( 348 TALER_TESTING_interpreter_get_context (is), 349 TALER_TESTING_get_exchange_url (is), 350 TALER_TESTING_get_keys (is), 351 wtid_ptr, 352 &track_transfer_cb, 353 tts); 354 GNUNET_assert (NULL != tts->tth); 355 } 356 357 358 struct TALER_TESTING_Command 359 TALER_TESTING_cmd_track_transfer_empty ( 360 const char *label, 361 const char *wtid_reference, 362 unsigned int expected_response_code) 363 { 364 struct TrackTransferState *tts; 365 366 tts = GNUNET_new (struct TrackTransferState); 367 tts->wtid_reference = wtid_reference; 368 tts->expected_response_code = expected_response_code; 369 { 370 struct TALER_TESTING_Command cmd = { 371 .cls = tts, 372 .label = label, 373 .run = &track_transfer_run, 374 .cleanup = &track_transfer_cleanup 375 }; 376 377 return cmd; 378 } 379 } 380 381 382 struct TALER_TESTING_Command 383 TALER_TESTING_cmd_track_transfer ( 384 const char *label, 385 const char *wtid_reference, 386 unsigned int expected_response_code, 387 const char *expected_total_amount, 388 const char *expected_wire_fee) 389 { 390 struct TrackTransferState *tts; 391 392 tts = GNUNET_new (struct TrackTransferState); 393 tts->wtid_reference = wtid_reference; 394 tts->expected_response_code = expected_response_code; 395 tts->expected_total_amount = expected_total_amount; 396 tts->expected_wire_fee = expected_wire_fee; 397 { 398 struct TALER_TESTING_Command cmd = { 399 .cls = tts, 400 .label = label, 401 .run = &track_transfer_run, 402 .cleanup = &track_transfer_cleanup 403 }; 404 405 return cmd; 406 } 407 } 408 409 410 /* end of testing_api_cmd_gransfer_get.c */