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_get_tips.c
21 : * @brief command to test GET /private/tips
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 : /**
32 : * State of a "GET tips" CMD.
33 : */
34 : struct GetTipsState
35 : {
36 :
37 : /**
38 : * Handle for a "GET tips" request.
39 : */
40 : struct TALER_MERCHANT_TipsGetHandle *tgh;
41 :
42 : /**
43 : * The interpreter state.
44 : */
45 : struct TALER_TESTING_Interpreter *is;
46 :
47 : /**
48 : * Base URL of the merchant serving the request.
49 : */
50 : const char *merchant_url;
51 :
52 : /**
53 : * Row to start querying the database from.
54 : */
55 : uint64_t offset;
56 :
57 : /**
58 : * How many rows to return (with direction).
59 : */
60 : int64_t limit;
61 :
62 : /**
63 : * Expected HTTP response code.
64 : */
65 : unsigned int http_status;
66 :
67 : /**
68 : * Length of @e tips.
69 : */
70 : unsigned int tips_length;
71 :
72 : /**
73 : * References to tips that we expect to be found.
74 : */
75 : const char **tips;
76 :
77 : };
78 :
79 : /**
80 : * Callback for a GET /private/tips operation.
81 : *
82 : * @param cls closure for this function
83 : * @param hr HTTP response details
84 : * @param tips_length length of the @a tips array
85 : * @param tips array of tips
86 : */
87 : static void
88 0 : get_tips_cb (void *cls,
89 : const struct TALER_MERCHANT_HttpResponse *hr,
90 : unsigned int tips_length,
91 : const struct TALER_MERCHANT_TipEntry tips[])
92 : {
93 0 : struct GetTipsState *gts = cls;
94 :
95 0 : gts->tgh = NULL;
96 0 : if (gts->http_status != hr->http_status)
97 : {
98 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
99 : "Unexpected response code %u (%d) to command %s\n",
100 : hr->http_status,
101 : (int) hr->ec,
102 : TALER_TESTING_interpreter_get_current_label (gts->is));
103 0 : TALER_TESTING_interpreter_fail (gts->is);
104 0 : return;
105 : }
106 0 : switch (hr->http_status)
107 : {
108 0 : case MHD_HTTP_OK:
109 0 : if (tips_length != gts->tips_length)
110 : {
111 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
112 : "Tips length does not match\n");
113 0 : TALER_TESTING_interpreter_fail (gts->is);
114 0 : return;
115 : }
116 0 : for (unsigned int i = 0; i < tips_length; ++i)
117 : {
118 : const struct TALER_TESTING_Command *tip_cmd;
119 :
120 0 : tip_cmd = TALER_TESTING_interpreter_lookup_command (
121 : gts->is,
122 0 : gts->tips[i]);
123 : {
124 : const struct TALER_TipIdentifierP *tip_id;
125 :
126 0 : if (GNUNET_OK !=
127 0 : TALER_TESTING_get_trait_tip_id (tip_cmd,
128 : &tip_id))
129 : {
130 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
131 : "Could not fetch tip id\n");
132 0 : TALER_TESTING_interpreter_fail (gts->is);
133 0 : return;
134 : }
135 0 : if (0 != GNUNET_memcmp (tip_id,
136 : &tips[i].tip_id))
137 : {
138 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
139 : "Tip id does not match\n");
140 0 : TALER_TESTING_interpreter_fail (gts->is);
141 0 : return;
142 : }
143 : }
144 : {
145 : const struct TALER_Amount *tip_amount;
146 :
147 0 : if (GNUNET_OK !=
148 0 : TALER_TESTING_get_trait_amount (tip_cmd,
149 : &tip_amount))
150 : {
151 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
152 : "Could not fetch tip amount\n");
153 0 : TALER_TESTING_interpreter_fail (gts->is);
154 0 : return;
155 : }
156 0 : if ((GNUNET_OK != TALER_amount_cmp_currency (tip_amount,
157 0 : &tips[i].tip_amount)) ||
158 0 : (0 != TALER_amount_cmp (tip_amount,
159 0 : &tips[i].tip_amount)))
160 : {
161 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
162 : "Tip amount does not match\n");
163 0 : TALER_TESTING_interpreter_fail (gts->is);
164 0 : return;
165 : }
166 : }
167 : }
168 0 : break;
169 0 : default:
170 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
171 : "Unhandled HTTP status.\n");
172 : }
173 0 : TALER_TESTING_interpreter_next (gts->is);
174 : }
175 :
176 :
177 : /**
178 : * Run the "GET /private/tips" CMD.
179 : *
180 : * @param cls closure.
181 : * @param cmd command being run now.
182 : * @param is interpreter state.
183 : */
184 : static void
185 0 : get_tips_run (void *cls,
186 : const struct TALER_TESTING_Command *cmd,
187 : struct TALER_TESTING_Interpreter *is)
188 : {
189 0 : struct GetTipsState *gts = cls;
190 :
191 0 : gts->is = is;
192 0 : gts->tgh = TALER_MERCHANT_tips_get2 (is->ctx,
193 : gts->merchant_url,
194 : TALER_EXCHANGE_YNA_NO,
195 : gts->limit,
196 : gts->offset,
197 : &get_tips_cb,
198 : gts);
199 :
200 0 : GNUNET_assert (NULL != gts->tgh);
201 0 : }
202 :
203 :
204 : /**
205 : * Free the state of a "GET tips" CMD, and possibly
206 : * cancel a pending operation thereof.
207 : *
208 : * @param cls closure.
209 : * @param cmd command being run.
210 : */
211 : static void
212 0 : get_tips_cleanup (void *cls,
213 : const struct TALER_TESTING_Command *cmd)
214 : {
215 0 : struct GetTipsState *gts = cls;
216 :
217 0 : if (NULL != gts->tgh)
218 : {
219 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
220 : "GET /private/tips operation did not complete\n");
221 0 : TALER_MERCHANT_tips_get_cancel (gts->tgh);
222 : }
223 0 : GNUNET_array_grow (gts->tips,
224 : gts->tips_length,
225 : 0);
226 0 : GNUNET_free (gts);
227 0 : }
228 :
229 :
230 : struct TALER_TESTING_Command
231 0 : TALER_TESTING_cmd_get_tips (const char *label,
232 : const char *merchant_url,
233 : unsigned int http_status,
234 : ...)
235 : {
236 : struct GetTipsState *gts;
237 :
238 0 : gts = GNUNET_new (struct GetTipsState);
239 0 : gts->merchant_url = merchant_url;
240 0 : gts->offset = INT64_MAX;
241 0 : gts->limit = -20;
242 0 : gts->http_status = http_status;
243 : {
244 : const char *clabel;
245 : va_list ap;
246 :
247 0 : va_start (ap, http_status);
248 0 : while (NULL != (clabel = va_arg (ap, const char *)))
249 : {
250 0 : GNUNET_array_append (gts->tips,
251 : gts->tips_length,
252 : clabel);
253 : }
254 0 : va_end (ap);
255 : }
256 : {
257 0 : struct TALER_TESTING_Command cmd = {
258 : .cls = gts,
259 : .label = label,
260 : .run = &get_tips_run,
261 : .cleanup = &get_tips_cleanup
262 : };
263 :
264 0 : return cmd;
265 : }
266 : }
267 :
268 :
269 : struct TALER_TESTING_Command
270 0 : TALER_TESTING_cmd_get_tips2 (const char *label,
271 : const char *merchant_url,
272 : uint64_t offset,
273 : int64_t limit,
274 : unsigned int http_status,
275 : ...)
276 : {
277 : struct GetTipsState *gts;
278 :
279 0 : gts = GNUNET_new (struct GetTipsState);
280 0 : gts->merchant_url = merchant_url;
281 0 : gts->offset = offset;
282 0 : gts->limit = limit;
283 0 : gts->http_status = http_status;
284 : {
285 : const char *clabel;
286 : va_list ap;
287 :
288 0 : va_start (ap, http_status);
289 0 : while (NULL != (clabel = va_arg (ap, const char *)))
290 : {
291 0 : GNUNET_array_append (gts->tips,
292 : gts->tips_length,
293 : clabel);
294 : }
295 0 : va_end (ap);
296 : }
297 : {
298 0 : struct TALER_TESTING_Command cmd = {
299 : .cls = gts,
300 : .label = label,
301 : .run = &get_tips_run,
302 : .cleanup = &get_tips_cleanup
303 : };
304 :
305 0 : return cmd;
306 : }
307 : }
308 :
309 :
310 : /* end of testing_api_cmd_get_tips.c */
|