Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2024 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 : /**
21 : * @file testing_api_cmd_post_tokenfamilies.c
22 : * @brief command to run POST /tokenfamilies
23 : * @author Christian Blättler
24 : */
25 : #include "platform.h"
26 : #include <gnunet/gnunet_time_lib.h>
27 : #include <taler/taler_exchange_service.h>
28 : #include <taler/taler_testing_lib.h>
29 : #include "taler_merchant_service.h"
30 : #include "taler_merchant_testing_lib.h"
31 :
32 :
33 : /**
34 : * State of a "POST /tokenfamilies" CMD.
35 : */
36 : struct PostTokenFamiliesState
37 : {
38 :
39 : /**
40 : * Expected status code.
41 : */
42 : unsigned int http_status;
43 :
44 : /**
45 : * Handle for a "POST /tokenfamilies" request.
46 : */
47 : struct TALER_MERCHANT_TokenFamiliesPostHandle *handle;
48 :
49 : /**
50 : * The interpreter state.
51 : */
52 : struct TALER_TESTING_Interpreter *is;
53 :
54 : /**
55 : * Base URL of the merchant serving the request.
56 : */
57 : const char *merchant_url;
58 :
59 : /**
60 : * Slug of the token family.
61 : */
62 : const char *slug;
63 :
64 : /**
65 : * Name of the token family.
66 : */
67 : const char *name;
68 :
69 : /**
70 : * Description of the token family.
71 : */
72 : const char *description;
73 :
74 : /**
75 : * Map from IETF BCP 47 language tags to localized descriptions.
76 : */
77 : json_t *description_i18n;
78 :
79 : /**
80 : * Start of the validity period.
81 : */
82 : struct GNUNET_TIME_Timestamp valid_after;
83 :
84 : /**
85 : * End of the validity period.
86 : */
87 : struct GNUNET_TIME_Timestamp valid_before;
88 :
89 : /**
90 : * Validity duation of issued tokens of this family.
91 : */
92 : struct GNUNET_TIME_Relative duration;
93 :
94 : /**
95 : * Rounding duation of token family.
96 : */
97 : struct GNUNET_TIME_Relative rounding;
98 :
99 : /**
100 : * Kind of the token family. "subscription" or "discount".
101 : */
102 : const char *kind;
103 : };
104 :
105 :
106 : /**
107 : * Callback for a POST /tokenfamilies operation.
108 : *
109 : * @param cls closure for this function
110 : * @param hr response being processed
111 : */
112 : static void
113 4 : post_tokenfamilies_cb (void *cls,
114 : const struct TALER_MERCHANT_HttpResponse *hr)
115 : {
116 4 : struct PostTokenFamiliesState *state = cls;
117 :
118 4 : state->handle = NULL;
119 4 : if (state->http_status != hr->http_status)
120 : {
121 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
122 : "Unexpected response code %u (%d) to command %s\n",
123 : hr->http_status,
124 : (int) hr->ec,
125 : TALER_TESTING_interpreter_get_current_label (state->is));
126 0 : TALER_TESTING_interpreter_fail (state->is);
127 0 : return;
128 : }
129 4 : switch (hr->http_status)
130 : {
131 4 : case MHD_HTTP_NO_CONTENT:
132 4 : break;
133 0 : case MHD_HTTP_UNAUTHORIZED:
134 0 : break;
135 0 : case MHD_HTTP_FORBIDDEN:
136 0 : break;
137 0 : case MHD_HTTP_NOT_FOUND:
138 0 : break;
139 0 : default:
140 0 : GNUNET_break (0);
141 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
142 : "Unhandled HTTP status %u for POST /tokenfamilies.\n",
143 : hr->http_status);
144 : }
145 4 : TALER_TESTING_interpreter_next (state->is);
146 : }
147 :
148 :
149 : /**
150 : * Run the "POST /tokenfamilies" CMD.
151 : *
152 : *
153 : * @param cls closure.
154 : * @param cmd command being run now.
155 : * @param is interpreter state.
156 : */
157 : static void
158 4 : post_tokenfamilies_run (void *cls,
159 : const struct TALER_TESTING_Command *cmd,
160 : struct TALER_TESTING_Interpreter *is)
161 : {
162 4 : struct PostTokenFamiliesState *state = cls;
163 :
164 4 : state->is = is;
165 4 : state->handle = TALER_MERCHANT_token_families_post (
166 : TALER_TESTING_interpreter_get_context (is),
167 : state->merchant_url,
168 : state->slug,
169 : state->name,
170 : state->description,
171 4 : state->description_i18n,
172 : NULL, /* extra data */
173 : state->valid_after,
174 : state->valid_before,
175 : state->duration,
176 : state->rounding,
177 4 : GNUNET_TIME_UNIT_ZERO, /* start_offset */
178 : state->kind,
179 : &post_tokenfamilies_cb,
180 : state);
181 4 : GNUNET_assert (NULL != state->handle);
182 4 : }
183 :
184 :
185 : /**
186 : * Offers information from the "POST /tokenfamilies" CMD state to other
187 : * commands.
188 : *
189 : * @param cls closure
190 : * @param[out] ret result (could be anything)
191 : * @param trait name of the trait
192 : * @param index index number of the object to extract.
193 : * @return #GNUNET_OK on success
194 : */
195 : static enum GNUNET_GenericReturnValue
196 0 : post_tokenfamilies_traits (void *cls,
197 : const void **ret,
198 : const char *trait,
199 : unsigned int index)
200 : {
201 0 : struct PostTokenFamiliesState *state = cls;
202 : struct TALER_TESTING_Trait traits[] = {
203 0 : TALER_TESTING_make_trait_token_family_slug (state->slug),
204 0 : TALER_TESTING_make_trait_timestamp (0,
205 0 : &state->valid_after),
206 0 : TALER_TESTING_make_trait_timestamp (1,
207 0 : &state->valid_before),
208 0 : TALER_TESTING_make_trait_token_family_duration (&state->duration),
209 0 : TALER_TESTING_make_trait_token_family_kind (state->kind),
210 0 : TALER_TESTING_trait_end ()
211 : };
212 :
213 0 : return TALER_TESTING_get_trait (traits,
214 : ret,
215 : trait,
216 : index);
217 : }
218 :
219 :
220 : /**
221 : * Free the state of a "POST /tokenfamilies" CMD, and possibly
222 : * cancel a pending operation thereof.
223 : *
224 : * @param cls closure.
225 : * @param cmd command being run.
226 : */
227 : static void
228 4 : post_tokenfamilies_cleanup (void *cls,
229 : const struct TALER_TESTING_Command *cmd)
230 : {
231 4 : struct PostTokenFamiliesState *state = cls;
232 :
233 4 : if (NULL != state->handle)
234 : {
235 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
236 : "POST /tokenfamilies operation did not complete\n");
237 0 : TALER_MERCHANT_token_families_post_cancel (state->handle);
238 : }
239 4 : json_decref (state->description_i18n);
240 4 : GNUNET_free (state);
241 4 : }
242 :
243 :
244 : struct TALER_TESTING_Command
245 4 : TALER_TESTING_cmd_merchant_post_tokenfamilies (
246 : const char *label,
247 : const char *merchant_url,
248 : unsigned int http_status,
249 : const char *slug,
250 : const char *name,
251 : const char *description,
252 : json_t *description_i18n,
253 : struct GNUNET_TIME_Timestamp valid_after,
254 : struct GNUNET_TIME_Timestamp valid_before,
255 : struct GNUNET_TIME_Relative duration,
256 : struct GNUNET_TIME_Relative rounding,
257 : const char *kind) /* "subscription" or "discount" */
258 : {
259 : struct PostTokenFamiliesState *state;
260 :
261 4 : GNUNET_assert ((NULL == description_i18n) ||
262 : json_is_object (description_i18n));
263 4 : state = GNUNET_new (struct PostTokenFamiliesState);
264 4 : state->merchant_url = merchant_url;
265 4 : state->http_status = http_status;
266 4 : state->slug = slug;
267 4 : state->name = name;
268 4 : state->description = description;
269 4 : state->description_i18n = description_i18n; /* ownership taken */
270 4 : state->valid_after = valid_after;
271 4 : state->valid_before = valid_before;
272 4 : state->duration = duration;
273 4 : state->rounding = rounding;
274 4 : state->kind = kind;
275 : {
276 4 : struct TALER_TESTING_Command cmd = {
277 : .cls = state,
278 : .label = label,
279 : .run = &post_tokenfamilies_run,
280 : .cleanup = &post_tokenfamilies_cleanup,
281 : .traits = &post_tokenfamilies_traits
282 : };
283 :
284 4 : return cmd;
285 : }
286 : }
|