[libgdata/wip/calendar-v3: 1/3] calendar: WIP work to port to the v3 API
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata/wip/calendar-v3: 1/3] calendar: WIP work to port to the v3 API
- Date: Tue, 31 Mar 2015 14:49:13 +0000 (UTC)
commit d0fd1f22a15f0e47d80490ebd588287c4cac6bd0
Author: Philip Withnall <philip tecnocode co uk>
Date: Sun Dec 14 23:14:31 2014 +0000
calendar: WIP work to port to the v3 API
https://bugzilla.gnome.org/show_bug.cgi?id=664353
gdata/gdata-entry.c | 2 +
gdata/gdata-feed.c | 4 +-
gdata/gdata-oauth2-authorizer.c | 9 +
gdata/gdata-parsable.c | 14 +-
gdata/gdata-parser.c | 91 +++++++++++
gdata/gdata-parser.h | 8 +
gdata/services/calendar/gdata-calendar-calendar.c | 179 ++++++++++-----------
gdata/services/calendar/gdata-calendar-feed.c | 73 ++-------
gdata/services/calendar/gdata-calendar-service.c | 88 ++++++----
gdata/tests/calendar.c | 169 ++++++++++++--------
10 files changed, 376 insertions(+), 261 deletions(-)
---
diff --git a/gdata/gdata-entry.c b/gdata/gdata-entry.c
index be242e5..c4430ea 100644
--- a/gdata/gdata-entry.c
+++ b/gdata/gdata-entry.c
@@ -884,10 +884,12 @@ gdata_entry_add_category (GDataEntry *self, GDataCategory *category)
GDataEntryClass *klass = GDATA_ENTRY_GET_CLASS (self);
GList *element;
+#if 0
if (klass->kind_term != NULL && g_strcmp0 (gdata_category_get_term (category),
klass->kind_term) != 0) {
g_warning ("Adding a kind category term, '%s', to an entry of kind '%s'.",
gdata_category_get_term (category), klass->kind_term);
}
+#endif
/* If it is a kind category, remove the entry’s existing kind category to allow the new one
* to be added. This is necessary because the existing category was set in
diff --git a/gdata/gdata-feed.c b/gdata/gdata-feed.c
index 68ed7a0..9609c8f 100644
--- a/gdata/gdata-feed.c
+++ b/gdata/gdata-feed.c
@@ -612,8 +612,10 @@ parse_json (GDataParsable *parsable, JsonReader *reader, gpointer user_data, GEr
/* Parse the node, passing it the reader cursor. */
entry = GDATA_ENTRY (_gdata_parsable_new_from_json_node (entry_type, reader, NULL,
error));
- if (entry == NULL)
+ if (entry == NULL) {
+ json_reader_end_element (reader);
return FALSE;
+ }
/* Calls the callbacks in the main thread */
if (data != NULL)
diff --git a/gdata/gdata-oauth2-authorizer.c b/gdata/gdata-oauth2-authorizer.c
index 3117b9d..52d6614 100644
--- a/gdata/gdata-oauth2-authorizer.c
+++ b/gdata/gdata-oauth2-authorizer.c
@@ -1019,6 +1019,15 @@ parse_grant_error (GDataOAuth2Authorizer *self, guint status,
/* Parse the error response */
parser = json_parser_new ();
+ if (response_body == NULL) {
+ g_clear_error (&child_error);
+ g_set_error_literal (&child_error, GDATA_SERVICE_ERROR,
+ GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
+ _("The server returned a malformed response."));
+
+ goto done;
+ }
+
json_parser_load_from_data (parser, response_body, length,
&child_error);
diff --git a/gdata/gdata-parsable.c b/gdata/gdata-parsable.c
index 242f6b8..e1822ec 100644
--- a/gdata/gdata-parsable.c
+++ b/gdata/gdata-parsable.c
@@ -209,17 +209,20 @@ _json_reader_dup_current_node (JsonReader *reader)
}
} else if (json_reader_is_object (reader) == TRUE) {
/* Object nodes require deep copies. */
- gint i, members;
+ gint i;
+ gchar **members;
JsonObject *obj;
obj = json_object_new ();
- for (i = 0, members = json_reader_count_members (reader); i < members; i++) {
- json_reader_read_element (reader, i);
- json_object_set_member (obj, json_reader_get_member_name (reader),
_json_reader_dup_current_node (reader));
- json_reader_end_element (reader);
+ for (i = 0, members = json_reader_list_members (reader); members[i] != NULL; i++) {
+ json_reader_read_member (reader, members[i]);
+ json_object_set_member (obj, members[i], _json_reader_dup_current_node (reader));
+ json_reader_end_member (reader);
}
+ g_strfreev (members);
+
value = json_node_new (JSON_NODE_OBJECT);
json_node_take_object (value, obj);
} else if (json_reader_is_array (reader) == TRUE) {
@@ -526,6 +529,7 @@ _gdata_parsable_new_from_json_node (GType parsable_type, JsonReader *reader, gpo
g_return_val_if_fail (json_reader_read_element (reader, i), NULL);
if (klass->parse_json (parsable, reader, user_data, error) == FALSE) {
+ json_reader_end_element (reader);
g_object_unref (parsable);
return NULL;
}
diff --git a/gdata/gdata-parser.c b/gdata/gdata-parser.c
index 0e655a5..bde97c9 100644
--- a/gdata/gdata-parser.c
+++ b/gdata/gdata-parser.c
@@ -29,6 +29,7 @@
#include "gdata-parser.h"
#include "gdata-service.h"
+#include "gdata-types.h"
#include "gdata-private.h"
static gchar *
@@ -916,6 +917,96 @@ gdata_parser_boolean_from_json_member (JsonReader *reader, const gchar *member_n
return TRUE;
}
+/*
+ * gdata_parser_color_from_json_member:
+ * @reader: #JsonReader cursor object to read JSON node from
+ * @element_name: the name of the element to parse
+ * @options: a bitwise combination of parsing options from #GDataParserOptions,
+ * or %P_NONE
+ * @output: (out caller-allocates): the return location for the parsed colour
+ * value
+ * @success: the return location for a value which is %TRUE if the colour was
+ * parsed successfully, %FALSE if an error was encountered, and undefined if
+ * @element didn't match @element_name
+ * @error: a #GError, or %NULL
+ *
+ * TODO
+ * Gets the colour value of @element if its name is @element_name, subject to various checks specified by
@options. It expects the text content
+ * of @element to be a date or time value in ISO 8601 format. The returned time value will be a UNIX
timestamp (seconds since the epoch).
+ *
+ * If @element doesn't match @element_name, %FALSE will be returned, @error will be unset and @success will
be unset.
+ *
+ * If @element matches @element_name but one of the checks specified by @options fails, %TRUE will be
returned, @error will be set to a
+ * %GDATA_SERVICE_ERROR_PROTOCOL_ERROR error and @success will be set to %FALSE.
+ *
+ * If @element matches @element_name and all of the checks specified by @options pass, %TRUE will be
returned, @error will be unset and
+ * @success will be set to %TRUE.
+ *
+ * The reason for returning the success of the parsing in @success is so that calls to
gdata_parser_int64_time_from_element() can be chained
+ * together in a large "or" statement based on their return values, for the purposes of determining whether
any of the calls matched
+ * a given @element. If any of the calls to gdata_parser_int64_time_from_element() return %TRUE, the value
of @success can be examined.
+ *
+ * Return value: %TRUE if @element matched @element_name, %FALSE otherwise
+ *
+ * Since: UNRELEASED
+ */
+gboolean
+gdata_parser_color_from_json_member (JsonReader *reader,
+ const gchar *member_name,
+ GDataParserOptions options,
+ GDataColor *output,
+ gboolean *success,
+ GError **error)
+{
+ const gchar *text;
+ GDataColor colour;
+ const GError *child_error = NULL;
+
+ /* Check if there's such an element */
+ if (g_strcmp0 (json_reader_get_member_name (reader), member_name) != 0) {
+ return FALSE;
+ }
+
+ /* Check if the output colour has already been set. The JSON parser
+ * guarantees this can't happen. */
+ g_assert (!(options & P_NO_DUPES) ||
+ (output->red == 0 && output->green == 0 && output->blue == 0));
+
+ /* Get the string and check it for NULLness. Check for errors first. */
+ text = json_reader_get_string_value (reader);
+ child_error = json_reader_get_error (reader);
+ if (child_error != NULL) {
+ *success = parser_error_from_json_error (reader, child_error, error);
+ return TRUE;
+ } else if (options & P_REQUIRED && (text == NULL || *text == '\0')) {
+ *success = gdata_parser_error_required_json_content_missing (reader, error);
+ return TRUE;
+ }
+
+ /* Attempt to parse the string as a hexadecimal colour. */
+ if (gdata_color_from_hexadecimal (text, &colour) == FALSE) {
+ /* Error */
+ g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
+ /* Translators: the first parameter is the name of an XML element (including the
angle brackets
+ * ("<" and ">"), and the second parameter is the erroneous value (which was not
in hexadecimal
+ * RGB format).
+ *
+ * For example:
+ * The content of a <entry/gCal:color> element ("00FG56") was not in
hexadecimal RGB format. */
+ _("The content of a %s element (\"%s\") was not in hexadecimal RGB format."),
+ member_name, text);
+ *success = FALSE;
+
+ return TRUE;
+ }
+
+ /* Success! */
+ *output = colour;
+ *success = TRUE;
+
+ return TRUE;
+}
+
void
gdata_parser_string_append_escaped (GString *xml_string, const gchar *pre, const gchar *element_content,
const gchar *post)
{
diff --git a/gdata/gdata-parser.h b/gdata/gdata-parser.h
index 2c5ad2f..31567f7 100644
--- a/gdata/gdata-parser.h
+++ b/gdata/gdata-parser.h
@@ -20,6 +20,7 @@
#include <glib.h>
#include "gdata-parsable.h"
+#include "gdata-types.h"
#ifndef GDATA_PARSER_H
#define GDATA_PARSER_H
@@ -90,6 +91,13 @@ gboolean gdata_parser_int64_time_from_json_member (JsonReader *reader, const gch
gint64 *output, gboolean *success, GError **error);
gboolean gdata_parser_boolean_from_json_member (JsonReader *reader, const gchar *member_name,
GDataParserOptions options,
gboolean *output, gboolean *success, GError **error);
+gboolean
+gdata_parser_color_from_json_member (JsonReader *reader,
+ const gchar *member_name,
+ GDataParserOptions options,
+ GDataColor *output,
+ gboolean *success,
+ GError **error);
void gdata_parser_string_append_escaped (GString *xml_string, const gchar *pre, const gchar
*element_content, const gchar *post);
gchar *gdata_parser_utf8_trim_whitespace (const gchar *s) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
diff --git a/gdata/services/calendar/gdata-calendar-calendar.c
b/gdata/services/calendar/gdata-calendar-calendar.c
index 93f1453..da0135b 100644
--- a/gdata/services/calendar/gdata-calendar-calendar.c
+++ b/gdata/services/calendar/gdata-calendar-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–2010 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009, 2010, 2014 <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
@@ -32,6 +32,8 @@
* For more details of Google Calendar's GData API, see the <ulink type="http"
url="http://code.google.com/apis/calendar/docs/2.0/reference.html">
* online documentation</ulink>.
*
+ * TODO: update examples, etags
+ *
* <example>
* <title>Listing Calendars</title>
* <programlisting>
@@ -77,7 +79,6 @@
#include <config.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
-#include <libxml/parser.h>
#include <string.h>
#include "gdata-calendar-calendar.h"
@@ -93,9 +94,9 @@ static GObject *gdata_calendar_calendar_constructor (GType type, guint n_constru
static void gdata_calendar_calendar_finalize (GObject *object);
static void gdata_calendar_calendar_get_property (GObject *object, guint property_id, GValue *value,
GParamSpec *pspec);
static void gdata_calendar_calendar_set_property (GObject *object, guint property_id, const GValue *value,
GParamSpec *pspec);
-static void get_xml (GDataParsable *parsable, GString *xml_string);
-static gboolean parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError
**error);
-static void get_namespaces (GDataParsable *parsable, GHashTable *namespaces);
+static void get_json (GDataParsable *parsable, JsonBuilder *builder);
+static gboolean parse_json (GDataParsable *parsable, JsonReader *reader, gpointer user_data, GError **error);
+static const gchar *get_content_type (void);
struct _GDataCalendarCalendarPrivate {
gchar *timezone;
@@ -136,17 +137,17 @@ gdata_calendar_calendar_class_init (GDataCalendarCalendarClass *klass)
gobject_class->get_property = gdata_calendar_calendar_get_property;
gobject_class->finalize = gdata_calendar_calendar_finalize;
- parsable_class->parse_xml = parse_xml;
- parsable_class->get_xml = get_xml;
- parsable_class->get_namespaces = get_namespaces;
+ parsable_class->parse_json = parse_json;
+ parsable_class->get_json = get_json;
+ parsable_class->get_content_type = get_content_type;
- entry_class->kind_term = "http://schemas.google.com/gCal/2005#calendarmeta";
+ entry_class->kind_term = "calendar#calendarListEntry";
/**
* GDataCalendarCalendar:timezone:
*
* The timezone in which the calendar's times are given. This is a timezone name in tz database
notation: <ulink type="http"
- * url="http://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones">reference</ulink>.
+ * url="http://en.wikipedia.org/wiki/Tz_database#Names_of_time_zones">reference</ulink>. TODO: is it?
**/
g_object_class_install_property (gobject_class, PROP_TIMEZONE,
g_param_spec_string ("timezone",
@@ -182,7 +183,7 @@ gdata_calendar_calendar_class_init (GDataCalendarCalendarClass *klass)
* GDataCalendarCalendar:color:
*
* The color used to highlight the calendar in the user's browser. This must be one of a limited set
of colors listed in the
- * <ulink type="http"
url="http://code.google.com/apis/calendar/data/2.0/reference.html#gCalcolor">online documentation</ulink>.
+ * <ulink type="http"
url="http://code.google.com/apis/calendar/data/2.0/reference.html#gCalcolor">online documentation</ulink>.
TODO
**/
g_object_class_install_property (gobject_class, PROP_COLOR,
g_param_spec_boxed ("color",
@@ -360,113 +361,103 @@ gdata_calendar_calendar_set_property (GObject *object, guint property_id, const
}
static gboolean
-parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
+parse_json (GDataParsable *parsable, JsonReader *reader, gpointer user_data, GError **error)
{
gboolean success;
+ gchar *summary = NULL;
GDataCalendarCalendar *self = GDATA_CALENDAR_CALENDAR (parsable);
- if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app") == TRUE &&
- gdata_parser_int64_time_from_element (node, "edited", P_REQUIRED | P_NO_DUPES,
&(self->priv->edited), &success, error) == TRUE) {
- return success;
- } else if (gdata_parser_is_namespace (node, "http://schemas.google.com/gCal/2005") == TRUE) {
- if (xmlStrcmp (node->name, (xmlChar*) "timezone") == 0) {
- /* gCal:timezone */
- xmlChar *_timezone = xmlGetProp (node, (xmlChar*) "value");
- if (_timezone == NULL)
- return gdata_parser_error_required_property_missing (node, "value", error);
- self->priv->timezone = (gchar*) _timezone;
- } else if (xmlStrcmp (node->name, (xmlChar*) "timesCleaned") == 0) {
- /* gCal:timesCleaned */
- xmlChar *times_cleaned = xmlGetProp (node, (xmlChar*) "value");
- if (times_cleaned == NULL)
- return gdata_parser_error_required_property_missing (node, "value", error);
- self->priv->times_cleaned = g_ascii_strtoull ((gchar*) times_cleaned, NULL, 10);
- xmlFree (times_cleaned);
- } else if (xmlStrcmp (node->name, (xmlChar*) "hidden") == 0) {
- /* gCal:hidden */
- if (gdata_parser_boolean_from_property (node, "value", &(self->priv->is_hidden), -1,
error) == FALSE)
- return FALSE;
- } else if (xmlStrcmp (node->name, (xmlChar*) "color") == 0) {
- /* gCal:color */
- xmlChar *value;
- GDataColor colour;
-
- value = xmlGetProp (node, (xmlChar*) "value");
- if (value == NULL)
- return gdata_parser_error_required_property_missing (node, "value", error);
- if (gdata_color_from_hexadecimal ((gchar*) value, &colour) == FALSE) {
- /* Error */
- g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
- /* Translators: the first parameter is the name of an XML
element (including the angle brackets
- * ("<" and ">"), and the second parameter is the erroneous
value (which was not in hexadecimal
- * RGB format).
- *
- * For example:
- * The content of a <entry/gCal:color> element ("00FG56") was
not in hexadecimal RGB format. */
- _("The content of a %s element (\"%s\") was not in hexadecimal
RGB format."),
- "<entry/gCal:color>", value);
- xmlFree (value);
-
- return FALSE;
- }
-
- gdata_calendar_calendar_set_color (self, &colour);
- xmlFree (value);
- } else if (xmlStrcmp (node->name, (xmlChar*) "selected") == 0) {
- /* gCal:selected */
- if (gdata_parser_boolean_from_property (node, "value", &(self->priv->is_selected),
-1, error) == FALSE)
- return FALSE;
- } else if (xmlStrcmp (node->name, (xmlChar*) "accesslevel") == 0) {
- /* gCal:accesslevel */
- self->priv->access_level = (gchar*) xmlGetProp (node, (xmlChar*) "value");
- if (self->priv->access_level == NULL)
- return gdata_parser_error_required_property_missing (node, "value", error);
- } else {
- return GDATA_PARSABLE_CLASS (gdata_calendar_calendar_parent_class)->parse_xml
(parsable, doc, node, user_data, error);
+ /* TODO: things removed:
+ * edited
+ * timesCleaned
+ *
+ * things not yet implemented
+ * description
+ * location
+ * summaryOverride
+ * colorId
+ * foregroundColor
+ * defaultReminders
+ * notificationSettings
+ * primary
+ * deleted
+ *
+ * TODO: check values for accesslevel
+ */
+
+ if (gdata_parser_string_from_json_member (reader, "timeZone", P_DEFAULT, &self->priv->timezone,
&success, error) ||
+ gdata_parser_string_from_json_member (reader, "accessRole", P_DEFAULT, &self->priv->access_level,
&success, error) ||
+ gdata_parser_color_from_json_member (reader, "backgroundColor", P_DEFAULT, &self->priv->colour,
&success, error) ||
+ gdata_parser_boolean_from_json_member (reader, "hidden", P_DEFAULT, &self->priv->is_hidden,
&success, error) ||
+ gdata_parser_boolean_from_json_member (reader, "selected", P_DEFAULT, &self->priv->is_selected,
&success, error) ||
+ gdata_parser_string_from_json_member (reader, "summary", P_DEFAULT, &summary, &success, error)) {
+ if (success) {
+ gdata_entry_set_title (GDATA_ENTRY (parsable), summary);
}
+
+ g_free (summary);
+
+ return success;
} else {
- return GDATA_PARSABLE_CLASS (gdata_calendar_calendar_parent_class)->parse_xml (parsable, doc,
node, user_data, error);
+ g_free (summary);
+ return GDATA_PARSABLE_CLASS (gdata_calendar_calendar_parent_class)->parse_json (parsable,
reader, user_data, error);
}
return TRUE;
}
static void
-get_xml (GDataParsable *parsable, GString *xml_string)
+get_json (GDataParsable *parsable, JsonBuilder *builder)
{
+ const gchar *id, *etag, *title;
gchar *colour;
GDataCalendarCalendarPrivate *priv = GDATA_CALENDAR_CALENDAR (parsable)->priv;
- /* Chain up to the parent class */
- GDATA_PARSABLE_CLASS (gdata_calendar_calendar_parent_class)->get_xml (parsable, xml_string);
+ id = gdata_entry_get_id (GDATA_ENTRY (parsable));
+ if (id != NULL) {
+ json_builder_set_member_name (builder, "id");
+ json_builder_add_string_value (builder, id);
+ }
- /* Add all the Calendar-specific XML */
- if (priv->timezone != NULL)
- gdata_parser_string_append_escaped (xml_string, "<gCal:timezone value='", priv->timezone,
"'/>");
+ json_builder_set_member_name (builder, "kind");
+ json_builder_add_string_value (builder, "calendar#calendar");
- if (priv->is_hidden == TRUE)
- g_string_append (xml_string, "<gCal:hidden value='true'/>");
- else
- g_string_append (xml_string, "<gCal:hidden value='false'/>");
+ /* Add the ETag, if available. */
+ etag = gdata_entry_get_etag (GDATA_ENTRY (parsable));
+ if (etag != NULL) {
+ json_builder_set_member_name (builder, "etag");
+ json_builder_add_string_value (builder, etag);
+ }
+
+ /* Calendar labels titles as ‘summary’. */
+ title = gdata_entry_get_title (GDATA_ENTRY (parsable));
+ if (title != NULL) {
+ json_builder_set_member_name (builder, "summary");
+ json_builder_add_string_value (builder, title);
+ }
+
+ /* Add all the calendar-specific JSON */
+ if (priv->timezone != NULL) {
+ json_builder_set_member_name (builder, "timeZone");
+ json_builder_add_string_value (builder, priv->timezone);
+ }
- colour = gdata_color_to_hexadecimal (&(priv->colour));
- g_string_append_printf (xml_string, "<gCal:color value='%s'/>", colour);
+ json_builder_set_member_name (builder, "hidden");
+ json_builder_add_boolean_value (builder, priv->is_hidden);
+
+ colour = gdata_color_to_hexadecimal (&priv->colour);
+ json_builder_set_member_name (builder, "backgroundColor");
+ json_builder_add_string_value (builder, colour);
g_free (colour);
- if (priv->is_selected == TRUE)
- g_string_append (xml_string, "<gCal:selected value='true'/>");
- else
- g_string_append (xml_string, "<gCal:selected value='false'/>");
+ json_builder_set_member_name (builder, "selected");
+ json_builder_add_boolean_value (builder, priv->is_selected);
}
-static void
-get_namespaces (GDataParsable *parsable, GHashTable *namespaces)
+static const gchar *
+get_content_type (void)
{
- /* Chain up to the parent class */
- GDATA_PARSABLE_CLASS (gdata_calendar_calendar_parent_class)->get_namespaces (parsable, namespaces);
-
- g_hash_table_insert (namespaces, (gchar*) "gCal", (gchar*) "http://schemas.google.com/gCal/2005");
- g_hash_table_insert (namespaces, (gchar*) "app", (gchar*) "http://www.w3.org/2007/app");
+ return "application/json";
}
/**
diff --git a/gdata/services/calendar/gdata-calendar-feed.c b/gdata/services/calendar/gdata-calendar-feed.c
index ce0ca91..78a6720 100644
--- a/gdata/services/calendar/gdata-calendar-feed.c
+++ b/gdata/services/calendar/gdata-calendar-feed.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–2010 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009, 2010, 2014 <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
@@ -25,6 +25,8 @@
*
* #GDataCalendarFeed is a subclass of #GDataFeed to represent a results feed from Google Calendar. It adds
a couple of
* properties which are specific to the Google Calendar API.
+ *
+ * TODO: deprecate things?
**/
#include <glib.h>
@@ -34,14 +36,7 @@
#include "gdata-feed.h"
#include "gdata-private.h"
-static void gdata_calendar_feed_finalize (GObject *object);
static void gdata_calendar_feed_get_property (GObject *object, guint property_id, GValue *value, GParamSpec
*pspec);
-static gboolean parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError
**error);
-
-struct _GDataCalendarFeedPrivate {
- gchar *timezone;
- guint times_cleaned;
-};
enum {
PROP_TIMEZONE = 1,
@@ -54,14 +49,8 @@ static void
gdata_calendar_feed_class_init (GDataCalendarFeedClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GDataParsableClass *parsable_class = GDATA_PARSABLE_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (GDataCalendarFeedPrivate));
gobject_class->get_property = gdata_calendar_feed_get_property;
- gobject_class->finalize = gdata_calendar_feed_finalize;
-
- parsable_class->parse_xml = parse_xml;
/**
* GDataCalendarFeed:timezone:
@@ -94,31 +83,22 @@ gdata_calendar_feed_class_init (GDataCalendarFeedClass *klass)
static void
gdata_calendar_feed_init (GDataCalendarFeed *self)
{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_CALENDAR_FEED, GDataCalendarFeedPrivate);
-}
-
-static void
-gdata_calendar_feed_finalize (GObject *object)
-{
- GDataCalendarFeedPrivate *priv = GDATA_CALENDAR_FEED (object)->priv;
-
- g_free (priv->timezone);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (gdata_calendar_feed_parent_class)->finalize (object);
+ /* Nothing to see here. */
}
static void
gdata_calendar_feed_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
- GDataCalendarFeedPrivate *priv = GDATA_CALENDAR_FEED (object)->priv;
+ GDataCalendarFeed *self = GDATA_CALENDAR_FEED (object);
switch (property_id) {
case PROP_TIMEZONE:
- g_value_set_string (value, priv->timezone);
+ g_value_set_string (value,
+ gdata_calendar_feed_get_timezone (self));
break;
case PROP_TIMES_CLEANED:
- g_value_set_uint (value, priv->times_cleaned);
+ g_value_set_uint (value,
+ gdata_calendar_feed_get_times_cleaned (self));
break;
default:
/* We don't have any other property... */
@@ -127,35 +107,6 @@ gdata_calendar_feed_get_property (GObject *object, guint property_id, GValue *va
}
}
-static gboolean
-parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
-{
- GDataCalendarFeed *self = GDATA_CALENDAR_FEED (parsable);
-
- if (gdata_parser_is_namespace (node, "http://schemas.google.com/gCal/2005") == FALSE)
- return GDATA_PARSABLE_CLASS (gdata_calendar_feed_parent_class)->parse_xml (parsable, doc,
node, user_data, error);
-
- if (xmlStrcmp (node->name, (xmlChar*) "timezone") == 0) {
- /* gCal:timezone */
- xmlChar *_timezone = xmlGetProp (node, (xmlChar*) "value");
- if (_timezone == NULL)
- return gdata_parser_error_required_property_missing (node, "value", error);
- g_free (self->priv->timezone);
- self->priv->timezone = (gchar*) _timezone;
- } else if (xmlStrcmp (node->name, (xmlChar*) "timesCleaned") == 0) {
- /* gCal:timesCleaned */
- xmlChar *times_cleaned = xmlGetProp (node, (xmlChar*) "value");
- if (times_cleaned == NULL)
- return gdata_parser_error_required_property_missing (node, "value", error);
- self->priv->times_cleaned = g_ascii_strtoull ((gchar*) times_cleaned, NULL, 10);
- xmlFree (times_cleaned);
- } else {
- return GDATA_PARSABLE_CLASS (gdata_calendar_feed_parent_class)->parse_xml (parsable, doc,
node, user_data, error);
- }
-
- return TRUE;
-}
-
/**
* gdata_calendar_feed_get_timezone:
* @self: a #GDataCalendarFeed
@@ -169,8 +120,9 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
const gchar *
gdata_calendar_feed_get_timezone (GDataCalendarFeed *self)
{
+ /* Not supported any more by version 3 of the API. */
g_return_val_if_fail (GDATA_IS_CALENDAR_FEED (self), NULL);
- return self->priv->timezone;
+ return NULL;
}
/**
@@ -186,6 +138,7 @@ gdata_calendar_feed_get_timezone (GDataCalendarFeed *self)
guint
gdata_calendar_feed_get_times_cleaned (GDataCalendarFeed *self)
{
+ /* Not supported any more by version 3 of the API. */
g_return_val_if_fail (GDATA_IS_CALENDAR_FEED (self), 0);
- return self->priv->times_cleaned;
+ return 0;
}
diff --git a/gdata/services/calendar/gdata-calendar-service.c
b/gdata/services/calendar/gdata-calendar-service.c
index e326eab..a141498 100644
--- a/gdata/services/calendar/gdata-calendar-service.c
+++ b/gdata/services/calendar/gdata-calendar-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 2009 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009, 2014 <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
@@ -15,6 +15,12 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * TODO: parse_error_response
+ * TODO: ACLs, batchable
+ * TODO: update links to references; proofread documentation
+ * TODO: add new API to avoid naked calls to gdata_service_insert_entry() (for example)
+ * TODO: port Evo and Geary code
*/
/**
@@ -316,7 +322,7 @@ gdata_calendar_service_query_all_calendars (GDataCalendarService *self, GDataQue
return NULL;
}
- request_uri = g_strconcat (_gdata_service_get_scheme (),
"://www.google.com/calendar/feeds/default/allcalendars/full", NULL);
+ request_uri = g_strconcat (_gdata_service_get_scheme (),
"://www.googleapis.com/calendar/v3/users/me/calendarList", NULL);
feed = gdata_service_query (GDATA_SERVICE (self), get_calendar_authorization_domain (), request_uri,
query, GDATA_TYPE_CALENDAR_CALENDAR,
cancellable, progress_callback, progress_user_data, error);
g_free (request_uri);
@@ -370,7 +376,7 @@ gdata_calendar_service_query_all_calendars_async (GDataCalendarService *self, GD
return;
}
- request_uri = g_strconcat (_gdata_service_get_scheme (),
"://www.google.com/calendar/feeds/default/allcalendars/full", NULL);
+ request_uri = g_strconcat (_gdata_service_get_scheme (),
"://www.googleapis.com/calendar/v3/users/me/calendarList", NULL);
gdata_service_query_async (GDATA_SERVICE (self), get_calendar_authorization_domain (), request_uri,
query, GDATA_TYPE_CALENDAR_CALENDAR,
cancellable, progress_callback, progress_user_data,
destroy_progress_user_data, callback, user_data);
g_free (request_uri);
@@ -413,7 +419,7 @@ gdata_calendar_service_query_own_calendars (GDataCalendarService *self, GDataQue
return NULL;
}
- request_uri = g_strconcat (_gdata_service_get_scheme (),
"://www.google.com/calendar/feeds/default/owncalendars/full", NULL);
+ request_uri = g_strconcat (_gdata_service_get_scheme (),
"://www.googleapis.com/calendar/v3/users/me/calendarList?minAccessRole=owner", NULL);
feed = gdata_service_query (GDATA_SERVICE (self), get_calendar_authorization_domain (), request_uri,
query, GDATA_TYPE_CALENDAR_CALENDAR,
cancellable, progress_callback, progress_user_data, error);
g_free (request_uri);
@@ -467,7 +473,7 @@ gdata_calendar_service_query_own_calendars_async (GDataCalendarService *self, GD
return;
}
- request_uri = g_strconcat (_gdata_service_get_scheme (),
"://www.google.com/calendar/feeds/default/owncalendars/full", NULL);
+ request_uri = g_strconcat (_gdata_service_get_scheme (),
"://www.googleapis.com/calendar/v3/users/me/calendarList?minAccessRole=owner", NULL);
gdata_service_query_async (GDATA_SERVICE (self), get_calendar_authorization_domain (), request_uri,
query, GDATA_TYPE_CALENDAR_CALENDAR,
cancellable, progress_callback, progress_user_data,
destroy_progress_user_data, callback, user_data);
g_free (request_uri);
@@ -493,7 +499,8 @@ GDataFeed *
gdata_calendar_service_query_events (GDataCalendarService *self, GDataCalendarCalendar *calendar, GDataQuery
*query, GCancellable *cancellable,
GDataQueryProgressCallback progress_callback, gpointer
progress_user_data, GError **error)
{
- const gchar *uri;
+ gchar *request_uri;
+ GDataFeed *feed;
g_return_val_if_fail (GDATA_IS_CALENDAR_SERVICE (self), NULL);
g_return_val_if_fail (GDATA_IS_CALENDAR_CALENDAR (calendar), NULL);
@@ -509,18 +516,21 @@ gdata_calendar_service_query_events (GDataCalendarService *self, GDataCalendarCa
return NULL;
}
- /* Use the calendar's content src */
- uri = gdata_entry_get_content_uri (GDATA_ENTRY (calendar));
- if (uri == NULL) {
- /* Erroring out is probably the safest thing to do */
- g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
- _("The calendar did not have a content URI."));
- return NULL;
- }
+ /* Execute the query. TODO: escaping? */
+ request_uri = g_strconcat (_gdata_service_get_scheme (),
+ "://www.googleapis.com/calendar/v3/calendars/",
+ gdata_entry_get_id (GDATA_ENTRY (calendar)),
+ "/events",
+ NULL);
+ feed = gdata_service_query (GDATA_SERVICE (self),
+ get_calendar_authorization_domain (),
+ request_uri, query,
+ GDATA_TYPE_CALENDAR_EVENT, cancellable,
+ progress_callback, progress_user_data,
+ error);
+ g_free (request_uri);
- /* Execute the query */
- return gdata_service_query (GDATA_SERVICE (self), get_calendar_authorization_domain (), uri, query,
GDATA_TYPE_CALENDAR_EVENT, cancellable,
- progress_callback, progress_user_data, error);
+ return feed;
}
/**
@@ -552,7 +562,7 @@ gdata_calendar_service_query_events_async (GDataCalendarService *self, GDataCale
GDestroyNotify destroy_progress_user_data,
GAsyncReadyCallback callback, gpointer user_data)
{
- const gchar *uri;
+ gchar *request_uri;
g_return_if_fail (GDATA_IS_CALENDAR_SERVICE (self));
g_return_if_fail (GDATA_IS_CALENDAR_CALENDAR (calendar));
@@ -572,22 +582,20 @@ gdata_calendar_service_query_events_async (GDataCalendarService *self, GDataCale
return;
}
- /* Use the calendar's content src */
- uri = gdata_entry_get_content_uri (GDATA_ENTRY (calendar));
- if (uri == NULL) {
- /* Erroring out is probably the safest thing to do */
- GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
gdata_service_query_async);
- g_simple_async_result_set_error (result, GDATA_SERVICE_ERROR,
GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED, "%s",
- _("The calendar did not have a content URI."));
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
-
- return;
- }
-
/* Execute the query */
- gdata_service_query_async (GDATA_SERVICE (self), get_calendar_authorization_domain (), uri, query,
GDATA_TYPE_CALENDAR_EVENT, cancellable,
- progress_callback, progress_user_data, destroy_progress_user_data,
callback, user_data);
+ request_uri = g_strconcat (_gdata_service_get_scheme (),
+ "://www.googleapis.com/calendar/v3/calendars/",
+ gdata_entry_get_id (GDATA_ENTRY (calendar)),
+ "/events",
+ NULL);
+ gdata_service_query_async (GDATA_SERVICE (self),
+ get_calendar_authorization_domain (),
+ request_uri, query,
+ GDATA_TYPE_CALENDAR_EVENT, cancellable,
+ progress_callback, progress_user_data,
+ destroy_progress_user_data, callback,
+ user_data);
+ g_free (request_uri);
}
/**
@@ -611,13 +619,18 @@ gdata_calendar_service_insert_event (GDataCalendarService *self, GDataCalendarEv
/* TODO: How do we choose which calendar? */
gchar *uri;
GDataEntry *entry;
+ const gchar *calendar_id = "default";
g_return_val_if_fail (GDATA_IS_CALENDAR_SERVICE (self), NULL);
g_return_val_if_fail (GDATA_IS_CALENDAR_EVENT (event), NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- uri = g_strconcat (_gdata_service_get_scheme (),
"://www.google.com/calendar/feeds/default/private/full", NULL);
+ uri = g_strconcat (_gdata_service_get_scheme (),
+ "://www.googleapis.com/calendar/v3/calendars/",
+ calendar_id,
+ "/events",
+ NULL);
entry = gdata_service_insert_entry (GDATA_SERVICE (self), get_calendar_authorization_domain (), uri,
GDATA_ENTRY (event), cancellable, error);
g_free (uri);
@@ -648,12 +661,17 @@ gdata_calendar_service_insert_event_async (GDataCalendarService *self, GDataCale
GAsyncReadyCallback callback, gpointer user_data)
{
gchar *uri;
+ const gchar *calendar_id = "default";
g_return_if_fail (GDATA_IS_CALENDAR_SERVICE (self));
g_return_if_fail (GDATA_IS_CALENDAR_EVENT (event));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- uri = g_strconcat (_gdata_service_get_scheme (),
"://www.google.com/calendar/feeds/default/private/full", NULL);
+ uri = g_strconcat (_gdata_service_get_scheme (),
+ "://www.googleapis.com/calendar/v3/calendars/",
+ calendar_id,
+ "/events",
+ NULL);
gdata_service_insert_entry_async (GDATA_SERVICE (self), get_calendar_authorization_domain (), uri,
GDATA_ENTRY (event), cancellable,
callback, user_data);
g_free (uri);
diff --git a/gdata/tests/calendar.c b/gdata/tests/calendar.c
index c54ddda..85b6da3 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–2010 <philip tecnocode co uk>
+ * Copyright (C) Philip Withnall 2009, 2010, 2014 <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
@@ -23,9 +23,16 @@
#include "gdata.h"
#include "common.h"
+#include "gdata-dummy-authorizer.h"
static UhmServer *mock_server = NULL;
+#undef CLIENT_ID /* from common.h */
+
+#define CLIENT_ID "352818697630-nqu2cmt5quqd6lr17ouoqmb684u84l1f.apps.googleusercontent.com"
+#define CLIENT_SECRET "-fA4pHQJxR3zJ-FyAMPQsikg"
+#define REDIRECT_URI "urn:ietf:wg:oauth:2.0:oob"
+
typedef struct {
GDataCalendarCalendar *calendar;
} TempCalendarData;
@@ -46,7 +53,7 @@ set_up_temp_calendar (TempCalendarData *data, gconstpointer service)
gdata_calendar_calendar_set_color (calendar, &colour);
data->calendar = GDATA_CALENDAR_CALENDAR (gdata_service_insert_entry (GDATA_SERVICE (service),
gdata_calendar_service_get_primary_authorization_domain (),
-
"https://www.google.com/calendar/feeds/default/owncalendars/full",
+
"https://www.googleapis.com/calendar/v3/calendars",
GDATA_ENTRY (calendar), NULL,
NULL));
g_assert (GDATA_IS_CALENDAR_CALENDAR (data->calendar));
g_object_unref (calendar);
@@ -70,75 +77,48 @@ tear_down_temp_calendar (TempCalendarData *data, gconstpointer service)
static void
test_authentication (void)
{
- gboolean retval;
- GDataClientLoginAuthorizer *authorizer;
- GError *error = NULL;
+ GDataOAuth2Authorizer *authorizer = NULL; /* owned */
+ gchar *authentication_uri, *authorisation_code;
gdata_test_mock_server_start_trace (mock_server, "authentication");
- /* Create an authorizer */
- authorizer = gdata_client_login_authorizer_new (CLIENT_ID, GDATA_TYPE_CALENDAR_SERVICE);
+ authorizer = gdata_oauth2_authorizer_new (CLIENT_ID, CLIENT_SECRET,
+ REDIRECT_URI,
+ GDATA_TYPE_CALENDAR_SERVICE);
- g_assert_cmpstr (gdata_client_login_authorizer_get_client_id (authorizer), ==, CLIENT_ID);
+ /* Get an authentication URI. */
+ authentication_uri = gdata_oauth2_authorizer_build_authentication_uri (authorizer, NULL, FALSE);
+ g_assert (authentication_uri != NULL);
- /* Log in */
- retval = gdata_client_login_authorizer_authenticate (authorizer, USERNAME, PASSWORD, NULL, &error);
- g_assert_no_error (error);
- g_assert (retval == TRUE);
- g_clear_error (&error);
+ /* Get the authorisation code off the user. */
+ if (uhm_server_get_enable_online (mock_server)) {
+ authorisation_code = gdata_test_query_user_for_verifier (authentication_uri);
+ } else {
+ /* Hard coded, extracted from the trace file. TODO */
+ authorisation_code = g_strdup
("4/OEX-S1iMbOA_dOnNgUlSYmGWh3TK.QrR73axcNMkWoiIBeO6P2m_su7cwkQI");
+ }
- /* Check all is as it should be */
- g_assert_cmpstr (gdata_client_login_authorizer_get_username (authorizer), ==, USERNAME);
- g_assert_cmpstr (gdata_client_login_authorizer_get_password (authorizer), ==, PASSWORD);
+ g_free (authentication_uri);
+
+ if (authorisation_code == NULL) {
+ /* Skip tests. */
+ goto skip_test;
+ }
+
+ /* Authorise the token */
+ g_assert (gdata_oauth2_authorizer_request_authorization (authorizer, authorisation_code, NULL, NULL)
== TRUE);
+ /* Check all is as it should be */
g_assert (gdata_authorizer_is_authorized_for_domain (GDATA_AUTHORIZER (authorizer),
gdata_calendar_service_get_primary_authorization_domain ()) == TRUE);
+skip_test:
+ g_free (authorisation_code);
g_object_unref (authorizer);
uhm_server_end_trace (mock_server);
}
-GDATA_ASYNC_TEST_FUNCTIONS (authentication, void,
-G_STMT_START {
- GDataClientLoginAuthorizer *authorizer;
-
- /* Create an authorizer */
- authorizer = gdata_client_login_authorizer_new (CLIENT_ID, GDATA_TYPE_CALENDAR_SERVICE);
-
- g_assert_cmpstr (gdata_client_login_authorizer_get_client_id (authorizer), ==, CLIENT_ID);
-
- gdata_client_login_authorizer_authenticate_async (authorizer, USERNAME, PASSWORD, cancellable,
async_ready_callback, async_data);
-
- g_object_unref (authorizer);
-} G_STMT_END,
-G_STMT_START {
- gboolean retval;
- GDataClientLoginAuthorizer *authorizer = GDATA_CLIENT_LOGIN_AUTHORIZER (obj);
-
- retval = gdata_client_login_authorizer_authenticate_finish (authorizer, async_result, &error);
-
- if (error == NULL) {
- g_assert (retval == TRUE);
-
- /* Check all is as it should be */
- g_assert_cmpstr (gdata_client_login_authorizer_get_username (authorizer), ==, USERNAME);
- g_assert_cmpstr (gdata_client_login_authorizer_get_password (authorizer), ==, PASSWORD);
-
- g_assert (gdata_authorizer_is_authorized_for_domain (GDATA_AUTHORIZER (authorizer),
-
gdata_calendar_service_get_primary_authorization_domain ()) == TRUE);
- } else {
- g_assert (retval == FALSE);
-
- /* Check nothing's changed */
- g_assert_cmpstr (gdata_client_login_authorizer_get_username (authorizer), ==, NULL);
- g_assert_cmpstr (gdata_client_login_authorizer_get_password (authorizer), ==, NULL);
-
- g_assert (gdata_authorizer_is_authorized_for_domain (GDATA_AUTHORIZER (authorizer),
-
gdata_calendar_service_get_primary_authorization_domain ()) == FALSE);
- }
-} G_STMT_END);
-
typedef struct {
GDataCalendarCalendar *calendar1;
GDataCalendarCalendar *calendar2;
@@ -158,9 +138,10 @@ set_up_query_calendars (QueryCalendarsData *data, gconstpointer service)
calendar = gdata_calendar_calendar_new (NULL);
gdata_entry_set_title (GDATA_ENTRY (calendar), "Test Calendar 1");
gdata_calendar_calendar_set_color (calendar, &colour);
+ /* TODO: abstract this */
data->calendar1 = GDATA_CALENDAR_CALENDAR (gdata_service_insert_entry (GDATA_SERVICE (service),
gdata_calendar_service_get_primary_authorization_domain (),
-
"https://www.google.com/calendar/feeds/default/owncalendars/full",
+
"https://www.googleapis.com/calendar/v3/calendars",
GDATA_ENTRY (calendar), NULL,
NULL));
g_assert (GDATA_IS_CALENDAR_CALENDAR (data->calendar1));
g_object_unref (calendar);
@@ -170,7 +151,7 @@ set_up_query_calendars (QueryCalendarsData *data, gconstpointer service)
gdata_calendar_calendar_set_color (calendar, &colour);
data->calendar2 = GDATA_CALENDAR_CALENDAR (gdata_service_insert_entry (GDATA_SERVICE (service),
gdata_calendar_service_get_primary_authorization_domain (),
-
"https://www.google.com/calendar/feeds/default/owncalendars/full",
+
"https://www.googleapis.com/calendar/v3/calendars",
GDATA_ENTRY (calendar), NULL,
NULL));
g_assert (GDATA_IS_CALENDAR_CALENDAR (data->calendar2));
g_object_unref (calendar);
@@ -184,6 +165,7 @@ tear_down_query_calendars (QueryCalendarsData *data, gconstpointer service)
gdata_test_mock_server_start_trace (mock_server, "teardown-query-calendars");
/* Delete the calendars */
+ /* TODO: Crashes because there’s no self link. Maybe insert one manually? */
g_assert (gdata_service_delete_entry (GDATA_SERVICE (service),
gdata_calendar_service_get_primary_authorization_domain (),
GDATA_ENTRY (data->calendar1), NULL, NULL) == TRUE);
g_object_unref (data->calendar1);
@@ -1442,9 +1424,68 @@ mock_server_notify_resolver_cb (GObject *object, GParamSpec *pspec, gpointer use
const gchar *ip_address = uhm_server_get_address (server);
uhm_resolver_add_A (resolver, "www.google.com", ip_address);
+ uhm_resolver_add_A (resolver, "www.googleapis.com", ip_address);
+ uhm_resolver_add_A (resolver,
+ "accounts.google.com", ip_address);
}
}
+/* Set up a global GDataAuthorizer to be used for all the tests. Unfortunately,
+ * the Google Calendar API is limited to OAuth1 and OAuth2 authorisation, so
+ * this requires user interaction when online.
+ *
+ * If not online, use a dummy authoriser. */
+static GDataAuthorizer *
+create_global_authorizer (void)
+{
+ GDataOAuth2Authorizer *authorizer = NULL; /* owned */
+ gchar *authentication_uri, *authorisation_code;
+ GError *error = NULL;
+
+ /* If not online, just return a dummy authoriser. */
+ if (!uhm_server_get_enable_online (mock_server)) {
+ return GDATA_AUTHORIZER (gdata_dummy_authorizer_new (GDATA_TYPE_CALENDAR_SERVICE));
+ }
+
+ /* Otherwise, go through the interactive OAuth dance. */
+ gdata_test_mock_server_start_trace (mock_server, "global-authentication");
+ authorizer = gdata_oauth2_authorizer_new (CLIENT_ID, CLIENT_SECRET,
+ REDIRECT_URI,
+ GDATA_TYPE_CALENDAR_SERVICE);
+
+ /* Get an authentication URI */
+ authentication_uri = gdata_oauth2_authorizer_build_authentication_uri (authorizer, NULL, FALSE);
+ g_assert (authentication_uri != NULL);
+
+ /* Get the authorisation code off the user. */
+ if (uhm_server_get_enable_online (mock_server)) {
+ authorisation_code = gdata_test_query_user_for_verifier (authentication_uri);
+ } else {
+ /* Hard coded, extracted from the trace file. TODO */
+ authorisation_code = g_strdup
("4/hmXZtrXmXMqK1hwiWPZs9F_N6DK-.Ap4OICAUIe0WoiIBeO6P2m8IDoMxkQI");
+ }
+
+ g_free (authentication_uri);
+
+ if (authorisation_code == NULL) {
+ /* Skip tests. */
+ g_object_unref (authorizer);
+ authorizer = NULL;
+ goto skip_test;
+ }
+
+ /* Authorise the token */
+ g_assert (gdata_oauth2_authorizer_request_authorization (authorizer, authorisation_code, NULL,
&error));
+ g_assert_no_error (error);
+
+skip_test:
+ g_free (authorisation_code);
+
+ uhm_server_end_trace (mock_server);
+
+ return GDATA_AUTHORIZER (authorizer);
+}
+
int
main (int argc, char *argv[])
{
@@ -1461,18 +1502,11 @@ main (int argc, char *argv[])
uhm_server_set_trace_directory (mock_server, trace_directory);
g_object_unref (trace_directory);
- gdata_test_mock_server_start_trace (mock_server, "global-authentication");
- authorizer = GDATA_AUTHORIZER (gdata_client_login_authorizer_new (CLIENT_ID,
GDATA_TYPE_CALENDAR_SERVICE));
- gdata_client_login_authorizer_authenticate (GDATA_CLIENT_LOGIN_AUTHORIZER (authorizer), USERNAME,
PASSWORD, NULL, NULL);
- uhm_server_end_trace (mock_server);
+ authorizer = create_global_authorizer ();
service = GDATA_SERVICE (gdata_calendar_service_new (authorizer));
g_test_add_func ("/calendar/authentication", test_authentication);
- g_test_add ("/calendar/authentication/async", GDataAsyncTestData, NULL, gdata_set_up_async_test_data,
test_authentication_async,
- gdata_tear_down_async_test_data);
- g_test_add ("/calendar/authentication/async/cancellation", GDataAsyncTestData, NULL,
gdata_set_up_async_test_data,
- test_authentication_async_cancellation, gdata_tear_down_async_test_data);
g_test_add ("/calendar/query/all_calendars", QueryCalendarsData, service, set_up_query_calendars,
test_query_all_calendars,
tear_down_query_calendars);
@@ -1515,10 +1549,13 @@ main (int argc, char *argv[])
g_test_add ("/calendar/access-rule/delete", TempCalendarAclsData, service, set_up_temp_calendar_acls,
test_access_rule_delete,
tear_down_temp_calendar_acls);
+#if 0
+TODO
g_test_add_data_func ("/calendar/batch", service, test_batch);
g_test_add ("/calendar/batch/async", BatchAsyncData, service, setup_batch_async, test_batch_async,
teardown_batch_async);
g_test_add ("/calendar/batch/async/cancellation", BatchAsyncData, service, setup_batch_async,
test_batch_async_cancellation,
teardown_batch_async);
+#endif
g_test_add_func ("/calendar/event/xml", test_event_xml);
g_test_add_func ("/calendar/event/xml/dates", test_event_xml_dates);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]