diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2014-08-31 00:59:12 +0100 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2014-09-18 00:22:05 +0100 |
commit | 65745626ffc893a06d2d27c562effed4b683002b (patch) | |
tree | 39d9507ddccfeaa96cc6b3909eb7b49bc1ead4da | |
parent | dfd4735d645bdf9d64718f7c72c68ad683bb96a3 (diff) | |
download | libgdata-65745626ffc893a06d2d27c562effed4b683002b.tar.gz |
tests: Add unit tests for the Google Tasks service
These are non-interactive and non-network tests, since I don’t currently
have time to get networked tests working for Google Tasks — they require
OAuth 2 support to land first (bug #646285).
By themselves, these non-network tests give 64% line coverage and 74%
function coverage of gdata/services/tasks/.
-rw-r--r-- | gdata/tests/Makefile.am | 4 | ||||
-rw-r--r-- | gdata/tests/tasks.c | 712 | ||||
-rw-r--r-- | gdata/tests/traces/tasks/authentication | 58 | ||||
-rw-r--r-- | gdata/tests/traces/tasks/global-authentication | 58 | ||||
-rw-r--r-- | gdata/tests/traces/tasks/tasklist-insert | 43 |
5 files changed, 875 insertions, 0 deletions
diff --git a/gdata/tests/Makefile.am b/gdata/tests/Makefile.am index c6474dfb..ce64ab50 100644 --- a/gdata/tests/Makefile.am +++ b/gdata/tests/Makefile.am @@ -51,6 +51,7 @@ TESTS = \ contacts \ picasaweb \ documents \ + tasks \ perf \ streams \ authorization \ @@ -372,6 +373,9 @@ EXTRA_DIST += \ traces/youtube/upload-async \ traces/youtube/upload-async-cancellation \ traces/youtube/upload-simple \ + \ + traces/tasks/authentication \ + traces/tasks/global-authentication \ $(NULL) -include $(top_srcdir)/git.mk diff --git a/gdata/tests/tasks.c b/gdata/tests/tasks.c new file mode 100644 index 00000000..051585a9 --- /dev/null +++ b/gdata/tests/tasks.c @@ -0,0 +1,712 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * GData Client + * Copyright (C) Philip Withnall 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GData Client is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * 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/>. + */ + +#include <glib.h> +#include <unistd.h> +#include <string.h> + +#include "gdata.h" +#include "common.h" +#include "gdata-dummy-authorizer.h" + +static UhmServer *mock_server = NULL; /* owned */ + +/* Test that building a query URI works with the various parameters. */ +static void +test_query_uri (void) +{ + gchar *query_uri; + GDataTasksQuery *query = gdata_tasks_query_new (NULL); + + /* General properties. */ + gdata_query_set_updated_min (GDATA_QUERY (query), 6789); + g_assert_cmpint (gdata_query_get_updated_min (GDATA_QUERY (query)), ==, + 6789); + + gdata_query_set_max_results (GDATA_QUERY (query), 10); + g_assert_cmpint (gdata_query_get_max_results (GDATA_QUERY (query)), ==, + 10); + + /* Google-Tasks-specific properties. */ + gdata_tasks_query_set_completed_max (query, 1234); + g_assert_cmpint (gdata_tasks_query_get_completed_max (query), ==, 1234); + + gdata_tasks_query_set_completed_min (query, 5678); + g_assert_cmpint (gdata_tasks_query_get_completed_min (query), ==, 5678); + + gdata_tasks_query_set_due_max (query, 3456); + g_assert_cmpint (gdata_tasks_query_get_due_max (query), ==, 3456); + + gdata_tasks_query_set_due_min (query, 2345); + g_assert_cmpint (gdata_tasks_query_get_due_min (query), ==, 2345); + + gdata_tasks_query_set_show_completed (query, TRUE); + g_assert (gdata_tasks_query_get_show_completed (query)); + + gdata_tasks_query_set_show_deleted (query, TRUE); + g_assert (gdata_tasks_query_get_show_deleted (query)); + + gdata_tasks_query_set_show_hidden (query, TRUE); + g_assert (gdata_tasks_query_get_show_hidden (query)); + + /* Test the URI. */ + query_uri = gdata_query_get_query_uri (GDATA_QUERY (query), + "http://example.com"); + g_assert_cmpstr (query_uri, ==, + "http://example.com" + "?maxResults=10" + "&updatedMin=1970-01-01T01:53:09.000001+00:00" + "&completedMin=1970-01-01T01:34:38.000001+00:00" + "&completedMax=1970-01-01T00:20:34.000001+00:00" + "&dueMin=1970-01-01T00:39:05.000001+00:00" + "&dueMax=1970-01-01T00:57:36.000001+00:00" + "&showCompleted=true" + "&showDeleted=true" + "&showHidden=true"); + g_free (query_uri); + + /* Flip the booleans and try again. */ + gdata_tasks_query_set_show_completed (query, FALSE); + g_assert (!gdata_tasks_query_get_show_completed (query)); + + gdata_tasks_query_set_show_deleted (query, FALSE); + g_assert (!gdata_tasks_query_get_show_deleted (query)); + + gdata_tasks_query_set_show_hidden (query, FALSE); + g_assert (!gdata_tasks_query_get_show_hidden (query)); + + /* Test the URI. */ + query_uri = gdata_query_get_query_uri (GDATA_QUERY (query), + "http://example.com"); + g_assert_cmpstr (query_uri, ==, + "http://example.com" + "?maxResults=10" + "&updatedMin=1970-01-01T01:53:09.000001+00:00" + "&completedMin=1970-01-01T01:34:38.000001+00:00" + "&completedMax=1970-01-01T00:20:34.000001+00:00" + "&dueMin=1970-01-01T00:39:05.000001+00:00" + "&dueMax=1970-01-01T00:57:36.000001+00:00" + "&showCompleted=false" + "&showDeleted=false" + "&showHidden=false"); + g_free (query_uri); + + /* TODO: pageToken */ + + g_object_unref (query); +} + +/* Test that setting any property will unset the ETag on a query. */ +static void +test_query_etag (void) +{ + GDataTasksQuery *query = NULL; /* owned */ + + query = gdata_tasks_query_new (NULL); + +#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_query_set_max_results (GDATA_QUERY (query), 50)) + CHECK_ETAG (gdata_tasks_query_set_show_deleted (query, FALSE)) + CHECK_ETAG (gdata_query_set_updated_min (GDATA_QUERY (query), 1234)) + CHECK_ETAG (gdata_tasks_query_set_completed_min (query, 4567)) + +#undef CHECK_ETAG + + g_object_unref (query); +} + +/* Test that getting/setting query properties works. */ +static void +test_query_properties (void) +{ + GDataTasksQuery *query = NULL; /* owned */ + gint64 completed_min, completed_max, due_min, due_max; + gboolean show_completed, show_deleted, show_hidden; + + query = gdata_tasks_query_new (NULL); + + /* Set the properties. */ + g_object_set (G_OBJECT (query), + "completed-min", (gint64) 1234, + "completed-max", (gint64) 2345, + "due-min", (gint64) 3456, + "due-max", (gint64) 4567, + "show-completed", TRUE, + "show-deleted", TRUE, + "show-hidden", TRUE, + NULL); + + /* Check the query’s properties. */ + g_object_get (G_OBJECT (query), + "completed-min", &completed_min, + "completed-max", &completed_max, + "due-min", &due_min, + "due-max", &due_max, + "show-completed", &show_completed, + "show-deleted", &show_deleted, + "show-hidden", &show_hidden, + NULL); + + g_assert_cmpint (completed_min, ==, 1234); + g_assert_cmpint (completed_max, ==, 2345); + g_assert_cmpint (due_min, ==, 3456); + g_assert_cmpint (due_max, ==, 4567); + g_assert (show_completed); + g_assert (show_deleted); + g_assert (show_hidden); + + g_object_unref (query); +} + +/* Test that getting/setting task properties works. */ +static void +test_task_properties (void) +{ + GDataTasksTask *task; + gchar *id, *etag, *title, *parent, *position, *notes, *status; + gint64 updated, due, completed; + gboolean is_deleted, is_hidden; + + task = gdata_tasks_task_new (NULL); + + /* Check the kind is present and correct */ + g_assert (GDATA_IS_TASKS_TASK (task)); + gdata_test_compare_kind (GDATA_ENTRY (task), "tasks#task", NULL); + + /* Set all the properties of the object. */ + gdata_entry_set_title (GDATA_ENTRY (task), "some-title"); + gdata_tasks_task_set_notes (task, "some-notes"); + gdata_tasks_task_set_status (task, GDATA_TASKS_STATUS_NEEDS_ACTION); + gdata_tasks_task_set_due (task, 1409419209); + gdata_tasks_task_set_completed (task, 1409419200); /* 9 seconds to spare! */ + gdata_tasks_task_set_is_deleted (task, FALSE); + + /* Check the properties of the object */ + g_object_get (G_OBJECT (task), + "id", &id, + "etag", &etag, + "title", &title, + "updated", &updated, + "parent", &parent, + "position", &position, + "notes", ¬es, + "status", &status, + "due", &due, + "completed", &completed, + "is-deleted", &is_deleted, + "is-hidden", &is_hidden, + NULL); + + g_assert_cmpstr (id, ==, NULL); + g_assert_cmpstr (etag, ==, NULL); + g_assert_cmpstr (title, ==, "some-title"); + g_assert_cmpint (updated, ==, -1); + g_assert_cmpstr (parent, ==, NULL); + g_assert_cmpstr (position, ==, NULL); + g_assert_cmpstr (notes, ==, "some-notes"); + g_assert_cmpstr (status, ==, GDATA_TASKS_STATUS_NEEDS_ACTION); + g_assert_cmpint (due, ==, 1409419209); + g_assert_cmpint (completed, ==, 1409419200); + g_assert (!is_deleted); + g_assert (!is_hidden); + + g_free (status); + g_free (notes); + g_free (position); + g_free (parent); + g_free (title); + g_free (etag); + g_free (id); + + /* Set the properties another way. */ + g_object_set (G_OBJECT (task), + "title", "some-other-title", + "notes", "more-notes", + "status", GDATA_TASKS_STATUS_COMPLETED, + "due", (gint64) 1409419200, + "completed", (gint64) 1409419200, /* no time to spare! */ + "is-deleted", TRUE, + NULL); + + /* Check the properties using the getters. */ + g_assert_cmpstr (gdata_tasks_task_get_parent (task), ==, NULL); + g_assert_cmpstr (gdata_tasks_task_get_position (task), ==, NULL); + g_assert_cmpstr (gdata_tasks_task_get_notes (task), ==, "more-notes"); + g_assert_cmpstr (gdata_tasks_task_get_status (task), ==, + GDATA_TASKS_STATUS_COMPLETED); + g_assert_cmpint (gdata_tasks_task_get_due (task), ==, 1409419200); + g_assert_cmpint (gdata_tasks_task_get_completed (task), ==, 1409419200); + g_assert (gdata_tasks_task_is_deleted (task)); + g_assert (!gdata_tasks_task_is_hidden (task)); + + /* Check the JSON. */ + gdata_test_assert_json (task, + "{" + "\"kind\": \"tasks#task\"," + "\"title\": \"some-other-title\"," + "\"notes\": \"more-notes\"," + "\"status\": \"completed\"," + "\"due\": \"2014-08-30T17:20:00.000001+00:00\"," + "\"completed\": \"2014-08-30T17:20:00.000001+00:00\"," + "\"deleted\": true," + "\"hidden\": false" + "}"); + + /* Try again, marking it as undeleted. */ + gdata_tasks_task_set_is_deleted (task, FALSE); + + gdata_test_assert_json (task, + "{" + "\"kind\": \"tasks#task\"," + "\"title\": \"some-other-title\"," + "\"notes\": \"more-notes\"," + "\"status\": \"completed\"," + "\"due\": \"2014-08-30T17:20:00.000001+00:00\"," + "\"completed\": \"2014-08-30T17:20:00.000001+00:00\"," + "\"deleted\": false," + "\"hidden\": false" + "}"); + + g_object_unref (task); +} + +/* Test that escaping task properties for JSON works. */ +static void +test_task_escaping (void) +{ + GDataTasksTask *task; + + task = gdata_tasks_task_new (NULL); + gdata_entry_set_title (GDATA_ENTRY (task), "Title \"with quotes\""); + gdata_tasks_task_set_notes (task, "Notes \"with quotes\" and Emoji 😂."); + gdata_tasks_task_set_status (task, "invalid status \"with quotes\""); + + /* Check the outputted JSON is escaped properly. */ + gdata_test_assert_json (task, + "{" + "\"kind\": \"tasks#task\"," + "\"title\": \"Title \\\"with quotes\\\"\"," + "\"notes\": \"Notes \\\"with quotes\\\" and Emoji 😂.\"," + "\"status\": \"invalid status \\\"with quotes\\\"\"," + "\"deleted\": false," + "\"hidden\": false" + "}"); + + g_object_unref (task); +} + +/* Test the task parser with the minimal number of properties specified. */ +static void +test_task_parser_minimal (void) +{ + GDataTasksTask *task = NULL; /* owned */ + GDataEntry *entry; /* unowned */ + GDataLink *self_link; /* unowned */ + GError *error = NULL; + + task = GDATA_TASKS_TASK (gdata_parsable_new_from_json (GDATA_TYPE_TASKS_TASK, + "{" + "\"kind\": \"tasks#task\"," + "\"id\": \"some-id\"," + "\"title\": \"some-title \\\"with quotes\\\"\"," + "\"updated\": \"2014-08-30T19:40:00Z\"," + "\"selfLink\": \"http://some-uri/\"," + "\"position\": \"some-position\"," + "\"status\": \"needsAction\"," + "\"deleted\": true," + "\"hidden\": true" + "}", -1, &error)); + g_assert_no_error (error); + g_assert (GDATA_IS_TASKS_TASK (task)); + gdata_test_compare_kind (GDATA_ENTRY (task), "tasks#task", NULL); + + entry = GDATA_ENTRY (task); + + /* Check the task’s properties. */ + g_assert_cmpstr (gdata_entry_get_id (entry), ==, "some-id"); + g_assert_cmpstr (gdata_entry_get_etag (entry), ==, NULL); + g_assert_cmpstr (gdata_entry_get_title (entry), ==, + "some-title \"with quotes\""); + g_assert_cmpint (gdata_entry_get_updated (entry), ==, 1409427600); + g_assert_cmpstr (gdata_tasks_task_get_parent (task), ==, NULL); + g_assert_cmpstr (gdata_tasks_task_get_notes (task), ==, NULL); + g_assert_cmpstr (gdata_tasks_task_get_status (task), ==, + GDATA_TASKS_STATUS_NEEDS_ACTION); + g_assert_cmpint (gdata_tasks_task_get_due (task), ==, -1); + g_assert_cmpint (gdata_tasks_task_get_completed (task), ==, -1); + g_assert (gdata_tasks_task_is_deleted (task)); + g_assert (gdata_tasks_task_is_hidden (task)); + + self_link = gdata_entry_look_up_link (entry, GDATA_LINK_SELF); + g_assert (GDATA_IS_LINK (self_link)); + g_assert_cmpstr (gdata_link_get_uri (self_link), ==, + "http://some-uri/"); + g_assert_cmpstr (gdata_link_get_relation_type (self_link), ==, + GDATA_LINK_SELF); + g_assert_cmpstr (gdata_link_get_content_type (self_link), ==, NULL); + g_assert_cmpstr (gdata_link_get_language (self_link), ==, NULL); + g_assert_cmpstr (gdata_link_get_title (self_link), ==, NULL); + g_assert_cmpint (gdata_link_get_length (self_link), ==, -1); + + g_object_unref (task); +} + +/* Test the task parser with a maximal number of properties specified. */ +static void +test_task_parser_normal (void) +{ + GDataTasksTask *task = NULL; /* owned */ + GDataEntry *entry; /* unowned */ + GDataLink *self_link; /* unowned */ + GError *error = NULL; + + task = GDATA_TASKS_TASK (gdata_parsable_new_from_json (GDATA_TYPE_TASKS_TASK, + "{" + "\"kind\": \"tasks#task\"," + "\"id\": \"some-id\"," + "\"etag\": \"some-etag\"," + "\"title\": \"some-title \\\"with quotes\\\"\"," + "\"updated\": \"2014-08-30T19:40:00Z\"," + "\"selfLink\": \"http://some-uri/\"," + "\"parent\": \"some-parent-id\"," + "\"position\": \"some-position\"," + "\"notes\": \"Some notes!\"," + "\"status\": \"needsAction\"," + "\"due\": \"2014-08-30T20:00:00Z\"," + "\"completed\": \"2014-08-30T20:10:05Z\"," + "\"deleted\": false," + "\"hidden\": true," + /* Unhandled for the moment: */ + "\"links\": [" + "{" + "\"type\": \"email\"," + "\"description\": \"some-email\"," + "\"link\": \"example@example.com\"" + "}" + "]" + "}", -1, &error)); + g_assert_no_error (error); + g_assert (GDATA_IS_TASKS_TASK (task)); + gdata_test_compare_kind (GDATA_ENTRY (task), "tasks#task", NULL); + + entry = GDATA_ENTRY (task); + + /* Check the task’s properties. */ + g_assert_cmpstr (gdata_entry_get_id (entry), ==, "some-id"); + g_assert_cmpstr (gdata_entry_get_etag (entry), ==, "some-etag"); + g_assert_cmpstr (gdata_entry_get_title (entry), ==, + "some-title \"with quotes\""); + g_assert_cmpint (gdata_entry_get_updated (entry), ==, 1409427600); + g_assert_cmpstr (gdata_tasks_task_get_parent (task), ==, + "some-parent-id"); + g_assert_cmpstr (gdata_tasks_task_get_notes (task), ==, "Some notes!"); + g_assert_cmpstr (gdata_tasks_task_get_status (task), ==, + GDATA_TASKS_STATUS_NEEDS_ACTION); + g_assert_cmpint (gdata_tasks_task_get_due (task), ==, 1409428800); + g_assert_cmpint (gdata_tasks_task_get_completed (task), ==, 1409429405); + g_assert (!gdata_tasks_task_is_deleted (task)); + g_assert (gdata_tasks_task_is_hidden (task)); + + self_link = gdata_entry_look_up_link (entry, GDATA_LINK_SELF); + g_assert (GDATA_IS_LINK (self_link)); + g_assert_cmpstr (gdata_link_get_uri (self_link), ==, + "http://some-uri/"); + g_assert_cmpstr (gdata_link_get_relation_type (self_link), ==, + GDATA_LINK_SELF); + g_assert_cmpstr (gdata_link_get_content_type (self_link), ==, NULL); + g_assert_cmpstr (gdata_link_get_language (self_link), ==, NULL); + g_assert_cmpstr (gdata_link_get_title (self_link), ==, NULL); + g_assert_cmpint (gdata_link_get_length (self_link), ==, -1); + + /* Check that the same JSON is re-generated. */ + gdata_test_assert_json (task, + "{" + "\"kind\": \"tasks#task\"," + "\"id\": \"some-id\"," + "\"etag\": \"some-etag\"," + "\"title\": \"some-title \\\"with quotes\\\"\"," + "\"updated\": \"2014-08-30T19:40:00.000001+00:00\"," + "\"selfLink\": \"http://some-uri/\"," + "\"parent\": \"some-parent-id\"," + "\"position\": \"some-position\"," + "\"notes\": \"Some notes!\"," + "\"status\": \"needsAction\"," + "\"due\": \"2014-08-30T20:00:00.000001+00:00\"," + "\"completed\": \"2014-08-30T20:10:05.000001+00:00\"," + "\"deleted\": false," + "\"hidden\": true," + /* Unhandled for the moment: */ + "\"links\": [" + "{" + "\"type\": \"email\"," + "\"description\": \"some-email\"," + "\"link\": \"example@example.com\"" + "}" + "]" + "}"); + + g_object_unref (task); +} + +/* Test that getting/setting tasklist properties works. */ +static void +test_tasklist_properties (void) +{ + GDataTasksTasklist *tasklist; + gchar *id, *etag, *title; + gint64 updated; + + tasklist = gdata_tasks_tasklist_new (NULL); + + /* Check the kind is present and correct */ + g_assert (GDATA_IS_TASKS_TASKLIST (tasklist)); + gdata_test_compare_kind (GDATA_ENTRY (tasklist), + "tasks#taskList", NULL); + + /* Set all the properties of the object. */ + gdata_entry_set_title (GDATA_ENTRY (tasklist), "some-title"); + + /* Check the properties of the object */ + g_object_get (G_OBJECT (tasklist), + "id", &id, + "etag", &etag, + "title", &title, + "updated", &updated, + NULL); + + g_assert_cmpstr (id, ==, NULL); + g_assert_cmpstr (etag, ==, NULL); + g_assert_cmpstr (title, ==, "some-title"); + g_assert_cmpint (updated, ==, -1); + + g_free (title); + g_free (etag); + g_free (id); + + /* Check the properties using the getters. */ + g_assert_cmpstr (gdata_entry_get_id (GDATA_ENTRY (tasklist)), ==, NULL); + g_assert_cmpstr (gdata_entry_get_etag (GDATA_ENTRY (tasklist)), ==, + NULL); + g_assert_cmpstr (gdata_entry_get_title (GDATA_ENTRY (tasklist)), ==, + "some-title"); + g_assert_cmpint (gdata_entry_get_updated (GDATA_ENTRY (tasklist)), ==, + -1); + + /* Check the JSON. */ + gdata_test_assert_json (tasklist, + "{" + "\"kind\": \"tasks#taskList\"," + "\"title\": \"some-title\"" + "}"); + + g_object_unref (tasklist); +} + +/* Test that escaping tasklist properties for JSON works. */ +static void +test_tasklist_escaping (void) +{ + GDataTasksTasklist *tasklist; + + tasklist = gdata_tasks_tasklist_new (NULL); + gdata_entry_set_title (GDATA_ENTRY (tasklist), "Title \"with quotes\""); + + /* Check the outputted JSON is escaped properly. */ + gdata_test_assert_json (tasklist, + "{" + "\"kind\": \"tasks#taskList\"," + "\"title\": \"Title \\\"with quotes\\\"\"" + "}"); + + g_object_unref (tasklist); +} + +/* Test the tasklist parser with a maximal number of properties specified. */ +static void +test_tasklist_parser_normal (void) +{ + GDataTasksTasklist *tasklist = NULL; /* owned */ + GDataEntry *entry; /* unowned */ + GDataLink *self_link; /* unowned */ + GError *error = NULL; + + tasklist = GDATA_TASKS_TASKLIST (gdata_parsable_new_from_json (GDATA_TYPE_TASKS_TASKLIST, + "{" + "\"kind\": \"tasks#taskList\"," + "\"id\": \"some-id\"," + "\"etag\": \"some-etag\"," + "\"title\": \"some-title \\\"with quotes\\\"\"," + "\"updated\": \"2014-08-30T19:40:00Z\"," + "\"selfLink\": \"http://some-uri/\"" + "}", -1, &error)); + g_assert_no_error (error); + g_assert (GDATA_IS_TASKS_TASKLIST (tasklist)); + gdata_test_compare_kind (GDATA_ENTRY (tasklist), + "tasks#taskList", NULL); + + entry = GDATA_ENTRY (tasklist); + + /* Check the tasklist’s properties. */ + g_assert_cmpstr (gdata_entry_get_id (entry), ==, "some-id"); + g_assert_cmpstr (gdata_entry_get_etag (entry), ==, "some-etag"); + g_assert_cmpstr (gdata_entry_get_title (entry), ==, + "some-title \"with quotes\""); + g_assert_cmpint (gdata_entry_get_updated (entry), ==, 1409427600); + + self_link = gdata_entry_look_up_link (entry, GDATA_LINK_SELF); + g_assert (GDATA_IS_LINK (self_link)); + g_assert_cmpstr (gdata_link_get_uri (self_link), ==, + "http://some-uri/"); + g_assert_cmpstr (gdata_link_get_relation_type (self_link), ==, + GDATA_LINK_SELF); + g_assert_cmpstr (gdata_link_get_content_type (self_link), ==, NULL); + g_assert_cmpstr (gdata_link_get_language (self_link), ==, NULL); + g_assert_cmpstr (gdata_link_get_title (self_link), ==, NULL); + g_assert_cmpint (gdata_link_get_length (self_link), ==, -1); + + g_object_unref (tasklist); +} + +static void +mock_server_notify_resolver_cb (GObject *object, GParamSpec *pspec, + gpointer user_data) +{ + UhmServer *server; + UhmResolver *resolver; + + server = UHM_SERVER (object); + + /* Set up the expected domain names here. This should technically be + * split up between the different unit test suites, but that's too much + * effort. */ + resolver = uhm_server_get_resolver (server); + + if (resolver != NULL) { + 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); + } +} + +/* Set up a global GDataAuthorizer to be used for all the tests. Unfortunately, + * the Google Tasks 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) +{ + GDataOAuth1Authorizer *authorizer = NULL; /* owned */ + gchar *authentication_uri, *token, *token_secret, *verifier; + 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_TASKS_SERVICE)); + } + + /* Otherwise, go through the interactive OAuth dance. */ + gdata_test_mock_server_start_trace (mock_server, "global-authentication"); + authorizer = gdata_oauth1_authorizer_new ("Application name", + GDATA_TYPE_TASKS_SERVICE); + + /* Get an authentication URI */ + authentication_uri = gdata_oauth1_authorizer_request_authentication_uri (authorizer, &token, &token_secret, NULL, &error); + g_assert_no_error (error); + g_assert (authentication_uri != NULL); + + /* Get the verifier off the user. + * + * FIXME: Won’t work due to nonces in the OAuth protocol. */ + if (uhm_server_get_enable_online (mock_server)) { + verifier = gdata_test_query_user_for_verifier (authentication_uri); + } + + g_free (authentication_uri); + + if (verifier == NULL) { + /* Skip tests. */ + g_object_unref (authorizer); + authorizer = NULL; + goto skip_test; + } + + /* Authorise the token */ + g_assert (gdata_oauth1_authorizer_request_authorization (authorizer, token, token_secret, verifier, NULL, &error)); + g_assert_no_error (error); + +skip_test: + g_free (token); + g_free (token_secret); + g_free (verifier); + + uhm_server_end_trace (mock_server); + + return GDATA_AUTHORIZER (authorizer); +} + +int +main (int argc, char *argv[]) +{ + gint retval; + GDataAuthorizer *authorizer = NULL; /* owned */ + GDataService *service = NULL; /* owned */ + GFile *trace_directory = NULL; /* owned */ + + gdata_test_init (argc, argv); + + mock_server = gdata_test_get_mock_server (); + g_signal_connect (G_OBJECT (mock_server), "notify::resolver", + (GCallback) mock_server_notify_resolver_cb, NULL); + trace_directory = g_file_new_for_path (TEST_FILE_DIR "traces/tasks"); + uhm_server_set_trace_directory (mock_server, trace_directory); + g_object_unref (trace_directory); + + authorizer = create_global_authorizer (); + + service = GDATA_SERVICE (gdata_tasks_service_new (authorizer)); + + g_test_add_func ("/tasks/task/properties", test_task_properties); + g_test_add_func ("/tasks/task/escaping", test_task_escaping); + g_test_add_func ("/tasks/task/parser/minimal", + test_task_parser_minimal); + g_test_add_func ("/tasks/task/parser/normal", test_task_parser_normal); + + g_test_add_func ("/tasks/tasklist/properties", + test_tasklist_properties); + g_test_add_func ("/tasks/tasklist/escaping", test_tasklist_escaping); + g_test_add_func ("/tasks/tasklist/parser/normal", + test_tasklist_parser_normal); + + g_test_add_func ("/tasks/query/uri", test_query_uri); + g_test_add_func ("/tasks/query/etag", test_query_etag); + g_test_add_func ("/tasks/query/properties", test_query_properties); + + retval = g_test_run (); + + g_clear_object (&service); + g_clear_object (&authorizer); + + return retval; +} diff --git a/gdata/tests/traces/tasks/authentication b/gdata/tests/traces/tasks/authentication new file mode 100644 index 00000000..90921dcd --- /dev/null +++ b/gdata/tests/traces/tasks/authentication @@ -0,0 +1,58 @@ +> POST /accounts/OAuthGetRequestToken HTTP/1.1 +> Soup-Debug-Timestamp: 1409422326 +> Soup-Debug: SoupSession 1 (0x12c74a0), SoupMessage 1 (0x148d2c0), SoupSocket 1 (0x15295f0) +> Host: www.google.com +> Content-Type: application/x-www-form-urlencoded +> Authorization: OAuth oauth_consumer_key="anonymous",oauth_signature_method="HMAC-SHA1",oauth_signature="FdGrzlgEmMBFhWVk1s7%2BAOAntZ4%3D",oauth_timestamp="1409422326",oauth_nonce="TulqpkiMKnDeZ0yZBYeMEbeCBMs21s",oauth_version="1.0" +> Accept-Encoding: gzip, deflate +> User-Agent: libgdata/0.15.3 - gzip +> Connection: Keep-Alive +> +> xoauth_displayname=Application+name&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Ftasks&oauth_callback=oob + +< HTTP/1.1 200 OK +< Soup-Debug-Timestamp: 1409422326 +< Soup-Debug: SoupMessage 1 (0x148d2c0) +< Content-Type: text/plain; charset=UTF-8 +< X-Frame-Options: DENY +< Content-Encoding: gzip +< Date: Sat, 30 Aug 2014 18:12:06 GMT +< Expires: Sat, 30 Aug 2014 18:12:06 GMT +< Cache-Control: private, max-age=0 +< X-Content-Type-Options: nosniff +< X-XSS-Protection: 1; mode=block +< Server: GSE +< Alternate-Protocol: 443:quic +< Transfer-Encoding: chunked +< +< oauth_token=4%2Fl5d93H05bTVol0AM-ElG13vOG5Uq&oauth_token_secret=XKiN1TLQqnTqqyJFtf4W04u0&oauth_callback_confirmed=true + +> POST /accounts/OAuthGetAccessToken HTTP/1.1 +> Soup-Debug-Timestamp: 1409422343 +> Soup-Debug: SoupSession 1 (0x12c74a0), SoupMessage 2 (0x148d3b0), SoupSocket 2 (0x15292b0) +> Host: www.google.com +> Content-Type: application/x-www-form-urlencoded +> Authorization: OAuth oauth_consumer_key="anonymous",oauth_token="4%2Fl5d93H05bTVol0AM-ElG13vOG5Uq",oauth_signature_method="HMAC-SHA1",oauth_signature="iOj0JfnbfuigBbqwbmk7WdW%2BwXA%3D",oauth_timestamp="1409422343",oauth_nonce="h6O8MxJ4GcCUZ1Q",oauth_version="1.0" +> Accept-Encoding: gzip, deflate +> User-Agent: libgdata/0.15.3 - gzip +> Connection: Keep-Alive +> +> oauth_verifier=xr1gdoOQNtflNMk58dgYiBIv + +< HTTP/1.1 200 OK +< Soup-Debug-Timestamp: 1409422343 +< Soup-Debug: SoupMessage 2 (0x148d3b0) +< Content-Type: text/plain; charset=UTF-8 +< X-Frame-Options: DENY +< Content-Encoding: gzip +< Date: Sat, 30 Aug 2014 18:12:23 GMT +< Expires: Sat, 30 Aug 2014 18:12:23 GMT +< Cache-Control: private, max-age=0 +< X-Content-Type-Options: nosniff +< X-XSS-Protection: 1; mode=block +< Server: GSE +< Alternate-Protocol: 443:quic +< Transfer-Encoding: chunked +< +< oauth_token=1%2FQHOXVuxNbP60WkZZ3KTYK3jxxC1L8k7VbTa6Mtz-Vko&oauth_token_secret=iDghWbJqQk_2N47DebnAxXN2 + diff --git a/gdata/tests/traces/tasks/global-authentication b/gdata/tests/traces/tasks/global-authentication new file mode 100644 index 00000000..543a0a67 --- /dev/null +++ b/gdata/tests/traces/tasks/global-authentication @@ -0,0 +1,58 @@ +> POST /accounts/OAuthGetRequestToken HTTP/1.1 +> Soup-Debug-Timestamp: 1409422415 +> Soup-Debug: SoupSession 1 (0x1452110), SoupMessage 1 (0x176e0d0), SoupSocket 1 (0x17918d0) +> Host: www.google.com +> Content-Type: application/x-www-form-urlencoded +> Authorization: OAuth oauth_consumer_key="anonymous",oauth_signature_method="HMAC-SHA1",oauth_signature="i2nl79VvYsmeJu3fqxbPvTiuzOs%3D",oauth_timestamp="1409422414",oauth_nonce="xEqfLPDaB3h9_tmfbaXy3fV3",oauth_version="1.0" +> Accept-Encoding: gzip, deflate +> User-Agent: libgdata/0.15.3 - gzip +> Connection: Keep-Alive +> +> xoauth_displayname=Application+name&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Ftasks&oauth_callback=oob + +< HTTP/1.1 200 OK +< Soup-Debug-Timestamp: 1409422415 +< Soup-Debug: SoupMessage 1 (0x176e0d0) +< Content-Type: text/plain; charset=UTF-8 +< X-Frame-Options: DENY +< Content-Encoding: gzip +< Date: Sat, 30 Aug 2014 18:13:35 GMT +< Expires: Sat, 30 Aug 2014 18:13:35 GMT +< Cache-Control: private, max-age=0 +< X-Content-Type-Options: nosniff +< X-XSS-Protection: 1; mode=block +< Server: GSE +< Alternate-Protocol: 443:quic +< Transfer-Encoding: chunked +< +< oauth_token=4%2FxtSo6-lke4k9-2pkKsbio8Hlug_3&oauth_token_secret=yu3WyKJeNUBgvbcEdWh-pmc6&oauth_callback_confirmed=true + +> POST /accounts/OAuthGetAccessToken HTTP/1.1 +> Soup-Debug-Timestamp: 1409422422 +> Soup-Debug: SoupSession 1 (0x1452110), SoupMessage 2 (0x176e1c0), SoupSocket 2 (0x1791b40) +> Host: www.google.com +> Content-Type: application/x-www-form-urlencoded +> Authorization: OAuth oauth_consumer_key="anonymous",oauth_token="4%2FxtSo6-lke4k9-2pkKsbio8Hlug_3",oauth_signature_method="HMAC-SHA1",oauth_signature="rqutQ8Pg3rEFvv2IXEfH7q1zrSA%3D",oauth_timestamp="1409422422",oauth_nonce="JlzqaeUaWbuNm_a8kTtIDPmBzmr0",oauth_version="1.0" +> Accept-Encoding: gzip, deflate +> User-Agent: libgdata/0.15.3 - gzip +> Connection: Keep-Alive +> +> oauth_verifier=pYWHuxLD1Ko430Ty7y6zlFpk + +< HTTP/1.1 200 OK +< Soup-Debug-Timestamp: 1409422422 +< Soup-Debug: SoupMessage 2 (0x176e1c0) +< Content-Type: text/plain; charset=UTF-8 +< X-Frame-Options: DENY +< Content-Encoding: gzip +< Date: Sat, 30 Aug 2014 18:13:42 GMT +< Expires: Sat, 30 Aug 2014 18:13:42 GMT +< Cache-Control: private, max-age=0 +< X-Content-Type-Options: nosniff +< X-XSS-Protection: 1; mode=block +< Server: GSE +< Alternate-Protocol: 443:quic +< Transfer-Encoding: chunked +< +< oauth_token=1%2FPWynNF1IaX9ebgNq9RZcL8_aawfAk2LeWeKH62x7xnw&oauth_token_secret=s1yZ_C890UZYYI99K1JVV6Yb + diff --git a/gdata/tests/traces/tasks/tasklist-insert b/gdata/tests/traces/tasks/tasklist-insert new file mode 100644 index 00000000..5298e255 --- /dev/null +++ b/gdata/tests/traces/tasks/tasklist-insert @@ -0,0 +1,43 @@ +> POST /tasks/v1/users/@me/lists HTTP/1.1 +> Soup-Debug-Timestamp: 1409440767 +> Soup-Debug: SoupSession 1 (0xe9c5d0), SoupMessage 1 (0x1033ac0), SoupSocket 1 (0x11dbdf0) +> Host: www.googleapis.com +> Authorization: OAuth oauth_consumer_key="anonymous",oauth_token="1%2Fz2LxDQgU_zI5e8bSFsM5whzWKbIgQOOxp16jbVMaCRI",oauth_signature_method="HMAC-SHA1",oauth_signature="N%2BaoKaK8znejOXtPpSMCViVoo9U%3D",oauth_timestamp="1409440767",oauth_nonce="VsowDzIyUz0n4y7XqeWeo_HS5O5U",oauth_version="1.0" +> GData-Version: 2 +> Content-Type: application/json +> Accept-Encoding: gzip, deflate +> User-Agent: libgdata/0.15.3 - gzip +> Connection: Keep-Alive +> +> {"title":"My list of things","kind":"tasks#taskList"} + +< HTTP/1.1 403 Forbidden +< Soup-Debug-Timestamp: 1409440767 +< Soup-Debug: SoupMessage 1 (0x1033ac0) +< Content-Type: application/json; charset=UTF-8 +< Content-Encoding: gzip +< Date: Sat, 30 Aug 2014 23:19:27 GMT +< Expires: Sat, 30 Aug 2014 23:19:27 GMT +< Cache-Control: private, max-age=0 +< X-Content-Type-Options: nosniff +< X-Frame-Options: SAMEORIGIN +< X-XSS-Protection: 1; mode=block +< Server: GSE +< Alternate-Protocol: 443:quic +< Transfer-Encoding: chunked +< +< { +< "error": { +< "errors": [ +< { +< "domain": "usageLimits", +< "reason": "dailyLimitExceededUnreg", +< "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.", +< "extendedHelp": "https://code.google.com/apis/console" +< } +< ], +< "code": 403, +< "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup." +< } +< } + |