Coding style and whitespace cleanups.
[platform/upstream/evolution-data-server.git] / tests / libebook / client / client-test-utils.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 #include <stdio.h>
4
5 #include "client-test-utils.h"
6
7 void
8 report_error (const gchar *operation,
9               GError **error)
10 {
11         g_return_if_fail (operation != NULL);
12
13         g_printerr ("Failed to %s: %s\n", operation, (error && *error) ? (*error)->message : "Unknown error");
14
15         g_clear_error (error);
16 }
17
18 void
19 print_email (EContact *contact)
20 {
21         const gchar *file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS);
22         const gchar *name_or_org = e_contact_get_const (contact, E_CONTACT_NAME_OR_ORG);
23         GList *emails, *e;
24
25         g_print ("   Contact: %s\n", file_as);
26         g_print ("   Name or org: %s\n", name_or_org);
27         g_print ("   Email addresses:\n");
28         emails = e_contact_get (contact, E_CONTACT_EMAIL);
29         for (e = emails; e; e = e->next) {
30                 g_print ("\t%s\n",  (gchar *)e->data);
31         }
32         g_list_foreach (emails, (GFunc) g_free, NULL);
33         g_list_free (emails);
34
35         g_print ("\n");
36 }
37
38 EBookClient *
39 open_system_book (gboolean only_if_exists)
40 {
41         EBookClient *book_client;
42         GError *error = NULL;
43
44         main_initialize ();
45
46         book_client = e_book_client_new_system (&error);
47         if (error) {
48                 report_error ("create system addressbook", &error);
49                 return NULL;
50         }
51
52         if (!e_client_open_sync (E_CLIENT (book_client), only_if_exists, NULL, &error)) {
53                 g_object_unref (book_client);
54                 report_error ("open client sync", &error);
55                 return NULL;
56         }
57
58         return book_client;
59 }
60
61 void
62 main_initialize (void)
63 {
64         static gboolean initialized = FALSE;
65
66         if (initialized)
67                 return;
68
69         g_type_init ();
70         g_thread_init (NULL);
71
72         initialized = TRUE;
73 }
74
75 struct IdleData {
76         GThreadFunc func;
77         gpointer data;
78         gboolean run_in_thread; /* FALSE to run in idle callback */
79 };
80
81 static gboolean
82 idle_cb (gpointer data)
83 {
84         struct IdleData *idle = data;
85
86         g_return_val_if_fail (idle != NULL, FALSE);
87         g_return_val_if_fail (idle->func != NULL, FALSE);
88
89         if (idle->run_in_thread) {
90                 GError *error = NULL;
91
92                 g_thread_create (idle->func, idle->data, FALSE, &error);
93
94                 if (error) {
95                         report_error ("create thread", &error);
96                         stop_main_loop (1);
97                 }
98         } else {
99                 idle->func (idle->data);
100         }
101
102         g_free (idle);
103
104         return FALSE;
105 }
106
107 static GMainLoop *loop = NULL;
108 static gint main_stop_result = 0;
109
110 static void
111 do_start (GThreadFunc func,
112           gpointer data)
113 {
114         main_initialize ();
115
116         g_return_if_fail (loop == NULL);
117
118         loop = g_main_loop_new (NULL, FALSE);
119
120         if (func)
121                 func (data);
122
123         g_main_loop_run (loop);
124
125         g_main_loop_unref (loop);
126         loop = NULL;
127 }
128
129 /* Starts new main-loop, but just before that calls 'func'.
130  * Main-loop is kept running, and this function blocks,
131  * until call of stop_main_loop (). */
132 void
133 start_main_loop (GThreadFunc func,
134                  gpointer data)
135 {
136         g_return_if_fail (loop == NULL);
137
138         do_start (func, data);
139 }
140
141 /* Starts new main-loop and then invokes func in a new thread.
142  * Main-loop is kept running, and this function blocks,
143  * until call of stop_main_loop (). */
144 void
145 start_in_thread_with_main_loop (GThreadFunc func,
146                                 gpointer data)
147 {
148         struct IdleData *idle;
149
150         g_return_if_fail (func != NULL);
151         g_return_if_fail (loop == NULL);
152
153         main_initialize ();
154
155         idle = g_new0 (struct IdleData, 1);
156         idle->func = func;
157         idle->data = data;
158         idle->run_in_thread = TRUE;
159
160         g_idle_add (idle_cb, idle);
161
162         do_start (NULL, NULL);
163 }
164
165 /* Starts new main-loop and then invokes func in an idle callback.
166  * Main-loop is kept running, and this function blocks,
167  * until call of stop_main_loop (). */
168 void
169 start_in_idle_with_main_loop (GThreadFunc func,
170                               gpointer data)
171 {
172         struct IdleData *idle;
173
174         g_return_if_fail (func != NULL);
175         g_return_if_fail (loop == NULL);
176
177         main_initialize ();
178
179         idle = g_new0 (struct IdleData, 1);
180         idle->func = func;
181         idle->data = data;
182         idle->run_in_thread = FALSE;
183
184         g_idle_add (idle_cb, idle);
185
186         do_start (NULL, NULL);
187 }
188
189 /* Stops main-loop previously run by start_main_loop,
190  * start_in_thread_with_main_loop or start_in_idle_with_main_loop.
191 */
192 void
193 stop_main_loop (gint stop_result)
194 {
195         g_return_if_fail (loop != NULL);
196
197         main_stop_result = stop_result;
198         g_main_loop_quit (loop);
199 }
200
201 /* returns value used in stop_main_loop() */
202 gint
203 get_main_loop_stop_result (void)
204 {
205         return main_stop_result;
206 }
207
208 void
209 foreach_configured_source (void (*func) (ESource *source))
210 {
211         gpointer foreach_async_data;
212         ESource *source = NULL;
213
214         g_return_if_fail (func != NULL);
215
216         main_initialize ();
217
218         foreach_async_data = foreach_configured_source_async_start (&source);
219         if (!foreach_async_data)
220                 return;
221
222         do {
223                 func (source);
224         } while (foreach_configured_source_async_next (&foreach_async_data, &source));
225 }
226
227 struct ForeachConfiguredData
228 {
229         ESourceList *source_list;
230         GSList *current_group;
231         GSList *current_source;
232 };
233
234 gpointer
235 foreach_configured_source_async_start (ESource **source)
236 {
237         struct ForeachConfiguredData *async_data;
238         ESourceList *source_list = NULL;
239         GError *error = NULL;
240
241         g_return_val_if_fail (source != NULL, NULL);
242
243         main_initialize ();
244
245         if (!e_book_client_get_sources (&source_list, &error)) {
246                 report_error ("get addressbooks", &error);
247                 return NULL;
248         }
249
250         g_return_val_if_fail (source_list != NULL, NULL);
251
252         async_data = g_new0 (struct ForeachConfiguredData, 1);
253         async_data->source_list = source_list;
254         async_data->current_group = e_source_list_peek_groups (source_list);
255         if (!async_data->current_group) {
256                 gpointer ad = async_data;
257
258                 foreach_configured_source_async_next (&ad, source);
259                 return ad;
260         }
261
262         async_data->current_source = e_source_group_peek_sources (async_data->current_group->data);
263         if (!async_data->current_source) {
264                 gpointer ad = async_data;
265
266                 if (foreach_configured_source_async_next (&ad, source))
267                         return ad;
268
269                 return NULL;
270         }
271
272         *source = async_data->current_source->data;
273
274         return async_data;
275 }
276
277 gboolean
278 foreach_configured_source_async_next (gpointer *foreach_async_data,
279                                       ESource **source)
280 {
281         struct ForeachConfiguredData *async_data;
282
283         g_return_val_if_fail (foreach_async_data != NULL, FALSE);
284         g_return_val_if_fail (source != NULL, FALSE);
285
286         async_data = *foreach_async_data;
287         g_return_val_if_fail (async_data != NULL, FALSE);
288         g_return_val_if_fail (async_data->source_list != NULL, FALSE);
289         g_return_val_if_fail (async_data->current_group != NULL, FALSE);
290
291         if (async_data->current_source)
292                 async_data->current_source = async_data->current_source->next;
293         if (async_data->current_source) {
294                 *source = async_data->current_source->data;
295                 return TRUE;
296         }
297
298         do {
299                 async_data->current_group = async_data->current_group->next;
300                 if (async_data->current_group)
301                         async_data->current_source = e_source_group_peek_sources (async_data->current_group->data);
302         } while (async_data->current_group && !async_data->current_source);
303
304         if (async_data->current_source) {
305                 *source = async_data->current_source->data;
306                 return TRUE;
307         }
308
309         g_object_unref (async_data->source_list);
310         g_free (async_data);
311
312         *foreach_async_data = NULL;
313
314         return FALSE;
315 }
316
317 EBookClient *
318 new_temp_client (gchar **uri)
319 {
320         EBookClient *book_client;
321         ESource *source;
322         gchar *abs_uri, *filename;
323         gint handle;
324         GError *error = NULL;
325
326         filename = g_build_filename (g_get_tmp_dir (), "e-book-client-test-XXXXXX/", NULL);
327         handle = g_mkstemp (filename);
328
329         if (handle != -1)
330                 close (handle);
331
332         g_return_val_if_fail (g_mkdir_with_parents (filename, 0700) == 0, NULL);
333
334         abs_uri = g_strconcat ("local://", filename, NULL);
335         g_free (filename);
336
337         source = e_source_new_with_absolute_uri ("Test book", abs_uri);
338         if (uri)
339                 *uri = abs_uri;
340         else
341                 g_free (abs_uri);
342
343         g_return_val_if_fail (source != NULL, NULL);
344
345         book_client = e_book_client_new (source, &error);
346         g_object_unref (source);
347
348         if (error)
349                 report_error ("new temp client", &error);
350
351         return book_client;
352 }
353
354 gchar *
355 new_vcard_from_test_case (const gchar *case_name)
356 {
357         gchar *filename;
358         gchar *case_filename;
359         GFile * file;
360         GError *error = NULL;
361         gchar *vcard;
362
363         case_filename = g_strdup_printf ("%s.vcf", case_name);
364         filename = g_build_filename (SRCDIR, "..", "data", "vcards", case_filename, NULL);
365         file = g_file_new_for_path (filename);
366         if (!g_file_load_contents (file, NULL, &vcard, NULL, NULL, &error)) {
367                 g_warning ("failed to read test contact file '%s': %s",
368                                 filename, error->message);
369                 exit (1);
370         }
371
372         g_free (case_filename);
373         g_free (filename);
374         g_object_unref (file);
375
376         return vcard;
377 }
378
379 static gboolean
380 contacts_are_equal_shallow (EContact *a,
381                             EContact *b)
382 {
383         const gchar *uid_a, *uid_b;
384
385         /* Avoid warnings if one or more are NULL, to make this function
386          * "NULL-friendly" */
387         if (!a && !b)
388                 return TRUE;
389
390         if (!E_IS_CONTACT (a) || !E_IS_CONTACT (b))
391                 return FALSE;
392
393         uid_a = e_contact_get_const (a, E_CONTACT_UID);
394         uid_b = e_contact_get_const (b, E_CONTACT_UID);
395
396         return g_strcmp0 (uid_a, uid_b) == 0;
397 }
398
399 gboolean
400 add_contact_from_test_case_verify (EBookClient *book_client,
401                                    const gchar *case_name,
402                                    EContact **contact)
403 {
404         gchar *vcard;
405         EContact *contact_orig;
406         EContact *contact_final;
407         gchar *uid;
408         GError *error = NULL;
409
410         vcard = new_vcard_from_test_case (case_name);
411         contact_orig = e_contact_new_from_vcard (vcard);
412         g_free (vcard);
413         if (!e_book_client_add_contact_sync (book_client, contact_orig, &uid, NULL, &error)) {
414                 report_error ("add contact sync", &error);
415                 g_object_unref (contact_orig);
416                 return FALSE;
417         }
418
419         e_contact_set (contact_orig, E_CONTACT_UID, uid);
420
421         if (!e_book_client_get_contact_sync (book_client, uid, &contact_final, NULL, &error)) {
422                 report_error ("get contact sync", &error);
423                 g_object_unref (contact_orig);
424                 g_free (uid);
425                 return FALSE;
426         }
427
428         /* verify the contact was added "successfully" (not thorough) */
429         g_assert (contacts_are_equal_shallow (contact_orig, contact_final));
430
431         if (contact)
432                 *contact = contact_final;
433         else
434                 g_object_unref (contact_final);
435         g_object_unref (contact_orig);
436         g_free (uid);
437
438         return TRUE;
439 }
440
441 gboolean
442 add_contact_verify (EBookClient *book_client,
443                     EContact *contact)
444 {
445         EContact *contact_final;
446         gchar *uid;
447         GError *error = NULL;
448
449         if (!e_book_client_add_contact_sync (book_client, contact, &uid, NULL, &error)) {
450                 report_error ("add contact sync", &error);
451                 return FALSE;
452         }
453
454         e_contact_set (contact, E_CONTACT_UID, uid);
455
456         if (!e_book_client_get_contact_sync (book_client, uid, &contact_final, NULL, &error)) {
457                 report_error ("get contact sync", &error);
458                 g_free (uid);
459                 return FALSE;
460         }
461
462         /* verify the contact was added "successfully" (not thorough) */
463         g_assert (contacts_are_equal_shallow (contact, contact_final));
464
465         g_object_unref (contact_final);
466         g_free (uid);
467
468         return TRUE;
469 }