Line data Source code
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 it under the
6 : terms of the GNU 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 kyclogic/test_kyclogic.c
18 : * @brief Tests for KYC rule evaluation
19 : * @author Florian Dold
20 : */
21 : #include "platform.h"
22 : #include "taler/taler_kyclogic_lib.h"
23 : #include "taler/taler_util.h"
24 :
25 :
26 : /**
27 : * Amounts to return from the test iterator.
28 : */
29 : struct TestAmounts
30 : {
31 : /**
32 : * Amounts, in reverse chronological order.
33 : */
34 : const char *const *amounts;
35 :
36 : /**
37 : * Number of entries in @e amounts.
38 : */
39 : unsigned int num_amounts;
40 : };
41 :
42 :
43 : /**
44 : * Return the amounts for one boundary test.
45 : *
46 : * @param cls a `struct TestAmounts`
47 : * @param limit earliest relevant transaction time
48 : * @param cb callback to invoke for each amount
49 : * @param cb_cls closure for @a cb
50 : * @return transaction status
51 : */
52 : static enum GNUNET_DB_QueryStatus
53 4 : amount_iterator (void *cls,
54 : struct GNUNET_TIME_Absolute limit,
55 : TALER_KYCLOGIC_KycAmountCallback cb,
56 : void *cb_cls)
57 : {
58 4 : const struct TestAmounts *ta = cls;
59 4 : struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
60 :
61 : (void) limit;
62 10 : for (unsigned int i=0; i<ta->num_amounts; i++)
63 : {
64 : struct TALER_Amount amount;
65 :
66 6 : GNUNET_assert (GNUNET_OK ==
67 : TALER_string_to_amount (ta->amounts[i],
68 : &amount));
69 6 : GNUNET_assert (GNUNET_OK ==
70 : cb (cb_cls,
71 : &amount,
72 : now));
73 : }
74 4 : return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
75 : }
76 :
77 :
78 : /**
79 : * Check whether the configured EUR:2 rule triggers for @a amounts.
80 : *
81 : * @param amounts amounts to add up
82 : * @param num_amounts length of @a amounts
83 : * @param expect_trigger true if the rule should trigger
84 : */
85 : static void
86 4 : check_threshold (const char *const amounts[],
87 : unsigned int num_amounts,
88 : bool expect_trigger)
89 : {
90 4 : struct TestAmounts ta = {
91 : .amounts = amounts,
92 : .num_amounts = num_amounts
93 : };
94 : const struct TALER_KYCLOGIC_KycRule *triggered_rule;
95 : struct TALER_Amount next_threshold;
96 : struct TALER_Amount expected_threshold;
97 :
98 4 : GNUNET_assert (
99 : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
100 : TALER_KYCLOGIC_kyc_test_required (
101 : TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT,
102 : NULL,
103 : &amount_iterator,
104 : &ta,
105 : &triggered_rule,
106 : &next_threshold));
107 4 : GNUNET_assert (expect_trigger == (NULL != triggered_rule));
108 4 : GNUNET_assert (GNUNET_OK ==
109 : TALER_string_to_amount ("EUR:2",
110 : &expected_threshold));
111 4 : GNUNET_assert (0 ==
112 : TALER_amount_cmp (&expected_threshold,
113 : &next_threshold));
114 4 : }
115 :
116 :
117 : int
118 1 : main (int argc,
119 : const char *const argv[])
120 : {
121 : struct GNUNET_CONFIGURATION_Handle *cfg;
122 1 : const char *const below[] = { "EUR:1.99999999" };
123 1 : const char *const equal[] = { "EUR:2" };
124 1 : const char *const cumulative_equal[] = { "EUR:1", "EUR:1" };
125 1 : const char *const cumulative_above[] = { "EUR:1", "EUR:1.00000001" };
126 :
127 : (void) argc;
128 : (void) argv;
129 1 : GNUNET_log_setup ("test-kyclogic",
130 : "WARNING",
131 : NULL);
132 1 : cfg = GNUNET_CONFIGURATION_create (TALER_EXCHANGE_project_data ());
133 1 : GNUNET_CONFIGURATION_set_value_string (cfg,
134 : "exchange",
135 : "CURRENCY",
136 : "EUR");
137 1 : GNUNET_CONFIGURATION_set_value_string (cfg,
138 : "kyc-rule-deposit-boundary",
139 : "ENABLED",
140 : "YES");
141 1 : GNUNET_CONFIGURATION_set_value_string (cfg,
142 : "kyc-rule-deposit-boundary",
143 : "EXPOSED",
144 : "YES");
145 1 : GNUNET_CONFIGURATION_set_value_string (cfg,
146 : "kyc-rule-deposit-boundary",
147 : "IS_AND_COMBINATOR",
148 : "YES");
149 1 : GNUNET_CONFIGURATION_set_value_string (cfg,
150 : "kyc-rule-deposit-boundary",
151 : "OPERATION_TYPE",
152 : "DEPOSIT");
153 1 : GNUNET_CONFIGURATION_set_value_string (cfg,
154 : "kyc-rule-deposit-boundary",
155 : "THRESHOLD",
156 : "EUR:2");
157 1 : GNUNET_CONFIGURATION_set_value_string (cfg,
158 : "kyc-rule-deposit-boundary",
159 : "TIMEFRAME",
160 : "1 day");
161 1 : GNUNET_CONFIGURATION_set_value_string (cfg,
162 : "kyc-rule-deposit-boundary",
163 : "NEXT_MEASURES",
164 : "verboten");
165 1 : GNUNET_assert (GNUNET_OK ==
166 : TALER_KYCLOGIC_kyc_init (cfg,
167 : NULL));
168 1 : GNUNET_CONFIGURATION_destroy (cfg);
169 :
170 : /* The configured threshold is an inclusive maximum. */
171 1 : check_threshold (below,
172 : sizeof (below) / sizeof (below[0]),
173 : false);
174 1 : check_threshold (equal,
175 : sizeof (equal) / sizeof (equal[0]),
176 : false);
177 1 : check_threshold (cumulative_equal,
178 : sizeof (cumulative_equal) /
179 : sizeof (cumulative_equal[0]),
180 : false);
181 1 : check_threshold (cumulative_above,
182 : sizeof (cumulative_above) /
183 : sizeof (cumulative_above[0]),
184 : true);
185 :
186 1 : TALER_KYCLOGIC_kyc_done ();
187 1 : return 0;
188 : }
|