Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2020 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 testing_api_cmd_post_reserves.c
21 : * @brief command to test POST /reserves
22 : * @author Jonathan Buchanan
23 : */
24 : #include "platform.h"
25 : #include <taler/taler_exchange_service.h>
26 : #include <taler/taler_testing_lib.h>
27 : #include "taler_merchant_service.h"
28 : #include "taler_merchant_testing_lib.h"
29 :
30 : /**
31 : * State of a "POST /reserves" CMD.
32 : */
33 : struct PostReservesState
34 : {
35 : /**
36 : * Handle for a "POST /reserves" request.
37 : */
38 : struct TALER_MERCHANT_PostReservesHandle *prh;
39 :
40 : /**
41 : * The interpreter state.
42 : */
43 : struct TALER_TESTING_Interpreter *is;
44 :
45 : /**
46 : * Base URL of the merchant
47 : */
48 : const char *merchant_url;
49 :
50 : /**
51 : * Base URL of the exchange.
52 : */
53 : const char *exchange_url;
54 :
55 : /**
56 : * Wire method for the reserve.
57 : */
58 : const char *wire_method;
59 :
60 : /**
61 : * The initial balance of the reserve.
62 : */
63 : struct TALER_Amount initial_balance;
64 :
65 : /**
66 : * Expected HTTP response code.
67 : */
68 : unsigned int http_status;
69 :
70 : /**
71 : * Public key assigned to the reserve
72 : */
73 : struct TALER_ReservePublicKeyP reserve_pub;
74 : };
75 :
76 :
77 : /**
78 : * Callbacks of this type are used to work the result of submitting a
79 : * POST /reserves request to a merchant
80 : *
81 : * @param cls closure
82 : * @param hr HTTP response details
83 : * @param reserve_pub public key of the created reserve, NULL on error
84 : * @param payto_uri where to make the payment to for filling the reserve, NULL on error
85 : */
86 : static void
87 0 : post_reserves_cb (void *cls,
88 : const struct TALER_MERCHANT_HttpResponse *hr,
89 : const struct TALER_ReservePublicKeyP *reserve_pub,
90 : const char *payto_uri)
91 : {
92 0 : struct PostReservesState *prs = cls;
93 :
94 0 : prs->prh = NULL;
95 0 : if (prs->http_status != hr->http_status)
96 : {
97 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
98 : "Unexpected response code %u (%d) to command %s\n",
99 : hr->http_status,
100 : (int) hr->ec,
101 : TALER_TESTING_interpreter_get_current_label (prs->is));
102 0 : TALER_TESTING_interpreter_fail (prs->is);
103 0 : return;
104 : }
105 0 : switch (hr->http_status)
106 : {
107 0 : case MHD_HTTP_OK:
108 0 : break;
109 0 : case MHD_HTTP_ACCEPTED:
110 0 : break;
111 0 : case MHD_HTTP_UNAUTHORIZED:
112 0 : break;
113 0 : case MHD_HTTP_NOT_FOUND:
114 0 : break;
115 0 : default:
116 0 : GNUNET_break (0);
117 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
118 : "Unhandled HTTP status %u for POST /reserves.\n",
119 : hr->http_status);
120 : }
121 0 : prs->reserve_pub = *reserve_pub;
122 0 : TALER_TESTING_interpreter_next (prs->is);
123 : }
124 :
125 :
126 : /**
127 : * Offers information from the POST /reserves CMD state to other
128 : * commands.
129 : *
130 : * @param cls closure
131 : * @param[out] ret result (could be anything)
132 : * @param trait name of the trait
133 : * @param index index number of the object to extract.
134 : * @return #GNUNET_OK on success
135 : */
136 : static enum GNUNET_GenericReturnValue
137 0 : post_reserves_traits (void *cls,
138 : const void **ret,
139 : const char *trait,
140 : unsigned int index)
141 : {
142 0 : struct PostReservesState *prs = cls;
143 : struct TALER_TESTING_Trait traits[] = {
144 0 : TALER_TESTING_make_trait_reserve_pub (&prs->reserve_pub),
145 0 : TALER_TESTING_make_trait_amount (&prs->initial_balance),
146 0 : TALER_TESTING_trait_end (),
147 : };
148 :
149 0 : return TALER_TESTING_get_trait (traits,
150 : ret,
151 : trait,
152 : index);
153 : }
154 :
155 :
156 : /**
157 : * Run the "POST /reserves" CMD.
158 : *
159 : * @param cls closure.
160 : * @param cmd command being run now.
161 : * @param is interpreter state.
162 : */
163 : static void
164 0 : post_reserves_run (void *cls,
165 : const struct TALER_TESTING_Command *cmd,
166 : struct TALER_TESTING_Interpreter *is)
167 : {
168 0 : struct PostReservesState *prs = cls;
169 :
170 0 : prs->is = is;
171 0 : prs->prh = TALER_MERCHANT_reserves_post (is->ctx,
172 : prs->merchant_url,
173 0 : &prs->initial_balance,
174 : prs->exchange_url,
175 : prs->wire_method,
176 : &post_reserves_cb,
177 : prs);
178 0 : GNUNET_assert (NULL != prs->prh);
179 0 : }
180 :
181 :
182 : /**
183 : * Run the fake "POST /reserves" CMD.
184 : *
185 : * @param cls closure.
186 : * @param cmd command being run now.
187 : * @param is interpreter state.
188 : */
189 : static void
190 0 : post_reserves_fake_run (void *cls,
191 : const struct TALER_TESTING_Command *cmd,
192 : struct TALER_TESTING_Interpreter *is)
193 : {
194 0 : struct PostReservesState *prs = cls;
195 : struct TALER_ReservePrivateKeyP reserve_priv;
196 :
197 0 : prs->is = is;
198 0 : GNUNET_CRYPTO_eddsa_key_create (&reserve_priv.eddsa_priv);
199 0 : GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv.eddsa_priv,
200 : &prs->reserve_pub.eddsa_pub);
201 :
202 0 : GNUNET_assert (GNUNET_OK == TALER_string_to_amount ("EUR:100.00",
203 : &prs->initial_balance));
204 0 : TALER_TESTING_interpreter_next (prs->is);
205 0 : }
206 :
207 :
208 : /**
209 : * Free the state of a "POST /reserves" CMD, and possibly
210 : * cancel a pending operation thereof.
211 : *
212 : * @param cls closure.
213 : * @param cmd command being run.
214 : */
215 : static void
216 0 : post_reserves_cleanup (void *cls,
217 : const struct TALER_TESTING_Command *cmd)
218 : {
219 0 : struct PostReservesState *prs = cls;
220 :
221 0 : if (NULL != prs->prh)
222 : {
223 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
224 : "POST /reserves operation did not complete\n");
225 0 : TALER_MERCHANT_reserves_post_cancel (prs->prh);
226 : }
227 0 : GNUNET_free (prs);
228 0 : }
229 :
230 :
231 : struct TALER_TESTING_Command
232 0 : TALER_TESTING_cmd_merchant_post_reserves (const char *label,
233 : const char *merchant_url,
234 : const char *initial_balance,
235 : const char *exchange_url,
236 : const char *wire_method,
237 : unsigned int http_status)
238 : {
239 : struct PostReservesState *prs;
240 :
241 0 : prs = GNUNET_new (struct PostReservesState);
242 0 : prs->merchant_url = merchant_url;
243 0 : prs->exchange_url = exchange_url;
244 0 : prs->wire_method = wire_method;
245 0 : prs->http_status = http_status;
246 0 : GNUNET_assert (GNUNET_OK ==
247 : TALER_string_to_amount (initial_balance,
248 : &prs->initial_balance));
249 : {
250 0 : struct TALER_TESTING_Command cmd = {
251 : .cls = prs,
252 : .label = label,
253 : .run = &post_reserves_run,
254 : .cleanup = &post_reserves_cleanup,
255 : .traits = &post_reserves_traits
256 : };
257 :
258 0 : return cmd;
259 : }
260 : }
261 :
262 :
263 : struct TALER_TESTING_Command
264 0 : TALER_TESTING_cmd_merchant_post_reserves_fake (const char *label)
265 : {
266 : struct PostReservesState *prs;
267 :
268 0 : prs = GNUNET_new (struct PostReservesState);
269 : {
270 0 : struct TALER_TESTING_Command cmd = {
271 : .cls = prs,
272 : .label = label,
273 : .run = &post_reserves_fake_run,
274 : .cleanup = &post_reserves_cleanup,
275 : .traits = &post_reserves_traits
276 : };
277 :
278 0 : return cmd;
279 : }
280 : }
|