[libgdata] Bug 610948 — Improve access control support



commit 745a59088cb0070ef3f5729ab62aa70e6d2487d3
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun Mar 7 22:23:12 2010 +0000

    Bug 610948 â?? Improve access control support
    
    Remove the gdata_youtube_video_[get|set]_no_embed() functions and replace
    them with gdata_youtube_video_[get|set]_access_control(), GDataYouTubeAction
    and GDataYouTubePermission. This allows more permissions to be set on
    YouTube videos, using their new permissions system. Closes: bgo#610948

 docs/reference/gdata-sections.txt            |   10 ++-
 gdata/gdata.symbols                          |    6 +-
 gdata/services/youtube/gdata-youtube-video.c |  150 +++++++++++++++++++-------
 gdata/services/youtube/gdata-youtube-video.h |   45 ++++++++-
 gdata/tests/youtube.c                        |   93 ++++++++++++++++
 5 files changed, 260 insertions(+), 44 deletions(-)
---
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index 2d42d10..138021a 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -209,6 +209,8 @@ GDataYouTubeServicePrivate
 GDataYouTubeVideo
 GDataYouTubeVideoClass
 GDataYouTubeAspectRatio
+GDataYouTubeAction
+GDataYouTubePermission
 gdata_youtube_video_new
 gdata_youtube_video_look_up_content
 gdata_youtube_video_get_thumbnails
@@ -225,8 +227,8 @@ gdata_youtube_video_set_location
 gdata_youtube_video_get_view_count
 gdata_youtube_video_get_favorite_count
 gdata_youtube_video_is_restricted_in_country
-gdata_youtube_video_get_no_embed
-gdata_youtube_video_set_no_embed
+gdata_youtube_video_get_access_control
+gdata_youtube_video_set_access_control
 gdata_youtube_video_get_player_uri
 gdata_youtube_video_is_private
 gdata_youtube_video_set_is_private
@@ -250,7 +252,11 @@ GDATA_YOUTUBE_VIDEO_CLASS
 GDATA_YOUTUBE_VIDEO_GET_CLASS
 gdata_youtube_video_get_type
 GDATA_TYPE_YOUTUBE_ASPECT_RATIO
+GDATA_TYPE_YOUTUBE_ACTION
+GDATA_TYPE_YOUTUBE_PERMISSION
 gdata_youtube_aspect_ratio_get_type
+gdata_youtube_action_get_type
+gdata_youtube_permission_get_type
 <SUBSECTION Private>
 GDataYouTubeVideoPrivate
 </SECTION>
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index 90c8364..893fec8 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -118,8 +118,8 @@ gdata_youtube_video_get_view_count
 gdata_youtube_video_get_favorite_count
 gdata_youtube_video_get_location
 gdata_youtube_video_set_location
-gdata_youtube_video_get_no_embed
-gdata_youtube_video_set_no_embed
+gdata_youtube_video_get_access_control
+gdata_youtube_video_set_access_control
 gdata_youtube_video_get_rating
 gdata_youtube_video_get_keywords
 gdata_youtube_video_set_keywords
@@ -713,3 +713,5 @@ gdata_gd_name_get_suffix
 gdata_gd_name_set_suffix
 gdata_gd_name_get_full_name
 gdata_gd_name_set_full_name
+gdata_youtube_action_get_type
+gdata_youtube_permission_get_type
diff --git a/gdata/services/youtube/gdata-youtube-video.c b/gdata/services/youtube/gdata-youtube-video.c
index f89a4a6..0379d5c 100644
--- a/gdata/services/youtube/gdata-youtube-video.c
+++ b/gdata/services/youtube/gdata-youtube-video.c
@@ -92,7 +92,7 @@ struct _GDataYouTubeVideoPrivate {
 	guint view_count;
 	guint favorite_count;
 	gchar *location;
-	gboolean no_embed;
+	GHashTable *access_controls;
 
 	/* gd:rating attributes */
 	struct {
@@ -114,7 +114,6 @@ enum {
 	PROP_VIEW_COUNT = 1,
 	PROP_FAVORITE_COUNT,
 	PROP_LOCATION,
-	PROP_NO_EMBED,
 	PROP_MIN_RATING,
 	PROP_MAX_RATING,
 	PROP_RATING_COUNT,
@@ -198,20 +197,6 @@ gdata_youtube_video_class_init (GDataYouTubeVideoClass *klass)
 					G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
 	/**
-	 * GDataYouTubeVideo:no-embed:
-	 *
-	 * Specifies whether the video may not be embedded on other websites.
-	 *
-	 * For more information, see the <ulink type="http"
-	 * url="http://code.google.com/apis/youtube/2.0/reference.html#youtube_data_api_tag_yt:noembed";>online documentation</ulink>.
-	 **/
-	g_object_class_install_property (gobject_class, PROP_NO_EMBED,
-				g_param_spec_boolean ("no-embed",
-					"No embed?", "Specifies whether the video may not be embedded on other websites.",
-					FALSE,
-					G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-	/**
 	 * GDataYouTubeVideo:min-rating:
 	 *
 	 * The minimum allowed rating for the video.
@@ -469,6 +454,7 @@ static void
 gdata_youtube_video_init (GDataYouTubeVideo *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_YOUTUBE_VIDEO, GDataYouTubeVideoPrivate);
+	self->priv->access_controls = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
 
 	/* The video's title is duplicated between atom:title and media:group/media:title, so listen for change notifications on atom:title
 	 * and propagate them to media:group/media:title accordingly. Since the media group isn't publically accessible, we don't need to
@@ -499,6 +485,7 @@ gdata_youtube_video_finalize (GObject *object)
 	GDataYouTubeVideoPrivate *priv = GDATA_YOUTUBE_VIDEO (object)->priv;
 
 	g_free (priv->location);
+	g_hash_table_destroy (priv->access_controls);
 
 	/* Chain up to the parent class */
 	G_OBJECT_CLASS (gdata_youtube_video_parent_class)->finalize (object);
@@ -519,9 +506,6 @@ gdata_youtube_video_get_property (GObject *object, guint property_id, GValue *va
 		case PROP_LOCATION:
 			g_value_set_string (value, priv->location);
 			break;
-		case PROP_NO_EMBED:
-			g_value_set_boolean (value, priv->no_embed);
-			break;
 		case PROP_MIN_RATING:
 			g_value_set_uint (value, priv->rating.min);
 			break;
@@ -591,9 +575,6 @@ gdata_youtube_video_set_property (GObject *object, guint property_id, const GVal
 		case PROP_LOCATION:
 			gdata_youtube_video_set_location (self, g_value_get_string (value));
 			break;
-		case PROP_NO_EMBED:
-			gdata_youtube_video_set_no_embed (self, g_value_get_boolean (value));
-			break;
 		case PROP_KEYWORDS:
 			gdata_youtube_video_set_keywords (self, g_value_get_string (value));
 			break;
@@ -741,7 +722,37 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 		self->priv->location = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "noembed") == 0) {
 		/* yt:noembed */
-		gdata_youtube_video_set_no_embed (self, TRUE);
+		/* Ignore this now; it's been superceded by yt:accessControl.
+		   See http://apiblog.youtube.com/2010/02/extended-access-controls-available-via.html */
+	} else if (xmlStrcmp (node->name, (xmlChar*) "accessControl") == 0) {
+		/* yt:accessControl */
+		xmlChar *action, *permission;
+		GDataYouTubePermission permission_enum;
+
+		action = xmlGetProp (node, (xmlChar*) "action");
+		if (action == NULL)
+			return gdata_parser_error_required_property_missing (node, "action", error);
+		permission = xmlGetProp (node, (xmlChar*) "permission");
+		if (permission == NULL) {
+			xmlFree (action);
+			return gdata_parser_error_required_property_missing (node, "permission", error);
+		}
+
+		/* Work out what the permission is */
+		if (xmlStrcmp (permission, (xmlChar*) "allowed") == 0) {
+			permission_enum = GDATA_YOUTUBE_PERMISSION_ALLOWED;
+		} else if (xmlStrcmp (permission, (xmlChar*) "denied") == 0) {
+			permission_enum = GDATA_YOUTUBE_PERMISSION_DENIED;
+		} else if (xmlStrcmp (permission, (xmlChar*) "moderated") == 0) {
+			permission_enum = GDATA_YOUTUBE_PERMISSION_MODERATED;
+		} else {
+			xmlFree (action);
+			xmlFree (permission);
+			return gdata_parser_error_unknown_property_value (node, "permission", (gchar*) permission, error);
+		}
+
+		/* Store the access control */
+		g_hash_table_insert (self->priv->access_controls, (gchar*) action, GINT_TO_POINTER (permission_enum));
 	} else if (xmlStrcmp (node->name, (xmlChar*) "recorded") == 0) {
 		/* yt:recorded */
 		xmlChar *recorded;
@@ -793,6 +804,29 @@ post_parse_xml (GDataParsable *parsable, gpointer user_data, GError **error)
 }
 
 static void
+access_control_cb (const gchar *action, gpointer value, GString *xml_string)
+{
+	GDataYouTubePermission permission = GPOINTER_TO_INT (value);
+	const gchar *permission_string;
+
+	switch (permission) {
+		case GDATA_YOUTUBE_PERMISSION_ALLOWED:
+			permission_string = "allowed";
+			break;
+		case GDATA_YOUTUBE_PERMISSION_DENIED:
+			permission_string = "denied";
+			break;
+		case GDATA_YOUTUBE_PERMISSION_MODERATED:
+			permission_string = "moderated";
+			break;
+		default:
+			g_assert_not_reached ();
+	}
+
+	g_string_append_printf (xml_string, "<yt:accessControl action='%s' permission='%s'/>", action, permission_string);
+}
+
+static void
 get_xml (GDataParsable *parsable, GString *xml_string)
 {
 	GDataYouTubeVideoPrivate *priv = GDATA_YOUTUBE_VIDEO (parsable)->priv;
@@ -812,8 +846,8 @@ get_xml (GDataParsable *parsable, GString *xml_string)
 		g_free (recorded);
 	}
 
-	if (priv->no_embed == TRUE)
-		g_string_append (xml_string, "<yt:noembed/>");
+	/* yt:accessControl */
+	g_hash_table_foreach (priv->access_controls, (GHFunc) access_control_cb, xml_string);
 
 	/* app:control */
 	_gdata_parsable_get_xml (GDATA_PARSABLE (priv->youtube_control), xml_string, FALSE);
@@ -903,34 +937,74 @@ gdata_youtube_video_set_location (GDataYouTubeVideo *self, const gchar *location
 	g_object_notify (G_OBJECT (self), "location");
 }
 
+/* Convert a GDataYouTubeAction into its string representation.
+ * See: http://code.google.com/apis/youtube/2.0/reference.html#youtube_data_api_tag_yt:accessControl */
+static const gchar *
+action_to_string (GDataYouTubeAction action)
+{
+	switch (action) {
+		case GDATA_YOUTUBE_ACTION_RATE:
+			return "rate";
+		case GDATA_YOUTUBE_ACTION_COMMENT:
+			return "comment";
+		case GDATA_YOUTUBE_ACTION_COMMENT_VOTE:
+			return "commentVote";
+		case GDATA_YOUTUBE_ACTION_VIDEO_RESPOND:
+			return "videoRespond";
+		case GDATA_YOUTUBE_ACTION_EMBED:
+			return "embed";
+		case GDATA_YOUTUBE_ACTION_SYNDICATE:
+			return "syndicate";
+		default:
+			g_assert_not_reached ();
+	}
+}
+
 /**
- * gdata_youtube_video_get_no_embed:
+ * gdata_youtube_video_get_access_control:
  * @self: a #GDataYouTubeVideo
+ * @action: the action whose permission should be returned
+ *
+ * Gets the permission associated with the given @action on the #GDataYouTubeVideo. If the given @action
+ * doesn't have a permission set on the video, %GDATA_YOUTUBE_PERMISSION_DENIED is returned.
  *
- * Gets the #GDataYouTubeVideo:no-embed property.
+ * Return value: the permission associated with @action, or %GDATA_YOUTUBE_PERMISSION_DENIED
  *
- * Return value: %TRUE if the video cannot be embedded on web pages, %FALSE otherwise
+ * Since: 0.7.0
  **/
-gboolean
-gdata_youtube_video_get_no_embed (GDataYouTubeVideo *self)
+GDataYouTubePermission
+gdata_youtube_video_get_access_control (GDataYouTubeVideo *self, GDataYouTubeAction action)
 {
-	g_return_val_if_fail (GDATA_IS_YOUTUBE_VIDEO (self), FALSE);
-	return self->priv->no_embed;
+	gpointer value;
+
+	g_return_val_if_fail (GDATA_IS_YOUTUBE_VIDEO (self), GDATA_YOUTUBE_PERMISSION_DENIED);
+
+	if (g_hash_table_lookup_extended (self->priv->access_controls, action_to_string (action), NULL, &value) == FALSE)
+		return GDATA_YOUTUBE_PERMISSION_DENIED;
+	return GPOINTER_TO_INT (value);
 }
 
 /**
- * gdata_youtube_video_set_no_embed:
+ * gdata_youtube_video_set_access_control:
  * @self: a #GDataYouTubeVideo
- * @no_embed: whether the video can be embedded 
+ * @action: the action whose permission is being set
+ * @permission: the permission to give to the action
+ *
+ * Sets the permission associated with @action on the #GDataYouTubeVideo, allowing restriction or derestriction of various
+ * operations on YouTube videos.
  *
- * Sets the #GDataYouTubeVideo:no-embed property to @no_embed.
+ * Note that only %GDATA_YOUTUBE_ACTION_RATE and %GDATA_YOUTUBE_ACTION_COMMENT actions can have the %GDATA_YOUTUBE_PERMISSION_MODERATED permission.
+ *
+ * Since: 0.7.0
  **/
 void
-gdata_youtube_video_set_no_embed (GDataYouTubeVideo *self, gboolean no_embed)
+gdata_youtube_video_set_access_control (GDataYouTubeVideo *self, GDataYouTubeAction action, GDataYouTubePermission permission)
 {
 	g_return_if_fail (GDATA_IS_YOUTUBE_VIDEO (self));
-	self->priv->no_embed = no_embed;
-	g_object_notify (G_OBJECT (self), "no-embed");
+	g_return_if_fail (action == GDATA_YOUTUBE_ACTION_RATE || action == GDATA_YOUTUBE_ACTION_COMMENT ||
+	                  permission != GDATA_YOUTUBE_PERMISSION_MODERATED);
+
+	g_hash_table_replace (self->priv->access_controls, g_strdup (action_to_string (action)), GINT_TO_POINTER (permission));
 }
 
 /**
diff --git a/gdata/services/youtube/gdata-youtube-video.h b/gdata/services/youtube/gdata-youtube-video.h
index a7b69e2..6f723a0 100644
--- a/gdata/services/youtube/gdata-youtube-video.h
+++ b/gdata/services/youtube/gdata-youtube-video.h
@@ -47,6 +47,47 @@ typedef enum {
 	GDATA_YOUTUBE_ASPECT_RATIO_WIDESCREEN
 } GDataYouTubeAspectRatio;
 
+/**
+ * GDataYouTubeAction:
+ * @GDATA_YOUTUBE_ACTION_RATE: rate the video
+ * @GDATA_YOUTUBE_ACTION_COMMENT: comment on the video
+ * @GDATA_YOUTUBE_ACTION_COMMENT_VOTE: rate other users' comments on the video
+ * @GDATA_YOUTUBE_ACTION_VIDEO_RESPOND: add a video response to the video
+ * @GDATA_YOUTUBE_ACTION_EMBED: embed the video on third-party websites
+ * @GDATA_YOUTUBE_ACTION_SYNDICATE: YouTube can show the video on mobile phones and televisions
+ *
+ * Access-controllable actions which can be performed on a #GDataYouTubeVideo. The permissions for each action
+ * can be set using gdata_youtube_video_set_access_control().
+ *
+ * Since: 0.7.0
+ **/
+typedef enum {
+	GDATA_YOUTUBE_ACTION_RATE,
+	GDATA_YOUTUBE_ACTION_COMMENT,
+	GDATA_YOUTUBE_ACTION_COMMENT_VOTE,
+	GDATA_YOUTUBE_ACTION_VIDEO_RESPOND,
+	GDATA_YOUTUBE_ACTION_EMBED,
+	GDATA_YOUTUBE_ACTION_SYNDICATE
+} GDataYouTubeAction;
+
+/**
+ * GDataYouTubePermission:
+ * @GDATA_YOUTUBE_PERMISSION_ALLOWED: the action is allowed for everyone
+ * @GDATA_YOUTUBE_PERMISSION_DENIED: the action is denied for everyone
+ * @GDATA_YOUTUBE_PERMISSION_MODERATED: the action is moderated by the video owner
+ *
+ * Permissions for #GDataYouTubeAction<!-- -->s which can be set on a #GDataYouTubeVideo using gdata_youtube_video_set_access_control().
+ *
+ * The only actions which can have the %GDATA_YOUTUBE_PERMISSION_MODERATED permission are %GDATA_YOUTUBE_ACTION_RATE and %GDATA_YOUTUBE_ACTION_COMMENT.
+ *
+ * Since: 0.7.0
+ **/
+typedef enum {
+	GDATA_YOUTUBE_PERMISSION_ALLOWED,
+	GDATA_YOUTUBE_PERMISSION_DENIED,
+	GDATA_YOUTUBE_PERMISSION_MODERATED
+} GDataYouTubePermission;
+
 #define GDATA_TYPE_YOUTUBE_VIDEO		(gdata_youtube_video_get_type ())
 #define GDATA_YOUTUBE_VIDEO(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), GDATA_TYPE_YOUTUBE_VIDEO, GDataYouTubeVideo))
 #define GDATA_YOUTUBE_VIDEO_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), GDATA_TYPE_YOUTUBE_VIDEO, GDataYouTubeVideoClass))
@@ -84,8 +125,8 @@ guint gdata_youtube_video_get_view_count (GDataYouTubeVideo *self);
 guint gdata_youtube_video_get_favorite_count (GDataYouTubeVideo *self);
 const gchar *gdata_youtube_video_get_location (GDataYouTubeVideo *self);
 void gdata_youtube_video_set_location (GDataYouTubeVideo *self, const gchar *location);
-gboolean gdata_youtube_video_get_no_embed (GDataYouTubeVideo *self);
-void gdata_youtube_video_set_no_embed (GDataYouTubeVideo *self, gboolean no_embed);
+GDataYouTubePermission gdata_youtube_video_get_access_control (GDataYouTubeVideo *self, GDataYouTubeAction action);
+void gdata_youtube_video_set_access_control (GDataYouTubeVideo *self, GDataYouTubeAction action, GDataYouTubePermission permission);
 void gdata_youtube_video_get_rating (GDataYouTubeVideo *self, guint *min, guint *max, guint *count, gdouble *average);
 const gchar *gdata_youtube_video_get_keywords (GDataYouTubeVideo *self);
 void gdata_youtube_video_set_keywords (GDataYouTubeVideo *self, const gchar *keywords);
diff --git a/gdata/tests/youtube.c b/gdata/tests/youtube.c
index 557ac8a..8b09807 100644
--- a/gdata/tests/youtube.c
+++ b/gdata/tests/youtube.c
@@ -450,6 +450,98 @@ test_parsing_yt_recorded (gconstpointer service)
 	g_object_unref (video);
 }
 
+static void
+test_parsing_yt_access_control (gconstpointer service)
+{
+	GDataYouTubeVideo *video;
+	gchar *xml;
+	GError *error = NULL;
+
+	video = GDATA_YOUTUBE_VIDEO (gdata_parsable_new_from_xml (GDATA_TYPE_YOUTUBE_VIDEO,
+		"<entry xmlns='http://www.w3.org/2005/Atom' "
+			"xmlns:media='http://search.yahoo.com/mrss/' "
+			"xmlns:yt='http://gdata.youtube.com/schemas/2007' "
+			"xmlns:gd='http://schemas.google.com/g/2005' "
+			"gd:etag='W/\"CEMFSX47eCp7ImA9WxVUGEw.\"'>"
+			"<id>tag:youtube.com,2008:video:JAagedeKdcQ</id>"
+			"<published>2006-05-16T14:06:37.000Z</published>"
+			"<updated>2009-03-23T12:46:58.000Z</updated>"
+			"<category scheme='http://schemas.google.com/g/2005#kind' term='http://gdata.youtube.com/schemas/2007#video'/>"
+			"<title>Judas Priest - Painkiller</title>"
+			"<link rel='http://www.iana.org/assignments/relation/alternate' type='text/html' href='http://www.youtube.com/watch?v=JAagedeKdcQ'/>"
+			"<link rel='http://www.iana.org/assignments/relation/self' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/JAagedeKdcQ?client=ytapi-google-jsdemo'/>"
+			"<author>"
+				"<name>eluves</name>"
+				"<uri>http://gdata.youtube.com/feeds/api/users/eluves</uri>"
+			"</author>"
+			"<media:group>"
+				"<media:title type='plain'>Judas Priest - Painkiller</media:title>"
+				"<media:credit role='uploader' scheme='urn:youtube'>eluves</media:credit>"
+				"<media:category label='Music' scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>Music</media:category>"
+			"</media:group>"
+			"<yt:accessControl action='rate' permission='allowed'/>"
+			"<yt:accessControl action='comment' permission='moderated'/>"
+			"<yt:accessControl action='commentVote' permission='denied'/>"
+			"<yt:accessControl action='videoRespond' permission='allowed'/>"
+			"<yt:accessControl action='syndicate' permission='denied'/>"
+			"<yt:accessControl action='random' permission='moderated'/>"
+		"</entry>", -1, &error));
+	g_assert_no_error (error);
+	g_assert (GDATA_IS_YOUTUBE_VIDEO (video));
+	g_clear_error (&error);
+
+	/* Test the access controls */
+	g_assert_cmpint (gdata_youtube_video_get_access_control (video, GDATA_YOUTUBE_ACTION_RATE), ==, GDATA_YOUTUBE_PERMISSION_ALLOWED);
+	g_assert_cmpint (gdata_youtube_video_get_access_control (video, GDATA_YOUTUBE_ACTION_COMMENT), ==, GDATA_YOUTUBE_PERMISSION_MODERATED);
+	g_assert_cmpint (gdata_youtube_video_get_access_control (video, GDATA_YOUTUBE_ACTION_COMMENT_VOTE), ==, GDATA_YOUTUBE_PERMISSION_DENIED);
+	g_assert_cmpint (gdata_youtube_video_get_access_control (video, GDATA_YOUTUBE_ACTION_VIDEO_RESPOND), ==, GDATA_YOUTUBE_PERMISSION_ALLOWED);
+	g_assert_cmpint (gdata_youtube_video_get_access_control (video, GDATA_YOUTUBE_ACTION_EMBED), ==, GDATA_YOUTUBE_PERMISSION_DENIED);
+	g_assert_cmpint (gdata_youtube_video_get_access_control (video, GDATA_YOUTUBE_ACTION_SYNDICATE), ==, GDATA_YOUTUBE_PERMISSION_DENIED);
+
+	/* Update some of them and see if the XML's written out OK */
+	gdata_youtube_video_set_access_control (video, GDATA_YOUTUBE_ACTION_RATE, GDATA_YOUTUBE_PERMISSION_MODERATED);
+	gdata_youtube_video_set_access_control (video, GDATA_YOUTUBE_ACTION_EMBED, GDATA_YOUTUBE_PERMISSION_DENIED);
+
+	/* Check the XML */
+	xml = gdata_parsable_get_xml (GDATA_PARSABLE (video));
+	g_assert_cmpstr (xml, ==,
+			 "<entry xmlns='http://www.w3.org/2005/Atom' "
+				"xmlns:media='http://search.yahoo.com/mrss/' "
+				"xmlns:gd='http://schemas.google.com/g/2005' "
+				"xmlns:yt='http://gdata.youtube.com/schemas/2007' "
+				"xmlns:app='http://www.w3.org/2007/app' "
+				"gd:etag='W/\"CEMFSX47eCp7ImA9WxVUGEw.\"'>"
+				"<title type='text'>Judas Priest - Painkiller</title>"
+				"<id>tag:youtube.com,2008:video:JAagedeKdcQ</id>"
+				"<updated>2009-03-23T12:46:58Z</updated>"
+				"<published>2006-05-16T14:06:37Z</published>"
+				"<category term='http://gdata.youtube.com/schemas/2007#video' scheme='http://schemas.google.com/g/2005#kind'/>"
+				"<link href='http://www.youtube.com/watch?v=JAagedeKdcQ' rel='http://www.iana.org/assignments/relation/alternate' type='text/html'/>"
+				"<link href='http://gdata.youtube.com/feeds/api/videos/JAagedeKdcQ?client=ytapi-google-jsdemo' rel='http://www.iana.org/assignments/relation/self' type='application/atom+xml'/>"
+				"<author>"
+					"<name>eluves</name>"
+					"<uri>http://gdata.youtube.com/feeds/api/users/eluves</uri>"
+				"</author>"
+				"<media:group>"
+					"<media:category scheme='http://gdata.youtube.com/schemas/2007/categories.cat' label='Music'>Music</media:category>"
+					"<media:title type='plain'>Judas Priest - Painkiller</media:title>"
+				"</media:group>"
+				"<yt:accessControl action='embed' permission='denied'/>"
+				"<yt:accessControl action='random' permission='moderated'/>"
+				"<yt:accessControl action='commentVote' permission='denied'/>"
+				"<yt:accessControl action='rate' permission='moderated'/>"
+				"<yt:accessControl action='comment' permission='moderated'/>"
+				"<yt:accessControl action='syndicate' permission='denied'/>"
+				"<yt:accessControl action='videoRespond' permission='allowed'/>"
+				"<app:control>"
+					"<app:draft>no</app:draft>"
+				"</app:control>"
+			 "</entry>");
+	g_free (xml);
+
+	g_object_unref (video);
+}
+
 /*static void
 test_parsing_comments_feed_link (void)
 {
@@ -672,6 +764,7 @@ main (int argc, char *argv[])
 	g_test_add_data_func ("/youtube/parsing/app:control", service, test_parsing_app_control);
 	/*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_data_func ("/youtube/query/single", service, test_query_single);
 	if (g_test_slow () == TRUE)



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