[libgdata] Bug 613529 — Sending ETag with modified query



commit 516f791014459a423930569edca0b470ded62473
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun Mar 21 23:29:32 2010 +0000

    Bug 613529 â?? Sending ETag with modified query
    
    Ensure #GDataQuery:etag is unset after any property of a query is changed.
    This ensures that if a single query instance is reused for multiple queries
    (as in Totem's YouTube plugin), there's no chance that the server could
    unexpectedly return an "unchanged" status. Closes: bgo#613529

 gdata/gdata-query.c                              |   58 +++++++++++++++++++---
 gdata/gdata-service.c                            |    6 +-
 gdata/services/calendar/gdata-calendar-query.c   |   29 ++++++++++-
 gdata/services/contacts/gdata-contacts-query.c   |   14 +++++-
 gdata/services/documents/gdata-documents-query.c |   19 +++++++
 gdata/services/picasaweb/gdata-picasaweb-query.c |   20 +++++++-
 gdata/services/youtube/gdata-youtube-query.c     |   29 ++++++++++-
 gdata/tests/calendar.c                           |   35 ++++++++++++-
 gdata/tests/contacts.c                           |   26 +++++++++-
 gdata/tests/documents.c                          |   33 +++++++++++--
 gdata/tests/general.c                            |   37 ++++++++++++++
 gdata/tests/picasaweb.c                          |   28 ++++++++++-
 gdata/tests/youtube.c                            |   35 ++++++++++++-
 13 files changed, 343 insertions(+), 26 deletions(-)
---
diff --git a/gdata/gdata-query.c b/gdata/gdata-query.c
index 1e342e7..53010c4 100644
--- a/gdata/gdata-query.c
+++ b/gdata/gdata-query.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,16 @@
  * set, with the aim of building a query URI using gdata_query_get_query_uri(). Pagination is supported using gdata_query_next_page() and
  * gdata_query_previous_page().
  *
+ * Each query can have an ETag associated with it, which is a unique identifier for the set of query results produced by the query.
+ * Each time a query is made, gdata_service_query() will set the #GDataQuery:etag property of the accompanying query to a value returned by the
+ * server. If the same query is made again (using the same #GDataQuery instance), the server can skip returning the resulting #GDataFeed if its
+ * contents haven't changed (in this case, gdata_service_query() will return %NULL with an empty error).
+ *
+ * For this reason, code using #GDataQuery should be careful when reusing #GDataQuery instances: the code should either unset #GDataQuery:etag after
+ * every query or (preferably) gracefully handle the case where gdata_service_query() returns %NULL to signify unchanged results.
+ *
+ * Every time a property of a #GDataQuery instance is changed, the instance's ETag will be unset.
+ *
  * For more information on the standard GData query parameters supported by #GDataQuery, see the <ulink type="http"
  * url="http://code.google.com/apis/gdata/docs/2.0/reference.html#Queries";>online documentation</ulink>.
  **/
@@ -278,6 +288,9 @@ gdata_query_class_init (GDataQueryClass *klass)
 	 * The ETag against which to check for updates. If the server-side ETag matches this one, the requested feed hasn't changed, and is not
 	 * returned unnecessarily.
 	 *
+	 * Setting any of the other query properties will unset the ETag, as ETags match against entire queries. If the ETag should be used in a
+	 * query, it must be set again using gdata_query_set_etag() after setting any other properties.
+	 *
 	 * Since: 0.2.0
 	 **/
 	g_object_class_install_property (gobject_class, PROP_ETAG,
@@ -633,6 +646,9 @@ gdata_query_set_q (GDataQuery *self, const gchar *q)
 		self->priv->parameter_mask |= GDATA_QUERY_PARAM_Q;
 
 	g_object_notify (G_OBJECT (self), "q");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -673,6 +689,9 @@ gdata_query_set_categories (GDataQuery *self, const gchar *categories)
 		self->priv->parameter_mask |= GDATA_QUERY_PARAM_CATEGORIES;
 
 	g_object_notify (G_OBJECT (self), "categories");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -713,6 +732,9 @@ gdata_query_set_author (GDataQuery *self, const gchar *author)
 		self->priv->parameter_mask |= GDATA_QUERY_PARAM_AUTHOR;
 
 	g_object_notify (G_OBJECT (self), "author");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -755,6 +777,9 @@ gdata_query_set_updated_min (GDataQuery *self, GTimeVal *updated_min)
 	}
 
 	g_object_notify (G_OBJECT (self), "updated-min");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -797,6 +822,9 @@ gdata_query_set_updated_max (GDataQuery *self, GTimeVal *updated_max)
 	}
 
 	g_object_notify (G_OBJECT (self), "updated-max");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -839,6 +867,9 @@ gdata_query_set_published_min (GDataQuery *self, GTimeVal *published_min)
 	}
 
 	g_object_notify (G_OBJECT (self), "published-min");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -881,6 +912,9 @@ gdata_query_set_published_max (GDataQuery *self, GTimeVal *published_max)
 	}
 
 	g_object_notify (G_OBJECT (self), "published-max");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -925,6 +959,9 @@ gdata_query_set_start_index (GDataQuery *self, gint start_index)
 		self->priv->parameter_mask |= GDATA_QUERY_PARAM_START_INDEX;
 
 	g_object_notify (G_OBJECT (self), "start-index");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -966,6 +1003,9 @@ gdata_query_set_is_strict (GDataQuery *self, gboolean is_strict)
 		self->priv->parameter_mask |= GDATA_QUERY_PARAM_IS_STRICT;
 
 	g_object_notify (G_OBJECT (self), "is-strict");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -1006,6 +1046,9 @@ gdata_query_set_max_results (GDataQuery *self, gint max_results)
 		self->priv->parameter_mask |= GDATA_QUERY_PARAM_MAX_RESULTS;
 
 	g_object_notify (G_OBJECT (self), "max-results");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -1046,6 +1089,9 @@ gdata_query_set_entry_id (GDataQuery *self, const gchar *entry_id)
 		self->priv->parameter_mask |= GDATA_QUERY_PARAM_ENTRY_ID;
 
 	g_object_notify (G_OBJECT (self), "entry-id");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -1130,9 +1176,8 @@ gdata_query_next_page (GDataQuery *self)
 		priv->start_index += priv->max_results;
 	}
 
-	/* Our current ETag will not be relevant */
-	g_free (priv->etag);
-	priv->etag = NULL;
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -1160,9 +1205,8 @@ gdata_query_previous_page (GDataQuery *self)
 		priv->start_index -= priv->max_results;
 	}
 
-	/* Our current ETag will not be relevant */
-	g_free (priv->etag);
-	priv->etag = NULL;
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 
 	return TRUE;
 }
diff --git a/gdata/gdata-service.c b/gdata/gdata-service.c
index 1e7d490..b5e90c5 100644
--- a/gdata/gdata-service.c
+++ b/gdata/gdata-service.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2008-2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2008â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1062,14 +1062,14 @@ _gdata_service_query (GDataService *self, const gchar *feed_uri, GDataQuery *que
  * If the query is successful and the feed supports pagination, @query will be updated with the pagination URIs, and the next or previous page
  * can then be loaded by calling gdata_query_next_page() or gdata_query_previous_page() before running the query again.
  *
- * If the #GDataQuery's ETag is set and it finds a match on the server, %FALSE will be returned, but @error will remain unset. Otherwise,
+ * If the #GDataQuery's ETag is set and it finds a match on the server, %NULL will be returned, but @error will remain unset. Otherwise,
  * @query's ETag will be updated with the ETag from the returned feed, if available.
  *
  * Return value: a #GDataFeed of query results, or %NULL; unref with g_object_unref()
  **/
 GDataFeed *
 gdata_service_query (GDataService *self, const gchar *feed_uri, GDataQuery *query, GType entry_type,
-		     GCancellable *cancellable, GDataQueryProgressCallback progress_callback, gpointer progress_user_data, GError **error)
+                     GCancellable *cancellable, GDataQueryProgressCallback progress_callback, gpointer progress_user_data, GError **error)
 {
 	GDataServiceClass *klass;
 	GDataFeed *feed;
diff --git a/gdata/services/calendar/gdata-calendar-query.c b/gdata/services/calendar/gdata-calendar-query.c
index 3be47f7..0b988c9 100644
--- a/gdata/services/calendar/gdata-calendar-query.c
+++ b/gdata/services/calendar/gdata-calendar-query.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -443,6 +443,9 @@ gdata_calendar_query_set_future_events (GDataCalendarQuery *self, gboolean futur
 	g_return_if_fail (GDATA_IS_CALENDAR_QUERY (self));
 	self->priv->future_events = future_events;
 	g_object_notify (G_OBJECT (self), "future-events");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -477,6 +480,9 @@ gdata_calendar_query_set_order_by (GDataCalendarQuery *self, const gchar *order_
 	g_free (self->priv->order_by);
 	self->priv->order_by = g_strdup (order_by);
 	g_object_notify (G_OBJECT (self), "order-by");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -518,6 +524,9 @@ gdata_calendar_query_set_recurrence_expansion_start (GDataCalendarQuery *self, G
 	}
 
 	g_object_notify (G_OBJECT (self), "recurrence-expansion-start");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -559,6 +568,9 @@ gdata_calendar_query_set_recurrence_expansion_end (GDataCalendarQuery *self, GTi
 	}
 
 	g_object_notify (G_OBJECT (self), "recurrence-expansion-end");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -589,6 +601,9 @@ gdata_calendar_query_set_single_events (GDataCalendarQuery *self, gboolean singl
 	g_return_if_fail (GDATA_IS_CALENDAR_QUERY (self));
 	self->priv->single_events = single_events;
 	g_object_notify (G_OBJECT (self), "single-events");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -623,6 +638,9 @@ gdata_calendar_query_set_sort_order (GDataCalendarQuery *self, const gchar *sort
 	g_free (self->priv->sort_order);
 	self->priv->sort_order = g_strdup (sort_order);
 	g_object_notify (G_OBJECT (self), "sort-order");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -664,6 +682,9 @@ gdata_calendar_query_set_start_min (GDataCalendarQuery *self, GTimeVal *start_mi
 	}
 
 	g_object_notify (G_OBJECT (self), "start-min");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -705,6 +726,9 @@ gdata_calendar_query_set_start_max (GDataCalendarQuery *self, GTimeVal *start_ma
 	}
 
 	g_object_notify (G_OBJECT (self), "start-max");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -757,4 +781,7 @@ gdata_calendar_query_set_timezone (GDataCalendarQuery *self, const gchar *_timez
 	}
 
 	g_object_notify (G_OBJECT (self), "timezone");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
diff --git a/gdata/services/contacts/gdata-contacts-query.c b/gdata/services/contacts/gdata-contacts-query.c
index e092090..3a61e46 100644
--- a/gdata/services/contacts/gdata-contacts-query.c
+++ b/gdata/services/contacts/gdata-contacts-query.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -309,6 +309,9 @@ gdata_contacts_query_set_order_by (GDataContactsQuery *self, const gchar *order_
 	g_free (self->priv->order_by);
 	self->priv->order_by = g_strdup (order_by);
 	g_object_notify (G_OBJECT (self), "order-by");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -343,6 +346,9 @@ gdata_contacts_query_set_show_deleted (GDataContactsQuery *self, gboolean show_d
 	g_return_if_fail (GDATA_IS_CONTACTS_QUERY (self));
 	self->priv->show_deleted = show_deleted;
 	g_object_notify (G_OBJECT (self), "show-deleted");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -381,6 +387,9 @@ gdata_contacts_query_set_sort_order (GDataContactsQuery *self, const gchar *sort
 	g_free (self->priv->sort_order);
 	self->priv->sort_order = g_strdup (sort_order);
 	g_object_notify (G_OBJECT (self), "sort-order");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -419,4 +428,7 @@ gdata_contacts_query_set_group (GDataContactsQuery *self, const gchar *group)
 	g_free (self->priv->group);
 	self->priv->group = g_strdup (group);
 	g_object_notify (G_OBJECT (self), "group");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
diff --git a/gdata/services/documents/gdata-documents-query.c b/gdata/services/documents/gdata-documents-query.c
index c6d904d..cf27ff5 100644
--- a/gdata/services/documents/gdata-documents-query.c
+++ b/gdata/services/documents/gdata-documents-query.c
@@ -2,6 +2,7 @@
 /*
  * GData Client
  * Copyright (C) Thibault Saunier 2009 <saunierthibault gmail com>
+ * Copyright (C) Philip Withnall 2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -361,6 +362,9 @@ gdata_documents_query_set_show_deleted (GDataDocumentsQuery *self, gboolean show
 	g_return_if_fail (GDATA_IS_DOCUMENTS_QUERY (self));
 	self->priv->show_deleted = show_deleted;
 	g_object_notify (G_OBJECT (self), "show-deleted");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -395,6 +399,9 @@ gdata_documents_query_set_show_folders (GDataDocumentsQuery *self, gboolean show
 	g_return_if_fail (GDATA_IS_DOCUMENTS_QUERY (self));
 	self->priv->show_folders = show_folders;
 	g_object_notify (G_OBJECT (self), "show-folders");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -433,6 +440,9 @@ gdata_documents_query_set_folder_id (GDataDocumentsQuery *self, const gchar *fol
 	g_free (self->priv->folder_id);
 	self->priv->folder_id = g_strdup (folder_id);
 	g_object_notify (G_OBJECT (self), "folder-id");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -494,6 +504,9 @@ gdata_documents_query_set_title (GDataDocumentsQuery *self, const gchar *title,
 	g_object_notify (G_OBJECT (self), "exact-title");
 	g_object_notify (G_OBJECT (self), "title");
 	g_object_thaw_notify (G_OBJECT (self));
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -549,6 +562,9 @@ gdata_documents_query_add_reader (GDataDocumentsQuery *self, const gchar *email_
 
 	address = gdata_gd_email_address_new (email_address, "reader", NULL, FALSE);
 	self->priv->reader_addresses = g_list_append (self->priv->reader_addresses, address);
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -570,4 +586,7 @@ gdata_documents_query_add_collaborator (GDataDocumentsQuery *self, const gchar *
 
 	address = gdata_gd_email_address_new (email_address, "collaborator", NULL, FALSE);
 	self->priv->collaborator_addresses = g_list_append (self->priv->collaborator_addresses, address);
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
diff --git a/gdata/services/picasaweb/gdata-picasaweb-query.c b/gdata/services/picasaweb/gdata-picasaweb-query.c
index da0f3bf..8408495 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-query.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-query.c
@@ -2,7 +2,7 @@
 /*
  * GData Client
  * Copyright (C) Richard Schwarting 2009 <aquarichy gmail com>
- * Copyright (C) Philip Withnall 2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -375,6 +375,9 @@ gdata_picasaweb_query_set_visibility (GDataPicasaWebQuery *self, GDataPicasaWebV
 	g_return_if_fail (GDATA_IS_PICASAWEB_QUERY (self));
 	self->priv->visibility = visibility;
 	g_object_notify (G_OBJECT (self), "visibility");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -413,6 +416,9 @@ gdata_picasaweb_query_set_thumbnail_size (GDataPicasaWebQuery *self, const gchar
 	g_free (self->priv->thumbnail_size);
 	self->priv->thumbnail_size = g_strdup (thumbnail_size);
 	g_object_notify (G_OBJECT (self), "thumbnail-size");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -453,6 +459,9 @@ gdata_picasaweb_query_set_image_size (GDataPicasaWebQuery *self, const gchar *im
 	g_free (self->priv->image_size);
 	self->priv->image_size = g_strdup (image_size);
 	g_object_notify (G_OBJECT (self), "image-size");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -491,6 +500,9 @@ gdata_picasaweb_query_set_tag (GDataPicasaWebQuery *self, const gchar *tag)
 	g_free (self->priv->tag);
 	self->priv->tag = g_strdup (tag);
 	g_object_notify (G_OBJECT (self), "tag");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -547,6 +559,9 @@ gdata_picasaweb_query_set_bounding_box (GDataPicasaWebQuery *self, gdouble north
 	self->priv->bounding_box.east = east;
 	self->priv->bounding_box.south = south;
 	self->priv->bounding_box.west = west;
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
 
 /**
@@ -585,4 +600,7 @@ gdata_picasaweb_query_set_location (GDataPicasaWebQuery *self, const gchar *loca
 	g_free (self->priv->location);
 	self->priv->location = g_strdup (location);
 	g_object_notify (G_OBJECT (self), "location");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (self, NULL);
 }
diff --git a/gdata/services/youtube/gdata-youtube-query.c b/gdata/services/youtube/gdata-youtube-query.c
index 787b65d..a6e94a5 100644
--- a/gdata/services/youtube/gdata-youtube-query.c
+++ b/gdata/services/youtube/gdata-youtube-query.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -554,6 +554,9 @@ gdata_youtube_query_set_format (GDataYouTubeQuery *self, GDataYouTubeFormat form
 	g_return_if_fail (GDATA_IS_YOUTUBE_QUERY (self));
 	self->priv->format = format;
 	g_object_notify (G_OBJECT (self), "format");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -613,6 +616,9 @@ gdata_youtube_query_set_location (GDataYouTubeQuery *self, gdouble latitude, gdo
 	g_object_notify (G_OBJECT (self), "location-radius");
 	g_object_notify (G_OBJECT (self), "has-location");
 	g_object_thaw_notify (G_OBJECT (self));
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -650,6 +656,9 @@ gdata_youtube_query_set_language (GDataYouTubeQuery *self, const gchar *language
 	g_free (self->priv->language);
 	self->priv->language = g_strdup (language);
 	g_object_notify (G_OBJECT (self), "language");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -688,6 +697,9 @@ gdata_youtube_query_set_order_by (GDataYouTubeQuery *self, const gchar *order_by
 	g_free (self->priv->order_by);
 	self->priv->order_by = g_strdup (order_by);
 	g_object_notify (G_OBJECT (self), "order-by");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -725,6 +737,9 @@ gdata_youtube_query_set_restriction (GDataYouTubeQuery *self, const gchar *restr
 	g_free (self->priv->restriction);
 	self->priv->restriction = g_strdup (restriction);
 	g_object_notify (G_OBJECT (self), "restriction");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -759,6 +774,9 @@ gdata_youtube_query_set_safe_search (GDataYouTubeQuery *self, GDataYouTubeSafeSe
 	g_return_if_fail (GDATA_IS_YOUTUBE_QUERY (self));
 	self->priv->safe_search = safe_search;
 	g_object_notify (G_OBJECT (self), "safe-search");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -795,6 +813,9 @@ gdata_youtube_query_set_sort_order (GDataYouTubeQuery *self, GDataYouTubeSortOrd
 	g_return_if_fail (GDATA_IS_YOUTUBE_QUERY (self));
 	self->priv->sort_order = sort_order;
 	g_object_notify (G_OBJECT (self), "sort-order");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -829,6 +850,9 @@ gdata_youtube_query_set_age (GDataYouTubeQuery *self, GDataYouTubeAge age)
 	g_return_if_fail (GDATA_IS_YOUTUBE_QUERY (self));
 	self->priv->age = age;
 	g_object_notify (G_OBJECT (self), "age");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
 
 /**
@@ -863,4 +887,7 @@ gdata_youtube_query_set_uploader (GDataYouTubeQuery *self, GDataYouTubeUploader
 	g_return_if_fail (GDATA_IS_YOUTUBE_QUERY (self));
 	self->priv->uploader = uploader;
 	g_object_notify (G_OBJECT (self), "uploader");
+
+	/* Our current ETag will no longer be relevant */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
diff --git a/gdata/tests/calendar.c b/gdata/tests/calendar.c
index 80aebde..78a4695 100644
--- a/gdata/tests/calendar.c
+++ b/gdata/tests/calendar.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -449,7 +449,7 @@ test_xml_recurrence (gconstpointer service)
 }
 
 static void
-test_query_uri (gconstpointer service)
+test_query_uri (void)
 {
 	GTimeVal time_val, time_val2;
 	gchar *query_uri;
@@ -520,6 +520,34 @@ test_query_uri (gconstpointer service)
 }
 
 static void
+test_query_etag (void)
+{
+	GDataCalendarQuery *query = gdata_calendar_query_new (NULL);
+
+	/* Test that setting any property will unset the ETag */
+	g_test_bug ("613529");
+
+#define CHECK_ETAG(C) \
+	gdata_query_set_etag (GDATA_QUERY (query), "foobar");		\
+	(C);								\
+	g_assert (gdata_query_get_etag (GDATA_QUERY (query)) == NULL);
+
+	CHECK_ETAG (gdata_calendar_query_set_future_events (query, FALSE))
+	CHECK_ETAG (gdata_calendar_query_set_order_by (query, "shizzle"))
+	CHECK_ETAG (gdata_calendar_query_set_recurrence_expansion_start (query, NULL))
+	CHECK_ETAG (gdata_calendar_query_set_recurrence_expansion_end (query, NULL))
+	CHECK_ETAG (gdata_calendar_query_set_single_events (query, FALSE))
+	CHECK_ETAG (gdata_calendar_query_set_sort_order (query, "shizzle"))
+	CHECK_ETAG (gdata_calendar_query_set_start_min (query, NULL))
+	CHECK_ETAG (gdata_calendar_query_set_start_max (query, NULL))
+	CHECK_ETAG (gdata_calendar_query_set_timezone (query, "about now"))
+
+#undef CHECK_ETAG
+
+	g_object_unref (query);
+}
+
+static void
 test_acls_get_rules (gconstpointer service)
 {
 	GDataFeed *feed;
@@ -722,7 +750,8 @@ main (int argc, char *argv[])
 		g_test_add_data_func ("/calendar/insert/simple", service, test_insert_simple);
 	g_test_add_data_func ("/calendar/xml/dates", service, test_xml_dates);
 	g_test_add_data_func ("/calendar/xml/recurrence", service, test_xml_recurrence);
-	g_test_add_data_func ("/calendar/query/uri", service, test_query_uri);
+	g_test_add_func ("/calendar/query/uri", test_query_uri);
+	g_test_add_func ("/calendar/query/etag", test_query_etag);
 	g_test_add_data_func ("/calendar/acls/get_rules", service, test_acls_get_rules);
 	if (g_test_slow () == TRUE) {
 		g_test_add_data_func ("/calendar/acls/insert_rule", service, test_acls_insert_rule);
diff --git a/gdata/tests/contacts.c b/gdata/tests/contacts.c
index 504efc4..0b4e6d3 100644
--- a/gdata/tests/contacts.c
+++ b/gdata/tests/contacts.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -376,6 +376,29 @@ test_query_uri (void)
 }
 
 static void
+test_query_etag (void)
+{
+	GDataContactsQuery *query = gdata_contacts_query_new (NULL);
+
+	/* Test that setting any property will unset the ETag */
+	g_test_bug ("613529");
+
+#define CHECK_ETAG(C) \
+	gdata_query_set_etag (GDATA_QUERY (query), "foobar");		\
+	(C);								\
+	g_assert (gdata_query_get_etag (GDATA_QUERY (query)) == NULL);
+
+	CHECK_ETAG (gdata_contacts_query_set_order_by (query, "foobar"))
+	CHECK_ETAG (gdata_contacts_query_set_show_deleted (query, FALSE))
+	CHECK_ETAG (gdata_contacts_query_set_sort_order (query, "shizzle"))
+	CHECK_ETAG (gdata_contacts_query_set_group (query, "support group"))
+
+#undef CHECK_ETAG
+
+	g_object_unref (query);
+}
+
+static void
 test_query_properties (void)
 {
 	gchar *order_by, *sort_order, *group;
@@ -676,6 +699,7 @@ main (int argc, char *argv[])
 	if (g_test_thorough () == TRUE)
 		g_test_add_data_func ("/contacts/query/all_contacts_async", service, test_query_all_contacts_async);
 	g_test_add_func ("/contacts/query/uri", test_query_uri);
+	g_test_add_func ("/contacts/query/etag", test_query_etag);
 	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);
diff --git a/gdata/tests/documents.c b/gdata/tests/documents.c
index e00b520..26c39c1 100644
--- a/gdata/tests/documents.c
+++ b/gdata/tests/documents.c
@@ -2,6 +2,7 @@
 /*
  * GData Client
  * Copyright (C) Thibault Saunier 2009 <saunierthibault gmail com>
+ * Copyright (C) Philip Withnall 2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -587,6 +588,31 @@ test_new_document_with_collaborator (gconstpointer service)
 	g_object_unref (new_access_rule);
 }
 
+static void
+test_query_etag (void)
+{
+	GDataDocumentsQuery *query = gdata_documents_query_new (NULL);
+
+	/* Test that setting any property will unset the ETag */
+	g_test_bug ("613529");
+
+#define CHECK_ETAG(C) \
+	gdata_query_set_etag (GDATA_QUERY (query), "foobar");		\
+	(C);								\
+	g_assert (gdata_query_get_etag (GDATA_QUERY (query)) == NULL);
+
+	CHECK_ETAG (gdata_documents_query_set_show_deleted (query, FALSE))
+	CHECK_ETAG (gdata_documents_query_set_show_folders (query, TRUE))
+	CHECK_ETAG (gdata_documents_query_set_folder_id (query, "this-is-an-id"))
+	CHECK_ETAG (gdata_documents_query_set_title (query, "Title", FALSE))
+	CHECK_ETAG (gdata_documents_query_add_reader (query, "foo example com"))
+	CHECK_ETAG (gdata_documents_query_add_collaborator (query, "foo example com"))
+
+#undef CHECK_ETAG
+
+	g_object_unref (query);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -611,8 +637,7 @@ main (int argc, char *argv[])
 	g_test_add_data_func ("/documents/update/only_file", service, test_update_file);
 	g_test_add_data_func ("/documents/update/metadata_file", service, test_update_metadata_file);
 
-	g_test_add_data_func ("/documents/access_rules/add_document_with_a_collaborator", service,
-			      test_new_document_with_collaborator);
+	g_test_add_data_func ("/documents/access_rules/add_document_with_a_collaborator", service, test_new_document_with_collaborator);
 
 	g_test_add_data_func ("/documents/query/all_documents_with_folder", service, test_query_all_documents_with_folder);
 	g_test_add_data_func ("/documents/query/all_documents", service, test_query_all_documents);
@@ -620,11 +645,11 @@ main (int argc, char *argv[])
 		g_test_add_data_func ("/documents/query/all_documents_async", service, test_query_all_documents_async);
 
 	g_test_add_data_func ("/documents/move/move_to_folder", service, test_add_file_folder_and_move);
-
 	g_test_add_data_func ("/documents/move/remove_from_folder", service, test_add_remove_file_from_folder);
-
 	/*g_test_add_data_func ("/documents/remove/all", service, test_remove_all_documents_and_folders);*/
 
+	g_test_add_func ("/documents/query/etag", test_query_etag);
+
 	retval = g_test_run ();
 
 	g_object_unref (service);
diff --git a/gdata/tests/general.c b/gdata/tests/general.c
index 7c6b176..3ba42e5 100644
--- a/gdata/tests/general.c
+++ b/gdata/tests/general.c
@@ -611,6 +611,42 @@ test_query_unicode (void)
 }
 
 static void
+test_query_etag (void)
+{
+	GDataQuery *query = gdata_query_new (NULL);
+
+	/* Test that setting any property will unset the ETag */
+	g_test_bug ("613529");
+
+	/* Also check that setting the ETag doesn't unset the ETag! */
+	gdata_query_set_etag (query, "foobar");
+	g_assert_cmpstr (gdata_query_get_etag (query), ==, "foobar");
+
+#define CHECK_ETAG(C) \
+	gdata_query_set_etag (query, "foobar");		\
+	(C);						\
+	g_assert (gdata_query_get_etag (query) == NULL);
+
+	CHECK_ETAG (gdata_query_set_q (query, "q"))
+	CHECK_ETAG (gdata_query_set_categories (query, "shizzle,foobar"))
+	CHECK_ETAG (gdata_query_set_author (query, "John Smith"))
+	CHECK_ETAG (gdata_query_set_updated_min (query, NULL))
+	CHECK_ETAG (gdata_query_set_updated_max (query, NULL))
+	CHECK_ETAG (gdata_query_set_published_min (query, NULL))
+	CHECK_ETAG (gdata_query_set_published_max (query, NULL))
+	CHECK_ETAG (gdata_query_set_start_index (query, 5))
+	CHECK_ETAG (gdata_query_set_is_strict (query, TRUE))
+	CHECK_ETAG (gdata_query_set_max_results (query, 1000))
+	CHECK_ETAG (gdata_query_set_entry_id (query, "id"))
+	CHECK_ETAG (gdata_query_next_page (query))
+	CHECK_ETAG (gdata_query_previous_page (query))
+
+#undef CHECK_ETAG
+
+	g_object_unref (query);
+}
+
+static void
 test_access_rule_get_xml (void)
 {
 	GDataAccessRule *rule, *rule2;
@@ -2229,6 +2265,7 @@ main (int argc, char *argv[])
 	g_test_add_func ("/feed/error_handling", test_feed_error_handling);
 	g_test_add_func ("/query/categories", test_query_categories);
 	g_test_add_func ("/query/unicode", test_query_unicode);
+	g_test_add_func ("/query/etag", test_query_etag);
 	g_test_add_func ("/access-rule/get_xml", test_access_rule_get_xml);
 	g_test_add_func ("/access-rule/error_handling", test_access_rule_error_handling);
 	g_test_add_func ("/color/parsing", test_color_parsing);
diff --git a/gdata/tests/picasaweb.c b/gdata/tests/picasaweb.c
index 083bca5..88db110 100644
--- a/gdata/tests/picasaweb.c
+++ b/gdata/tests/picasaweb.c
@@ -2,7 +2,7 @@
 /*
  * GData Client
  * Copyright (C) Richard Schwarting 2009 <aquarichy gmail com>
- * Copyright (C) Philip Withnall 2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1283,6 +1283,31 @@ test_album_new (gconstpointer service)
 	g_object_unref (album);
 }
 
+static void
+test_query_etag (void)
+{
+	GDataPicasaWebQuery *query = gdata_picasaweb_query_new (NULL);
+
+	/* Test that setting any property will unset the ETag */
+	g_test_bug ("613529");
+
+#define CHECK_ETAG(C) \
+	gdata_query_set_etag (GDATA_QUERY (query), "foobar");		\
+	(C);								\
+	g_assert (gdata_query_get_etag (GDATA_QUERY (query)) == NULL);
+
+	CHECK_ETAG (gdata_picasaweb_query_set_visibility (query, GDATA_PICASAWEB_PUBLIC))
+	CHECK_ETAG (gdata_picasaweb_query_set_thumbnail_size (query, "500x430"))
+	CHECK_ETAG (gdata_picasaweb_query_set_image_size (query, "1024x768"))
+	CHECK_ETAG (gdata_picasaweb_query_set_tag (query, "tag"))
+	CHECK_ETAG (gdata_picasaweb_query_set_bounding_box (query, 0.0, 1.0, 20.0, 12.5))
+	CHECK_ETAG (gdata_picasaweb_query_set_location (query, "Somewhere near here"))
+
+#undef CHECK_ETAG
+
+	g_object_unref (query);
+}
+
 /* TODO: test private, public albums, test uploading */
 /* TODO: add queries to update albums, files on the server; test those */
 
@@ -1319,6 +1344,7 @@ main (int argc, char *argv[])
 	g_test_add_data_func ("/picasaweb/download/photo", service, test_download);
 	g_test_add_data_func ("/picasaweb/download/thumbnails", service, test_download_thumbnails);
 	g_test_add_data_func ("/picasaweb/album/new", service, test_album_new);
+	g_test_add_func ("/picasaweb/query/etag", test_query_etag);
 
 	retval = g_test_run ();
 	g_object_unref (service);
diff --git a/gdata/tests/youtube.c b/gdata/tests/youtube.c
index d22a799..6db6e9e 100644
--- a/gdata/tests/youtube.c
+++ b/gdata/tests/youtube.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * GData Client
- * Copyright (C) Philip Withnall 2008-2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2008â??2010 <philip tecnocode co uk>
  *
  * GData Client is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -593,7 +593,7 @@ test_parsing_comments_feed_link (void)
 }*/
 
 static void
-test_query_uri (gconstpointer service)
+test_query_uri (void)
 {
 	gdouble latitude, longitude, radius;
 	gboolean has_location;
@@ -672,6 +672,34 @@ test_query_uri (gconstpointer service)
 }
 
 static void
+test_query_etag (void)
+{
+	GDataYouTubeQuery *query = gdata_youtube_query_new (NULL);
+
+	/* Test that setting any property will unset the ETag */
+	g_test_bug ("613529");
+
+#define CHECK_ETAG(C) \
+	gdata_query_set_etag (GDATA_QUERY (query), "foobar");		\
+	(C);								\
+	g_assert (gdata_query_get_etag (GDATA_QUERY (query)) == NULL);
+
+	CHECK_ETAG (gdata_youtube_query_set_format (query, GDATA_YOUTUBE_FORMAT_RTSP_H263_AMR))
+	CHECK_ETAG (gdata_youtube_query_set_location (query, 0.0, 65.0, 15.0, TRUE))
+	CHECK_ETAG (gdata_youtube_query_set_language (query, "British English"))
+	CHECK_ETAG (gdata_youtube_query_set_order_by (query, "shizzle"))
+	CHECK_ETAG (gdata_youtube_query_set_restriction (query, "restriction"))
+	CHECK_ETAG (gdata_youtube_query_set_safe_search (query, GDATA_YOUTUBE_SAFE_SEARCH_MODERATE))
+	CHECK_ETAG (gdata_youtube_query_set_sort_order (query, GDATA_YOUTUBE_SORT_DESCENDING))
+	CHECK_ETAG (gdata_youtube_query_set_age (query, GDATA_YOUTUBE_AGE_THIS_WEEK))
+	CHECK_ETAG (gdata_youtube_query_set_uploader (query, GDATA_YOUTUBE_UPLOADER_PARTNER))
+
+#undef CHECK_ETAG
+
+	g_object_unref (query);
+}
+
+static void
 test_query_single (gconstpointer service)
 {
 	GDataYouTubeVideo *video;
@@ -779,7 +807,8 @@ main (int argc, char *argv[])
 	/*g_test_add_func ("/youtube/parsing/comments/feedLink", test_parsing_comments_feed_link);*/
 	g_test_add_data_func ("/youtube/parsing/yt:recorded", service, test_parsing_yt_recorded);
 	g_test_add_data_func ("/youtube/parsing/yt:accessControl", service, test_parsing_yt_access_control);
-	g_test_add_data_func ("/youtube/query/uri", service, test_query_uri);
+	g_test_add_func ("/youtube/query/uri", test_query_uri);
+	g_test_add_func ("/youtube/query/etag", test_query_etag);
 	g_test_add_data_func ("/youtube/query/single", service, test_query_single);
 	if (g_test_slow () == TRUE)
 		g_test_add_data_func ("/youtube/query/single_async", service, test_query_single_async);



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