[libgdata] [contacts] Improved test coverage and fixed a few small bugs



commit 023e14a4cd33561209ba6148ff02a99cedb1073c
Author: Philip Withnall <philip tecnocode co uk>
Date:   Tue Dec 29 17:19:57 2009 +0000

    [contacts] Improved test coverage and fixed a few small bugs
    
    Improved the test coverage of the Google Contacts service, and consequently
    fixed a few small bugs, such as some uninitialised timestamps and incorrect
    signal names. This takes our overall test coverage up to about 60%, not
    including the Google Documents code.

 gdata/services/contacts/gdata-contacts-contact.c |   17 +-
 gdata/services/documents/gdata-documents-entry.c |    3 +
 gdata/services/picasaweb/gdata-picasaweb-album.c |    3 +-
 gdata/services/picasaweb/gdata-picasaweb-file.c  |    3 +-
 gdata/tests/contacts.c                           |  247 ++++++++++++++++++++-
 5 files changed, 254 insertions(+), 19 deletions(-)
---
diff --git a/gdata/services/contacts/gdata-contacts-contact.c b/gdata/services/contacts/gdata-contacts-contact.c
index 11081b8..4626432 100644
--- a/gdata/services/contacts/gdata-contacts-contact.c
+++ b/gdata/services/contacts/gdata-contacts-contact.c
@@ -179,9 +179,12 @@ gdata_contacts_contact_init (GDataContactsContact *self)
 	/* Create a default name, so the name's properties can be set for a blank contact */
 	self->priv->name = gdata_gd_name_new (NULL, NULL);
 
-	/* Listen to change notifications for the entry's title, since it's linked to GDataGDName:fullName */
+	/* Listen to change notifications for the entry's title, since it's linked to GDataGDName:full-name */
 	g_signal_connect (self, "notify::title", (GCallback) notify_title_cb, self);
-	g_signal_connect (self->priv->name, "notify::fullName", (GCallback) notify_full_name_cb, self);
+	g_signal_connect (self->priv->name, "notify::full-name", (GCallback) notify_full_name_cb, self);
+
+	/* Set the edited property to the current time (creation time) */
+	g_get_current_time (&(self->priv->edited));
 }
 
 static void
@@ -341,16 +344,20 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		/* Get either the value property, or the element's content */
 		value = xmlGetProp (node, (xmlChar*) "value");
 		if (value == NULL) {
+			xmlNode *child_node;
+
 			/* Use the element's content instead (arbitrary XML) */
 			buffer = xmlBufferCreate ();
-			xmlNodeDump (buffer, doc, node, 0, 0);
+			for (child_node = node->children; child_node != NULL; child_node = child_node->next)
+				xmlNodeDump (buffer, doc, child_node, 0, 0);
 			value = (xmlChar*) xmlBufferContent (buffer);
-			xmlBufferFree (buffer);
 		}
 
 		gdata_contacts_contact_set_extended_property (self, (gchar*) name, (gchar*) value);
 
-		if (buffer == NULL)
+		if (buffer != NULL)
+			xmlBufferFree (buffer);
+		else
 			xmlFree (value);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "groupMembershipInfo") == 0) {
 		/* gContact:groupMembershipInfo */
diff --git a/gdata/services/documents/gdata-documents-entry.c b/gdata/services/documents/gdata-documents-entry.c
index 5d4bbf9..cb21f5a 100644
--- a/gdata/services/documents/gdata-documents-entry.c
+++ b/gdata/services/documents/gdata-documents-entry.c
@@ -181,6 +181,9 @@ static void
 gdata_documents_entry_init (GDataDocumentsEntry *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_DOCUMENTS_ENTRY, GDataDocumentsEntryPrivate);
+
+	/* Initialise the edited properties to the current time */
+	g_get_current_time (&(self->priv->edited));
 }
 
 static gboolean
diff --git a/gdata/services/picasaweb/gdata-picasaweb-album.c b/gdata/services/picasaweb/gdata-picasaweb-album.c
index 3bd2e40..e960450 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-album.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-album.c
@@ -405,8 +405,9 @@ gdata_picasaweb_album_init (GDataPicasaWebAlbum *self)
 	self->priv->georss_where = g_object_new (GDATA_TYPE_GEORSS_WHERE, NULL);
 	self->priv->visibility = GDATA_PICASAWEB_PRIVATE;
 
-	/* Initialise the timestamp to the current time (bgo#599140) */
+	/* Initialise the timestamp and edited properties to the current time (bgo#599140) */
 	g_get_current_time (&(self->priv->timestamp));
+	g_get_current_time (&(self->priv->edited));
 
 	/* Connect to the notify::title signal from GDataEntry so our media:group title can be kept in sync
 	 * (the title of an album is duplicated in atom:title and media:group/media:title) */
diff --git a/gdata/services/picasaweb/gdata-picasaweb-file.c b/gdata/services/picasaweb/gdata-picasaweb-file.c
index 037c927..edcf852 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-file.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-file.c
@@ -590,8 +590,9 @@ gdata_picasaweb_file_init (GDataPicasaWebFile *self)
 	self->priv->georss_where = g_object_new (GDATA_TYPE_GEORSS_WHERE, NULL);
 	self->priv->is_commenting_enabled = TRUE;
 
-	/* Initialise the timestamp to the current time (bgo#599140) */
+	/* Initialise the timestamp and edited properties to the current time (bgo#599140) */
 	g_get_current_time (&(self->priv->timestamp));
+	g_get_current_time (&(self->priv->edited));
 
 	/* We need to keep atom:title (the canonical title for the file) in sync with media:group/media:title */
 	g_signal_connect (self, "notify::title", G_CALLBACK (notify_title_cb), NULL);
diff --git a/gdata/tests/contacts.c b/gdata/tests/contacts.c
index 0737476..3e4deb1 100644
--- a/gdata/tests/contacts.c
+++ b/gdata/tests/contacts.c
@@ -30,6 +30,12 @@ get_contact (gconstpointer service)
 	GDataEntry *entry;
 	GList *entries;
 	GError *error = NULL;
+	GDataQuery *query = NULL;
+	static gchar *entry_id = NULL;
+
+	/* Make sure we use the same contact throughout */
+	if (entry_id != NULL)
+		query = gdata_query_new_for_id (entry_id);
 
 	feed = gdata_contacts_service_query_contacts (GDATA_CONTACTS_SERVICE (service), NULL, NULL, NULL, NULL, &error);
 	g_assert_no_error (error);
@@ -44,6 +50,9 @@ get_contact (gconstpointer service)
 	g_object_ref (entry);
 	g_object_unref (feed);
 
+	if (entry_id == NULL)
+		entry_id = g_strdup (gdata_entry_get_id (entry));
+
 	return GDATA_CONTACTS_CONTACT (entry);
 }
 
@@ -125,16 +134,28 @@ test_insert_simple (gconstpointer service)
 {
 	GDataContactsContact *contact, *new_contact;
 	GDataCategory *category;
+	GDataGDName *name, *name2;
 	GDataGDEmailAddress *email_address1, *email_address2;
 	GDataGDPhoneNumber *phone_number1, *phone_number2;
 	GDataGDIMAddress *im_address;
 	GDataGDPostalAddress *postal_address;
 	gchar *xml;
+	GList *list;
+	GHashTable *properties;
+	GTimeVal *edited, creation_time;
+	gboolean deleted, has_photo;
 	GError *error = NULL;
 
 	contact = gdata_contacts_contact_new (NULL);
+	g_get_current_time (&creation_time);
 
+	/* Set and check the name (to check if the title of the entry is updated) */
 	gdata_entry_set_title (GDATA_ENTRY (contact), "Elizabeth Bennet");
+	name = gdata_contacts_contact_get_name (contact);
+	g_assert_cmpstr (gdata_gd_name_get_full_name (name), ==, "Elizabeth Bennet");
+	gdata_gd_name_set_full_name (name, "Lizzie Bennet");
+	g_assert_cmpstr (gdata_entry_get_title (GDATA_ENTRY (contact)), ==, "Lizzie Bennet");
+
 	gdata_entry_set_content (GDATA_ENTRY (contact), "Notes");
 	/* TODO: Have it add this category automatically? Same for GDataCalendarEvent */
 	category = gdata_category_new ("http://schemas.google.com/contact/2008#contact";, "http://schemas.google.com/g/2005#kind";, NULL);
@@ -166,6 +187,22 @@ test_insert_simple (gconstpointer service)
 	g_assert (gdata_contacts_contact_set_extended_property (contact, "ROLE", "") == TRUE);
 	g_assert (gdata_contacts_contact_set_extended_property (contact, "CALURI", "http://example.com/";) == TRUE);
 
+	/* Check the properties of the object */
+	g_object_get (G_OBJECT (contact),
+	              "edited", &edited,
+	              "deleted", &deleted,
+	              "has-photo", &has_photo,
+	              "name", &name2,
+	              NULL);
+
+	g_assert_cmpint (edited->tv_sec, ==, creation_time.tv_sec);
+	/*g_assert_cmpint (edited->tv_usec, ==, creation_time.tv_usec); --- testing to the nearest microsecond is too precise, and always fails */
+	g_assert (deleted == FALSE);
+	g_assert (has_photo == FALSE);
+	g_assert (name2 == name);
+
+	g_object_unref (name2);
+
 	/* Check the XML */
 	xml = gdata_parsable_get_xml (GDATA_PARSABLE (contact));
 	g_assert_cmpstr (xml, ==,
@@ -173,10 +210,10 @@ test_insert_simple (gconstpointer service)
 			 	"xmlns:gd='http://schemas.google.com/g/2005' "
 			 	"xmlns:app='http://www.w3.org/2007/app' "
 			 	"xmlns:gContact='http://schemas.google.com/contact/2008'>"
-			 	"<title type='text'>Elizabeth Bennet</title>"
+			 	"<title type='text'>Lizzie Bennet</title>"
 			 	"<content type='text'>Notes</content>"
 				"<category term='http://schemas.google.com/contact/2008#contact' scheme='http://schemas.google.com/g/2005#kind'/>"
-				"<gd:name><gd:fullName>Elizabeth Bennet</gd:fullName></gd:name>"
+				"<gd:name><gd:fullName>Lizzie Bennet</gd:fullName></gd:name>"
 				"<gd:email address='liz gmail com' rel='http://schemas.google.com/g/2005#work' primary='false'/>"
 				"<gd:email address='liz example org' rel='http://schemas.google.com/g/2005#home' primary='false'/>"
 				"<gd:im address='liz gmail com' protocol='http://schemas.google.com/g/2005#GOOGLE_TALK' "
@@ -196,14 +233,68 @@ test_insert_simple (gconstpointer service)
 	g_assert (GDATA_IS_CONTACTS_CONTACT (new_contact));
 	g_clear_error (&error);
 
+	/* Check its edited date */
+	gdata_contacts_contact_get_edited (new_contact, &creation_time);
+	g_assert_cmpint (creation_time.tv_sec, >=, edited->tv_sec);
+
+	/* E-mail addresses */
+	list = gdata_contacts_contact_get_email_addresses (new_contact);
+	g_assert_cmpuint (g_list_length (list), ==, 2);
+	g_assert (GDATA_IS_GD_EMAIL_ADDRESS (list->data));
+
+	g_assert (gdata_contacts_contact_get_primary_email_address (new_contact) == NULL);
+
+	/* IM addresses */
+	list = gdata_contacts_contact_get_im_addresses (new_contact);
+	g_assert_cmpuint (g_list_length (list), ==, 1);
+	g_assert (GDATA_IS_GD_IM_ADDRESS (list->data));
+
+	g_assert (gdata_contacts_contact_get_primary_im_address (new_contact) == NULL);
+
+	/* Phone numbers */
+	list = gdata_contacts_contact_get_phone_numbers (new_contact);
+	g_assert_cmpuint (g_list_length (list), ==, 2);
+	g_assert (GDATA_IS_GD_PHONE_NUMBER (list->data));
+
+	g_assert (GDATA_IS_GD_PHONE_NUMBER (gdata_contacts_contact_get_primary_phone_number (new_contact)));
+
+	/* Postal addresses */
+	list = gdata_contacts_contact_get_postal_addresses (new_contact);
+	g_assert_cmpuint (g_list_length (list), ==, 1);
+	g_assert (GDATA_IS_GD_POSTAL_ADDRESS (list->data));
+
+	g_assert (GDATA_IS_GD_POSTAL_ADDRESS (gdata_contacts_contact_get_primary_postal_address (new_contact)));
+
+	/* Organizations */
+	list = gdata_contacts_contact_get_organizations (new_contact);
+	g_assert (list == NULL);
+
+	g_assert (gdata_contacts_contact_get_primary_organization (new_contact) == NULL);
+
+	/* Extended properties */
+	g_assert_cmpstr (gdata_contacts_contact_get_extended_property (new_contact, "CALURI"), ==, "http://example.com/";);
+	g_assert (gdata_contacts_contact_get_extended_property (new_contact, "non-existent") == NULL);
+
+	properties = gdata_contacts_contact_get_extended_properties (new_contact);
+	g_assert (properties != NULL);
+	g_assert_cmpuint (g_hash_table_size (properties), ==, 1);
+
+	/* Groups */
+	list = gdata_contacts_contact_get_groups (new_contact);
+	g_assert (list == NULL);
+
+	/* Deleted? */
+	g_assert (gdata_contacts_contact_is_deleted (new_contact) == FALSE);
+
 	/* TODO: check entries and feed properties */
 
+	g_free (edited);
 	g_object_unref (contact);
 	g_object_unref (new_contact);
 }
 
 static void
-test_query_uri (gconstpointer service)
+test_query_uri (void)
 {
 	gchar *query_uri;
 	GDataContactsQuery *query = gdata_contacts_query_new ("q");
@@ -211,6 +302,14 @@ test_query_uri (gconstpointer service)
 	gdata_contacts_query_set_order_by (query, "lastmodified");
 	g_assert_cmpstr (gdata_contacts_query_get_order_by (query), ==, "lastmodified");
 
+	gdata_contacts_query_set_show_deleted (query, FALSE);
+	g_assert (gdata_contacts_query_show_deleted (query) == FALSE);
+
+	/* Test it with both values of show-deleted */
+	query_uri = gdata_query_get_query_uri (GDATA_QUERY (query), "http://example.com";);
+	g_assert_cmpstr (query_uri, ==, "http://example.com?q=q&orderby=lastmodified&showdeleted=false";);
+	g_free (query_uri);
+
 	gdata_contacts_query_set_show_deleted (query, TRUE);
 	g_assert (gdata_contacts_query_show_deleted (query) == TRUE);
 
@@ -242,6 +341,46 @@ test_query_uri (gconstpointer service)
 }
 
 static void
+test_query_properties (void)
+{
+	gchar *order_by, *sort_order, *group;
+	gboolean show_deleted;
+	guint start_index, max_results;
+	GDataContactsQuery *query = gdata_contacts_query_new_with_limits ("q", 1, 10);
+
+	/* Set the properties */
+	g_object_set (G_OBJECT (query),
+	              "order-by", "lastmodified",
+	              "show-deleted", TRUE,
+	              "sort-order", "descending",
+	              "group", "http://www.google.com/feeds/contacts/groups/jo gmail com/base/1234a",
+	              NULL);
+
+	/* Check the query's properties */
+	g_object_get (G_OBJECT (query),
+	              "order-by", &order_by,
+	              "show-deleted", &show_deleted,
+	              "sort-order", &sort_order,
+	              "group", &group,
+	              "start-index", &start_index,
+	              "max-results", &max_results,
+	              NULL);
+
+	g_assert_cmpstr (order_by, ==, "lastmodified");
+	g_assert (show_deleted == TRUE);
+	g_assert_cmpstr (sort_order, ==, "descending");
+	g_assert_cmpstr (group, ==, "http://www.google.com/feeds/contacts/groups/jo gmail com/base/1234a");
+	g_assert_cmpuint (start_index, ==, 1);
+	g_assert_cmpuint (max_results, ==, 10);
+
+	g_free (order_by);
+	g_free (sort_order);
+	g_free (group);
+
+	g_object_unref (query);
+}
+
+static void
 test_parser_minimal (gconstpointer service)
 {
 	GDataContactsContact *contact;
@@ -277,6 +416,90 @@ test_parser_minimal (gconstpointer service)
 }
 
 static void
+test_parser_normal (gconstpointer service)
+{
+	GDataContactsContact *contact;
+	GError *error = NULL;
+
+	contact = GDATA_CONTACTS_CONTACT (gdata_parsable_new_from_xml (GDATA_TYPE_CONTACTS_CONTACT,
+		"<entry xmlns='http://www.w3.org/2005/Atom' "
+			"xmlns:gd='http://schemas.google.com/g/2005' "
+			"xmlns:gContact='http://schemas.google.com/contact/2008' "
+			"gd:etag='&quot;QngzcDVSLyp7ImA9WxJTFkoITgU.&quot;'>"
+			"<id>http://www.google.com/m8/feeds/contacts/libgdata test googlemail com/base/1b46cdd20bfbee3b</id>"
+			"<updated>2009-04-25T15:21:53.688Z</updated>"
+			"<app:edited xmlns:app='http://www.w3.org/2007/app'>2009-04-25T15:21:53.688Z</app:edited>"
+			"<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact'/>"
+			"<title></title>" /* Here's where it all went wrong */
+			"<link rel='http://schemas.google.com/contacts/2008/rel#photo' type='image/*' href='http://www.google.com/m8/feeds/photos/media/libgdata test googlemail com/1b46cdd20bfbee3b'/>"
+			"<link rel='http://www.iana.org/assignments/relation/self' type='application/atom+xml' href='http://www.google.com/m8/feeds/contacts/libgdata test googlemail com/full/1b46cdd20bfbee3b'/>"
+			"<link rel='http://www.iana.org/assignments/relation/edit' type='application/atom+xml' href='http://www.google.com/m8/feeds/contacts/libgdata test googlemail com/full/1b46cdd20bfbee3b'/>"
+			"<gd:email rel='http://schemas.google.com/g/2005#other' address='bob example com'/>"
+			"<gd:extendedProperty name='test' value='test value'/>"
+			"<gd:organization rel='http://schemas.google.com/g/2005#work' label='Work' primary='true'/>"
+			"<gContact:groupMembershipInfo href='http://www.google.com/feeds/contacts/groups/jo%40gmail.com/base/1234a' "
+				"deleted='true'/>"
+			"<gContact:groupMembershipInfo href='http://www.google.com/feeds/contacts/groups/jo%40gmail.com/base/1234b'/>"
+			"<gd:deleted/>"
+		"</entry>", -1, &error));
+	g_assert_no_error (error);
+	g_assert (GDATA_IS_ENTRY (contact));
+	g_clear_error (&error);
+
+	/* TODO: Check the other properties */
+
+	g_object_unref (contact);
+}
+
+static void
+test_parser_error_handling (gconstpointer service)
+{
+	GDataContactsContact *contact;
+	GError *error = NULL;
+
+#define TEST_XML_ERROR_HANDLING(x) \
+	contact = GDATA_CONTACTS_CONTACT (gdata_parsable_new_from_xml (GDATA_TYPE_CONTACTS_CONTACT,\
+		"<entry xmlns='http://www.w3.org/2005/Atom' "\
+		"xmlns:gd='http://schemas.google.com/g/2005' "\
+		"xmlns:gContact='http://schemas.google.com/contact/2008'>"\
+			x\
+		"</entry>", -1, &error));\
+	g_assert_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR);\
+	g_assert (contact == NULL);\
+	g_clear_error (&error)
+
+	/* app:edited */
+	TEST_XML_ERROR_HANDLING ("<app:edited xmlns:app='http://www.w3.org/2007/app'>this shouldn't parse</app:edited>");
+
+	/* gd:name */
+	TEST_XML_ERROR_HANDLING ("<gd:name><gd:givenName>Spartacus</gd:givenName><gd:givenName>Spartacus</gd:givenName></gd:name>");
+
+	/* gd:email */
+	TEST_XML_ERROR_HANDLING ("<gd:email>neither should this</gd:email>");
+
+	/* gd:im */
+	TEST_XML_ERROR_HANDLING ("<gd:im>nor this</gd:im>");
+
+	/* gd:phoneNumber */
+	TEST_XML_ERROR_HANDLING ("<gd:phoneNumber/>");
+
+	/* gd:structuredPostalAddress */
+	TEST_XML_ERROR_HANDLING ("<gd:structuredPostalAddress rel=''/>");
+
+	/* gd:organization */
+	TEST_XML_ERROR_HANDLING ("<gd:organization rel=''/>");
+
+	/* gd:extendedProperty */
+	TEST_XML_ERROR_HANDLING ("<gd:extendedProperty/>");
+
+	/* gContact:groupMembershipInfo */
+	TEST_XML_ERROR_HANDLING ("<gContact:groupMembershipInfo/>");
+	TEST_XML_ERROR_HANDLING ("<gContact:groupMembershipInfo href='http://foobar.com/base/1234b' deleted='maybe'/>");
+
+#undef TEST_XML_ERROR_HANDLING
+}
+
+static void
 test_photo_has_photo (gconstpointer service)
 {
 	GDataContactsContact *contact;
@@ -368,7 +591,7 @@ test_photo_get (gconstpointer service)
 	g_assert_no_error (error);
 	g_assert (data != NULL);
 	g_assert (length != 0);
-	g_assert_cmpstr (content_type, ==, "image/jpg");
+	g_assert_cmpstr (content_type, ==, "image/jpeg");
 
 	g_assert (gdata_contacts_contact_has_photo (contact) == TRUE);
 
@@ -412,19 +635,19 @@ main (int argc, char *argv[])
 	gdata_service_authenticate (service, USERNAME, PASSWORD, NULL, NULL);
 
 	g_test_add_func ("/contacts/authentication", test_authentication);
-	if (g_test_slow () == TRUE)
-		g_test_add_data_func ("/contacts/insert/simple", service, test_insert_simple);
+	g_test_add_data_func ("/contacts/insert/simple", service, test_insert_simple);
 	g_test_add_data_func ("/contacts/query/all_contacts", service, test_query_all_contacts);
 	if (g_test_thorough () == TRUE)
 		g_test_add_data_func ("/contacts/query/all_contacts_async", service, test_query_all_contacts_async);
-	g_test_add_data_func ("/contacts/query/uri", service, test_query_uri);
+	g_test_add_func ("/contacts/query/uri", test_query_uri);
+	g_test_add_func ("/contacts/query/properties", test_query_properties);
 	g_test_add_data_func ("/contacts/parser/minimal", service, test_parser_minimal);
+	g_test_add_data_func ("/contacts/parser/normal", service, test_parser_normal);
+	g_test_add_data_func ("/contacts/parser/error_handling", service, test_parser_error_handling);
 	g_test_add_data_func ("/contacts/photo/has_photo", service, test_photo_has_photo);
-	if (g_test_slow () == TRUE) {
-		g_test_add_data_func ("/contacts/photo/add", service, test_photo_add);
-		g_test_add_data_func ("/contacts/photo/get", service, test_photo_get);
-		g_test_add_data_func ("/contacts/photo/delete", service, test_photo_delete);
-	}
+	g_test_add_data_func ("/contacts/photo/add", service, test_photo_add);
+	g_test_add_data_func ("/contacts/photo/get", service, test_photo_get);
+	g_test_add_data_func ("/contacts/photo/delete", service, test_photo_delete);
 
 	retval = g_test_run ();
 	g_object_unref (service);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]