Add e_book_client_view_ref_client().
[platform/upstream/evolution-data-server.git] / tests / libebook / client / test-client-photo-is-uri.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 #include <stdlib.h>
3 #include <libebook/libebook.h>
4
5 #include "client-test-utils.h"
6 #include "e-test-server-utils.h"
7
8 static ETestServerClosure book_closure = { E_TEST_SERVER_ADDRESS_BOOK, NULL, 0 };
9
10 static const gchar *photo_data =
11 "/9j / 4AAQSkZJRgABAQEARwBHAAD//gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q / 9sAQwAIBgYHB\
12 gUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04Mjw\
13 uMzQy / 9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyM\
14 jIyMjIyMjIyMjIyMjIyMjIy / 8AAEQgAMgAyAwEiAAIRAQMRAf / EABsAAQACAwEBAAAAAAAAAAA\
15 AAAAHCAQFBgID / 8QAMBAAAgEDAQYEBQQDAAAAAAAAAQIDAAQRBQYSEyExQQdhcYEiI0JRkRQVM\
16 qFiguH / xAAaAQADAQEBAQAAAAAAAAAAAAAABAUCBgED / 8QAIxEAAgICAQQCAwAAAAAAAAAAAAE\
17 CAwQRQRITITEUYQUiUf / aAAwDAQACEQMRAD8An + sHUtWtNKjVrmQ7754cajLvjrgfbzPIdzWdV\
18 fds9pJb3XdQkMrcFZGj + HqY0bdVV9Tz / wBia + N9vbjvkaxMb5E9N6SJB1HxLEEjJaWsUjD6QzS\
19 MPXdGB7E1zV74t63HINy1s4F7CWCTn77wrA0TY86jY3N1qsUk6wxBxBDvYjLHkoUH4j3JP / a0V\
20 3s1CvF / QM9tKpw0THeU + TLkj8VLnmzT8y0n9FujBx5bioba / rZLWx3iPZ7RzLp95GtnqRGVTez\
21 HNjruH7 / 4n + 67iqpq7Qi3uYWMMsNynfnE6sM8 / Lr6VamFi0KMepUE1Sx7XZHbI + fjxos1H0z3S\
22 lKYEjzISI2I64OKqsyu8sck2QYrmPjBvpIYg598Vauoh8VtlY7JW2isoBwpPl6hGByZTyD + o6E\
23 +h7UtlVOcPHA/+PyI1Wal6Zp7vaC / 06wnTTLtEeUDiKwzu4H8vI9AM9Tiuctkng1Nnk1G5cOoY\
24 ifB4nI / jB7VjWuoT21qPmwXUCHKlphHKvqG5N6g0 / cLi / Rg88FhbkbxlaUSu3kqpnn6kDzqGqb\
25 NdPB0XyK4 / svZr9RVntL50GePdcKEDqzhVBx7sKtPpayppNosxzKIlDHzxUFeG2zo2n2kivWhK\
26 6PpHwwoTnfk65J7kZyT9z5VYADAwKuYtfRA5zPv7tnjgUpSmREV8bq1hvbWW1uY1khlUo6MMhg\
27 eor7UoAje18FtmLe9eeQT3EXPcglkJRPbv71EWu7Dajp2o3MGmlRCkjKQ30jPUe1WlrlNW0Rpt\
28 TleNB84DnjkD0P9VlxT4Nqck9pmn8JuFp2zo0cgCWFi2e7555 / NSHXLadso2m3sU0NxlV65HM+\
29 VdTW3rgwvsUpSvAFKUoAUxSlAClKUAKUpQB//2Q==";
30
31 static GMainLoop *loop = NULL;
32 static gchar     *micheal_jackson_uid = NULL;
33 static gchar     *james_brown_uid = NULL;
34
35 /* Decide what to do with every "view-completed" signal */
36 enum {
37         ITERATION_SWAP_FACE = 0,
38         ITERATION_DELETE_JAMES,
39         ITERATION_UPDATE_MICHEAL,
40         ITERATION_DELETE_MICHEAL,
41         ITERATION_FINISH
42 };
43 static gint       iteration = ITERATION_SWAP_FACE;
44
45 static void
46 print_contact (EContact *contact)
47 {
48         EContactPhoto *photo = e_contact_get (contact, E_CONTACT_PHOTO);
49
50         g_assert (photo != NULL);
51         g_assert (photo->type == E_CONTACT_PHOTO_TYPE_URI);
52         g_print ("Test passed with photo uri: %s\n", photo->data.uri);
53 }
54
55 static void
56 objects_added (EBookView *book_view,
57                const GSList *contacts)
58 {
59         const GSList *l;
60
61         for (l = (GSList *) contacts; l; l = l->next) {
62                 print_contact (l->data);
63         }
64 }
65
66 static void
67 objects_modified (EBookView *book_view,
68                   const GSList *contacts)
69 {
70         GSList *l;
71
72         for (l = (GSList *) contacts; l; l = l->next) {
73                 print_contact (l->data);
74         }
75 }
76
77 static void
78 objects_removed (EBookClientView *book_view,
79                  const GSList *ids)
80 {
81         GSList *l;
82
83         for (l = (GSList *) ids; l; l = l->next) {
84                 g_print ("Removed contact: %s\n", (gchar *) l->data);
85         }
86 }
87
88 /* This provokes the backend to handle a cross-referenced photo
89  * between contacts, how the backend handles this is it's choice,
90  * we should test that when deleting one of the contacts, the other
91  * contact does not lose it's photo on disk as a result.
92  */
93 static void
94 give_james_brown_micheal_jacksons_face (EBookClient *book)
95 {
96         EContact       *micheal = NULL, *james = NULL;
97         EContactPhoto  *micheal_face;
98         EContactPhoto  *james_face;
99         GError         *error = NULL;
100
101         if (!e_book_client_get_contact_sync (book, micheal_jackson_uid, &micheal, NULL, &error))
102           g_error ("Unable to get micheal jackson's contact information: %s", error->message);
103
104         if (!e_book_client_get_contact_sync (book, james_brown_uid, &james, NULL, &error))
105           g_error ("Unable to get james brown's contact information: %s", error->message);
106
107         g_assert (micheal);
108         g_assert (james);
109
110         micheal_face = e_contact_get (micheal, E_CONTACT_PHOTO);
111         g_assert (micheal_face->type == E_CONTACT_PHOTO_TYPE_URI);
112
113         james_face  = g_new (EContactPhoto, 1);
114         james_face->type     = E_CONTACT_PHOTO_TYPE_URI;
115         james_face->data.uri = g_strdup (micheal_face->data.uri);
116
117         e_contact_set (james, E_CONTACT_PHOTO, james_face);
118
119         g_print ("Giving james brown micheal jacksons face: %s\n", micheal_face->data.uri);
120
121         if (!e_book_client_modify_contact_sync (book, james, NULL, &error))
122                 g_error ("Failed to modify contact with cross referenced photo: %s", error->message);
123 }
124
125 static void
126 update_contact_inline (EBookClient *book,
127                        const gchar *uid)
128 {
129         EContact *contact = NULL;
130         EContactPhoto *photo;
131         guchar *data;
132         gsize length = 0;
133         GError *error = NULL;
134
135         if (!e_book_client_get_contact_sync (book, uid, &contact, NULL, &error))
136           g_error ("Unable to get contact: %s", error->message);
137
138         g_assert (contact);
139
140         data = g_base64_decode (photo_data, &length);
141
142         photo = g_new (EContactPhoto, 1);
143         photo->type = E_CONTACT_PHOTO_TYPE_INLINED;
144         photo->data.inlined.mime_type = NULL;
145         photo->data.inlined.data = data;
146         photo->data.inlined.length = length;
147
148         /* set the photo */
149         e_contact_set (contact, E_CONTACT_PHOTO, photo);
150
151         if (!e_book_client_modify_contact_sync (book, contact, NULL, &error))
152             g_error ("Failed to modify contact with inline photo data: %s", error->message);
153 }
154
155 /* This assertion is made a couple of times in the view-complete
156  * handler, we run it to ensure that binary blobs and cross-referenced
157  * photo uris exist on disk while they should */
158 static void
159 assert_uri_exists (EBookClient *book,
160                    const gchar *uid)
161 {
162         EContact      *contact;
163         EContactPhoto *photo;
164         const gchar   *filename;
165         GError        *error = NULL;
166
167         if (!e_book_client_get_contact_sync (book, uid, &contact, NULL, &error))
168           g_error ("Unable to get contact: %s", error->message);
169
170         g_assert (contact);
171
172         photo = e_contact_get (contact, E_CONTACT_PHOTO);
173         g_assert (photo);
174         g_assert (photo->type == E_CONTACT_PHOTO_TYPE_URI);
175
176         filename = g_filename_from_uri (photo->data.uri, NULL, NULL);
177         g_assert (filename);
178
179         /* The file should absolutely exist at this point */
180         g_assert (g_file_test (filename, G_FILE_TEST_EXISTS));
181 }
182
183 static void
184 complete (EBookClientView *view,
185           const GError *error)
186 {
187         EBookClient *book = e_book_client_view_ref_client (view);
188         GError *local_error = NULL;
189
190         g_print ("View complete, iteration %d\n", iteration);
191
192         /* We get another "complete" notification after removing or modifying a contact */
193         switch (iteration++) {
194         case ITERATION_SWAP_FACE:
195                 give_james_brown_micheal_jacksons_face (book);
196                 break;
197         case ITERATION_DELETE_JAMES:
198                 assert_uri_exists (book, james_brown_uid);
199
200                 if (!e_book_client_remove_contact_by_uid_sync (book, james_brown_uid, NULL, &local_error))
201                         g_error ("Error removing contact: %s", local_error->message);
202
203                 g_free (james_brown_uid);
204                 james_brown_uid = NULL;
205                 break;
206         case ITERATION_UPDATE_MICHEAL:
207                 assert_uri_exists (book, micheal_jackson_uid);
208
209                 update_contact_inline (book, micheal_jackson_uid);
210                 break;
211         case ITERATION_DELETE_MICHEAL:
212                 assert_uri_exists (book, micheal_jackson_uid);
213
214                 if (!e_book_client_remove_contact_by_uid_sync (book, micheal_jackson_uid, NULL, &local_error))
215                         g_error ("Error removing contact: %s", local_error->message);
216
217                 g_free (micheal_jackson_uid);
218                 micheal_jackson_uid = NULL;
219                 break;
220         case ITERATION_FINISH:
221                 e_book_client_view_stop (view, NULL);
222                 g_object_unref (view);
223                 g_main_loop_quit (loop);
224                 break;
225         default:
226                 g_assert_not_reached ();
227                 break;
228         }
229
230         g_object_unref (book);
231 }
232
233 static void
234 setup_and_start_view (EBookClientView *view)
235 {
236         GError *error = NULL;
237
238         g_signal_connect (view, "objects-added", G_CALLBACK (objects_added), NULL);
239         g_signal_connect (view, "objects-removed", G_CALLBACK (objects_removed), NULL);
240         g_signal_connect (view, "objects-modified", G_CALLBACK (objects_modified), NULL);
241         g_signal_connect (view, "complete", G_CALLBACK (complete), NULL);
242
243         e_book_client_view_set_fields_of_interest (view, NULL, &error);
244         if (error)
245                 g_error ("set fields of interest: %s", error->message);
246
247         e_book_client_view_start (view, &error);
248         if (error)
249                 g_error ("start view: %s", error->message);
250 }
251
252 static void
253 add_contact_inline (EBookClient *book)
254 {
255         EContact *contact;
256         EContactPhoto *photo;
257         guchar *data;
258         gsize length = 0;
259
260         contact = e_contact_new ();
261
262         data = g_base64_decode (photo_data, &length);
263
264         photo = g_new (EContactPhoto, 1);
265         photo->type = E_CONTACT_PHOTO_TYPE_INLINED;
266         photo->data.inlined.mime_type = NULL;
267         photo->data.inlined.data = data;
268         photo->data.inlined.length = length;
269
270         /* set the photo */
271         e_contact_set (contact, E_CONTACT_PHOTO, photo);
272         e_contact_set (contact, E_CONTACT_FULL_NAME, "Micheal Jackson");
273
274         if (!add_contact_verify  (book, contact))
275                 g_error ("Failed to add contact");
276
277         micheal_jackson_uid = e_contact_get (contact, E_CONTACT_UID);
278 }
279
280 static void
281 add_contact_uri (EBookClient *book)
282 {
283         EContact *contact;
284         EContactPhoto *photo;
285
286         contact = e_contact_new ();
287
288         photo           = g_new (EContactPhoto, 1);
289         photo->type     = E_CONTACT_PHOTO_TYPE_URI;
290         photo->data.uri = g_strdup ("http://en.wikipedia.org/wiki/File:Jamesbrown4.jpg");
291
292         /* set the photo */
293         e_contact_set (contact, E_CONTACT_PHOTO, photo);
294         e_contact_set (contact, E_CONTACT_FULL_NAME, "James Brown");
295
296         if (!add_contact_verify  (book, contact))
297                 g_error ("Failed to add contact");
298
299         james_brown_uid = e_contact_get (contact, E_CONTACT_UID);
300 }
301
302 static void
303 test_photo_is_uri (ETestServerFixture *fixture,
304                    gconstpointer user_data)
305 {
306         EBookClient *book_client;
307         EBookClientView *view;
308         EBookQuery *query;
309         GError     *error = NULL;
310         gchar      *sexp;
311
312         book_client = E_TEST_SERVER_UTILS_SERVICE (fixture, EBookClient);
313
314         add_contact_inline (book_client);
315         add_contact_uri (book_client);
316
317         query = e_book_query_any_field_contains ("");
318         sexp = e_book_query_to_string (query);
319         e_book_query_unref (query);
320         if (!e_book_client_get_view_sync (book_client, sexp, &view, NULL, &error))
321                 g_error ("get book view sync: %s", error->message);
322
323         g_free (sexp);
324
325         setup_and_start_view (view);
326
327         loop = fixture->loop;
328         g_main_loop_run (loop);
329 }
330
331 gint
332 main (gint argc,
333       gchar **argv)
334 {
335 #if !GLIB_CHECK_VERSION (2, 35, 1)
336         g_type_init ();
337 #endif
338         g_test_init (&argc, &argv, NULL);
339
340         g_test_add (
341                 "/EBookClient/PhotoIsUri", ETestServerFixture, &book_closure,
342                 e_test_server_utils_setup, test_photo_is_uri, e_test_server_utils_teardown);
343
344         return e_test_server_utils_run ();
345 }