1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * This program is free software: you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
10 * for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 */
16
17 #include <stdlib.h>
18 #include <libecal/libecal.h>
19
20 #include "e-test-server-utils.h"
21
22 static ETestServerClosure cal_closure =
23 { E_TEST_SERVER_CALENDAR, NULL, E_CAL_CLIENT_SOURCE_TYPE_EVENTS };
24
25 #define NB_COMPONENTS 5
26
27 static void
test_icomps(ICalComponent * icomp1,ICalComponent * icomp2)28 test_icomps (ICalComponent *icomp1,
29 ICalComponent *icomp2)
30 {
31 ICalTime *t1, *t2;
32
33 if (!icomp2)
34 g_error ("Failure: get object returned NULL");
35
36 g_assert_cmpstr (i_cal_component_get_uid (icomp1), ==, i_cal_component_get_uid (icomp2));
37 g_assert_cmpstr (i_cal_component_get_summary (icomp1), ==, i_cal_component_get_summary (icomp2));
38
39 t1 = i_cal_component_get_dtstart (icomp1);
40 t2 = i_cal_component_get_dtstart (icomp2);
41
42 if (i_cal_time_compare (t1, t2) != 0) {
43 gchar *str1, *str2;
44
45 str1 = i_cal_time_as_ical_string (t1);
46 str2 = i_cal_time_as_ical_string (t2);
47
48 g_error ("Failure: dtend doesn't match, expected '%s', got '%s'\n", str1, str2);
49
50 g_free (str1);
51 g_free (str2);
52 }
53
54 g_clear_object (&t1);
55 g_clear_object (&t2);
56
57 t1 = i_cal_component_get_dtend (icomp1);
58 t2 = i_cal_component_get_dtend (icomp2);
59
60 if (i_cal_time_compare (t1, t2) != 0) {
61 gchar *str1, *str2;
62
63 str1 = i_cal_time_as_ical_string (t1);
64 str2 = i_cal_time_as_ical_string (t2);
65
66 g_error ("Failure: dtend doesn't match, expected '%s', got '%s'\n", str1, str2);
67
68 g_free (str1);
69 g_free (str2);
70 }
71
72 g_clear_object (&t1);
73 g_clear_object (&t2);
74 }
75
76 static void
check_removed(ECalClient * cal_client,const GSList * uids)77 check_removed (ECalClient *cal_client,
78 const GSList *uids)
79 {
80 g_assert (cal_client != NULL);
81 g_assert (uids != NULL);
82
83 while (uids) {
84 GError *error = NULL;
85 ICalComponent *icomp = NULL;
86
87 if (!e_cal_client_get_object_sync (cal_client, uids->data, NULL, &icomp, NULL, &error) &&
88 g_error_matches (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) {
89 g_clear_error (&error);
90 } else if (error) {
91 g_error ("check objects removed sync: %s", error->message);
92 g_clear_error (&error);
93 } else {
94 g_clear_object (&icomp);
95
96 g_error ("check objects removed sync: object found in the backend");
97 }
98
99 uids = uids->next;
100 }
101 }
102
103 static GSList *
uid_slist_to_ecalcomponentid_slist(GSList * uids)104 uid_slist_to_ecalcomponentid_slist (GSList *uids)
105 {
106 GSList *ids = NULL;
107 const GSList *l;
108
109 for (l = uids; l; l = l->next) {
110 ids = g_slist_append (ids, e_cal_component_id_new (l->data, NULL));
111 }
112
113 return ids;
114 }
115
116 static void
check_icomps_exist(ECalClient * cal_client,GSList * icomps)117 check_icomps_exist (ECalClient *cal_client,
118 GSList *icomps)
119 {
120 GSList *link;
121
122 for (link = icomps; link; link = g_slist_next (link)) {
123 GError *error = NULL;
124 ICalComponent *icomp = link->data;
125 ICalComponent *icomp2 = NULL;
126 const gchar *uid = i_cal_component_get_uid (icomp);
127
128 if (!e_cal_client_get_object_sync (cal_client, uid, NULL, &icomp2, NULL, &error))
129 g_error ("get object sync: %s", error->message);
130
131 g_assert_nonnull (icomp2);
132
133 test_icomps (icomp, icomp2);
134
135 g_object_unref (icomp2);
136 }
137 }
138
139 static void
test_bulk_methods_sync(ECalClient * cal_client,GSList * icomps)140 test_bulk_methods_sync (ECalClient *cal_client,
141 GSList *icomps)
142 {
143 GError *error = NULL;
144 GSList *uids = NULL, *ids = NULL;
145 const GSList *lcomp, *luid;
146 gint i = 0;
147
148 g_assert_nonnull (icomps);
149
150 /* Create all the objects in bulk */
151 if (!e_cal_client_create_objects_sync (cal_client, icomps, E_CAL_OPERATION_FLAG_NONE, &uids, NULL, &error))
152 g_error ("create objects sync: %s", error->message);
153
154 g_assert (uids != NULL);
155 g_assert_cmpint (g_slist_length (uids), ==, NB_COMPONENTS);
156
157 /* Update ICalComponents uids */
158 luid = uids;
159 lcomp = icomps;
160 while (luid && lcomp) {
161 i_cal_component_set_uid (lcomp->data, luid->data);
162 luid = luid->next;
163 lcomp = lcomp->next;
164 }
165
166 /* Retrieve all the objects and check that they are the same */
167 check_icomps_exist (cal_client, icomps);
168
169 /* Modify the objects */
170 for (lcomp = icomps; lcomp; lcomp = lcomp->next) {
171 gchar *summary;
172 ICalComponent *icomp = lcomp->data;
173
174 summary = g_strdup_printf ("Edited test summary %d", i);
175 i_cal_component_set_summary (icomp, summary);
176
177 g_free (summary);
178 ++i;
179 }
180
181 /* Save the modified objects in bulk */
182 if (!e_cal_client_modify_objects_sync (cal_client, icomps, E_CAL_OBJ_MOD_ALL, E_CAL_OPERATION_FLAG_NONE, NULL, &error))
183 g_error ("modify objects sync: %s", error->message);
184
185 /* Retrieve all the objects and check that they have been modified */
186 check_icomps_exist (cal_client, icomps);
187
188 /* Remove all the objects in bulk */
189 ids = uid_slist_to_ecalcomponentid_slist (uids);
190
191 if (!e_cal_client_remove_objects_sync (cal_client, ids, E_CAL_OBJ_MOD_ALL, E_CAL_OPERATION_FLAG_NONE, NULL, &error))
192 g_error ("remove objects sync: %s", error->message);
193
194 g_slist_free_full (ids, e_cal_component_id_free);
195
196 /* Check that the objects don't exist anymore */
197 check_removed (cal_client, uids);
198
199 g_slist_free_full (uids, g_free);
200 }
201
202 typedef struct _AsyncContext {
203 ECalClient *cal_client;
204 GSList *icomps; /* ICalComponent * */
205 GSList *ids; /* ECalComponentId * */
206 GSList *uids; /* gchar * */
207 GMainLoop *main_loop;
208 } AsyncContext;
209
210 static void
bulk_async_remove_objects_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)211 bulk_async_remove_objects_cb (GObject *source_object,
212 GAsyncResult *result,
213 gpointer user_data)
214 {
215 AsyncContext *async_context = user_data;
216 gboolean success;
217 GError *error = NULL;
218
219 g_assert_nonnull (async_context);
220 g_assert (E_IS_CAL_CLIENT (source_object));
221 g_assert (async_context->cal_client == E_CAL_CLIENT (source_object));
222
223 success = e_cal_client_remove_objects_finish (async_context->cal_client, result, &error);
224 g_assert_no_error (error);
225 g_assert (success);
226
227 /* Check that the objects don't exist anymore */
228 check_removed (async_context->cal_client, async_context->uids);
229
230 g_main_loop_quit (async_context->main_loop);
231 }
232
233 static void
bulk_async_modify_objects_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)234 bulk_async_modify_objects_cb (GObject *source_object,
235 GAsyncResult *result,
236 gpointer user_data)
237 {
238 AsyncContext *async_context = user_data;
239 gboolean success;
240 GError *error = NULL;
241
242 g_assert_nonnull (async_context);
243 g_assert (E_IS_CAL_CLIENT (source_object));
244 g_assert (async_context->cal_client == E_CAL_CLIENT (source_object));
245
246 success = e_cal_client_modify_objects_finish (async_context->cal_client, result, &error);
247 g_assert_no_error (error);
248 g_assert (success);
249
250 /* Retrieve all the objects and check that they have been modified */
251 check_icomps_exist (async_context->cal_client, async_context->icomps);
252
253 /* Remove all the objects in bulk */
254 async_context->ids = uid_slist_to_ecalcomponentid_slist (async_context->uids);
255
256 e_cal_client_remove_objects (async_context->cal_client, async_context->ids, E_CAL_OBJ_MOD_ALL, E_CAL_OPERATION_FLAG_NONE,
257 NULL, bulk_async_remove_objects_cb, async_context);
258 }
259
260 static void
bulk_async_create_objects_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)261 bulk_async_create_objects_cb (GObject *source_object,
262 GAsyncResult *result,
263 gpointer user_data)
264 {
265 AsyncContext *async_context = user_data;
266 GSList *luid, *lcomp;
267 gboolean success;
268 gint ii;
269 GError *error = NULL;
270
271 g_assert_nonnull (async_context);
272 g_assert (E_IS_CAL_CLIENT (source_object));
273 g_assert (async_context->cal_client == E_CAL_CLIENT (source_object));
274
275 success = e_cal_client_create_objects_finish (async_context->cal_client, result, &async_context->uids, &error);
276 g_assert_no_error (error);
277 g_assert (success);
278 g_assert_nonnull (async_context->uids);
279 g_assert_cmpint (g_slist_length (async_context->uids), ==, NB_COMPONENTS);
280
281 /* Update ICalComponents uids */
282 for (luid = async_context->uids, lcomp = async_context->icomps;
283 luid && lcomp;
284 luid = g_slist_next (luid), lcomp = g_slist_next (lcomp)) {
285 i_cal_component_set_uid (lcomp->data, luid->data);
286 }
287
288 /* Retrieve all the objects and check that they are the same */
289 check_icomps_exist (async_context->cal_client, async_context->icomps);
290
291 /* Modify the objects */
292 for (ii = 0, lcomp = async_context->icomps; lcomp; ii++, lcomp = g_slist_next (lcomp)) {
293 gchar *summary;
294 ICalComponent *icomp = lcomp->data;
295
296 summary = g_strdup_printf ("Edited test summary %d", ii);
297 i_cal_component_set_summary (icomp, summary);
298
299 g_free (summary);
300 }
301
302 e_cal_client_modify_objects (async_context->cal_client, async_context->icomps, E_CAL_OBJ_MOD_ALL, E_CAL_OPERATION_FLAG_NONE,
303 NULL, bulk_async_modify_objects_cb, async_context);
304 }
305
306 static void
test_bulk_methods_async(ECalClient * cal_client,GSList * icomps)307 test_bulk_methods_async (ECalClient *cal_client,
308 GSList *icomps)
309 {
310 AsyncContext async_context;
311
312 g_assert_nonnull (icomps);
313
314 async_context.cal_client = cal_client;
315 async_context.icomps = icomps;
316 async_context.ids = NULL;
317 async_context.uids = NULL;
318 async_context.main_loop = g_main_loop_new (NULL, FALSE);
319
320 e_cal_client_create_objects (async_context.cal_client, async_context.icomps, E_CAL_OPERATION_FLAG_NONE, NULL,
321 bulk_async_create_objects_cb, &async_context);
322
323 g_main_loop_run (async_context.main_loop);
324
325 g_slist_free_full (async_context.ids, e_cal_component_id_free);
326 g_slist_free_full (async_context.uids, g_free);
327 g_main_loop_unref (async_context.main_loop);
328 }
329
330 static void
run_test_bulk_methods_wrapper(ETestServerFixture * fixture,void (* func)(ECalClient * cal_client,GSList * icomps))331 run_test_bulk_methods_wrapper (ETestServerFixture *fixture,
332 void (* func)(ECalClient *cal_client,
333 GSList *icomps))
334 {
335 ECalClient *cal_client;
336 GSList *icomps = NULL;
337 ICalTime *dtstart, *dtend;
338 gint ii;
339
340 cal_client = E_TEST_SERVER_UTILS_SERVICE (fixture, ECalClient);
341
342 dtstart = i_cal_time_new_current_with_zone (i_cal_timezone_get_utc_timezone ());
343 dtend = i_cal_time_clone (dtstart);
344 i_cal_time_adjust (dtend, 0, 1, 0, 0);
345
346 /* Build up new components */
347 for (ii = 0; ii < NB_COMPONENTS; ++ii) {
348 ICalComponent *icomp;
349 gchar *summary;
350
351 icomp = i_cal_component_new (I_CAL_VEVENT_COMPONENT);
352 summary = g_strdup_printf ("Test summary %d", ii);
353 i_cal_component_set_summary (icomp, summary);
354 i_cal_component_set_dtstart (icomp, dtstart);
355 i_cal_component_set_dtend (icomp, dtend);
356
357 icomps = g_slist_append (icomps, icomp);
358 g_free (summary);
359 }
360
361 g_clear_object (&dtstart);
362 g_clear_object (&dtend);
363
364 /* Test synchronous bulk methods */
365 func (cal_client, icomps);
366
367 g_slist_free_full (icomps, g_object_unref);
368 }
369
370 static void
run_test_bulk_methods_sync(ETestServerFixture * fixture,gconstpointer user_data)371 run_test_bulk_methods_sync (ETestServerFixture *fixture,
372 gconstpointer user_data)
373 {
374 run_test_bulk_methods_wrapper (fixture, test_bulk_methods_sync);
375 }
376
377 static void
run_test_bulk_methods_async(ETestServerFixture * fixture,gconstpointer user_data)378 run_test_bulk_methods_async (ETestServerFixture *fixture,
379 gconstpointer user_data)
380 {
381 run_test_bulk_methods_wrapper (fixture, test_bulk_methods_async);
382 }
383
384 gint
main(gint argc,gchar ** argv)385 main (gint argc,
386 gchar **argv)
387 {
388 g_test_init (&argc, &argv, NULL);
389 g_test_bug_base ("http://bugzilla.gnome.org/");
390
391 g_test_add (
392 "/ECalClient/BulkMethods/Sync",
393 ETestServerFixture,
394 &cal_closure,
395 e_test_server_utils_setup,
396 run_test_bulk_methods_sync,
397 e_test_server_utils_teardown);
398 g_test_add (
399 "/ECalClient/BulkMethods/Async",
400 ETestServerFixture,
401 &cal_closure,
402 e_test_server_utils_setup,
403 run_test_bulk_methods_async,
404 e_test_server_utils_teardown);
405
406 return e_test_server_utils_run (argc, argv);
407 }
408