Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2025 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 src/testing/testing_api_cmd_post_categories.c
18 : * @brief command to test POST /private/categories
19 : * @author Bohdan Potuzhnyi
20 : */
21 : #include "platform.h"
22 : struct PostCategoriesState;
23 : #define TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE struct PostCategoriesState
24 : #include <jansson.h>
25 : #include <microhttpd.h>
26 : #include <taler/taler_testing_lib.h>
27 : #include "taler/taler_merchant_service.h"
28 : #include "taler/taler_merchant_testing_lib.h"
29 : #include <taler/merchant/post-private-categories.h>
30 :
31 : /**
32 : * State of a "POST /private/categories" CMD.
33 : */
34 : struct PostCategoriesState
35 : {
36 : /**
37 : * Handle for a "POST /private/categories" request.
38 : */
39 : struct TALER_MERCHANT_PostPrivateCategoriesHandle *cph;
40 :
41 : /**
42 : * The interpreter state.
43 : */
44 : struct TALER_TESTING_Interpreter *is;
45 :
46 : /**
47 : * Base URL of the merchant serving the request.
48 : */
49 : const char *merchant_url;
50 :
51 : /**
52 : * Category name.
53 : */
54 : const char *name;
55 :
56 : /**
57 : * Category name translations.
58 : */
59 : json_t *name_i18n;
60 :
61 : /**
62 : * Expected HTTP response code.
63 : */
64 : unsigned int http_status;
65 :
66 : /**
67 : * Expected category id (0 to ignore).
68 : */
69 : uint64_t expected_category_id;
70 :
71 : /**
72 : * Category id returned by the backend.
73 : */
74 : uint64_t category_id;
75 : };
76 :
77 : /**
78 : * Callback for POST /private/categories.
79 : *
80 : * @param cls closure
81 : * @param cpr response details
82 : */
83 : static void
84 6 : post_categories_cb (struct PostCategoriesState *pcs,
85 : const struct TALER_MERCHANT_PostPrivateCategoriesResponse *
86 : cpr)
87 : {
88 :
89 6 : pcs->cph = NULL;
90 6 : if (pcs->http_status != cpr->hr.http_status)
91 : {
92 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
93 : "Unexpected response code %u (%d) to command %s\n",
94 : cpr->hr.http_status,
95 : (int) cpr->hr.ec,
96 : TALER_TESTING_interpreter_get_current_label (pcs->is));
97 0 : TALER_TESTING_interpreter_fail (pcs->is);
98 0 : return;
99 : }
100 6 : if (MHD_HTTP_OK == cpr->hr.http_status)
101 : {
102 6 : pcs->category_id = cpr->details.ok.category_id;
103 6 : if ( (0 != pcs->expected_category_id) &&
104 6 : (pcs->expected_category_id != pcs->category_id) )
105 : {
106 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
107 : "Unexpected category_id %lu (expected %lu)\n",
108 : pcs->category_id,
109 : pcs->expected_category_id);
110 0 : TALER_TESTING_interpreter_fail (pcs->is);
111 0 : return;
112 : }
113 : }
114 6 : TALER_TESTING_interpreter_next (pcs->is);
115 : }
116 :
117 :
118 : /**
119 : * Run the "POST /private/categories" CMD.
120 : *
121 : * @param cls closure.
122 : * @param cmd command being run now.
123 : * @param is interpreter state.
124 : */
125 : static void
126 6 : post_categories_run (void *cls,
127 : const struct TALER_TESTING_Command *cmd,
128 : struct TALER_TESTING_Interpreter *is)
129 : {
130 6 : struct PostCategoriesState *pcs = cls;
131 :
132 6 : pcs->is = is;
133 6 : pcs->cph = TALER_MERCHANT_post_private_categories_create (
134 : TALER_TESTING_interpreter_get_context (is),
135 : pcs->merchant_url,
136 : pcs->name);
137 6 : if (NULL != pcs->name_i18n)
138 : {
139 6 : TALER_MERCHANT_post_private_categories_set_options (
140 : pcs->cph,
141 : TALER_MERCHANT_post_private_categories_option_name_i18n (
142 : pcs->name_i18n));
143 : }
144 : {
145 : enum TALER_ErrorCode ec;
146 :
147 6 : ec = TALER_MERCHANT_post_private_categories_start (pcs->cph,
148 : &post_categories_cb,
149 : pcs);
150 6 : GNUNET_assert (TALER_EC_NONE == ec);
151 : }
152 6 : }
153 :
154 :
155 : /**
156 : * Offer internal data to other commands.
157 : *
158 : * @param cls closure
159 : * @param[out] ret result
160 : * @param trait name of the trait
161 : * @param index index number of the object to extract.
162 : * @return #GNUNET_OK on success
163 : */
164 : static enum GNUNET_GenericReturnValue
165 0 : post_categories_traits (void *cls,
166 : const void **ret,
167 : const char *trait,
168 : unsigned int index)
169 : {
170 0 : struct PostCategoriesState *pcs = cls;
171 : struct TALER_TESTING_Trait traits[] = {
172 0 : TALER_TESTING_make_trait_category_id (&pcs->category_id),
173 0 : TALER_TESTING_trait_end ()
174 : };
175 :
176 0 : return TALER_TESTING_get_trait (traits,
177 : ret,
178 : trait,
179 : index);
180 : }
181 :
182 :
183 : /**
184 : * Free the state of a "POST /private/categories" CMD, and possibly
185 : * cancel a pending operation thereof.
186 : *
187 : * @param cls closure.
188 : * @param cmd command being run.
189 : */
190 : static void
191 6 : post_categories_cleanup (void *cls,
192 : const struct TALER_TESTING_Command *cmd)
193 : {
194 6 : struct PostCategoriesState *pcs = cls;
195 :
196 6 : if (NULL != pcs->cph)
197 : {
198 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
199 : "POST /private/categories operation did not complete\n");
200 0 : TALER_MERCHANT_post_private_categories_cancel (pcs->cph);
201 : }
202 6 : json_decref (pcs->name_i18n);
203 6 : GNUNET_free (pcs);
204 6 : }
205 :
206 :
207 : struct TALER_TESTING_Command
208 6 : TALER_TESTING_cmd_merchant_post_categories (
209 : const char *label,
210 : const char *merchant_url,
211 : const char *name,
212 : json_t *name_i18n,
213 : uint64_t expected_category_id,
214 : unsigned int http_status)
215 : {
216 : struct PostCategoriesState *pcs;
217 :
218 6 : GNUNET_assert ((NULL == name_i18n) ||
219 : json_is_object (name_i18n));
220 6 : pcs = GNUNET_new (struct PostCategoriesState);
221 6 : pcs->merchant_url = merchant_url;
222 6 : pcs->name = name;
223 6 : pcs->name_i18n = name_i18n; /* ownership taken */
224 6 : pcs->http_status = http_status;
225 6 : pcs->expected_category_id = expected_category_id;
226 : {
227 6 : struct TALER_TESTING_Command cmd = {
228 : .cls = pcs,
229 : .label = label,
230 : .run = &post_categories_run,
231 : .cleanup = &post_categories_cleanup,
232 : .traits = &post_categories_traits
233 : };
234 :
235 6 : return cmd;
236 : }
237 : }
238 :
239 :
240 : /* end of testing_api_cmd_post_categories.c */
|