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