Added test case showing photo data stored as uris.
authorTristan Van Berkom <tristan.van.berkom@gmail.com>
Sat, 23 Jul 2011 00:06:38 +0000 (20:06 -0400)
committerTristan Van Berkom <tristan.van.berkom@gmail.com>
Tue, 1 Nov 2011 22:15:24 +0000 (18:15 -0400)
The test asserts:
  o binary inlined photos added to the EBook come out
    as uris in the EBookView signals
  o that it is still possible to use an external uri that the
    addressbook does not recognize at which point the addressbook
    is simply expected to store the provided URI string without
    any extra management (the test does this, however it only
    asserts that a uri is indeed returned).
  o When sharing an addressbook owned uri fetched from one contact
    and assigning it to the next contact, the second contact's uri
    is still accessible on disk after deleting the first contact.

tests/libebook/client/Makefile.am
tests/libebook/client/test-client-photo-is-uri.c [new file with mode: 0644]

index 0c63ce4..c272e9f 100644 (file)
@@ -31,6 +31,7 @@ TESTS =                                                               \
        test-client-remove-contact                              \
        test-client-remove-contact-by-uid                       \
        test-client-remove-contacts                             \
+       test-client-photo-is-uri                                \
        test-client-stress-factory--serial                      \
        test-client-stress-factory--fifo                        \
        test-client-stress-factory--single-book                 \
@@ -86,6 +87,8 @@ test_client_remove_contact_by_uid_LDADD=$(TEST_LIBS)
 test_client_remove_contact_by_uid_CPPFLAGS=$(TEST_CPPFLAGS)
 test_client_remove_contacts_LDADD=$(TEST_LIBS)
 test_client_remove_contacts_CPPFLAGS=$(TEST_CPPFLAGS)
+test_client_photo_is_uri_LDADD=$(TEST_LIBS)
+test_client_photo_is_uri_CPPFLAGS=$(TEST_CPPFLAGS)
 test_client_stress_factory__fifo_LDADD=$(TEST_LIBS)
 test_client_stress_factory__fifo_CPPFLAGS=$(TEST_CPPFLAGS)
 test_client_stress_factory__serial_LDADD=$(TEST_LIBS)
diff --git a/tests/libebook/client/test-client-photo-is-uri.c b/tests/libebook/client/test-client-photo-is-uri.c
new file mode 100644 (file)
index 0000000..8818cb7
--- /dev/null
@@ -0,0 +1,361 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+#include <stdlib.h>
+#include <libebook/e-book.h>
+
+#include "client-test-utils.h"
+
+
+static const gchar *photo_data =
+"/9j/4AAQSkZJRgABAQEARwBHAAD//gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAIBgYHB\
+gUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04Mjw\
+uMzQy/9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyM\
+jIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAMgAyAwEiAAIRAQMRAf/EABsAAQACAwEBAAAAAAAAAAA\
+AAAAHCAQFBgID/8QAMBAAAgEDAQYEBQQDAAAAAAAAAQIDAAQRBQYSEyExQQdhcYEiI0JRkRQVM\
+qFiguH/xAAaAQADAQEBAQAAAAAAAAAAAAAABAUCBgED/8QAIxEAAgICAQQCAwAAAAAAAAAAAAE\
+CAwQRQRITITEUYQUiUf/aAAwDAQACEQMRAD8An+sHUtWtNKjVrmQ7754cajLvjrgfbzPIdzWdV\
+fds9pJb3XdQkMrcFZGj+HqY0bdVV9Tz/wBia+N9vbjvkaxMb5E9N6SJB1HxLEEjJaWsUjD6QzS\
+MPXdGB7E1zV74t63HINy1s4F7CWCTn77wrA0TY86jY3N1qsUk6wxBxBDvYjLHkoUH4j3JP/a0V\
+3s1CvF/QM9tKpw0THeU+TLkj8VLnmzT8y0n9FujBx5bioba/rZLWx3iPZ7RzLp95GtnqRGVTez\
+HNjruH7/4n+67iqpq7Qi3uYWMMsNynfnE6sM8/Lr6VamFi0KMepUE1Sx7XZHbI+fjxos1H0z3S\
+lKYEjzISI2I64OKqsyu8sck2QYrmPjBvpIYg598Vauoh8VtlY7JW2isoBwpPl6hGByZTyD+o6E\
++h7UtlVOcPHA/+PyI1Wal6Zp7vaC/06wnTTLtEeUDiKwzu4H8vI9AM9Tiuctkng1Nnk1G5cOoY\
+ifB4nI/jB7VjWuoT21qPmwXUCHKlphHKvqG5N6g0/cLi/Rg88FhbkbxlaUSu3kqpnn6kDzqGqb\
+NdPB0XyK4/svZr9RVntL50GePdcKEDqzhVBx7sKtPpayppNosxzKIlDHzxUFeG2zo2n2kivWhK\
+6PpHwwoTnfk65J7kZyT9z5VYADAwKuYtfRA5zPv7tnjgUpSmREV8bq1hvbWW1uY1khlUo6MMhg\
+eor7UoAje18FtmLe9eeQT3EXPcglkJRPbv71EWu7Dajp2o3MGmlRCkjKQ30jPUe1WlrlNW0Rpt\
+TleNB84DnjkD0P9VlxT4Nqck9pmn8JuFp2zo0cgCWFi2e7555/NSHXLadso2m3sU0NxlV65HM+\
+VdTW3rgwvsUpSvAFKUoAUxSlAClKUAKUpQB//2Q==";
+
+
+static GMainLoop *loop = NULL;
+static gchar     *micheal_jackson_uid = NULL;
+static gchar     *james_brown_uid = NULL;
+
+
+/* Decide what to do with every "view-completed" signal */
+enum {
+       ITERATION_SWAP_FACE = 0,
+       ITERATION_DELETE_JAMES,
+       ITERATION_UPDATE_MICHEAL,
+       ITERATION_DELETE_MICHEAL,
+       ITERATION_FINISH
+};
+static gint       iteration = ITERATION_SWAP_FACE;
+
+
+static void
+print_contact (EContact *contact)
+{
+       EContactPhoto *photo = e_contact_get (contact, E_CONTACT_PHOTO);
+
+       g_assert (photo != NULL);
+       g_assert (photo->type == E_CONTACT_PHOTO_TYPE_URI);
+       g_print ("Test passed with photo uri: %s\n", photo->data.uri);
+}
+
+static void
+objects_added (EBookView *book_view, const GSList *contacts)
+{
+       const GSList *l;
+
+       for (l = (GSList*)contacts; l; l = l->next) {
+               print_contact (l->data);
+       }
+}
+
+static void
+objects_modified (EBookView *book_view, const GSList *contacts)
+{
+       GSList *l;
+
+       for (l = (GSList*)contacts; l; l = l->next) {
+               print_contact (l->data);
+       }
+}
+
+static void
+objects_removed (EBookClientView *book_view, const GSList *ids)
+{
+       GSList *l;
+
+       for (l = (GSList*)ids; l; l = l->next) {
+               g_print ("Removed contact: %s\n", (gchar *)l->data);
+       }
+}
+
+
+/* This provokes the backend to handle a cross-referenced photo
+ * between contacts, how the backend handles this is it's choice,
+ * we should test that when deleting one of the contacts, the other
+ * contact does not lose it's photo on disk as a result.
+ */
+static void
+give_james_brown_micheal_jacksons_face (EBookClient *book)
+{
+       EContact       *micheal = NULL, *james = NULL;
+       EContactPhoto  *micheal_face;
+       EContactPhoto  *james_face;
+       GError         *error = NULL;
+
+       if (!e_book_client_get_contact_sync (book, micheal_jackson_uid, &micheal, NULL, &error))
+         g_error ("Unable to get micheal jackson's contact information: %s", error->message);
+
+       if (!e_book_client_get_contact_sync (book, james_brown_uid, &james, NULL, &error))
+         g_error ("Unable to get james brown's contact information: %s", error->message);
+
+       g_assert (micheal);
+       g_assert (james);
+
+       micheal_face = e_contact_get (micheal, E_CONTACT_PHOTO);
+       g_assert (micheal_face->type == E_CONTACT_PHOTO_TYPE_URI);
+
+       james_face  = g_new (EContactPhoto, 1);
+       james_face->type     = E_CONTACT_PHOTO_TYPE_URI;
+       james_face->data.uri = g_strdup (micheal_face->data.uri);
+       
+       e_contact_set (james, E_CONTACT_PHOTO, james_face);
+
+       g_print ("Giving james brown micheal jacksons face: %s\n", micheal_face->data.uri);
+
+       if (!e_book_client_modify_contact_sync (book, james, NULL, &error))
+               g_error ("Failed to modify contact with cross referenced photo: %s", error->message);
+}
+
+static void
+update_contact_inline (EBookClient *book, 
+                      const gchar *uid)
+{
+       EContact *contact = NULL;
+       EContactPhoto *photo;
+       guchar *data;
+       gsize length = 0;
+       GError *error = NULL;
+
+       if (!e_book_client_get_contact_sync (book, uid, &contact, NULL, &error))
+         g_error ("Unable to get contact: %s", error->message);
+
+       g_assert (contact);
+
+       data = g_base64_decode (photo_data, &length);
+
+       photo = g_new (EContactPhoto, 1);
+       photo->type = E_CONTACT_PHOTO_TYPE_INLINED;
+       photo->data.inlined.mime_type = NULL;
+       photo->data.inlined.data = data;
+       photo->data.inlined.length = length;
+
+       /* set the photo */
+       e_contact_set (contact, E_CONTACT_PHOTO, photo);
+
+       if (!e_book_client_modify_contact_sync (book, contact, NULL, &error))
+           g_error ("Failed to modify contact with inline photo data: %s", error->message);
+}
+
+/* This assertion is made a couple of times in the view-complete
+ * handler, we run it to ensure that binary blobs and cross-referenced
+ * photo uris exist on disk while they should */
+static void
+assert_uri_exists (EBookClient *book,
+                  const gchar *uid)
+{
+       EContact      *contact;
+       EContactPhoto *photo;
+       const gchar   *filename;
+       GError        *error = NULL;
+
+       if (!e_book_client_get_contact_sync (book, uid, &contact, NULL, &error))
+         g_error ("Unable to get contact: %s", error->message);
+
+       g_assert (contact);
+
+       photo = e_contact_get (contact, E_CONTACT_PHOTO);
+       g_assert (photo);
+       g_assert (photo->type == E_CONTACT_PHOTO_TYPE_URI);
+
+       filename = g_filename_from_uri (photo->data.uri, NULL, NULL);
+       g_assert (filename);
+
+       /* The file should absolutely exist at this point */
+       g_assert (g_file_test (filename, G_FILE_TEST_EXISTS));
+}
+
+static void
+complete (EBookClientView *view, const GError *error)
+{
+       EBookClient *book = e_book_client_view_get_client (view);
+       GError *local_error = NULL;
+
+       g_print ("View complete, iteration %d\n", iteration);
+
+       /* We get another "complete" notification after removing or modifying a contact */
+       switch (iteration++) {
+       case ITERATION_SWAP_FACE:
+               give_james_brown_micheal_jacksons_face (book);
+               break;
+       case ITERATION_DELETE_JAMES:
+               assert_uri_exists (book, james_brown_uid);
+
+               if (!e_book_client_remove_contact_by_uid_sync (book, james_brown_uid, NULL, &local_error))
+                       g_error ("Error removing contact: %s", local_error->message);
+
+               g_free (james_brown_uid);
+               james_brown_uid = NULL;
+               break;
+       case ITERATION_UPDATE_MICHEAL:
+               assert_uri_exists (book, micheal_jackson_uid);
+
+               update_contact_inline (book, micheal_jackson_uid);
+               break;
+       case ITERATION_DELETE_MICHEAL:
+               assert_uri_exists (book, micheal_jackson_uid);
+
+               if (!e_book_client_remove_contact_by_uid_sync (book, micheal_jackson_uid, NULL, &local_error))
+                       g_error ("Error removing contact: %s", local_error->message);
+
+               g_free (micheal_jackson_uid);
+               micheal_jackson_uid = NULL;
+               break;
+       case ITERATION_FINISH:
+               e_book_client_view_stop (view, NULL);
+               g_object_unref (view);
+               g_main_loop_quit (loop);
+               break;
+       default:
+               g_assert_not_reached ();
+               break;
+       }
+
+}
+
+static void
+setup_and_start_view (EBookClientView *view)
+{
+       GError *error = NULL;
+
+       g_signal_connect (view, "objects-added", G_CALLBACK (objects_added), NULL);
+       g_signal_connect (view, "objects-removed", G_CALLBACK (objects_removed), NULL);
+       g_signal_connect (view, "objects-modified", G_CALLBACK (objects_modified), NULL);
+       g_signal_connect (view, "complete", G_CALLBACK (complete), NULL);
+
+       e_book_client_view_set_fields_of_interest (view, NULL, &error);
+       if (error)
+               report_error ("set fields of interest", &error);
+
+       e_book_client_view_start (view, &error);
+       if (error)
+               report_error ("start view", &error);
+}
+
+static void
+add_contact_inline (EBookClient *book)
+{
+       EContact *contact;
+       EContactPhoto *photo;
+       GError *error = NULL;
+       guchar *data;
+       gsize length = 0;
+
+       contact = e_contact_new ();
+
+       data = g_base64_decode (photo_data, &length);
+
+       photo = g_new (EContactPhoto, 1);
+       photo->type = E_CONTACT_PHOTO_TYPE_INLINED;
+       photo->data.inlined.mime_type = NULL;
+       photo->data.inlined.data = data;
+       photo->data.inlined.length = length;
+
+       /* set the photo */
+       e_contact_set (contact, E_CONTACT_PHOTO, photo);
+       e_contact_set (contact, E_CONTACT_FULL_NAME, "Micheal Jackson");
+
+       if (!add_contact_verify  (book, contact))
+         g_error ("Failed to add contact: %s", error->message);
+
+       micheal_jackson_uid = e_contact_get (contact, E_CONTACT_UID);
+}
+
+static void
+add_contact_uri (EBookClient *book)
+{
+       EContact *contact;
+       EContactPhoto *photo;
+       GError *error = NULL;
+
+       contact = e_contact_new ();
+
+       photo           = g_new (EContactPhoto, 1);
+       photo->type     = E_CONTACT_PHOTO_TYPE_URI;
+       photo->data.uri = g_strdup ("http://en.wikipedia.org/wiki/File:Jamesbrown4.jpg");
+
+       /* set the photo */
+       e_contact_set (contact, E_CONTACT_PHOTO, photo);
+       e_contact_set (contact, E_CONTACT_FULL_NAME, "James Brown");
+
+       if (!add_contact_verify  (book, contact))
+         g_error ("Failed to add contact: %s", error->message);
+
+       james_brown_uid = e_contact_get (contact, E_CONTACT_UID);
+}
+
+static void
+setup_book (EBookClient     **book_out)
+{
+       EBookClient *book;
+       GError      *error = NULL;
+
+       book = new_temp_client (NULL);
+       g_assert (book != NULL);
+
+       if (!e_client_open_sync (E_CLIENT (book), FALSE, NULL, &error)) {
+               g_error ("failed to open client: %s", error->message);
+       }
+
+       add_contact_inline (book);
+       add_contact_uri (book);
+
+       *book_out = book;
+}
+
+gint
+main (gint argc, gchar **argv)
+{
+       EBookClient *book;
+       EBookClientView *view;
+       EBookQuery *query;
+       GError     *error = NULL;
+       gchar      *sexp;
+
+       g_type_init ();
+
+       setup_book (&book);
+
+       query = e_book_query_any_field_contains ("");
+       sexp = e_book_query_to_string (query);
+       e_book_query_unref (query);
+       if (!e_book_client_get_view_sync (book, sexp, &view, NULL, &error)) {
+               report_error ("get book view sync", &error);
+               g_free (sexp);
+               g_object_unref (book);
+
+               return 1;
+       }
+
+       g_free (sexp);
+
+       setup_and_start_view (view);
+
+       loop = g_main_loop_new (NULL, TRUE);
+       g_main_loop_run (loop);
+
+       if (!e_client_remove_sync (E_CLIENT (book), NULL, &error)) {
+               report_error ("client remove sync", &error);
+               g_object_unref (book);
+
+               return 1;
+       }
+
+       g_object_unref (book);
+
+       return 0;
+}