diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 7 | ||||
-rw-r--r-- | tests/wocky-loopback-test.c | 191 | ||||
-rw-r--r-- | tests/wocky-pep-service-test.c | 4 | ||||
-rw-r--r-- | tests/wocky-ping-test.c | 4 | ||||
-rw-r--r-- | tests/wocky-porter-test.c | 848 | ||||
-rw-r--r-- | tests/wocky-pubsub-node-test.c | 32 | ||||
-rw-r--r-- | tests/wocky-pubsub-service-test.c | 35 | ||||
-rw-r--r-- | tests/wocky-roster-test.c | 70 | ||||
-rw-r--r-- | tests/wocky-session-test.c | 6 | ||||
-rw-r--r-- | tests/wocky-stanza-test.c | 279 | ||||
-rw-r--r-- | tests/wocky-test-helper.c | 4 | ||||
-rw-r--r-- | tests/wocky-xmpp-reader-test.c | 82 |
12 files changed, 1404 insertions, 158 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index ee86652..c2d5c0a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,6 +42,7 @@ TEST_PROGS = wocky-xmpp-reader-test \ wocky-xmpp-readwrite-test \ wocky-xmpp-connection-test \ wocky-porter-test \ + wocky-loopback-test \ wocky-xmpp-node-test \ wocky-node-tree-test \ wocky-stanza-test \ @@ -130,6 +131,12 @@ wocky_porter_test_SOURCES = \ wocky-test-helper.c wocky-test-helper.h \ wocky-test-stream.c wocky-test-stream.h +wocky_loopback_test_DEPENDENCIES = $(LIBWOCKY) +wocky_loopback_test_SOURCES = \ + wocky-test-helper.c wocky-test-helper.h \ + wocky-test-stream.c wocky-test-stream.h \ + wocky-loopback-test.c + wocky_xmpp_node_test_DEPENDENCIES = $(LIBWOCKY) wocky_xmpp_node_test_SOURCES = \ wocky-test-helper.c wocky-test-helper.h \ diff --git a/tests/wocky-loopback-test.c b/tests/wocky-loopback-test.c new file mode 100644 index 0000000..712fc3e --- /dev/null +++ b/tests/wocky-loopback-test.c @@ -0,0 +1,191 @@ +#include <wocky/wocky-c2s-porter.h> +#include <wocky/wocky-loopback-stream.h> + +#include "wocky-test-helper.h" + +/* I'm not happy about this, but the existing test stuff really relies + * on having multiple streams */ +typedef struct +{ + test_data_t data; + GIOStream *stream; + WockyXmppConnection *conn; + WockySession *session; + WockyPorter *porter; +} loopback_test_t; + +static gboolean +test_timeout (gpointer data) +{ + g_test_message ("Timeout reached :("); + g_assert_not_reached (); + + return FALSE; +} + +static loopback_test_t * +setup (void) +{ + loopback_test_t *test = g_slice_new0 (loopback_test_t); + + test->data.loop = g_main_loop_new (NULL, FALSE); + test->data.cancellable = g_cancellable_new (); + test->data.timeout_id = g_timeout_add_seconds (10, test_timeout, NULL); + test->data.expected_stanzas = g_queue_new (); + + test->stream = wocky_loopback_stream_new (); + + test->conn = wocky_xmpp_connection_new (test->stream); + + test->session = wocky_session_new_with_connection (test->conn, + "example.com"); + + test->porter = wocky_session_get_porter (test->session); + + return test; +} + +static void +send_received_open_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + WockyXmppConnection *conn = WOCKY_XMPP_CONNECTION (source); + loopback_test_t *d = (loopback_test_t *) user_data; + + g_assert (wocky_xmpp_connection_recv_open_finish (conn, res, + NULL, NULL, NULL, NULL, NULL, NULL)); + + wocky_session_start (d->session); + + d->data.outstanding--; + g_main_loop_quit (d->data.loop); +} + +static void +send_open_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + WockyXmppConnection *conn = WOCKY_XMPP_CONNECTION (source); + + g_assert (wocky_xmpp_connection_send_open_finish (conn, + res, NULL)); + + wocky_xmpp_connection_recv_open_async (conn, + NULL, send_received_open_cb, user_data); +} + +static void +start_test (loopback_test_t *test) +{ + wocky_xmpp_connection_send_open_async (test->conn, + NULL, NULL, NULL, NULL, NULL, NULL, send_open_cb, test); + + test->data.outstanding++; + + test_wait_pending (&(test->data)); +} + +static void +close_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + loopback_test_t *test = user_data; + + g_assert (wocky_porter_close_finish (WOCKY_PORTER (source), + res, NULL)); + + test->data.outstanding--; + g_main_loop_quit (test->data.loop); + + g_main_loop_unref (test->data.loop); + + g_object_unref (test->session); + g_object_unref (test->conn); + g_object_unref (test->data.cancellable); + g_source_remove (test->data.timeout_id); + + g_assert (g_queue_get_length (test->data.expected_stanzas) == 0); + g_queue_free (test->data.expected_stanzas); + + g_slice_free (loopback_test_t, test); +} + +static void +cleanup (loopback_test_t *test) +{ + wocky_porter_close_async (test->porter, NULL, close_cb, test); + + test->data.outstanding++; + test_wait_pending (&(test->data)); +} + +static void +send_stanza_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + test_data_t *data = (test_data_t *) user_data; + + g_assert (wocky_porter_send_finish ( + WOCKY_PORTER (source), res, NULL)); + + data->outstanding--; + g_main_loop_quit (data->loop); +} + +/* receive testing */ +static gboolean +test_receive_stanza_received_cb (WockyPorter *porter, + WockyStanza *stanza, + gpointer user_data) +{ + test_data_t *test = (test_data_t *) user_data; + test_expected_stanza_received (test, stanza); + return TRUE; +} + +static void +test_receive (void) +{ + loopback_test_t *test = setup (); + WockyStanza *s; + + start_test (test); + + wocky_porter_register_handler_from_anyone (test->porter, + WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, 0, + test_receive_stanza_received_cb, test, NULL); + + /* Send a stanza */ + s = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, + WOCKY_STANZA_SUB_TYPE_CHAT, "juliet@example.com", "romeo@example.net", + NULL); + + wocky_porter_send_async (test->porter, s, NULL, + send_stanza_cb, test); + g_queue_push_tail (test->data.expected_stanzas, s); + /* We are waiting for the stanza to be sent and received on the other + * side */ + test->data.outstanding += 2; + + test_wait_pending (&(test->data)); + + cleanup (test); +} + +int +main (int argc, char **argv) +{ + int result; + + test_init (argc, argv); + + g_test_add_func ("/loopback-porter/receive", test_receive); + + result = g_test_run (); + test_deinit (); + return result; +} diff --git a/tests/wocky-pep-service-test.c b/tests/wocky-pep-service-test.c index ad3fd26..668f6ea 100644 --- a/tests/wocky-pep-service-test.c +++ b/tests/wocky-pep-service-test.c @@ -195,8 +195,8 @@ test_get (void) wocky_porter_start (test->sched_out); wocky_porter_start (test->sched_in); - handler_id = wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + handler_id = wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_send_query_stanza_received_cb, test, NULL); diff --git a/tests/wocky-ping-test.c b/tests/wocky-ping-test.c index 58ac668..af0cbcc 100644 --- a/tests/wocky-ping-test.c +++ b/tests/wocky-ping-test.c @@ -63,8 +63,8 @@ test_periodic_ping (void) wocky_porter_start (test->sched_in); wocky_porter_start (test->sched_out); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, ping_recv_cb, test, '(', "ping", ':', WOCKY_XMPP_NS_PING, diff --git a/tests/wocky-porter-test.c b/tests/wocky-porter-test.c index c233a20..9c6111a 100644 --- a/tests/wocky-porter-test.c +++ b/tests/wocky-porter-test.c @@ -4,7 +4,7 @@ #include <glib.h> -#include <wocky/wocky-porter.h> +#include <wocky/wocky-c2s-porter.h> #include <wocky/wocky-utils.h> #include <wocky/wocky-namespaces.h> #include <wocky/wocky-xmpp-error.h> @@ -21,7 +21,7 @@ test_instantiation (void) stream = g_object_new (WOCKY_TYPE_TEST_STREAM, NULL); connection = wocky_xmpp_connection_new (stream->stream0); - porter = wocky_porter_new (connection, "juliet@example.com/Balcony"); + porter = wocky_c2s_porter_new (connection, "juliet@example.com/Balcony"); g_assert (porter != NULL); g_assert_cmpstr (wocky_porter_get_full_jid (porter), ==, @@ -267,8 +267,8 @@ test_receive (void) * side */ test->outstanding += 2; - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 0, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, 0, test_receive_stanza_received_cb, test, NULL); wocky_porter_start (test->sched_out); @@ -310,13 +310,13 @@ test_filter (void) test_open_both_connections (test); /* register an IQ filter */ - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 0, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, 0, test_filter_iq_received_cb, test, NULL); /* register a presence filter */ - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_PRESENCE, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 0, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_PRESENCE, WOCKY_STANZA_SUB_TYPE_NONE, 0, test_filter_presence_received_cb, test, NULL); wocky_porter_start (test->sched_out); @@ -846,13 +846,13 @@ test_handler_priority (void) test_open_both_connections (test); /* register an IQ handler with a priority of 10 */ - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 10, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, 10, test_handler_priority_10, test, NULL); /* register an IQ handler with a priority of 5 */ - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 5, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, 5, test_handler_priority_5, test, NULL); wocky_porter_start (test->sched_out); @@ -865,8 +865,8 @@ test_handler_priority (void) send_stanza (test, iq, TRUE); /* register an IQ handler with a priority of 15 */ - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 15, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, 15, test_handler_priority_15, test, NULL); /* Send a 'set' IQ */ @@ -911,13 +911,13 @@ test_unregister_handler (void) test_open_both_connections (test); /* register an IQ handler with a priority of 10 */ - id = wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 10, + id = wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, 10, test_unregister_handler_10, test, NULL); /* register an IQ handler with a priority of 5 */ - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 5, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, 5, test_unregister_handler_5, test, NULL); wocky_porter_start (test->sched_out); @@ -956,7 +956,7 @@ test_handler_bare_jid (void) test_open_both_connections (test); /* register an IQ handler for all IQ from a bare jid */ - wocky_porter_register_handler (test->sched_out, + wocky_porter_register_handler_from (test->sched_out, WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, "juliet@example.com", 0, test_handler_bare_jid_cb, test, NULL); @@ -1004,7 +1004,7 @@ test_handler_full_jid (void) test_open_both_connections (test); /* register an IQ handler for all IQ from a bare jid */ - wocky_porter_register_handler (test->sched_out, + wocky_porter_register_handler_from (test->sched_out, WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, "juliet@example.com/Pub", 0, test_handler_full_jid_cb, test, NULL); @@ -1074,9 +1074,9 @@ test_handler_stanza (void) /* register an IQ handler for all the jingle stanzas related to one jingle * session */ - wocky_porter_register_handler (test->sched_out, + wocky_porter_register_handler_from (test->sched_out, WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, - NULL, 0, + "juliet@example.com", 0, test_handler_stanza_jingle_cb, test, '(', "jingle", ':', "urn:xmpp:jingle:1", @@ -1102,6 +1102,16 @@ test_handler_stanza (void) ')', NULL); send_stanza (test, iq, FALSE); + /* Send a jingle IQ with the right sid but from the wrong contact */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_SET, "tybalt@example.com", "romeo@example.net", + '@', "id", "2", + '(', "jingle", + ':', "urn:xmpp:jingle:1", + '@', "sid", "my_sid", + ')', NULL); + send_stanza (test, iq, FALSE); + /* Send a jingle IQ related to the right session */ iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, "juliet@example.com", "romeo@example.net", @@ -1114,9 +1124,9 @@ test_handler_stanza (void) /* register a new IQ handler,with higher priority, handling session-terminate * with a specific test message */ - wocky_porter_register_handler (test->sched_out, + wocky_porter_register_handler_from (test->sched_out, WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, - NULL, 10, + "juliet@example.com", 10, test_handler_stanza_terminate_cb, test, '(', "jingle", ':', "urn:xmpp:jingle:1", @@ -1206,9 +1216,9 @@ test_cancel_sent_stanza (void) wocky_porter_start (test->sched_in); /* register a message handler */ - wocky_porter_register_handler (test->sched_out, + wocky_porter_register_handler_from_anyone (test->sched_out, WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, - NULL, 0, + 0, test_cancel_sent_stanza_cb, test, NULL); stanza = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, @@ -1432,9 +1442,9 @@ test_send_iq (void) wocky_porter_start (test->sched_in); /* register an IQ handler */ - wocky_porter_register_handler (test->sched_out, + wocky_porter_register_handler_from_anyone (test->sched_out, WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, - NULL, 0, + 0, test_send_iq_cb, test, NULL); /* Send an IQ query. We are going to cancel it after it has been received @@ -1467,6 +1477,373 @@ test_send_iq (void) teardown_test (test); } +static gboolean +test_acknowledge_iq_acknowledge_cb ( + WockyPorter *porter, + WockyStanza *stanza, + gpointer user_data) +{ + test_data_t *test = user_data; + + wocky_porter_acknowledge_iq (porter, stanza, + '(', "sup-dawg", + '@', "lions", "tigers", + ')', + NULL); + + test->outstanding--; + g_main_loop_quit (test->loop); + return TRUE; +} + +static void +test_iq_reply_no_id_cb ( + GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + WockyPorter *porter = WOCKY_PORTER (source); + test_data_t *test = user_data; + WockyStanza *reply; + WockyStanza *expected_reply; + GError *error = NULL; + + reply = wocky_porter_send_iq_finish (porter, result, &error); + g_assert_no_error (error); + g_assert (reply != NULL); + + expected_reply = g_queue_pop_head (test->expected_stanzas); + g_assert (expected_reply != NULL); + + /* If we got the reply dispatched to us, the ID was correct — this is tested + * elsewhere. So we don't need to test it again here. */ + test_assert_stanzas_equal_no_id (reply, expected_reply); + + g_object_unref (reply); + g_object_unref (expected_reply); + + test->outstanding--; + g_main_loop_quit (test->loop); +} + +/* Tests wocky_porter_acknowledge_iq(). */ +static void +test_acknowledge_iq (void) +{ + test_data_t *test = setup_test (); + WockyStanza *iq, *expected_reply; + + test_open_both_connections (test); + wocky_porter_start (test->sched_out); + wocky_porter_start (test->sched_in); + + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, + 0, + test_acknowledge_iq_acknowledge_cb, test, NULL); + + /* We re-construct expected_reply for every test because… + * test_assert_stanzas_equal_no_id() modifies the stanzas it's comparing to + * add an id='' to the one which doesn't have one. + */ + + /* Send a legal IQ (with a single child element). */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + '(', "sup-dawg", ')', NULL); + expected_reply = wocky_stanza_build ( + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_RESULT, + "romeo@example.net", "juliet@example.com", + '(', "sup-dawg", + '@', "lions", "tigers", + ')', + NULL); + wocky_porter_send_iq_async (test->sched_in, iq, + NULL, test_iq_reply_no_id_cb, test); + test->outstanding += 2; + g_queue_push_tail (test->expected_stanzas, expected_reply); + g_object_unref (iq); + + /* Send an illegal IQ with two child elements. We expect that + * wocky_porter_acknowledge_iq() should cope. */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + '(', "sup-dawg", ')', + '(', "i-heard-you-like-stanzas", ')', + NULL); + expected_reply = wocky_stanza_build ( + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_RESULT, + "romeo@example.net", "juliet@example.com", + '(', "sup-dawg", + '@', "lions", "tigers", + ')', + NULL); + wocky_porter_send_iq_async (test->sched_in, iq, + NULL, test_iq_reply_no_id_cb, test); + test->outstanding += 2; + g_queue_push_tail (test->expected_stanzas, expected_reply); + g_object_unref (iq); + + /* Send another illegal IQ, with no child element at all. Obviously in real + * life it should be nacked, but wocky_porter_acknowledge_iq() should still + * cope. */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + NULL); + expected_reply = wocky_stanza_build ( + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_RESULT, + "romeo@example.net", "juliet@example.com", + '(', "sup-dawg", + '@', "lions", "tigers", + ')', + NULL); + wocky_porter_send_iq_async (test->sched_in, iq, + NULL, test_iq_reply_no_id_cb, test); + test->outstanding += 2; + g_queue_push_tail (test->expected_stanzas, expected_reply); + g_object_unref (iq); + + /* Finally, send an IQ that doesn't have an id='' attribute. This is really + * illegal, but wocky_porter_acknowledge_iq() needs to deal because it + * happens in practice. + */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + NULL); + wocky_porter_send (test->sched_in, iq); + /* In this case, we only expect the recipient's callback to fire. There's no + * way for it to send us an IQ back, so we don't need to wait for a reply + * there. + */ + test->outstanding += 1; + g_object_unref (iq); + + /* Off we go! */ + test_wait_pending (test); + + test_close_both_porters (test); + teardown_test (test); +} + +static gboolean +test_send_iq_error_nak_cb ( + WockyPorter *porter, + WockyStanza *stanza, + gpointer user_data) +{ + test_data_t *test = user_data; + + wocky_porter_send_iq_error (porter, stanza, + WOCKY_XMPP_ERROR_BAD_REQUEST, "bye bye beautiful"); + + test->outstanding--; + g_main_loop_quit (test->loop); + return TRUE; +} + +/* Tests wocky_porter_send_iq_error(). */ +static void +test_send_iq_error (void) +{ + test_data_t *test = setup_test (); + WockyStanza *iq, *expected_reply; + + test_open_both_connections (test); + wocky_porter_start (test->sched_out); + wocky_porter_start (test->sched_in); + + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, + 0, + test_send_iq_error_nak_cb, test, NULL); + + /* Send a legal IQ (with a single child element). */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + '(', "sup-dawg", ')', + NULL); + expected_reply = wocky_stanza_build ( + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_ERROR, + "romeo@example.net", "juliet@example.com", + '(', "sup-dawg", ')', + '(', "error", + '@', "code", "400", + '@', "type", "modify", + '(', "bad-request", ':', WOCKY_XMPP_NS_STANZAS, ')', + '(', "text", ':', WOCKY_XMPP_NS_STANZAS, + '$', "bye bye beautiful", + ')', + ')', NULL); + wocky_porter_send_iq_async (test->sched_in, iq, + NULL, test_iq_reply_no_id_cb, test); + test->outstanding += 2; + g_queue_push_tail (test->expected_stanzas, expected_reply); + g_object_unref (iq); + + /* Send an illegal IQ with two child elements. We expect that + * wocky_porter_send_iq_error() should cope by just picking the first one. + */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + '(', "sup-dawg", ')', + '(', "i-heard-you-like-stanzas", ')', + NULL); + expected_reply = wocky_stanza_build ( + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_ERROR, + "romeo@example.net", "juliet@example.com", + '(', "sup-dawg", ')', + '(', "error", + '@', "code", "400", + '@', "type", "modify", + '(', "bad-request", ':', WOCKY_XMPP_NS_STANZAS, ')', + '(', "text", ':', WOCKY_XMPP_NS_STANZAS, + '$', "bye bye beautiful", + ')', + ')', NULL); + wocky_porter_send_iq_async (test->sched_in, iq, + NULL, test_iq_reply_no_id_cb, test); + test->outstanding += 2; + g_queue_push_tail (test->expected_stanzas, expected_reply); + g_object_unref (iq); + + /* Send another illegal IQ, with no child element at all. + * wocky_porter_send_iq_error() should not blow up. + */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + NULL); + expected_reply = wocky_stanza_build ( + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_ERROR, + "romeo@example.net", "juliet@example.com", + '(', "error", + '@', "code", "400", + '@', "type", "modify", + '(', "bad-request", ':', WOCKY_XMPP_NS_STANZAS, ')', + '(', "text", ':', WOCKY_XMPP_NS_STANZAS, + '$', "bye bye beautiful", + ')', + ')', NULL); + wocky_porter_send_iq_async (test->sched_in, iq, + NULL, test_iq_reply_no_id_cb, test); + test->outstanding += 2; + g_queue_push_tail (test->expected_stanzas, expected_reply); + g_object_unref (iq); + + /* Finally, send an IQ that doesn't have an id='' attribute. This is really + * illegal, but wocky_porter_send_iq_error() needs to deal because it + * happens in practice. + */ + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + NULL); + wocky_porter_send (test->sched_in, iq); + /* In this case, we only expect the recipient's callback to fire. There's no + * way for it to send us an IQ back, so we don't need to wait for a reply + * there. + */ + test->outstanding += 1; + g_object_unref (iq); + + test_wait_pending (test); + + test_close_both_porters (test); + teardown_test (test); +} + +typedef struct { + test_data_t *test; + GError error; +} TestSendIqGErrorCtx; + +static gboolean +test_send_iq_gerror_nak_cb ( + WockyPorter *porter, + WockyStanza *stanza, + gpointer user_data) +{ + TestSendIqGErrorCtx *ctx = user_data; + + wocky_porter_send_iq_gerror (porter, stanza, &ctx->error); + + ctx->test->outstanding--; + g_main_loop_quit (ctx->test->loop); + return TRUE; +} + +/* Tests wocky_porter_send_iq_gerror(). */ +static void +test_send_iq_gerror (void) +{ + test_data_t *test = setup_test (); + TestSendIqGErrorCtx ctx = { test, }; + WockyStanza *iq, *expected_reply; + + test_open_both_connections (test); + wocky_porter_start (test->sched_out); + wocky_porter_start (test->sched_in); + + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, + 0, + test_send_iq_gerror_nak_cb, &ctx, NULL); + + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + '(', "sup-dawg", ')', + NULL); + + /* Test responding with a simple error */ + ctx.error.domain = WOCKY_XMPP_ERROR; + ctx.error.code = WOCKY_XMPP_ERROR_UNEXPECTED_REQUEST; + ctx.error.message = "i'm twelve years old and what is this?"; + expected_reply = wocky_stanza_build ( + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_ERROR, + "romeo@example.net", "juliet@example.com", + '(', "sup-dawg", ')', + '(', "error", + '@', "code", "400", + '@', "type", "wait", + '(', "unexpected-request", ':', WOCKY_XMPP_NS_STANZAS, ')', + '(', "text", ':', WOCKY_XMPP_NS_STANZAS, + '$', ctx.error.message, + ')', + ')', NULL); + wocky_porter_send_iq_async (test->sched_in, iq, + NULL, test_iq_reply_no_id_cb, test); + test->outstanding += 2; + g_queue_push_tail (test->expected_stanzas, expected_reply); + + test_wait_pending (test); + + /* Test responding with an application-specific error */ + ctx.error.domain = WOCKY_JINGLE_ERROR; + ctx.error.code = WOCKY_JINGLE_ERROR_OUT_OF_ORDER; + ctx.error.message = "i'm twelve years old and what is this?"; + expected_reply = wocky_stanza_build ( + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_ERROR, + "romeo@example.net", "juliet@example.com", + '(', "sup-dawg", ')', + '(', "error", + '@', "code", "400", + '@', "type", "wait", + '(', "unexpected-request", ':', WOCKY_XMPP_NS_STANZAS, ')', + '(', "out-of-order", ':', WOCKY_XMPP_NS_JINGLE_ERRORS, ')', + '(', "text", ':', WOCKY_XMPP_NS_STANZAS, + '$', ctx.error.message, + ')', + ')', NULL); + wocky_porter_send_iq_async (test->sched_in, iq, + NULL, test_iq_reply_no_id_cb, test); + test->outstanding += 2; + g_queue_push_tail (test->expected_stanzas, expected_reply); + + test_wait_pending (test); + + g_object_unref (iq); + test_close_both_porters (test); + teardown_test (test); +} + static void test_send_iq_abnormal (void) { @@ -1478,9 +1855,9 @@ test_send_iq_abnormal (void) wocky_porter_start (test->sched_in); /* register an IQ handler (to send both the good and spoofed reply) */ - wocky_porter_register_handler (test->sched_out, + wocky_porter_register_handler_from_anyone (test->sched_out, WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, - NULL, 0, + 0, test_send_iq_abnormal_cb, test, NULL); /* Send an IQ query */ @@ -1520,7 +1897,7 @@ test_send_iq_error_cb (GObject *source, } static void -test_send_iq_error (void) +test_error_while_sending_iq (void) { test_data_t *test = setup_test (); WockyStanza *iq; @@ -1593,14 +1970,14 @@ test_handler_filter (void) test_open_both_connections (test); /* register an IQ handler which will act as a filter */ - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 10, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, 10, test_handler_filter_get_filter, test, NULL); /* register another handler with a smaller priority which will be called * after the filter */ - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, NULL, 5, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, 5, test_handler_filter_cb, test, NULL); wocky_porter_start (test->sched_out); @@ -1639,7 +2016,7 @@ test_handler_filter_from_juliet_cb (WockyPorter *porter, } static gboolean -test_handler_filter_from_null_cb (WockyPorter *porter, +test_handler_filter_from_anyone_cb (WockyPorter *porter, WockyStanza *stanza, gpointer user_data) { @@ -1656,15 +2033,15 @@ test_handler_filter_from (void) test_open_both_connections (test); - /* Register a handler for from=juliet@example.com messages stanzas. */ - wocky_porter_register_handler (test->sched_out, + /* Register a handler for IQs with from=juliet@example.com */ + wocky_porter_register_handler_from (test->sched_out, WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, "juliet@example.com", 10, test_handler_filter_from_juliet_cb, test, NULL); - /* Register a handler for from= unset or any messages stanzas. */ - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, NULL, - 5, test_handler_filter_from_null_cb, test, NULL); + /* Register another handler, at a lower priority, for IQs from anyone */ + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, + 5, test_handler_filter_from_anyone_cb, test, NULL); wocky_porter_start (test->sched_out); @@ -1809,9 +2186,9 @@ test_send_iq_server (void) wocky_porter_start (test->sched_in); /* register an IQ handler */ - wocky_porter_register_handler (test->sched_out, + wocky_porter_register_handler_from_anyone (test->sched_out, WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, - NULL, WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, + WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, test_send_iq_server_received_cb, test, NULL); /* From XMPP RFC: @@ -2325,9 +2702,9 @@ open_connections_and_send_one_iq (test_data_t *test, wocky_porter_start (test->sched_in); /* register an IQ handler */ - wocky_porter_register_handler (test->sched_out, + wocky_porter_register_handler_from_anyone (test->sched_out, WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_NONE, - NULL, 0, + 0, test_receive_stanza_received_cb, test, NULL); /* Send an IQ query */ @@ -2538,6 +2915,373 @@ send_and_disconnect (void) g_object_unref (lions); } +static gboolean +got_stanza_for_example_com ( + WockyPorter *porter, + WockyStanza *stanza, + gpointer user_data) +{ + test_data_t *test = user_data; + + g_assert_cmpstr (wocky_stanza_get_from (stanza), ==, "example.com"); + test->outstanding--; + g_main_loop_quit (test->loop); + + return TRUE; +} + +/* This is a regression test for a bug where registering a handler for a JID + * with no node part was equivalent to registering a handler with from=NULL; + * that is, we'd erroneously pass stanzas from *any* server to the handler + * function even if it explicitly specified a JID which was just a domain, as + * opposed to a JID with an '@' sign in it. + */ +static void +handler_for_domain (void) +{ + test_data_t *test = setup_test (); + WockyStanza *irrelevant, *relevant; + + test_open_both_connections (test); + wocky_porter_start (test->sched_out); + wocky_porter_start (test->sched_in); + + wocky_porter_register_handler_from (test->sched_in, WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "example.com", + WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, + got_stanza_for_example_com, test, + NULL); + + /* Send a stanza from some other random jid (at example.com, for the sake of + * argument). The porter should ignore this stanza. + */ + irrelevant = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "lol@example.com", NULL, + '(', "this-is-bullshit", ')', NULL); + wocky_porter_send (test->sched_out, irrelevant); + g_object_unref (irrelevant); + + relevant = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "example.com", NULL, + '(', "i-am-a-fan-of-cocaine", ')', NULL); + wocky_porter_send (test->sched_out, relevant); + g_object_unref (relevant); + + test->outstanding += 1; + test_wait_pending (test); + + test_close_both_porters (test); + teardown_test (test); +} + +static gboolean +got_stanza_from_anyone ( + WockyPorter *porter, + WockyStanza *stanza, + gpointer user_data) +{ + test_data_t *test = user_data; + WockyNode *top = wocky_stanza_get_top_node (stanza); + WockyNode *query = wocky_node_get_first_child (top); + + g_assert_cmpstr (query->name, ==, "anyone"); + test->outstanding--; + g_main_loop_quit (test->loop); + return TRUE; +} + +static gboolean +got_stanza_from_ourself ( + WockyPorter *porter, + WockyStanza *stanza, + gpointer user_data) +{ + test_data_t *test = user_data; + WockyNode *top = wocky_stanza_get_top_node (stanza); + WockyNode *query = wocky_node_get_first_child (top); + + g_assert_cmpstr (query->name, ==, "ourself"); + test->outstanding--; + g_main_loop_quit (test->loop); + return TRUE; +} + +static gboolean +got_stanza_from_server ( + WockyPorter *porter, + WockyStanza *stanza, + gpointer user_data) +{ + test_data_t *test = user_data; + WockyNode *top = wocky_stanza_get_top_node (stanza); + WockyNode *query = wocky_node_get_first_child (top); + + g_assert_cmpstr (query->name, ==, "server"); + test->outstanding--; + g_main_loop_quit (test->loop); + return TRUE; +} + +static void +send_query_from ( + test_data_t *test, + const gchar *from, + const gchar *query) +{ + WockyStanza *s = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, from, NULL, + '(', query, ')', NULL); + wocky_porter_send (test->sched_out, s); + g_object_unref (s); + + test->outstanding += 1; + test_wait_pending (test); +} + +static void +handler_from_anyone (void) +{ + test_data_t *test = setup_test_with_jids ("juliet@capulet.lit/Balcony", + "capulet.lit"); + + test_open_both_connections (test); + wocky_porter_start (test->sched_out); + wocky_porter_start (test->sched_in); + + + wocky_c2s_porter_register_handler_from_server ( + WOCKY_C2S_PORTER (test->sched_in), + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, + WOCKY_PORTER_HANDLER_PRIORITY_NORMAL + 10, + got_stanza_from_server, test, NULL); + + /* A catch-all IQ get handler. */ + wocky_porter_register_handler_from_anyone (test->sched_in, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, + WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, + got_stanza_from_anyone, test, NULL); + + /* And, for completeness, a handler for IQs sent by any incarnation + * of ourself, at a lower priority to the handler for stanzas from the + * server, but a higher priority to the catch-all handler. */ + wocky_porter_register_handler_from (test->sched_in, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, + "juliet@capulet.lit", + WOCKY_PORTER_HANDLER_PRIORITY_NORMAL + 5, + got_stanza_from_ourself, test, NULL); + + /* All of the handlers assert on the name of the first child node, and then + * return TRUE to prevent the stanza being handed to a lower-priority + * handler. */ + + /* A stanza from a contact on a completely different server should be picked + * up only by the general handler. */ + send_query_from (test, "romeo@montague.lit/Garden", "anyone"); + + /* A stanza from a contact on our server should be picked up only by the + * general handler (irrespective of whether they have a resource). */ + send_query_from (test, "tybalt@capulet.lit", "anyone"); + send_query_from (test, "tybalt@capulet.lit/FIXME", "anyone"); + + /* Slightly counterintuitively, a stanza from our server's domain should not + * be matched by got_stanza_from_server(). + */ + send_query_from (test, "capulet.lit", "anyone"); + + /* On the other hand, a stanza with no sender should be picked up by + * got_stanza_from_server(). */ + send_query_from (test, NULL, "server"); + + /* Similarly, stanzas from our bare JID should be handed to + * got_stanza_from_server(). Because that function returns TRUE, the stanza + * should not be handed to got_stanza_from_ourself(). + */ + send_query_from (test, "juliet@capulet.lit", "server"); + send_query_from (test, "jULIet@cAPUlet.lIT", "server"); + + /* Similarly, stanzas from our own full JID go to got_stanza_from_server. */ + send_query_from (test, "juliet@capulet.lit/Balcony", "server"); + send_query_from (test, "JUlIet@CAPulet.LIt/Balcony", "server"); + + /* But stanzas from our other resources should go to + * got_stanza_from_ourself(). */ + send_query_from (test, "juliet@capulet.lit/FIXME", "ourself"); + /* Heh, heh, resources are case-sensitive */ + send_query_from (test, "juliet@capulet.lit/balcony", "ourself"); + + /* Meanwhile, back in communist russia: */ + /* + КАПУЛЭТ + капулэт + */ + + test_close_both_porters (test); + teardown_test (test); +} + +static void +closed_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + WockyPorter *porter = WOCKY_PORTER (source); + test_data_t *test = user_data; + gboolean ret; + GError *error = NULL; + + ret = wocky_porter_close_finish (porter, result, &error); + g_assert_no_error (error); + g_assert (ret); + + test->outstanding--; + g_main_loop_quit (test->loop); +} + +static void +sent_stanza_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + WockyPorter *porter = WOCKY_PORTER (source); + test_data_t *test = user_data; + gboolean ret; + GError *error = NULL; + + ret = wocky_porter_send_finish (porter, result, &error); + g_assert_no_error (error); + g_assert (ret); + + /* Close up both porters. There's no reason why either of these operations + * should fail. + */ + wocky_porter_close_async (test->sched_out, NULL, closed_cb, test); + wocky_porter_close_async (test->sched_in, NULL, closed_cb, test); +} + +static void +close_from_send_callback (void) +{ + test_data_t *test = setup_test (); + WockyStanza *stanza = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, + WOCKY_STANZA_SUB_TYPE_NONE, NULL, NULL, + '(', "body", '$', "I am made of chalk.", ')', NULL); + + /* Fire up porters in both directions. */ + test_open_both_connections (test); + wocky_porter_start (test->sched_in); + wocky_porter_start (test->sched_out); + + /* Send a stanza. Once it's been safely sent, we should be able to close up + * the connection in both directions without any trouble. + */ + wocky_porter_send_async (test->sched_in, stanza, NULL, sent_stanza_cb, test); + g_object_unref (stanza); + + /* The two outstanding events are both porters ultimately closing + * successfully. */ + test->outstanding += 2; + test_wait_pending (test); + + teardown_test (test); +} + +/* Callbacks used in send_from_send_callback() */ +static gboolean +message_received_cb ( + WockyPorter *porter, + WockyStanza *stanza, + gpointer user_data) +{ + test_data_t *test = user_data; + + test_expected_stanza_received (test, stanza); + return TRUE; +} + +static void +sent_second_or_third_stanza_cb ( + GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + test_data_t *test = user_data; + GError *error = NULL; + + wocky_porter_send_finish (WOCKY_PORTER (source), result, &error); + g_assert_no_error (error); + + test->outstanding--; + g_main_loop_quit (test->loop); +} + +static void +sent_first_stanza_cb ( + GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + test_data_t *test = user_data; + WockyStanza *third_stanza; + GError *error = NULL; + + wocky_porter_send_finish (WOCKY_PORTER (source), result, &error); + g_assert_no_error (error); + + third_stanza = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, + WOCKY_STANZA_SUB_TYPE_NONE, NULL, NULL, + '(', "body", '$', "I am made of dur butter.", ')', NULL); + wocky_porter_send_async (test->sched_in, third_stanza, NULL, + sent_second_or_third_stanza_cb, test); + g_queue_push_tail (test->expected_stanzas, third_stanza); + /* One for the callback; one for the receiving end. */ + test->outstanding += 2; + + test->outstanding--; + g_main_loop_quit (test->loop); +} + +static void +send_from_send_callback (void) +{ + test_data_t *test = setup_test (); + WockyStanza *stanza; + + test_open_both_connections (test); + wocky_porter_start (test->sched_in); + wocky_porter_start (test->sched_out); + + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE, + WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, message_received_cb, test, + '(', "body", ')', NULL); + + /* Send a stanza; in the callback for this stanza, we'll send another stanza. + */ + stanza = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, + WOCKY_STANZA_SUB_TYPE_NONE, NULL, NULL, + '(', "body", '$', "I am made of chalk.", ')', NULL); + wocky_porter_send_async (test->sched_in, stanza, NULL, + sent_first_stanza_cb, test); + g_queue_push_tail (test->expected_stanzas, stanza); + /* One for the callback; one for the receiving end. */ + test->outstanding += 2; + + /* But before we've had a chance to send that one, send a second. */ + stanza = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, + WOCKY_STANZA_SUB_TYPE_NONE, NULL, NULL, + '(', "body", '$', "I am made of jelly.", ')', NULL); + wocky_porter_send_async (test->sched_in, stanza, NULL, + sent_second_or_third_stanza_cb, test); + g_queue_push_tail (test->expected_stanzas, stanza); + /* One for the callback; one for the receiving end. */ + test->outstanding += 2; + + test_wait_pending (test); + + test_close_both_porters (test); + teardown_test (test); +} + int main (int argc, char **argv) { @@ -2566,8 +3310,12 @@ main (int argc, char **argv) test_cancel_sent_stanza); g_test_add_func ("/xmpp-porter/writing-error", test_writing_error); g_test_add_func ("/xmpp-porter/send-iq", test_send_iq); - g_test_add_func ("/xmpp-porter/send-iq-denormalised", test_send_iq_abnormal); + g_test_add_func ("/xmpp-porter/acknowledge-iq", test_acknowledge_iq); g_test_add_func ("/xmpp-porter/send-iq-error", test_send_iq_error); + g_test_add_func ("/xmpp-porter/send-iq-gerror", test_send_iq_gerror); + g_test_add_func ("/xmpp-porter/send-iq-denormalised", test_send_iq_abnormal); + g_test_add_func ("/xmpp-porter/error-while-sending-iq", + test_error_while_sending_iq); g_test_add_func ("/xmpp-porter/handler-filter", test_handler_filter); g_test_add_func ("/xmpp-porter/send-invalid-iq", test_send_invalid_iq); g_test_add_func ("/xmpp-porter/handler-filter-from", @@ -2590,6 +3338,12 @@ main (int argc, char **argv) test_wait_iq_reply_force_close); g_test_add_func ("/xmpp-porter/avoid-double-force-close", test_remote_error); g_test_add_func ("/xmpp-porter/send-and-disconnect", send_and_disconnect); + g_test_add_func ("/xmpp-porter/handler-for-domain", handler_for_domain); + g_test_add_func ("/xmpp-porter/handler-from-anyone", handler_from_anyone); + g_test_add_func ("/xmpp-porter/close-from-send-callback", + close_from_send_callback); + g_test_add_func ("/xmpp-porter/send-from-send-callback", + send_from_send_callback); result = g_test_run (); test_deinit (); diff --git a/tests/wocky-pubsub-node-test.c b/tests/wocky-pubsub-node-test.c index 38edd8d..fb53370 100644 --- a/tests/wocky-pubsub-node-test.c +++ b/tests/wocky-pubsub-node-test.c @@ -25,7 +25,7 @@ test_instantiation (void) stream = g_object_new (WOCKY_TYPE_TEST_STREAM, NULL); connection = wocky_xmpp_connection_new (stream->stream0); - session = wocky_session_new (connection, "example.com"); + session = wocky_session_new_with_connection (connection, "example.com"); pubsub = wocky_pubsub_service_new (session, "pubsub.localhost"); g_assert (pubsub != NULL); @@ -56,7 +56,7 @@ test_make_publish_stanza (void) stream = g_object_new (WOCKY_TYPE_TEST_STREAM, NULL); connection = wocky_xmpp_connection_new (stream->stream0); - session = wocky_session_new (connection, "example.com"); + session = wocky_session_new_with_connection (connection, "example.com"); pubsub = wocky_pubsub_service_new (session, "pubsub.localhost"); node = wocky_pubsub_service_ensure_node (pubsub, "track1"); @@ -170,8 +170,8 @@ test_subscribe (void) pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_subscribe_iq_cb, test, '(', "pubsub", @@ -271,8 +271,8 @@ test_unsubscribe (void) pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_unsubscribe_iq_cb, &ctx, '(', "pubsub", @@ -353,8 +353,8 @@ test_delete (void) pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_delete_iq_cb, test, '(', "pubsub", @@ -474,8 +474,8 @@ test_list_subscribers (void) pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_list_subscribers_iq_cb, test, '(', "pubsub", @@ -598,8 +598,8 @@ test_list_affiliates (void) pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_list_affiliates_iq_cb, test, '(', "pubsub", @@ -699,8 +699,8 @@ test_modify_affiliates (void) pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_modify_affiliates_iq_cb, test, '(', "pubsub", @@ -840,8 +840,8 @@ test_get_configuration (void) pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_get_configuration_iq_cb, test, '(', "pubsub", diff --git a/tests/wocky-pubsub-service-test.c b/tests/wocky-pubsub-service-test.c index f2c6fb0..2ea4df4 100644 --- a/tests/wocky-pubsub-service-test.c +++ b/tests/wocky-pubsub-service-test.c @@ -24,7 +24,7 @@ create_session (void) stream = g_object_new (WOCKY_TYPE_TEST_STREAM, NULL); connection = wocky_xmpp_connection_new (stream->stream0); - session = wocky_session_new (connection, "example.com"); + session = wocky_session_new_with_connection (connection, "example.com"); g_object_unref (connection); g_object_unref (stream); @@ -157,8 +157,8 @@ get_default_node_configuration_test (WockyPorterHandlerFunc iq_cb, pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_cb, test, '(', "pubsub", @@ -198,12 +198,6 @@ test_get_default_node_configuration_insufficient_iq_cb (WockyPorter *porter, WockyStanza *reply; reply = wocky_stanza_build_iq_error (stanza, - '(', "pubsub", - ':', WOCKY_XMPP_NS_PUBSUB_OWNER, - '(', "configure", - '@', "node", "node1", - ')', - ')', '(', "error", '@', "type", "auth", '(', "forbidden", @@ -309,8 +303,8 @@ create_node_test (WockyPorterHandlerFunc iq_cb, pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_cb, test, '(', "pubsub", @@ -348,13 +342,6 @@ test_create_node_unsupported_iq_cb (WockyPorter *porter, WockyStanza *reply; reply = wocky_stanza_build_iq_error (stanza, - '(', "pubsub", - ':', WOCKY_XMPP_NS_PUBSUB, - '(', "create", - '@', "node", "node1", - ')', - '(', "configure", ')', - ')', '(', "error", '@', "type", "cancel", '(', "feature-not-implemented", @@ -622,8 +609,8 @@ test_create_node_config (void) pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_get_default_node_configuration_iq_cb, test, '(', "pubsub", @@ -632,8 +619,8 @@ test_create_node_config (void) ')', NULL); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_create_node_config_create_iq_cb, test, '(', "pubsub", @@ -844,8 +831,8 @@ test_retrieve_subscriptions (gconstpointer mode_) pubsub = wocky_pubsub_service_new (test->session_in, "pubsub.localhost"); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, test_retrieve_subscriptions_iq_cb, &ctx, '(', "pubsub", diff --git a/tests/wocky-roster-test.c b/tests/wocky-roster-test.c index f99818e..49a0efc 100644 --- a/tests/wocky-roster-test.c +++ b/tests/wocky-roster-test.c @@ -26,7 +26,7 @@ test_instantiation (void) stream = g_object_new (WOCKY_TYPE_TEST_STREAM, NULL); connection = wocky_xmpp_connection_new (stream->stream0); - session = wocky_session_new (connection, "example.com"); + session = wocky_session_new_with_connection (connection, "example.com"); roster = wocky_roster_new (session); @@ -115,8 +115,8 @@ test_fetch_roster_send_iq (void) test_open_both_connections (test); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, fetch_roster_send_iq_cb, test, NULL); @@ -263,8 +263,8 @@ create_initial_roster (test_data_t *test) { WockyRoster *roster; - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, fetch_roster_reply_cb, test, NULL); @@ -717,8 +717,8 @@ test_roster_add_contact (void) roster = create_initial_roster (test); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, add_contact_send_iq_cb, test, '(', "query", @@ -820,8 +820,8 @@ test_roster_remove_contact (void) contact = wocky_roster_get_contact (roster, "romeo@example.net"); g_assert (contact != NULL); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, remove_contact_send_iq_cb, test, '(', "query", @@ -949,8 +949,8 @@ test_roster_change_name (void) g_assert (contact != NULL); g_assert (wocky_bare_contact_equal (contact, romeo)); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, change_name_send_iq_cb, test, '(', "query", @@ -1098,8 +1098,8 @@ test_contact_add_group (void) g_assert (contact != NULL); g_assert (wocky_bare_contact_equal (contact, romeo)); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, add_group_send_iq_cb, test, '(', "query", @@ -1231,8 +1231,8 @@ test_contact_remove_group (void) g_assert (contact != NULL); g_assert (wocky_bare_contact_equal (contact, romeo)); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, remove_group_send_iq_cb, test, '(', "query", @@ -1307,8 +1307,8 @@ test_remove_contact_re_add (void) contact = wocky_roster_get_contact (roster, "romeo@example.net"); g_assert (contact != NULL); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", @@ -1390,8 +1390,8 @@ test_remove_contact_edit (void) contact = wocky_roster_get_contact (roster, "romeo@example.net"); g_assert (contact != NULL); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", @@ -1460,8 +1460,8 @@ test_multi_contact_edit (void) juliet = create_juliet (); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", @@ -1573,8 +1573,8 @@ test_edit_contact_remove (void) contact = wocky_roster_get_contact (roster, "romeo@example.net"); g_assert (contact != NULL); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", @@ -1654,8 +1654,8 @@ test_change_name_twice (void) romeo = create_romeo (); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", @@ -1721,8 +1721,8 @@ test_remove_contact_twice (void) contact = wocky_roster_get_contact (roster, "romeo@example.net"); g_assert (contact != NULL); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", @@ -1790,8 +1790,8 @@ test_change_name_remove_add (void) romeo = create_romeo (); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", @@ -1867,8 +1867,8 @@ test_add_two_groups (void) romeo = create_romeo (); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", @@ -1952,8 +1952,8 @@ test_remove_two_groups (void) juliet = create_juliet (); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", @@ -2031,8 +2031,8 @@ test_add_contact_twice (void) roster = create_initial_roster (test); - wocky_porter_register_handler (test->sched_out, - WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, + wocky_porter_register_handler_from_anyone (test->sched_out, + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, WOCKY_PORTER_HANDLER_PRIORITY_MAX, iq_set_cb, test, '(', "query", diff --git a/tests/wocky-session-test.c b/tests/wocky-session-test.c index f6846b7..8cca2a5 100644 --- a/tests/wocky-session-test.c +++ b/tests/wocky-session-test.c @@ -19,7 +19,7 @@ test_instantiation (void) stream = g_object_new (WOCKY_TYPE_TEST_STREAM, NULL); connection = wocky_xmpp_connection_new (stream->stream0); - session = wocky_session_new (connection, "example.com"); + session = wocky_session_new_with_connection (connection, "example.com"); g_assert (session != NULL); g_assert (WOCKY_IS_SESSION (session)); @@ -35,7 +35,7 @@ test_get_porter (void) WockySession *session; WockyPorter *porter; - session = wocky_session_new (test->in, "example.com"); + session = wocky_session_new_with_connection (test->in, "example.com"); porter = wocky_session_get_porter (session); g_assert (WOCKY_IS_PORTER (porter)); @@ -51,7 +51,7 @@ test_get_contact_factory (void) WockySession *session; WockyContactFactory *factory; - session = wocky_session_new (test->in, "example.com"); + session = wocky_session_new_with_connection (test->in, "example.com"); factory = wocky_session_get_contact_factory (session); g_assert (WOCKY_IS_CONTACT_FACTORY (factory)); diff --git a/tests/wocky-stanza-test.c b/tests/wocky-stanza-test.c index 8515e73..cf60d17 100644 --- a/tests/wocky-stanza-test.c +++ b/tests/wocky-stanza-test.c @@ -12,7 +12,40 @@ #include "wocky-test-helper.h" static void -test_build_iq_result (void) +test_copy (void) +{ + WockyStanza *iq, *copy, *expected; + + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + '@', "id", "one", + '(', "query", + ':', "http://jabber.org/protocol/disco#items", + ')', + NULL); + + /* just to make sure */ + expected = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + '@', "id", "one", + '(', "query", + ':', "http://jabber.org/protocol/disco#items", + ')', + NULL); + + copy = wocky_stanza_copy (iq); + g_assert (copy != NULL); + + test_assert_stanzas_equal (iq, copy); + test_assert_stanzas_equal (expected, copy); + + g_object_unref (iq); + g_object_unref (copy); + g_object_unref (expected); +} + +static void +test_build_iq_result_simple_ack (void) { WockyStanza *iq, *reply, *expected; @@ -37,6 +70,21 @@ test_build_iq_result (void) g_object_unref (reply); g_object_unref (expected); + g_object_unref (iq); +} + +static void +test_build_iq_result_complex_reply (void) +{ + WockyStanza *iq, *reply, *expected; + + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + '@', "id", "one", + '(', "query", + ':', "http://jabber.org/protocol/disco#items", + ')', + NULL); /* Send a more complex reply */ expected = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, @@ -67,6 +115,12 @@ test_build_iq_result (void) g_object_unref (reply); g_object_unref (expected); g_object_unref (iq); +} + +static void +test_build_iq_result_no_to_attr (void) +{ + WockyStanza *iq, *reply, *expected; /* Send a reply to an IQ with no "to" attribute. */ iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, @@ -94,7 +148,7 @@ test_build_iq_result (void) } static void -test_build_iq_error (void) +test_build_iq_error_simple_error (void) { WockyStanza *iq, *reply, *expected; @@ -110,6 +164,9 @@ test_build_iq_error (void) expected = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_ERROR, "romeo@example.net", "juliet@example.com", '@', "id", "one", + '(', "query", + ':', "http://jabber.org/protocol/disco#items", + ')', NULL); reply = wocky_stanza_build_iq_error (iq, NULL); @@ -119,6 +176,21 @@ test_build_iq_error (void) g_object_unref (reply); g_object_unref (expected); + g_object_unref (iq); +} + +static void +test_build_iq_error_complex (void) +{ + WockyStanza *iq, *reply, *expected; + + iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, + WOCKY_STANZA_SUB_TYPE_GET, "juliet@example.com", "romeo@example.net", + '@', "id", "one", + '(', "query", + ':', "http://jabber.org/protocol/disco#items", + ')', + NULL); /* Send a more complex reply */ expected = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, @@ -126,20 +198,17 @@ test_build_iq_error (void) '@', "id", "one", '(', "query", ':', "http://jabber.org/protocol/disco#items", - '(', "error", - '@', "code", "403", - '@', "type", "auth", - ')', + ')', + '(', "error", + '@', "code", "403", + '@', "type", "auth", ')', NULL); reply = wocky_stanza_build_iq_error (iq, - '(', "query", - ':', "http://jabber.org/protocol/disco#items", - '(', "error", - '@', "code", "403", - '@', "type", "auth", - ')', + '(', "error", + '@', "code", "403", + '@', "type", "auth", ')', NULL); @@ -227,10 +296,9 @@ test_extract_stanza_error (void) } static void -test_extract_errors (void) +test_extract_errors_not_error (void) { WockyStanza *stanza; - const gchar *description = "I am a sentence."; WockyXmppErrorType type; GError *core = NULL, *specialized = NULL; WockyNode *specialized_node = NULL; @@ -253,6 +321,16 @@ test_extract_errors (void) g_assert (specialized_node == NULL); g_object_unref (stanza); +} + +static void +test_extract_errors_without_description (void) +{ + WockyStanza *stanza; + WockyXmppErrorType type; + GError *core = NULL, *specialized = NULL; + WockyNode *specialized_node = NULL; + gboolean ret; /* Test a boring error with no description */ stanza = wocky_stanza_build ( @@ -280,6 +358,16 @@ test_extract_errors (void) g_assert (specialized_node == NULL); g_object_unref (stanza); +} + +static void +test_extract_errors_with_text (void) +{ + WockyStanza *stanza; + const gchar *description = "I am a sentence."; + WockyXmppErrorType type; + GError *core = NULL, *specialized = NULL; + WockyNode *specialized_node = NULL; /* Now a different error with some text */ stanza = wocky_stanza_build ( @@ -310,6 +398,15 @@ test_extract_errors (void) g_assert (specialized_node == NULL); g_object_unref (stanza); +} + +static void +test_extract_errors_application_specific_unknown (void) +{ + WockyStanza *stanza; + WockyXmppErrorType type; + GError *core = NULL, *specialized = NULL; + WockyNode *specialized_node = NULL; /* Another error, with an application-specific element we don't understand */ stanza = wocky_stanza_build ( @@ -338,14 +435,26 @@ test_extract_errors (void) g_assert_no_error (specialized); - /* This is questionable: maybe wocky_xmpp_error_extract() should assume that - * a child of <error/> in a NS it doesn't understand is a specialized error, - * rather than requiring the ns to be registered with - * wocky_xmpp_error_register_domain(). + /* The namespace is not registered, @specialized is not set. However we + * assume that any other namespace element is a specialized error, and it + * should get returned in @specialized_node */ - g_assert (specialized_node == NULL); + g_assert (specialized_node); + g_assert_cmpstr (specialized_node->name, ==, "buy-a-private-cloud"); + g_assert_cmpstr (wocky_node_get_ns (specialized_node), ==, + "http://example.com/angry-cloud"); g_object_unref (stanza); +} + +static void +test_extract_errors_jingle_error (void) +{ + WockyStanza *stanza; + const gchar *description = "I am a sentence."; + WockyXmppErrorType type; + GError *core = NULL, *specialized = NULL; + WockyNode *specialized_node = NULL; /* A Jingle error! With the child nodes in an erratic order */ stanza = wocky_stanza_build ( @@ -387,6 +496,66 @@ test_extract_errors (void) wocky_stanza_extract_errors (stanza, NULL, NULL, NULL, NULL); g_object_unref (stanza); +} + +static void +test_extract_errors_extra_application_specific (void) +{ + WockyStanza *stanza; + const gchar *description = "I am a sentence."; + WockyXmppErrorType type; + GError *core = NULL, *specialized = NULL; + WockyNode *specialized_node = NULL; + + /* Jingle error! + Bogus extra app specific error, which should be ignored */ + stanza = wocky_stanza_build ( + WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_ERROR, + "from", "to", + '(', "error", + '@', "type", "cancel", + '(', "tie-break", + ':', WOCKY_XMPP_NS_JINGLE_ERRORS, + ')', + '(', "out-of-order", + ':', WOCKY_XMPP_NS_JINGLE_ERRORS, + ')', + '(', "text", + ':', WOCKY_XMPP_NS_STANZAS, + '$', description, + ')', + '(', "conflict", + ':', WOCKY_XMPP_NS_STANZAS, + ')', + ')', + NULL); + + wocky_stanza_extract_errors (stanza, &type, &core, &specialized, + &specialized_node); + + g_assert_cmpuint (type, ==, WOCKY_XMPP_ERROR_TYPE_CANCEL); + + g_assert_error (core, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_CONFLICT); + g_assert_cmpstr (core->message, ==, description); + g_clear_error (&core); + + g_assert_error (specialized, WOCKY_JINGLE_ERROR, + WOCKY_JINGLE_ERROR_TIE_BREAK); + g_assert_cmpstr (specialized->message, ==, description); + g_clear_error (&specialized); + + g_assert (specialized_node != NULL); + g_assert_cmpstr (specialized_node->name, ==, "tie-break"); + + g_object_unref (stanza); +} + +static void +test_extract_errors_legacy_code (void) +{ + WockyStanza *stanza; + WockyXmppErrorType type; + GError *core = NULL, *specialized = NULL; + WockyNode *specialized_node = NULL; /* How about a legacy error code? */ stanza = wocky_stanza_build ( @@ -414,6 +583,15 @@ test_extract_errors (void) g_assert (specialized_node == NULL); g_object_unref (stanza); +} + +static void +test_extract_errors_no_sense (void) +{ + WockyStanza *stanza; + WockyXmppErrorType type; + GError *core = NULL, *specialized = NULL; + WockyNode *specialized_node = NULL; /* An error that makes no sense */ stanza = wocky_stanza_build ( @@ -439,9 +617,19 @@ test_extract_errors (void) g_clear_error (&core); g_assert_no_error (specialized); - g_assert (specialized_node == NULL); + g_assert (specialized_node != NULL); + g_assert_cmpstr (specialized_node->name, ==, "hoobily-lala-whee"); g_object_unref (stanza); +} + +static void +test_extract_errors_not_really (void) +{ + WockyStanza *stanza; + WockyXmppErrorType type; + GError *core = NULL, *specialized = NULL; + WockyNode *specialized_node = NULL; /* And finally, a stanza with type='error' but no <error/> at all... */ stanza = wocky_stanza_build ( @@ -469,7 +657,7 @@ test_extract_errors (void) } G_STMT_END static void -test_stanza_error_to_node (void) +test_stanza_error_to_node_core (void) { GError *e = NULL; GError *core = NULL, *specialized = NULL; @@ -514,6 +702,15 @@ test_stanza_error_to_node (void) g_object_unref (expected); g_clear_error (&e); g_clear_error (&core); +} + +static void +test_stanza_error_to_node_jingle (void) +{ + GError *e = NULL; + GError *core = NULL, *specialized = NULL; + const gchar *description = "bzzzt"; + WockyStanza *stanza, *expected; /* How about a nice game of Jingle? */ g_set_error_literal (&e, WOCKY_JINGLE_ERROR, @@ -565,13 +762,41 @@ main (int argc, char **argv) int result; test_init (argc, argv); - g_test_add_func ("/xmpp-stanza/build-iq-result", test_build_iq_result); - g_test_add_func ("/xmpp-stanza/build-iq-error", test_build_iq_error); - g_test_add_func ("/xmpp-stanza/extract-stanza-error", + g_test_add_func ("/xmpp-stanza/copy", test_copy); + g_test_add_func ("/xmpp-stanza/iq-result/build-simple-ack", + test_build_iq_result_simple_ack); + g_test_add_func ("/xmpp-stanza/iq-result/build-complex-reply", + test_build_iq_result_complex_reply); + g_test_add_func ("/xmpp-stanza/iq-result/build-no-to-attr", + test_build_iq_result_no_to_attr); + g_test_add_func ("/xmpp-stanza/errors/build-simple", + test_build_iq_error_simple_error); + g_test_add_func ("/xmpp-stanza/errors/build-complex", + test_build_iq_error_complex); + g_test_add_func ("/xmpp-stanza/errors/extract-stanza", test_extract_stanza_error); - g_test_add_func ("/xmpp-stanza/extract-errors", test_extract_errors); - g_test_add_func ("/xmpp-stanza/stanza-error-to-node", - test_stanza_error_to_node); + g_test_add_func ("/xmpp-stanza/errors/not-error", + test_extract_errors_not_error); + g_test_add_func ("/xmpp-stanza/errors/without-description", + test_extract_errors_without_description); + g_test_add_func ("/xmpp-stanza/errors/with-text", + test_extract_errors_with_text); + g_test_add_func ("/xmpp-stanza/errors/application-specific-unknown", + test_extract_errors_application_specific_unknown); + g_test_add_func ("/xmpp-stanza/errors/jingle-error", + test_extract_errors_jingle_error); + g_test_add_func ("/xmpp-stanza/errors/extra-application-specific", + test_extract_errors_extra_application_specific); + g_test_add_func ("/xmpp-stanza/errors/legacy-code", + test_extract_errors_legacy_code); + g_test_add_func ("/xmpp-stanza/errors/no-sense", + test_extract_errors_no_sense); + g_test_add_func ("/xmpp-stanza/errors/not-really", + test_extract_errors_not_really); + g_test_add_func ("/xmpp-stanza/errors/stanza-to-node", + test_stanza_error_to_node_core); + g_test_add_func ("/xmpp-stanza/errors/stanza-to-node-jingle", + test_stanza_error_to_node_jingle); result = g_test_run (); test_deinit (); diff --git a/tests/wocky-test-helper.c b/tests/wocky-test-helper.c index ee5e754..3bf7496 100644 --- a/tests/wocky-test-helper.c +++ b/tests/wocky-test-helper.c @@ -30,8 +30,8 @@ setup_test_full (guint timeout, data->in = wocky_xmpp_connection_new (data->stream->stream0); data->out = wocky_xmpp_connection_new (data->stream->stream1); - data->session_in = wocky_session_new (data->in, in_jid); - data->session_out = wocky_session_new (data->out, out_jid); + data->session_in = wocky_session_new_with_connection (data->in, in_jid); + data->session_out = wocky_session_new_with_connection (data->out, out_jid); data->sched_in = wocky_session_get_porter (data->session_in); data->sched_out = wocky_session_get_porter (data->session_out); diff --git a/tests/wocky-xmpp-reader-test.c b/tests/wocky-xmpp-reader-test.c index 62cdb64..8d91e32 100644 --- a/tests/wocky-xmpp-reader-test.c +++ b/tests/wocky-xmpp-reader-test.c @@ -22,6 +22,12 @@ "<stream:streamsss xmlns='jabber:client' " \ " xmlns:stream='http://etherx.jabber.org/streams'> " +#define HEADER_WITH_UNQUALIFIED_LANG \ +"<?xml version='1.0' encoding='UTF-8'?> " \ +"<stream:stream xmlns='jabber:client' " \ +" xmlns:stream='http://etherx.jabber.org/streams' " \ +" lang='fi'> " + #define BROKEN_MESSAGE \ " <message to='juliet@example.com' from='romeo@example.net' xml:lang='en' " \ " id=\"0\"> " \ @@ -69,6 +75,22 @@ " </branch> " \ "</iq> " +#define WHITESPACE_PADDED_BODY " The Wench is Dead! " + +#define MESSAGE_WITH_WHITESPACE_PADDED_BODY \ +" <message to='morse@thamesvalley.police.uk' " \ +" from='lewis@thamesvalley.police.uk'> " \ +" <body>" WHITESPACE_PADDED_BODY "</body>" \ +" </message>" + + +#define WHITESPACE_ONLY_BODY " " + +#define MESSAGE_WITH_WHITESPACE_ONLY_BODY \ +" <message to='morse@thamesvalley.police.uk' " \ +" from='lewis@thamesvalley.police.uk'> " \ +" <body>" WHITESPACE_ONLY_BODY "</body>" \ +" </message>" static void test_stream_no_stanzas (void) @@ -130,6 +152,24 @@ test_stream_open_error (void) } static void +test_stream_open_unqualified_lang (void) +{ + WockyXmppReader *reader = wocky_xmpp_reader_new (); + + g_assert (wocky_xmpp_reader_get_state (reader) + == WOCKY_XMPP_READER_STATE_INITIAL); + + wocky_xmpp_reader_push (reader, + (guint8 *) HEADER_WITH_UNQUALIFIED_LANG, + strlen (HEADER_WITH_UNQUALIFIED_LANG)); + + g_assert (wocky_xmpp_reader_get_state (reader) + == WOCKY_XMPP_READER_STATE_OPENED); + + g_object_unref (reader); +} + +static void test_parse_error (void) { WockyXmppReader *reader; @@ -282,6 +322,44 @@ test_invalid_namespace (void) g_object_unref (reader); } +/* Helper function for the whitespace body tests */ +static void +test_body ( + const gchar *xml, + const gchar *expected_body_text) +{ + WockyXmppReader *reader = wocky_xmpp_reader_new_no_stream (); + WockyStanza *stanza; + WockyNode *body; + + wocky_xmpp_reader_push (reader, (guint8 *) xml, strlen (xml)); + + stanza = wocky_xmpp_reader_pop_stanza (reader); + g_assert (stanza != NULL); + + body = wocky_node_get_child (wocky_stanza_get_top_node (stanza), "body"); + g_assert (body != NULL); + + g_assert_cmpstr (body->content, ==, expected_body_text); + + g_object_unref (stanza); + g_object_unref (reader); +} + +/* Test that whitespace around the text contents of a message isn't ignored */ +static void +test_whitespace_padding (void) +{ + test_body (MESSAGE_WITH_WHITESPACE_PADDED_BODY, WHITESPACE_PADDED_BODY); +} + +/* Test that a message body consisting entirely of whitespace isn't ignored */ +static void +test_whitespace_only (void) +{ + test_body (MESSAGE_WITH_WHITESPACE_ONLY_BODY, WHITESPACE_ONLY_BODY); +} + int main (int argc, char **argv) @@ -292,11 +370,15 @@ main (int argc, g_test_add_func ("/xmpp-reader/stream-no-stanzas", test_stream_no_stanzas); g_test_add_func ("/xmpp-reader/stream-open-error", test_stream_open_error); + g_test_add_func ("/xmpp-reader/stream-open-unqualified-lang", + test_stream_open_unqualified_lang); g_test_add_func ("/xmpp-reader/parse-error", test_parse_error); g_test_add_func ("/xmpp-reader/no-stream-hunks", test_no_stream_hunks); g_test_add_func ("/xmpp-reader/no-stream-resetting", test_no_stream_reset); g_test_add_func ("/xmpp-reader/vcard-namespace", test_vcard_namespace); g_test_add_func ("/xmpp-reader/invalid-namespace", test_invalid_namespace); + g_test_add_func ("/xmpp-reader/whitespace-padding", test_whitespace_padding); + g_test_add_func ("/xmpp-reader/whitespace-only", test_whitespace_only); result = g_test_run (); test_deinit (); |