test_merchant_high_fee_order.c (5791B)
1 /* 2 This file is part of TALER 3 (C) 2026 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Lesser General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file src/backend/test_merchant_high_fee_order.c 18 * @brief unit test for the deposit-fee arithmetic in GET /private/orders/ID 19 */ 20 #include "platform.h" 21 #include <gnunet/gnunet_util_lib.h> 22 #include <taler/taler_json_lib.h> 23 #include "taler-merchant-httpd_helper.h" 24 25 26 /** 27 * Wrapper around #TMH_compute_expected_transfer that also checks the 28 * resulting expected total against an expected value. 29 * 30 * @param label label for the test case 31 * @param amount order amount string 32 * @param refund refund amount string 33 * @param deposit_fee deposit fee total string 34 * @param deposit_fee_refunded refunded deposit fee string 35 * @param max_fee maximum merchant fee string, or NULL 36 * @param want expected total string (only checked on success) 37 * @param want_ret expected return value 38 */ 39 static void 40 test_case (const char *label, 41 const char *amount, 42 const char *refund, 43 const char *deposit_fee, 44 const char *deposit_fee_refunded, 45 const char *max_fee, 46 const char *want, 47 enum GNUNET_GenericReturnValue want_ret) 48 { 49 struct TALER_Amount contract_amount; 50 struct TALER_Amount refund_amount; 51 struct TALER_Amount deposit_fees_total; 52 struct TALER_Amount deposit_fees_refunded_total; 53 struct TALER_Amount max_fee_amount; 54 struct TALER_Amount expected_total; 55 enum GNUNET_GenericReturnValue ret; 56 57 GNUNET_assert (GNUNET_OK == 58 TALER_string_to_amount (amount, 59 &contract_amount)); 60 GNUNET_assert (GNUNET_OK == 61 TALER_string_to_amount (refund, 62 &refund_amount)); 63 GNUNET_assert (GNUNET_OK == 64 TALER_string_to_amount (deposit_fee, 65 &deposit_fees_total)); 66 GNUNET_assert (GNUNET_OK == 67 TALER_string_to_amount (deposit_fee_refunded, 68 &deposit_fees_refunded_total)); 69 if (NULL != max_fee) 70 GNUNET_assert (GNUNET_OK == 71 TALER_string_to_amount (max_fee, 72 &max_fee_amount)); 73 74 ret = TMH_compute_expected_transfer ( 75 &contract_amount, 76 &refund_amount, 77 &deposit_fees_total, 78 &deposit_fees_refunded_total, 79 (NULL != max_fee) ? &max_fee_amount : NULL, 80 NULL != max_fee, 81 &expected_total); 82 83 if (ret != want_ret) 84 { 85 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 86 "Test '%s': expected return %d, got %d\n", 87 label, 88 want_ret, 89 ret); 90 GNUNET_assert (0); 91 } 92 if (GNUNET_OK == ret) 93 { 94 struct TALER_Amount want_total; 95 96 GNUNET_assert (GNUNET_OK == 97 TALER_string_to_amount (want, 98 &want_total)); 99 if (0 != TALER_amount_cmp (&expected_total, 100 &want_total)) 101 { 102 const char *got = TALER_amount2s (&expected_total); 103 104 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 105 "Test '%s': expected total %s, got %s\n", 106 label, 107 want, 108 got); 109 GNUNET_assert (0); 110 } 111 } 112 } 113 114 115 int 116 main (int argc, 117 char *const argv[]) 118 { 119 (void) argc; 120 (void) argv; 121 122 test_case ("fee below amount", 123 "TESTKUDOS:10", 124 "TESTKUDOS:0", 125 "TESTKUDOS:1", 126 "TESTKUDOS:0", 127 "TESTKUDOS:2", 128 "TESTKUDOS:9", 129 GNUNET_OK); 130 131 /* the per-coin deposit fee exceeds 132 the order amount, but the merchant max_fee caps what the merchant 133 pays. Without the max_fee cap this would fail with 134 deposit fees exceed total. */ 135 test_case ("fee exceeds amount but capped by max_fee", 136 "TESTKUDOS:1", 137 "TESTKUDOS:0", 138 "TESTKUDOS:2", 139 "TESTKUDOS:0", 140 "TESTKUDOS:0.2", 141 "TESTKUDOS:0.8", 142 GNUNET_OK); 143 144 test_case ("fee exceeds amount with refunded fee", 145 "TESTKUDOS:1", 146 "TESTKUDOS:0", 147 "TESTKUDOS:2", 148 "TESTKUDOS:0.5", 149 "TESTKUDOS:0.2", 150 "TESTKUDOS:0.8", 151 GNUNET_OK); 152 153 /* Without a max_fee the strict check must still fail when fees exceed 154 the amount. */ 155 test_case ("fee exceeds amount without max_fee", 156 "TESTKUDOS:1", 157 "TESTKUDOS:0", 158 "TESTKUDOS:2", 159 "TESTKUDOS:0", 160 NULL, 161 NULL, 162 GNUNET_NO); 163 164 /* Refunded deposit fees must not exceed the total deposit fees. */ 165 test_case ("refunded fees exceed total", 166 "TESTKUDOS:10", 167 "TESTKUDOS:0", 168 "TESTKUDOS:1", 169 "TESTKUDOS:2", 170 "TESTKUDOS:2", 171 NULL, 172 GNUNET_SYSERR); 173 174 /* Refunds must not exceed the contract value. */ 175 test_case ("refund exceeds contract", 176 "TESTKUDOS:1", 177 "TESTKUDOS:2", 178 "TESTKUDOS:0.1", 179 "TESTKUDOS:0", 180 "TESTKUDOS:0.1", 181 NULL, 182 GNUNET_SYSERR); 183 184 return 0; 185 }