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