testing_api_cmd_check_order_external.c (6358B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2026 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_check_order_external.c 21 * @brief command to check the external payments and refunds an order 22 * reports through GET /private/orders/$ORDER_ID 23 * @author Bohdan Potuzhnyi 24 * @author Volodymyr Potuzhnyi 25 */ 26 #include "platform.h" 27 struct CheckOrderExternalState; 28 #define TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE \ 29 struct CheckOrderExternalState 30 #include <taler/taler_exchange_service.h> 31 #include <taler/taler_testing_lib.h> 32 #include "taler/taler_merchant_service.h" 33 #include "taler/taler_merchant_testing_lib.h" 34 35 36 /** 37 * State of a "check order external" CMD. 38 */ 39 struct CheckOrderExternalState 40 { 41 42 /** 43 * Handle for the order status request. 44 */ 45 struct TALER_MERCHANT_GetPrivateOrderHandle *ogh; 46 47 /** 48 * The interpreter state. 49 */ 50 struct TALER_TESTING_Interpreter *is; 51 52 /** 53 * Base URL of the merchant serving the request. 54 */ 55 const char *merchant_url; 56 57 /** 58 * ID of the order to check. 59 */ 60 const char *order_id; 61 62 /** 63 * Number of entries expected in "amount_external" of the contract. 64 */ 65 unsigned int expected_payments; 66 67 /** 68 * Number of entries expected in "refunds_external" of the status. 69 */ 70 unsigned int expected_refunds; 71 72 /** 73 * Choice the order is expected to have been paid with, -1 if the 74 * contract has no choices. 75 */ 76 int expected_choice_index; 77 78 }; 79 80 81 /** 82 * Callback for the order status request. 83 * 84 * @param coes closure for this function 85 * @param osr response being processed 86 */ 87 static void 88 check_order_external_cb ( 89 struct CheckOrderExternalState *coes, 90 const struct TALER_MERCHANT_GetPrivateOrderResponse *osr) 91 { 92 size_t payments; 93 size_t refunds; 94 95 coes->ogh = NULL; 96 if (MHD_HTTP_OK != osr->hr.http_status) 97 { 98 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 99 "Unexpected response code %u (%d) to command %s\n", 100 osr->hr.http_status, 101 (int) osr->hr.ec, 102 TALER_TESTING_interpreter_get_current_label (coes->is)); 103 TALER_TESTING_interpreter_fail (coes->is); 104 return; 105 } 106 if (TALER_MERCHANT_OSC_PAID != osr->details.ok.status) 107 { 108 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 109 "Order `%s' is not paid, cannot check external payments\n", 110 coes->order_id); 111 TALER_TESTING_interpreter_fail (coes->is); 112 return; 113 } 114 payments = json_array_size ( 115 json_object_get (osr->details.ok.details.paid.contract_terms, 116 "amount_external")); 117 refunds = json_array_size (osr->details.ok.details.paid.refunds_external); 118 if (coes->expected_choice_index != 119 osr->details.ok.details.paid.choice_index) 120 { 121 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 122 "Order `%s' was paid with choice %d, expected %d\n", 123 coes->order_id, 124 osr->details.ok.details.paid.choice_index, 125 coes->expected_choice_index); 126 TALER_TESTING_interpreter_fail (coes->is); 127 return; 128 } 129 if ( (payments != (size_t) coes->expected_payments) || 130 (refunds != (size_t) coes->expected_refunds) ) 131 { 132 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 133 "Order `%s' reports %u external payments and %u external refunds, expected %u and %u\n", 134 coes->order_id, 135 (unsigned int) payments, 136 (unsigned int) refunds, 137 coes->expected_payments, 138 coes->expected_refunds); 139 TALER_TESTING_interpreter_fail (coes->is); 140 return; 141 } 142 TALER_TESTING_interpreter_next (coes->is); 143 } 144 145 146 /** 147 * Run the "check order external" CMD. 148 * 149 * @param cls closure. 150 * @param cmd command being run now. 151 * @param is interpreter state. 152 */ 153 static void 154 check_order_external_run (void *cls, 155 const struct TALER_TESTING_Command *cmd, 156 struct TALER_TESTING_Interpreter *is) 157 { 158 struct CheckOrderExternalState *coes = cls; 159 160 coes->is = is; 161 coes->ogh = TALER_MERCHANT_get_private_order_create ( 162 TALER_TESTING_interpreter_get_context (is), 163 coes->merchant_url, 164 coes->order_id); 165 GNUNET_assert (NULL != coes->ogh); 166 { 167 enum TALER_ErrorCode ec; 168 169 ec = TALER_MERCHANT_get_private_order_start (coes->ogh, 170 &check_order_external_cb, 171 coes); 172 GNUNET_assert (TALER_EC_NONE == ec); 173 } 174 } 175 176 177 /** 178 * Free the state of a "check order external" CMD. 179 * 180 * @param cls closure. 181 * @param cmd command being run. 182 */ 183 static void 184 check_order_external_cleanup (void *cls, 185 const struct TALER_TESTING_Command *cmd) 186 { 187 struct CheckOrderExternalState *coes = cls; 188 189 if (NULL != coes->ogh) 190 { 191 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 192 "GET /private/orders/$ORDER_ID operation did not complete\n"); 193 TALER_MERCHANT_get_private_order_cancel (coes->ogh); 194 } 195 GNUNET_free (coes); 196 } 197 198 199 struct TALER_TESTING_Command 200 TALER_TESTING_cmd_merchant_check_order_external ( 201 const char *label, 202 const char *merchant_url, 203 const char *order_id, 204 unsigned int expected_payments, 205 unsigned int expected_refunds, 206 int expected_choice_index) 207 { 208 struct CheckOrderExternalState *coes; 209 210 coes = GNUNET_new (struct CheckOrderExternalState); 211 coes->merchant_url = merchant_url; 212 coes->order_id = order_id; 213 coes->expected_payments = expected_payments; 214 coes->expected_refunds = expected_refunds; 215 coes->expected_choice_index = expected_choice_index; 216 { 217 struct TALER_TESTING_Command cmd = { 218 .cls = coes, 219 .label = label, 220 .run = &check_order_external_run, 221 .cleanup = &check_order_external_cleanup 222 }; 223 224 return cmd; 225 } 226 }