[librest/gwagner/oauth2] oauth2: tests
- From: Günther Wagner <gwagner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librest/gwagner/oauth2] oauth2: tests
- Date: Wed, 17 Nov 2021 06:17:14 +0000 (UTC)
commit 315a4c0a0ba000b9695d1bc832c2f600b1dd0600
Author: Günther Wagner <info gunibert de>
Date: Wed Nov 17 07:16:46 2021 +0100
oauth2: tests
rest/rest-oauth2-proxy.c | 19 ++-
rest/rest-oauth2-proxy.h | 9 +-
rest/rest-pkce-code-challenge.c | 14 +++
rest/rest-pkce-code-challenge.h | 6 +
rest/rest-utils.c | 8 ++
tests/flickr.c | 13 ++
tests/helper/test-server.c | 123 +++++++++++++++++++
tests/helper/test-server.h | 34 ++++++
tests/meson.build | 3 +-
tests/oauth2.c | 215 +++++++++++++++++++++++++++++++++
tests/proxy.c | 260 ++++++++++++----------------------------
11 files changed, 514 insertions(+), 190 deletions(-)
---
diff --git a/rest/rest-oauth2-proxy.c b/rest/rest-oauth2-proxy.c
index 14ecaab..7c0d222 100644
--- a/rest/rest-oauth2-proxy.c
+++ b/rest/rest-oauth2-proxy.c
@@ -40,6 +40,8 @@ typedef struct
G_DEFINE_TYPE_WITH_PRIVATE (RestOAuth2Proxy, rest_oauth2_proxy, REST_TYPE_PROXY)
+G_DEFINE_QUARK (rest-oauth2-proxy-error-quark, rest_oauth2_proxy_error)
+
enum {
PROP_0,
PROP_AUTH_URL,
@@ -342,7 +344,7 @@ rest_oauth2_proxy_init (RestOAuth2Proxy *self)
*
* Since: 0.8
*/
-const gchar *
+gchar *
rest_oauth2_proxy_build_authorization_url (RestOAuth2Proxy *self,
const gchar *code_challenge,
const gchar *scope,
@@ -356,13 +358,15 @@ rest_oauth2_proxy_build_authorization_url (RestOAuth2Proxy *self,
g_return_val_if_fail (REST_IS_OAUTH2_PROXY (self), NULL);
- *state = random_string (10);
+ if (state != NULL)
+ *state = random_string (10);
params = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (params, "response_type", "code");
g_hash_table_insert (params, "client_id", priv->client_id);
g_hash_table_insert (params, "redirect_uri", priv->redirect_uri);
- g_hash_table_insert (params, "state", *state);
+ if (state != NULL)
+ g_hash_table_insert (params, "state", *state);
g_hash_table_insert (params, "code_challenge", (gchar *)code_challenge);
g_hash_table_insert (params, "code_challenge_method", "S256");
if (scope)
@@ -478,6 +482,15 @@ rest_oauth2_proxy_refresh_access_token_async (RestOAuth2Proxy *self,
g_return_if_fail (REST_IS_OAUTH2_PROXY (self));
+ if (priv->refresh_token == NULL)
+ {
+ g_task_return_new_error (task,
+ REST_OAUTH2_PROXY_ERROR,
+ REST_OAUTH2_PROXY_NO_REFRESH_TOKEN,
+ "No refresh token available");
+ return;
+ }
+
params = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (params, "client_id", priv->client_id);
diff --git a/rest/rest-oauth2-proxy.h b/rest/rest-oauth2-proxy.h
index c41884f..7ba3111 100644
--- a/rest/rest-oauth2-proxy.h
+++ b/rest/rest-oauth2-proxy.h
@@ -39,13 +39,20 @@ struct _RestOAuth2ProxyClass
gpointer padding[8];
};
+enum {
+ REST_OAUTH2_PROXY_NO_REFRESH_TOKEN,
+};
+
+#define REST_OAUTH2_PROXY_ERROR rest_oauth2_proxy_error_quark ()
+GQuark rest_oauth2_proxy_error_quark ();
+
RestOAuth2Proxy *rest_oauth2_proxy_new (const gchar *authurl,
const gchar *tokenurl,
const gchar *redirecturl,
const gchar *client_id,
const gchar *client_secret,
const gchar *baseurl);
-const gchar *rest_oauth2_proxy_build_authorization_url (RestOAuth2Proxy *self,
+gchar *rest_oauth2_proxy_build_authorization_url (RestOAuth2Proxy *self,
const gchar *code_challenge,
const gchar *scope,
gchar **state);
diff --git a/rest/rest-pkce-code-challenge.c b/rest/rest-pkce-code-challenge.c
index f9932ec..a235232 100644
--- a/rest/rest-pkce-code-challenge.c
+++ b/rest/rest-pkce-code-challenge.c
@@ -96,12 +96,26 @@ rest_pkce_code_challenge_free (RestPkceCodeChallenge *self)
g_slice_free (RestPkceCodeChallenge, self);
}
+/**
+ * rest_pkce_code_challenge_get_challenge:
+ *
+ * Returns the Code Challenge for the Pkce verification.
+ *
+ * Returns: the code_challenge
+ */
const gchar *
rest_pkce_code_challenge_get_challenge (RestPkceCodeChallenge *self)
{
return self->code_challenge;
}
+/**
+ * rest_pkce_code_challenge_get_verifier:
+ *
+ * Returns the Code Verifier for the Pkce verification.
+ *
+ * Returns: the code_verifier
+ */
const gchar *
rest_pkce_code_challenge_get_verifier (RestPkceCodeChallenge *self)
{
diff --git a/rest/rest-pkce-code-challenge.h b/rest/rest-pkce-code-challenge.h
index eba1ea6..7823861 100644
--- a/rest/rest-pkce-code-challenge.h
+++ b/rest/rest-pkce-code-challenge.h
@@ -26,6 +26,12 @@ G_BEGIN_DECLS
#define REST_TYPE_PKCE_CODE_CHALLENGE (rest_pkce_code_challenge_get_type ())
+/**
+ * RestPkceCodeChallenge:
+ *
+ * In order to play a Pkce Code Verification during a OAuth2 authorization
+ * you need this structure which handles the algorithmic part.
+ */
typedef struct _RestPkceCodeChallenge RestPkceCodeChallenge;
GType rest_pkce_code_challenge_get_type (void) G_GNUC_CONST;
diff --git a/rest/rest-utils.c b/rest/rest-utils.c
index bb5a877..385ee55 100644
--- a/rest/rest-utils.c
+++ b/rest/rest-utils.c
@@ -20,6 +20,14 @@
#include "rest-utils.h"
+/**
+ * random_string:
+ * @length: the length of the random string
+ *
+ * Creates a random string from a given alphabeth with length @length
+ *
+ * Returns: (transfer full): a random string
+ */
gchar *
random_string (guint length)
{
diff --git a/tests/flickr.c b/tests/flickr.c
index 11301fa..2d1ee99 100644
--- a/tests/flickr.c
+++ b/tests/flickr.c
@@ -108,6 +108,18 @@ test_flickr ()
}
+static void
+test_build_login_url (void)
+{
+ RestProxy *p = flickr_proxy_new ("api", "secret");
+ g_autofree gchar *login_url = flickr_proxy_build_login_url (FLICKR_PROXY (p), NULL, "read");
+
+ g_assert_cmpstr (login_url, ==,
"http://flickr.com/services/auth/?api_key=api&perms=read&api_sig=55e7647bc1a6e512172b8fda472a64a8");
+
+ login_url = flickr_proxy_build_login_url (FLICKR_PROXY (p), "746563215463214621", "read");
+
+ g_assert_cmpstr (login_url, ==,
"http://flickr.com/services/auth/?frob=746563215463214621&api_key=api&perms=read&api_sig=bcabfd22f3beb489aeb3605b8c9e0441");
+}
int
main (int argc, char **argv)
@@ -115,6 +127,7 @@ main (int argc, char **argv)
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/flickr/flickr", test_flickr);
+ g_test_add_func ("/flickr/test_build_login_url", test_build_login_url);
return g_test_run ();
}
diff --git a/tests/helper/test-server.c b/tests/helper/test-server.c
new file mode 100644
index 0000000..764ef10
--- /dev/null
+++ b/tests/helper/test-server.c
@@ -0,0 +1,123 @@
+/* test-server.c
+ *
+ * Copyright 2021 Günther Wagner <info gunibert de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "test-server.h"
+
+static GMutex server_start_mutex;
+static GCond server_start_cond;
+
+SoupServer *
+test_server_new ()
+{
+ SoupServer *server = soup_server_new ("tls-certificate", NULL, NULL);
+ return server;
+}
+
+gchar *
+test_server_get_uri (SoupServer *server,
+ const char *scheme,
+ const char *host)
+{
+ GSList *uris, *u;
+#ifdef WITH_SOUP_2
+ SoupURI *uri, *ret_uri = NULL;
+#else
+ GUri *uri, *ret_uri = NULL;
+#endif
+
+ uris = soup_server_get_uris (server);
+ for (u = uris; u; u = u->next) {
+ uri = u->data;
+
+#ifdef WITH_SOUP_2
+ if (scheme && strcmp (soup_uri_get_scheme (uri), scheme) != 0)
+ continue;
+ if (host && strcmp (soup_uri_get_host (uri), host) != 0)
+ continue;
+
+ ret_uri = soup_uri_copy (uri);
+#else
+ if (scheme && strcmp (g_uri_get_scheme (uri), scheme) != 0)
+ continue;
+ if (host && strcmp (g_uri_get_host (uri), host) != 0)
+ continue;
+
+ ret_uri = g_uri_ref (uri);
+#endif
+ break;
+ }
+
+#ifdef WITH_SOUP_2
+ g_slist_free_full (uris, (GDestroyNotify)soup_uri_free);
+ return soup_uri_to_string (ret_uri, FALSE);
+#else
+ g_slist_free_full (uris, (GDestroyNotify)g_uri_unref);
+ return g_uri_to_string (ret_uri);
+#endif
+}
+
+static gpointer
+run_server_thread (gpointer user_data)
+{
+ SoupServer *server = user_data;
+ GMainContext *context;
+ GMainLoop *loop;
+ GError *error = NULL;
+
+ context = g_main_context_new ();
+ g_main_context_push_thread_default (context);
+ loop = g_main_loop_new (context, FALSE);
+ g_object_set_data (G_OBJECT (server), "GMainLoop", loop);
+
+ // TODO: error handling
+ soup_server_listen_local (server, 0, 0, &error);
+ if (error != NULL)
+ g_error ("%s", error->message);
+
+ g_mutex_lock (&server_start_mutex);
+ g_cond_signal (&server_start_cond);
+ g_mutex_unlock (&server_start_mutex);
+
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+
+ g_print("%s\n", "Shutting down server...");
+
+ soup_server_disconnect (server);
+
+ g_main_context_pop_thread_default (context);
+ g_main_context_unref (context);
+
+ return NULL;
+}
+
+void
+test_server_run_in_thread (SoupServer *server)
+{
+ GThread *thread;
+
+ g_mutex_lock (&server_start_mutex);
+
+ thread = g_thread_new ("server_thread", run_server_thread, server);
+ g_cond_wait (&server_start_cond, &server_start_mutex);
+ g_mutex_unlock (&server_start_mutex);
+
+ g_object_set_data (G_OBJECT (server), "thread", thread);
+}
diff --git a/tests/helper/test-server.h b/tests/helper/test-server.h
new file mode 100644
index 0000000..28b5ec3
--- /dev/null
+++ b/tests/helper/test-server.h
@@ -0,0 +1,34 @@
+/* test-server.h
+ *
+ * Copyright 2021 Günther Wagner <info gunibert de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <glib.h>
+#include <libsoup/soup.h>
+
+G_BEGIN_DECLS
+
+SoupServer *test_server_new (void);
+void test_server_run_in_thread (SoupServer *server);
+gchar *test_server_get_uri (SoupServer *server,
+ const char *scheme,
+ const char *host);
+
+G_END_DECLS
diff --git a/tests/meson.build b/tests/meson.build
index 8a0b3d6..c7c9170 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -5,6 +5,7 @@ test_suites = {
'threaded',
'xml',
'custom-serialize',
+ 'oauth2',
],
'rest-extras': [
'flickr',
@@ -22,7 +23,7 @@ test_deps = [
foreach suite, test_names : test_suites
foreach name : test_names
test_bin = executable(name,
- '@0@.c'.format(name),
+ ['@0@.c'.format(name), 'helper/test-server.c'],
dependencies: test_deps,
include_directories: config_h_inc,
)
diff --git a/tests/oauth2.c b/tests/oauth2.c
new file mode 100644
index 0000000..c9ba8d2
--- /dev/null
+++ b/tests/oauth2.c
@@ -0,0 +1,215 @@
+/* oauth2.c
+ *
+ * Copyright 2021 Günther Wagner <info gunibert de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <glib.h>
+#include "rest/rest.h"
+#include "helper/test-server.h"
+
+static void
+server_callback (SoupServer *server,
+ SoupMessage *msg,
+ const gchar *path,
+ GHashTable *query,
+ SoupClientContext *client,
+ gpointer user_data)
+{
+ g_print ("%s\n", path);
+ if (g_strcmp0 (path, "/token") == 0)
+ {
+ g_print ("%s\n", msg->request_body->data);
+ gchar *json = "{"
+ "\"access_token\":\"2YotnFZFEjr1zCsicMWpAA\","
+ "\"token_type\":\"example\","
+ "\"expires_in\":3600,"
+ "\"refresh_token\":\"tGzv3JOkF0XG5Qx2TlKWIA\","
+ "\"example_parameter\":\"example_value\""
+ "}";
+ soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_message_set_response (msg, "application/json", SOUP_MEMORY_COPY, json, strlen(json));
+ return;
+ }
+ else if (g_strcmp0 (path, "/api/bearer") == 0)
+ {
+ const gchar *authorization = soup_message_headers_get_one (msg->request_headers, "Authorization");
+ g_print ("%s\n", authorization);
+ soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, authorization, strlen(authorization));
+ return;
+ }
+}
+
+static void
+test_authorization_url (gconstpointer url)
+{
+ g_autoptr(RestProxy) proxy = REST_PROXY (rest_oauth2_proxy_new ("http://www.example.com/auth",
+ "http://www.example.com/token",
+ "http://www.example.com",
+ "client-id",
+ "client-secret",
+ "http://www.example.com/api"));
+ g_autoptr(RestPkceCodeChallenge) pkce = rest_pkce_code_challenge_new_random ();
+
+ gchar *authorization_url = rest_oauth2_proxy_build_authorization_url (REST_OAUTH2_PROXY (proxy),
+ rest_pkce_code_challenge_get_challenge (pkce),
+ NULL,
+ NULL);
+ g_autofree gchar *expected = g_strdup_printf
("http://www.example.com/auth?code_challenge_method=S256&redirect_uri=http%%3A%%2F%%2Fwww.example.com&client_id=client-id&code_challenge=%s&response_type=code",
rest_pkce_code_challenge_get_challenge (pkce));
+ g_assert_cmpstr (authorization_url, ==, expected);
+}
+
+static void
+test_fetch_access_token_finished (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ g_autoptr(GError) error = NULL;
+ gboolean *finished = user_data;
+
+ g_assert (G_IS_OBJECT (object));
+ g_assert (G_IS_ASYNC_RESULT (result));
+
+ rest_oauth2_proxy_fetch_access_token_finish (REST_OAUTH2_PROXY (object), result, &error);
+ g_assert_no_error (error);
+
+ *finished = TRUE;
+}
+
+static void
+test_fetch_access_token (gconstpointer url)
+{
+ GMainContext *async_context = g_main_context_ref_thread_default ();
+ g_autoptr(GError) error = NULL;
+
+ g_autofree gchar *tokenurl = g_strdup_printf ("%stoken", (gchar *)url);
+ g_autofree gchar *baseurl = g_strdup_printf ("%sapi", (gchar *)url);
+
+ gboolean finished = FALSE;
+ g_autoptr(RestProxy) proxy = REST_PROXY (rest_oauth2_proxy_new ("http://www.example.com/auth",
+ tokenurl,
+ "http://www.example.com",
+ "client-id",
+ "client-secret",
+ baseurl));
+ rest_oauth2_proxy_fetch_access_token_async (REST_OAUTH2_PROXY (proxy), "1234567890", "code_verifier",
NULL, test_fetch_access_token_finished, &finished);
+ while (!finished) {
+ g_main_context_iteration (async_context, TRUE);
+ }
+
+ g_assert_cmpstr ("2YotnFZFEjr1zCsicMWpAA", ==, rest_oauth2_proxy_get_access_token (REST_OAUTH2_PROXY
(proxy)));
+ g_assert_cmpstr ("tGzv3JOkF0XG5Qx2TlKWIA", ==, rest_oauth2_proxy_get_refresh_token (REST_OAUTH2_PROXY
(proxy)));
+
+ g_autoptr(RestProxyCall) call = rest_proxy_new_call (proxy);
+ rest_proxy_call_set_method (call, "GET");
+ rest_proxy_call_set_function (call, "bearer");
+ rest_proxy_call_sync (call, &error);
+ g_assert_no_error (error);
+ g_autofree gchar *payload = g_strndup (rest_proxy_call_get_payload (call),
rest_proxy_call_get_payload_length (call));
+ g_assert_cmpstr ("Bearer 2YotnFZFEjr1zCsicMWpAA", ==, payload);
+
+ g_main_context_unref (async_context);
+}
+
+static void
+test_refresh_access_token_finished_error (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ g_autoptr(GError) error = NULL;
+ gboolean *finished = user_data;
+
+ g_assert (G_IS_OBJECT (object));
+ g_assert (G_IS_ASYNC_RESULT (result));
+
+ rest_oauth2_proxy_refresh_access_token_finish (REST_OAUTH2_PROXY (object), result, &error);
+ g_assert_error (error, REST_OAUTH2_PROXY_ERROR, REST_OAUTH2_PROXY_NO_REFRESH_TOKEN);
+
+ *finished = TRUE;
+}
+
+static void
+test_refresh_access_token_finished (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ g_autoptr(GError) error = NULL;
+ gboolean *finished = user_data;
+
+ g_assert (G_IS_OBJECT (object));
+ g_assert (G_IS_ASYNC_RESULT (result));
+
+ rest_oauth2_proxy_refresh_access_token_finish (REST_OAUTH2_PROXY (object), result, &error);
+ g_assert_no_error (error);
+
+ *finished = TRUE;
+}
+
+static void
+test_refresh_access_token (gconstpointer url)
+{
+ GMainContext *async_context = g_main_context_ref_thread_default ();
+ g_autoptr(GError) error = NULL;
+
+ g_autofree gchar *tokenurl = g_strdup_printf ("%stoken", (gchar *)url);
+ g_autofree gchar *baseurl = g_strdup_printf ("%sapi", (gchar *)url);
+
+ gboolean finished = FALSE;
+ g_autoptr(RestProxy) proxy = REST_PROXY (rest_oauth2_proxy_new ("http://www.example.com/auth",
+ tokenurl,
+ "http://www.example.com",
+ "client-id",
+ "client-secret",
+ baseurl));
+ rest_oauth2_proxy_refresh_access_token_async (REST_OAUTH2_PROXY (proxy), NULL,
test_refresh_access_token_finished_error, &finished);
+
+ while (!finished) {
+ g_main_context_iteration (async_context, TRUE);
+ }
+
+ rest_oauth2_proxy_set_refresh_token (REST_OAUTH2_PROXY (proxy), "refresh_token");
+ rest_oauth2_proxy_refresh_access_token_async (REST_OAUTH2_PROXY (proxy), NULL,
test_refresh_access_token_finished, &finished);
+
+ while (!finished) {
+ g_main_context_iteration (async_context, TRUE);
+ }
+
+ g_assert_cmpstr ("2YotnFZFEjr1zCsicMWpAA", ==, rest_oauth2_proxy_get_access_token (REST_OAUTH2_PROXY
(proxy)));
+ g_assert_cmpstr ("tGzv3JOkF0XG5Qx2TlKWIA", ==, rest_oauth2_proxy_get_refresh_token (REST_OAUTH2_PROXY
(proxy)));
+}
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ SoupServer *server;
+ g_autofree gchar *url;
+
+ g_test_init (&argc, &argv, NULL);
+
+ server = test_server_new ();
+ soup_server_add_handler (server, NULL, server_callback, NULL, NULL);
+ test_server_run_in_thread (server);
+ url = test_server_get_uri (server, "http", NULL);
+
+ g_test_add_data_func ("/oauth2/authorization_url", url, test_authorization_url);
+ g_test_add_data_func ("/oauth2/fetch_access_token", url, test_fetch_access_token);
+ g_test_add_data_func ("/oauth2/refresh_access_token", url, test_refresh_access_token);
+
+ return g_test_run ();
+}
diff --git a/tests/proxy.c b/tests/proxy.c
index 3abbc1c..fc77869 100644
--- a/tests/proxy.c
+++ b/tests/proxy.c
@@ -35,19 +35,13 @@
#include <stdlib.h>
#include <libsoup/soup.h>
#include <rest/rest-proxy.h>
+#include "helper/test-server.h"
#if SOUP_CHECK_VERSION (2, 28, 0)
/* Avoid deprecation warning with newer libsoup */
#define soup_message_headers_get soup_message_headers_get_one
#endif
-#define PORT 8080
-
-static int errors = 0;
-
-SoupServer *server;
-GMainLoop *server_loop;
-
#ifdef WITH_SOUP_2
static void
server_callback (SoupServer *server,
@@ -182,257 +176,153 @@ server_callback (SoupServer *server,
static void
ping_test (RestProxy *proxy)
{
- RestProxyCall *call;
+ g_autoptr(RestProxyCall) call;
GError *error = NULL;
call = rest_proxy_new_call (proxy);
rest_proxy_call_set_function (call, "ping");
rest_proxy_call_set_method (call, "GET");
-
- if (!rest_proxy_call_sync (call, &error)) {
- g_printerr ("2: Call failed: %s\n", error->message);
- g_error_free (error);
- errors++;
- g_object_unref (call);
- return;
- }
- g_assert(error == NULL);
-
- if (rest_proxy_call_get_status_code (call) != SOUP_STATUS_OK) {
- g_printerr ("wrong response code\n");
- errors++;
- return;
- }
-
- if (rest_proxy_call_get_payload_length (call) != 0) {
- g_printerr ("wrong length returned\n");
- errors++;
- return;
- }
+ rest_proxy_call_sync (call, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (rest_proxy_call_get_status_code (call), ==, SOUP_STATUS_OK);
+ g_assert_cmpint (rest_proxy_call_get_payload_length (call), ==, 0);
g_object_unref (call);
-
call = rest_proxy_new_call (proxy);
rest_proxy_call_set_function (call, "ping");
rest_proxy_call_set_method (call, "POST");
-
rest_proxy_call_sync (call, &error);
- /* g_assert_nonnull(error); */
-
- if (rest_proxy_call_get_status_code (call) != SOUP_STATUS_NOT_FOUND) {
- g_printerr ("wrong response code\n");
- errors++;
- return;
- }
-
- g_object_unref (call);
+ g_assert_error (error, REST_PROXY_ERROR, 404);
+ g_assert_cmpint (rest_proxy_call_get_status_code (call), ==, SOUP_STATUS_NOT_FOUND);
}
static void
echo_test (RestProxy *proxy)
{
- RestProxyCall *call;
+ g_autoptr(RestProxyCall) call;
GError *error = NULL;
call = rest_proxy_new_call (proxy);
rest_proxy_call_set_function (call, "echo");
rest_proxy_call_add_param (call, "value", "echome");
-
- if (!rest_proxy_call_sync (call, &error)) {
- g_printerr ("3: Call failed: %s\n", error->message);
- g_error_free (error);
- errors++;
- g_object_unref (call);
- return;
- }
- g_assert(error == NULL);
-
- if (rest_proxy_call_get_status_code (call) != SOUP_STATUS_OK) {
- g_printerr ("wrong response code\n");
- errors++;
- g_object_unref (call);
- return;
- }
- if (rest_proxy_call_get_payload_length (call) != 6) {
- g_printerr ("wrong length returned\n");
- errors++;
- g_object_unref (call);
- return;
- }
- if (g_strcmp0 ("echome", rest_proxy_call_get_payload (call)) != 0) {
- g_printerr ("wrong string returned\n");
- errors++;
- g_object_unref (call);
- return;
- }
- g_object_unref (call);
+ rest_proxy_call_sync (call, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (rest_proxy_call_get_status_code (call), ==, SOUP_STATUS_OK);
+ g_assert_cmpint (rest_proxy_call_get_payload_length (call), ==, 6);
+ g_assert_cmpstr (rest_proxy_call_get_payload (call), ==, "echome");
}
static void
reverse_test (RestProxy *proxy)
{
- RestProxyCall *call;
+ g_autoptr(RestProxyCall) call;
GError *error = NULL;
call = rest_proxy_new_call (proxy);
rest_proxy_call_set_function (call, "reverse");
rest_proxy_call_add_param (call, "value", "reverseme");
-
- if (!rest_proxy_call_sync (call, &error)) {
- g_printerr ("4: Call failed: %s\n", error->message);
- g_error_free (error);
- errors++;
- g_object_unref (call);
- return;
- }
- g_assert(error == NULL);
-
- if (rest_proxy_call_get_status_code (call) != SOUP_STATUS_OK) {
- g_printerr ("wrong response code\n");
- errors++;
- g_object_unref (call);
- return;
- }
- if (rest_proxy_call_get_payload_length (call) != 9) {
- g_printerr ("wrong length returned\n");
- errors++;
- g_object_unref (call);
- return;
- }
- if (g_strcmp0 ("emesrever", rest_proxy_call_get_payload (call)) != 0) {
- g_printerr ("wrong string returned\n");
- errors++;
- g_object_unref (call);
- return;
- }
- g_object_unref (call);
+ rest_proxy_call_sync (call, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (rest_proxy_call_get_status_code (call), ==, SOUP_STATUS_OK);
+ g_assert_cmpint (rest_proxy_call_get_payload_length (call), ==, 9);
+ g_assert_cmpstr (rest_proxy_call_get_payload (call), ==, "emesrever");
}
static void
status_ok_test (RestProxy *proxy, guint status)
{
- RestProxyCall *call;
+ g_autoptr(RestProxyCall) call;
+ g_autofree gchar *status_str;
GError *error = NULL;
- char *status_str;
call = rest_proxy_new_call (proxy);
rest_proxy_call_set_function (call, "status");
status_str = g_strdup_printf ("%d", status);
rest_proxy_call_add_param (call, "status", status_str);
- g_free (status_str);
-
- if (!rest_proxy_call_sync (call, &error)) {
- g_printerr ("1: Call failed: %s\n", error->message);
- g_error_free (error);
- errors++;
- g_object_unref (call);
- return;
- }
- g_assert(error == NULL);
-
- if (rest_proxy_call_get_status_code (call) != status) {
- g_printerr ("wrong response code, got %d\n", rest_proxy_call_get_status_code (call));
- errors++;
- return;
- }
+ rest_proxy_call_sync (call, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (rest_proxy_call_get_status_code (call), ==, status);
+}
- g_object_unref (call);
+static void
+status_test (RestProxy *proxy)
+{
+ status_ok_test (proxy, SOUP_STATUS_OK);
+ status_ok_test (proxy, SOUP_STATUS_NO_CONTENT);
}
static void
status_error_test (RestProxy *proxy, guint status)
{
- RestProxyCall *call;
- GError *error = NULL;
- char *status_str;
+ g_autoptr(RestProxyCall) call;
+ g_autoptr(GError) error = NULL;
+ g_autofree gchar *status_str;
call = rest_proxy_new_call (proxy);
rest_proxy_call_set_function (call, "status");
status_str = g_strdup_printf ("%d", status);
rest_proxy_call_add_param (call, "status", status_str);
- g_free (status_str);
-
- if (rest_proxy_call_sync (call, &error)) {
- g_printerr ("Call succeeded should have failed");
- errors++;
- g_object_unref (call);
- return;
- }
- g_error_free (error);
-
- if (rest_proxy_call_get_status_code (call) != status) {
- g_printerr ("wrong response code, got %d\n", rest_proxy_call_get_status_code (call));
- errors++;
- return;
- }
+ rest_proxy_call_sync (call, &error);
+ g_assert_error (error, REST_PROXY_ERROR, status);
+ g_assert_cmpint (rest_proxy_call_get_status_code (call), ==, status);
+}
- g_object_unref (call);
+static void
+status_test_error (RestProxy *proxy)
+{
+ status_error_test (proxy, SOUP_STATUS_BAD_REQUEST);
+ status_error_test (proxy, SOUP_STATUS_NOT_IMPLEMENTED);
}
static void
test_status_ok (RestProxy *proxy, const char *function)
{
- RestProxyCall *call;
- GError *error = NULL;
+ g_autoptr(RestProxyCall) call;
+ g_autoptr(GError) error = NULL;
call = rest_proxy_new_call (proxy);
rest_proxy_call_set_function (call, function);
-
- if (!rest_proxy_call_sync (call, &error)) {
- g_printerr ("%s call failed: %s\n", function, error->message);
- g_error_free (error);
- errors++;
- g_object_unref (call);
- return;
- }
- g_assert(error == NULL);
-
- if (rest_proxy_call_get_status_code (call) != SOUP_STATUS_OK) {
- g_printerr ("wrong response code, got %d\n", rest_proxy_call_get_status_code (call));
- errors++;
- return;
- }
-
- g_object_unref (call);
+ rest_proxy_call_sync (call, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (rest_proxy_call_get_status_code (call), ==, SOUP_STATUS_OK);
}
-static void *
-server_thread_func (gpointer data)
+static void
+test_user_agent (RestProxy *proxy)
{
- server_loop = g_main_loop_new (NULL, TRUE);
- soup_server_add_handler (server, NULL, server_callback, NULL, NULL);
-
- soup_server_listen_local (server, PORT, 0, NULL);
- g_main_loop_run (server_loop);
-
- return NULL;
+ test_status_ok (proxy, "useragent/none");
+ rest_proxy_set_user_agent (proxy, "TestSuite-1.0");
+ test_status_ok (proxy, "useragent/testsuite");
}
int
-main (int argc, char **argv)
+main (int argc,
+ gchar **argv)
{
- char *url;
RestProxy *proxy;
+ SoupServer *server;
+ gint ret;
+ gchar *uri;
- server = g_object_new (SOUP_TYPE_SERVER, NULL);
- g_thread_new ("Server Thread", server_thread_func, NULL);
+ g_test_init (&argc, &argv, NULL);
- url = g_strdup_printf ("http://127.0.0.1:%d/", PORT);
- proxy = rest_proxy_new (url, FALSE);
- g_free (url);
+ server = test_server_new ();
+ soup_server_add_handler (server, NULL, server_callback, NULL, NULL);
+ test_server_run_in_thread (server);
+ uri = test_server_get_uri (server, "http", NULL);
- ping_test (proxy);
- echo_test (proxy);
- reverse_test (proxy);
- status_ok_test (proxy, SOUP_STATUS_OK);
- status_ok_test (proxy, SOUP_STATUS_NO_CONTENT);
- status_error_test (proxy, SOUP_STATUS_BAD_REQUEST);
- status_error_test (proxy, SOUP_STATUS_NOT_IMPLEMENTED);
+ proxy = rest_proxy_new (uri, FALSE);
- test_status_ok (proxy, "useragent/none");
- rest_proxy_set_user_agent (proxy, "TestSuite-1.0");
- test_status_ok (proxy, "useragent/testsuite");
+ g_test_add_data_func ("/proxy/ping", proxy, ping_test);
+ g_test_add_data_func ("/proxy/echo", proxy, echo_test);
+ g_test_add_data_func ("/proxy/reverse", proxy, reverse_test);
+ g_test_add_data_func ("/proxy/status_ok_test", proxy, status_test);
+ g_test_add_data_func ("/proxy/status_error_test", proxy, status_test_error);
+ g_test_add_data_func ("/proxy/user_agent", proxy, test_user_agent);
+
+ ret = g_test_run ();
+
+ g_main_context_unref (g_main_context_default ());
- g_main_loop_quit (server_loop);
- return errors != 0;
+ return ret;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]