/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* * GData Client * Copyright (C) Philip Withnall 2011 * * 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 . */ #include #include #include #include "common.h" /* Used as common "testing domains" to simplify test code. */ static GDataAuthorizationDomain *test_domain1 = NULL; static GDataAuthorizationDomain *test_domain2 = NULL; static void test_authorization_domain_properties (void) { GDataAuthorizationDomain *domain; gchar *service_name, *scope; /* NOTE: It's not expected that client code will normally get hold of GDataAuthorizationDomain instances this way. * This is just for testing purposes. */ domain = GDATA_AUTHORIZATION_DOMAIN (g_object_new (GDATA_TYPE_AUTHORIZATION_DOMAIN, "service-name", "service-name", "scope", "scope", NULL)); g_assert_cmpstr (gdata_authorization_domain_get_service_name (domain), ==, "service-name"); g_assert_cmpstr (gdata_authorization_domain_get_scope (domain), ==, "scope"); g_object_get (domain, "service-name", &service_name, "scope", &scope, NULL); g_assert_cmpstr (service_name, ==, "service-name"); g_assert_cmpstr (scope, ==, "scope"); g_free (service_name); g_free (scope); } /* Simple implementation of GDataAuthorizer for test purposes */ #define TYPE_SIMPLE_AUTHORIZER (simple_authorizer_get_type ()) #define SIMPLE_AUTHORIZER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SIMPLE_TYPE_AUTHORIZER, SimpleAuthorizer)) #define SIMPLE_AUTHORIZER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SIMPLE_TYPE_AUTHORIZER, SimpleAuthorizerClass)) #define IS_SIMPLE_AUTHORIZER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SIMPLE_TYPE_AUTHORIZER)) #define IS_SIMPLE_AUTHORIZER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SIMPLE_TYPE_AUTHORIZER)) #define SIMPLE_AUTHORIZER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SIMPLE_TYPE_AUTHORIZER, SimpleAuthorizerClass)) typedef struct { GObject parent; } SimpleAuthorizer; typedef struct { GObjectClass parent; } SimpleAuthorizerClass; static GType simple_authorizer_get_type (void) G_GNUC_CONST; static void simple_authorizer_authorizer_init (GDataAuthorizerInterface *iface); G_DEFINE_TYPE_WITH_CODE (SimpleAuthorizer, simple_authorizer, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GDATA_TYPE_AUTHORIZER, simple_authorizer_authorizer_init)) static void simple_authorizer_class_init (SimpleAuthorizerClass *klass) { /* Nothing to see here */ } static void simple_authorizer_init (SimpleAuthorizer *self) { /* Nothing to see here */ } static void simple_authorizer_process_request (GDataAuthorizer *self, GDataAuthorizationDomain *domain, SoupMessage *message) { SoupURI *test_uri; /* Check that the domain and message are as expected */ g_assert (domain == NULL || GDATA_IS_AUTHORIZATION_DOMAIN (domain)); if (domain != NULL) { g_assert_cmpstr (gdata_authorization_domain_get_scope (domain), ==, "scope1"); } g_assert (message != NULL); g_assert (SOUP_IS_MESSAGE (message)); test_uri = soup_uri_new ("http://example.com/"); g_assert (soup_uri_equal (soup_message_get_uri (message), test_uri) == TRUE); soup_uri_free (test_uri); /* Check that this is the first time we've touched the message, and if so, flag the message as touched */ if (domain != NULL) { g_assert (soup_message_headers_get_one (message->request_headers, "process_request") == NULL); soup_message_headers_append (message->request_headers, "process_request", "1"); } else { soup_message_headers_append (message->request_headers, "process_request_null", "1"); } } static gboolean simple_authorizer_is_authorized_for_domain (GDataAuthorizer *self, GDataAuthorizationDomain *domain) { gboolean is_test_domain1, is_test_domain2; /* Check that the domain is as expected */ g_assert (domain != NULL); g_assert (GDATA_IS_AUTHORIZATION_DOMAIN (domain)); is_test_domain1 = (strcmp (gdata_authorization_domain_get_scope (domain), "scope1") == 0) ? TRUE : FALSE; is_test_domain2 = (strcmp (gdata_authorization_domain_get_scope (domain), "scope2") == 0) ? TRUE : FALSE; g_assert (is_test_domain1 == TRUE || is_test_domain2 == TRUE); /* Increment the counter on the domain so we know if this function's been called more than once on each domain */ g_object_set_data (G_OBJECT (domain), "counter", GUINT_TO_POINTER (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (domain), "counter")) + 1)); /* Only authorise test_domain1 */ return is_test_domain1; } static void simple_authorizer_authorizer_init (GDataAuthorizerInterface *iface) { iface->process_request = simple_authorizer_process_request; iface->is_authorized_for_domain = simple_authorizer_is_authorized_for_domain; } /* Normal implementation of GDataAuthorizer for test purposes */ #define TYPE_NORMAL_AUTHORIZER (normal_authorizer_get_type ()) #define NORMAL_AUTHORIZER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NORMAL_TYPE_AUTHORIZER, NormalAuthorizer)) #define NORMAL_AUTHORIZER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NORMAL_TYPE_AUTHORIZER, NormalAuthorizerClass)) #define IS_NORMAL_AUTHORIZER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NORMAL_TYPE_AUTHORIZER)) #define IS_NORMAL_AUTHORIZER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NORMAL_TYPE_AUTHORIZER)) #define NORMAL_AUTHORIZER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NORMAL_TYPE_AUTHORIZER, NormalAuthorizerClass)) typedef struct { GObject parent; } NormalAuthorizer; typedef struct { GObjectClass parent; } NormalAuthorizerClass; static GType normal_authorizer_get_type (void) G_GNUC_CONST; static void normal_authorizer_authorizer_init (GDataAuthorizerInterface *iface); G_DEFINE_TYPE_WITH_CODE (NormalAuthorizer, normal_authorizer, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GDATA_TYPE_AUTHORIZER, normal_authorizer_authorizer_init)) static void normal_authorizer_class_init (NormalAuthorizerClass *klass) { /* Nothing to see here */ } static void normal_authorizer_init (NormalAuthorizer *self) { /* Nothing to see here */ } static gboolean normal_authorizer_refresh_authorization (GDataAuthorizer *self, GCancellable *cancellable, GError **error) { /* Check the inputs */ g_assert (GDATA_IS_AUTHORIZER (self)); g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_assert (error == NULL || *error == NULL); /* Increment the counter on the authorizer so we know if this function's been called more than once */ g_object_set_data (G_OBJECT (self), "counter", GUINT_TO_POINTER (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (self), "counter")) + 1)); /* If we're instructed to set an error, do so (with an arbitrary error code) */ if (g_object_get_data (G_OBJECT (self), "error") != NULL) { g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR, "Error message"); return FALSE; } return TRUE; } static void normal_authorizer_authorizer_init (GDataAuthorizerInterface *iface) { /* Use the same implementation as SimpleAuthorizer for process_request() and is_authorized_for_domain(). */ iface->process_request = simple_authorizer_process_request; iface->is_authorized_for_domain = simple_authorizer_is_authorized_for_domain; /* Unlike SimpleAuthorizer, also implement refresh_authorization() (but not the async versions). */ iface->refresh_authorization = normal_authorizer_refresh_authorization; } /* Complex implementation of GDataAuthorizer for test purposes */ #define TYPE_COMPLEX_AUTHORIZER (complex_authorizer_get_type ()) #define COMPLEX_AUTHORIZER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), COMPLEX_TYPE_AUTHORIZER, ComplexAuthorizer)) #define COMPLEX_AUTHORIZER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), COMPLEX_TYPE_AUTHORIZER, ComplexAuthorizerClass)) #define IS_COMPLEX_AUTHORIZER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), COMPLEX_TYPE_AUTHORIZER)) #define IS_COMPLEX_AUTHORIZER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), COMPLEX_TYPE_AUTHORIZER)) #define COMPLEX_AUTHORIZER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), COMPLEX_TYPE_AUTHORIZER, ComplexAuthorizerClass)) typedef struct { GObject parent; } ComplexAuthorizer; typedef struct { GObjectClass parent; } ComplexAuthorizerClass; static GType complex_authorizer_get_type (void) G_GNUC_CONST; static void complex_authorizer_authorizer_init (GDataAuthorizerInterface *iface); G_DEFINE_TYPE_WITH_CODE (ComplexAuthorizer, complex_authorizer, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GDATA_TYPE_AUTHORIZER, complex_authorizer_authorizer_init)) static void complex_authorizer_class_init (ComplexAuthorizerClass *klass) { /* Nothing to see here */ } static void complex_authorizer_init (ComplexAuthorizer *self) { /* Nothing to see here */ } static void complex_authorizer_refresh_authorization_async (GDataAuthorizer *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_autoptr(GTask) task = NULL; g_autoptr(GError) error = NULL; /* Check the inputs */ g_assert (GDATA_IS_AUTHORIZER (self)); g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, complex_authorizer_refresh_authorization_async); /* Increment the async counter on the authorizer so we know if this function's been called more than once */ g_object_set_data (G_OBJECT (self), "async-counter", GUINT_TO_POINTER (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (self), "async-counter")) + 1)); if (g_cancellable_set_error_if_cancelled (cancellable, &error) == TRUE) { /* Handle cancellation */ g_task_return_error (task, g_steal_pointer (&error)); } else if (g_object_get_data (G_OBJECT (self), "error") != NULL) { /* If we're instructed to set an error, do so (with an arbitrary error code) */ g_task_return_new_error (task, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_NETWORK_ERROR, "%s", "Error message"); } else { g_task_return_boolean (task, TRUE); } } static gboolean complex_authorizer_refresh_authorization_finish (GDataAuthorizer *self, GAsyncResult *async_result, GError **error) { /* Check the inputs */ g_assert (GDATA_IS_AUTHORIZER (self)); g_assert (G_IS_ASYNC_RESULT (async_result)); g_assert (error == NULL || *error == NULL); g_assert (g_task_is_valid (async_result, self)); g_assert (g_async_result_is_tagged (async_result, complex_authorizer_refresh_authorization_async)); /* Assert that the async function's already been called (once) */ g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (self), "async-counter")), ==, 1); /* Increment the finish counter on the authorizer so we know if this function's been called more than once */ g_object_set_data (G_OBJECT (self), "finish-counter", GUINT_TO_POINTER (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (self), "finish-counter")) + 1)); return g_task_propagate_boolean (G_TASK (async_result), error); } static void complex_authorizer_authorizer_init (GDataAuthorizerInterface *iface) { /* Use the same implementation as SimpleAuthorizer/NormalAuthorizer for process_request(), is_authorized_for_domain() and * refresh_authorization(). */ iface->process_request = simple_authorizer_process_request; iface->is_authorized_for_domain = simple_authorizer_is_authorized_for_domain; iface->refresh_authorization = normal_authorizer_refresh_authorization; /* Unlike NormalAuthorizer, also implement the async versions of refresh_authorization(). */ iface->refresh_authorization_async = complex_authorizer_refresh_authorization_async; iface->refresh_authorization_finish = complex_authorizer_refresh_authorization_finish; } /* Testing data for generic GDataAuthorizer interface tests */ typedef struct { GDataAuthorizer *authorizer; } AuthorizerData; static void set_up_simple_authorizer_data (AuthorizerData *data, gconstpointer user_data) { data->authorizer = GDATA_AUTHORIZER (g_object_new (TYPE_SIMPLE_AUTHORIZER, NULL)); } static void set_up_normal_authorizer_data (AuthorizerData *data, gconstpointer user_data) { data->authorizer = GDATA_AUTHORIZER (g_object_new (TYPE_NORMAL_AUTHORIZER, NULL)); } static void set_up_complex_authorizer_data (AuthorizerData *data, gconstpointer user_data) { data->authorizer = GDATA_AUTHORIZER (g_object_new (TYPE_COMPLEX_AUTHORIZER, NULL)); } static void tear_down_authorizer_data (AuthorizerData *data, gconstpointer user_data) { g_object_unref (data->authorizer); } /* Test that calling gdata_authorizer_process_request() happens correctly */ static void test_authorizer_process_request (AuthorizerData *data, gconstpointer user_data) { SoupMessage *message; message = soup_message_new (SOUP_METHOD_GET, "http://example.com/"); gdata_authorizer_process_request (data->authorizer, test_domain1, message); g_assert_cmpstr (soup_message_headers_get_one (message->request_headers, "process_request"), ==, "1"); g_assert (soup_message_headers_get_one (message->request_headers, "process_request_null") == NULL); g_object_unref (message); } /* Test that calling gdata_authorizer_process_request() happens correctly for a NULL domain */ static void test_authorizer_process_request_null (AuthorizerData *data, gconstpointer user_data) { SoupMessage *message; message = soup_message_new (SOUP_METHOD_GET, "http://example.com/"); gdata_authorizer_process_request (data->authorizer, NULL, message); g_assert (soup_message_headers_get_one (message->request_headers, "process_request") == NULL); g_assert_cmpstr (soup_message_headers_get_one (message->request_headers, "process_request_null"), ==, "1"); g_object_unref (message); } /* Test that calling gdata_authorizer_is_authorized_for_domain() happens correctly */ static void test_authorizer_is_authorized_for_domain (AuthorizerData *data, gconstpointer user_data) { /* Set some counters on the test domains to check that the interface implementation is only called once per domain */ g_object_set_data (G_OBJECT (test_domain1), "counter", GUINT_TO_POINTER (0)); g_object_set_data (G_OBJECT (test_domain2), "counter", GUINT_TO_POINTER (0)); g_assert (gdata_authorizer_is_authorized_for_domain (data->authorizer, test_domain1) == TRUE); g_assert (gdata_authorizer_is_authorized_for_domain (data->authorizer, test_domain2) == FALSE); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (test_domain1), "counter")), ==, 1); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (test_domain2), "counter")), ==, 1); } /* Test that calling gdata_authorizer_is_authorized_for_domain() with a NULL authorizer always returns FALSE */ static void test_authorizer_is_authorized_for_domain_null (AuthorizerData *data, gconstpointer user_data) { g_assert (gdata_authorizer_is_authorized_for_domain (NULL, test_domain1) == FALSE); g_assert (gdata_authorizer_is_authorized_for_domain (NULL, test_domain2) == FALSE); } /* Test that calling refresh_authorization() on an authorizer which implements it returns TRUE without error, and only calls the implementation * once */ static void test_authorizer_refresh_authorization (AuthorizerData *data, gconstpointer user_data) { gboolean success; GError *error = NULL; /* Set a counter on the authoriser to check that the interface implementation is only called once */ g_object_set_data (G_OBJECT (data->authorizer), "counter", GUINT_TO_POINTER (0)); success = gdata_authorizer_refresh_authorization (data->authorizer, NULL, &error); g_assert_no_error (error); g_assert (success == TRUE); g_clear_error (&error); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "counter")), ==, 1); } /* Test that calling refresh_authorization() on an authorizer which implements it with errors returns FALSE with an error, and only calls the * implementation once */ static void test_authorizer_refresh_authorization_error (AuthorizerData *data, gconstpointer user_data) { gboolean success; GError *error = NULL; /* Set a counter on the authoriser to check that the interface implementation is only called once */ g_object_set_data (G_OBJECT (data->authorizer), "counter", GUINT_TO_POINTER (0)); /* Set a flag on the authoriser to make the NormalAuthorizer implementation return an error for refresh_authorization() */ g_object_set_data (G_OBJECT (data->authorizer), "error", GUINT_TO_POINTER (TRUE)); success = gdata_authorizer_refresh_authorization (data->authorizer, NULL, &error); g_assert_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR); g_assert (success == FALSE); g_clear_error (&error); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "counter")), ==, 1); } /* Test that calling refresh_authorization() on an authorizer which doesn't implement it returns FALSE without an error */ static void test_authorizer_refresh_authorization_unimplemented (AuthorizerData *data, gconstpointer user_data) { gboolean success; GError *error = NULL; success = gdata_authorizer_refresh_authorization (data->authorizer, NULL, &error); g_assert_no_error (error); g_assert (success == FALSE); g_clear_error (&error); } /* Test that calling refresh_authorization() on an authorizer which doesn't implement it, then cancelling the call returns FALSE without an error * (not even a cancellation error) */ static void test_authorizer_refresh_authorization_cancellation_unimplemented (AuthorizerData *data, gconstpointer user_data) { GCancellable *cancellable; gboolean success; GError *error = NULL; cancellable = g_cancellable_new (); g_cancellable_cancel (cancellable); success = gdata_authorizer_refresh_authorization (data->authorizer, cancellable, &error); g_assert_no_error (error); g_assert (success == FALSE); g_clear_error (&error); g_object_unref (cancellable); } /* Set of standard async callback functions for refresh_authorization_async() which check various combinations of success and error value */ static void test_authorizer_refresh_authorization_async_success_no_error_cb (GDataAuthorizer *authorizer, GAsyncResult *async_result, GMainLoop *main_loop) { gboolean success; GError *error = NULL; success = gdata_authorizer_refresh_authorization_finish (authorizer, async_result, &error); g_assert_no_error (error); g_assert (success == TRUE); g_clear_error (&error); g_main_loop_quit (main_loop); } static void test_authorizer_refresh_authorization_async_failure_no_error_cb (GDataAuthorizer *authorizer, GAsyncResult *async_result, GMainLoop *main_loop) { gboolean success; GError *error = NULL; success = gdata_authorizer_refresh_authorization_finish (authorizer, async_result, &error); g_assert_no_error (error); g_assert (success == FALSE); g_clear_error (&error); g_main_loop_quit (main_loop); } static void test_authorizer_refresh_authorization_async_network_error_cb (GDataAuthorizer *authorizer, GAsyncResult *async_result, GMainLoop *main_loop) { gboolean success; GError *error = NULL; success = gdata_authorizer_refresh_authorization_finish (authorizer, async_result, &error); g_assert_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_NETWORK_ERROR); g_assert (success == FALSE); g_clear_error (&error); g_main_loop_quit (main_loop); } static void test_authorizer_refresh_authorization_async_protocol_error_cb (GDataAuthorizer *authorizer, GAsyncResult *async_result, GMainLoop *main_loop) { gboolean success; GError *error = NULL; success = gdata_authorizer_refresh_authorization_finish (authorizer, async_result, &error); g_assert_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR); g_assert (success == FALSE); g_clear_error (&error); g_main_loop_quit (main_loop); } static void test_authorizer_refresh_authorization_async_cancelled_error_cb (GDataAuthorizer *authorizer, GAsyncResult *async_result, GMainLoop *main_loop) { gboolean success; GError *error = NULL; success = gdata_authorizer_refresh_authorization_finish (authorizer, async_result, &error); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_assert (success == FALSE); g_clear_error (&error); g_main_loop_quit (main_loop); } /* Test that calling refresh_authorization_async() on an authorizer which implements it returns TRUE without an error */ static void test_authorizer_refresh_authorization_async (AuthorizerData *data, gconstpointer user_data) { GMainLoop *main_loop; /* Set counters on the authoriser to check that the interface implementations are only called once */ g_object_set_data (G_OBJECT (data->authorizer), "counter", GUINT_TO_POINTER (0)); g_object_set_data (G_OBJECT (data->authorizer), "async-counter", GUINT_TO_POINTER (0)); g_object_set_data (G_OBJECT (data->authorizer), "finish-counter", GUINT_TO_POINTER (0)); main_loop = g_main_loop_new (NULL, FALSE); gdata_authorizer_refresh_authorization_async (data->authorizer, NULL, (GAsyncReadyCallback) test_authorizer_refresh_authorization_async_success_no_error_cb, main_loop); g_main_loop_run (main_loop); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "counter")), ==, 0); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "async-counter")), ==, 1); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "finish-counter")), ==, 1); g_main_loop_unref (main_loop); } /* Test that calling refresh_authorization_async() on an authorizer which implements it with an error returns FALSE with the appropriate error */ static void test_authorizer_refresh_authorization_async_error (AuthorizerData *data, gconstpointer user_data) { GMainLoop *main_loop; /* Set counters on the authoriser to check that the interface implementations are only called once */ g_object_set_data (G_OBJECT (data->authorizer), "counter", GUINT_TO_POINTER (0)); g_object_set_data (G_OBJECT (data->authorizer), "async-counter", GUINT_TO_POINTER (0)); g_object_set_data (G_OBJECT (data->authorizer), "finish-counter", GUINT_TO_POINTER (0)); /* Set a flag on the authoriser to make the ComplexAuthorizer implementation return an error for refresh_authorization_async() */ g_object_set_data (G_OBJECT (data->authorizer), "error", GUINT_TO_POINTER (TRUE)); main_loop = g_main_loop_new (NULL, FALSE); gdata_authorizer_refresh_authorization_async (data->authorizer, NULL, (GAsyncReadyCallback) test_authorizer_refresh_authorization_async_network_error_cb, main_loop); g_main_loop_run (main_loop); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "counter")), ==, 0); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "async-counter")), ==, 1); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "finish-counter")), ==, 1); g_main_loop_unref (main_loop); } /* Test that calling refresh_authorization_async() on an authorizer which implements it, then cancelling the call returns FALSE with a cancellation * error */ static void test_authorizer_refresh_authorization_async_cancellation (AuthorizerData *data, gconstpointer user_data) { GCancellable *cancellable; GMainLoop *main_loop; /* Set counters on the authoriser to check that the interface implementations are only called once */ g_object_set_data (G_OBJECT (data->authorizer), "counter", GUINT_TO_POINTER (0)); g_object_set_data (G_OBJECT (data->authorizer), "async-counter", GUINT_TO_POINTER (0)); g_object_set_data (G_OBJECT (data->authorizer), "finish-counter", GUINT_TO_POINTER (0)); main_loop = g_main_loop_new (NULL, FALSE); cancellable = g_cancellable_new (); g_cancellable_cancel (cancellable); gdata_authorizer_refresh_authorization_async (data->authorizer, cancellable, (GAsyncReadyCallback) test_authorizer_refresh_authorization_async_cancelled_error_cb, main_loop); g_main_loop_run (main_loop); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "counter")), ==, 0); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "async-counter")), ==, 1); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "finish-counter")), ==, 1); g_object_unref (cancellable); g_main_loop_unref (main_loop); } /* Test that calling refresh_authorization_async() on an authorizer which doesn't implement it, but does implement refresh_authorization(), returns * TRUE without an error */ static void test_authorizer_refresh_authorization_async_simulated (AuthorizerData *data, gconstpointer user_data) { GMainLoop *main_loop; /* Set a counter on the authoriser to check that the interface implementation is only called once */ g_object_set_data (G_OBJECT (data->authorizer), "counter", GUINT_TO_POINTER (0)); main_loop = g_main_loop_new (NULL, FALSE); gdata_authorizer_refresh_authorization_async (data->authorizer, NULL, (GAsyncReadyCallback) test_authorizer_refresh_authorization_async_success_no_error_cb, main_loop); g_main_loop_run (main_loop); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "counter")), ==, 1); g_main_loop_unref (main_loop); } /* Test that calling refresh_authorization_async() on an authorizer which doesn't implement it, but does implement refresh_authorization() with an * error, returns FALSE with the appropriate error */ static void test_authorizer_refresh_authorization_async_error_simulated (AuthorizerData *data, gconstpointer user_data) { GMainLoop *main_loop; /* Set a counter on the authoriser to check that the interface implementation is only called once */ g_object_set_data (G_OBJECT (data->authorizer), "counter", GUINT_TO_POINTER (0)); /* Set a flag on the authoriser to make the NormalAuthorizer implementation return an error for refresh_authorization() */ g_object_set_data (G_OBJECT (data->authorizer), "error", GUINT_TO_POINTER (TRUE)); main_loop = g_main_loop_new (NULL, FALSE); gdata_authorizer_refresh_authorization_async (data->authorizer, NULL, (GAsyncReadyCallback) test_authorizer_refresh_authorization_async_protocol_error_cb, main_loop); g_main_loop_run (main_loop); g_assert_cmpuint (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (data->authorizer), "counter")), ==, 1); g_main_loop_unref (main_loop); } /* Test that calling refresh_authorization_async() on an authorizer which doesn't implement it, but does implement refresh_authorization(), then * cancelling the call returns FALSE with a cancellation error */ static void test_authorizer_refresh_authorization_async_cancellation_simulated (AuthorizerData *data, gconstpointer user_data) { GCancellable *cancellable; GMainLoop *main_loop; main_loop = g_main_loop_new (NULL, FALSE); cancellable = g_cancellable_new (); g_cancellable_cancel (cancellable); /* Note we don't count how many times the implementation of refresh_authorization() is called, since cancellation can legitimately be * handled by the gdata_authorizer_refresh_authorization_async() code before refresh_authorization() is ever called. */ gdata_authorizer_refresh_authorization_async (data->authorizer, cancellable, (GAsyncReadyCallback) test_authorizer_refresh_authorization_async_cancelled_error_cb, main_loop); g_main_loop_run (main_loop); g_object_unref (cancellable); g_main_loop_unref (main_loop); } /* Test that calling refresh_authorization_async() on an authorizer which doesn't implement it returns FALSE without an error */ static void test_authorizer_refresh_authorization_async_unimplemented (AuthorizerData *data, gconstpointer user_data) { GMainLoop *main_loop; main_loop = g_main_loop_new (NULL, FALSE); gdata_authorizer_refresh_authorization_async (data->authorizer, NULL, (GAsyncReadyCallback) test_authorizer_refresh_authorization_async_failure_no_error_cb, main_loop); g_main_loop_run (main_loop); g_main_loop_unref (main_loop); } /* Test that calling refresh_authorization_async() on an authorizer which doesn't implement it, then cancelling the call returns FALSE without an * error (not even a cancellation error) */ static void test_authorizer_refresh_authorization_async_cancellation_unimplemented (AuthorizerData *data, gconstpointer user_data) { GCancellable *cancellable; GMainLoop *main_loop; main_loop = g_main_loop_new (NULL, FALSE); cancellable = g_cancellable_new (); g_cancellable_cancel (cancellable); gdata_authorizer_refresh_authorization_async (data->authorizer, cancellable, (GAsyncReadyCallback) test_authorizer_refresh_authorization_async_failure_no_error_cb, main_loop); g_main_loop_run (main_loop); g_object_unref (cancellable); g_main_loop_unref (main_loop); } int main (int argc, char *argv[]) { int retval; gdata_test_init (argc, argv); /* Note: This is not how GDataAuthorizationDomains are meant to be constructed. Client code is not expected to do this. */ test_domain1 = g_object_new (GDATA_TYPE_AUTHORIZATION_DOMAIN, "service-name", "service-name1", "scope", "scope1", NULL); test_domain2 = g_object_new (GDATA_TYPE_AUTHORIZATION_DOMAIN, "service-name", "service-name2", "scope", "scope2", NULL); /* GDataAuthorizationDomain tests */ g_test_add_func ("/authorization-domain/properties", test_authorization_domain_properties); /* GDataAuthorizer interface tests */ g_test_add ("/authorizer/process-request", AuthorizerData, NULL, set_up_simple_authorizer_data, test_authorizer_process_request, tear_down_authorizer_data); g_test_add ("/authorizer/process-request/null", AuthorizerData, NULL, set_up_simple_authorizer_data, test_authorizer_process_request_null, tear_down_authorizer_data); g_test_add ("/authorizer/is-authorized-for-domain", AuthorizerData, NULL, set_up_simple_authorizer_data, test_authorizer_is_authorized_for_domain, tear_down_authorizer_data); g_test_add ("/authorizer/is-authorized-for-domain/null", AuthorizerData, NULL, set_up_simple_authorizer_data, test_authorizer_is_authorized_for_domain_null, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization", AuthorizerData, NULL, set_up_normal_authorizer_data, test_authorizer_refresh_authorization, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/error", AuthorizerData, NULL, set_up_normal_authorizer_data, test_authorizer_refresh_authorization_error, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/unimplemented", AuthorizerData, NULL, set_up_simple_authorizer_data, test_authorizer_refresh_authorization_unimplemented, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/cancellation/unimplemented", AuthorizerData, NULL, set_up_simple_authorizer_data, test_authorizer_refresh_authorization_cancellation_unimplemented, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/async", AuthorizerData, NULL, set_up_complex_authorizer_data, test_authorizer_refresh_authorization_async, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/async/error", AuthorizerData, NULL, set_up_complex_authorizer_data, test_authorizer_refresh_authorization_async_error, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/async/cancellation", AuthorizerData, NULL, set_up_complex_authorizer_data, test_authorizer_refresh_authorization_async_cancellation, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/async/simulated", AuthorizerData, NULL, set_up_normal_authorizer_data, test_authorizer_refresh_authorization_async_simulated, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/async/error/simulated", AuthorizerData, NULL, set_up_normal_authorizer_data, test_authorizer_refresh_authorization_async_error_simulated, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/async/cancellation/simulated", AuthorizerData, NULL, set_up_normal_authorizer_data, test_authorizer_refresh_authorization_async_cancellation_simulated, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/async/unimplemented", AuthorizerData, NULL, set_up_simple_authorizer_data, test_authorizer_refresh_authorization_async_unimplemented, tear_down_authorizer_data); g_test_add ("/authorizer/refresh-authorization/async/cancellation/unimplemented", AuthorizerData, NULL, set_up_simple_authorizer_data, test_authorizer_refresh_authorization_async_cancellation_unimplemented, tear_down_authorizer_data); retval = g_test_run (); g_object_unref (test_domain2); g_object_unref (test_domain1); return retval; }