1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <string.h>
8
9 #include <glib.h>
10
11 #include <wocky/wocky.h>
12
13 #include "wocky-test-stream.h"
14 #include "wocky-test-helper.h"
15
16 #define TEST_NODE1 "http://test.com/node1"
17 #define TEST_NODE2 "http://test.com/node2"
18
19 /* Test to instantiate a WockyPepService object */
20 static void
test_instantiation(void)21 test_instantiation (void)
22 {
23 WockyPepService *pep;
24
25 pep = wocky_pep_service_new ("http://test.com/badger", FALSE);
26 g_assert (pep != NULL);
27
28 g_object_unref (pep);
29 }
30
31 /* Test that the 'changed' signal is properly fired */
32 gboolean event_received;
33
34 static void
test_changed_signal_cb(WockyPepService * pep,WockyBareContact * contact,WockyStanza * stanza,WockyNode * item,test_data_t * test)35 test_changed_signal_cb (WockyPepService *pep,
36 WockyBareContact *contact,
37 WockyStanza *stanza,
38 WockyNode *item,
39 test_data_t *test)
40 {
41 const gchar *id = wocky_node_get_attribute (
42 wocky_stanza_get_top_node (stanza), "id");
43
44 g_assert_cmpstr (wocky_bare_contact_get_jid (contact), ==,
45 "alice@example.org");
46
47 /* the id happens to hold the number of <item> children; we expect to get the
48 * first one if there is more than one. */
49 if (wocky_strdiff (id, "0"))
50 {
51 g_assert (item != NULL);
52 g_assert_cmpstr (item->name, ==, "item");
53 g_assert_cmpstr (wocky_node_get_attribute (item, "id"), ==, "1");
54 }
55 else
56 {
57 g_assert (item == NULL);
58 }
59
60 test->outstanding--;
61 g_main_loop_quit (test->loop);
62 event_received = TRUE;
63 }
64
65 static void
send_pep_event(WockyPorter * porter,const gchar * node,guint n_items)66 send_pep_event (WockyPorter *porter,
67 const gchar *node,
68 guint n_items)
69 {
70 WockyStanza *stanza;
71 WockyNode *items;
72 gchar *n_items_str = g_strdup_printf ("%d", n_items);
73 guint i;
74
75 stanza = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE,
76 WOCKY_STANZA_SUB_TYPE_NONE,
77 "alice@example.org", NULL,
78 /* This is a hint for test_changed_signal_cb. */
79 '@', "id", n_items_str,
80 '(', "event",
81 ':', WOCKY_XMPP_NS_PUBSUB_EVENT,
82 '(', "items",
83 '@', "node", node,
84 '*', &items,
85 ')',
86 ')',
87 NULL);
88
89 for (i = 1; i <= n_items; i++)
90 {
91 gchar *i_str = g_strdup_printf ("%d", i);
92 wocky_node_add_build (items,
93 '(', "item",
94 '@', "id", i_str,
95 '(', "payload", ')',
96 ')', NULL);
97 g_free (i_str);
98 }
99
100 wocky_porter_send (porter, stanza);
101 g_object_unref (stanza);
102 g_free (n_items_str);
103 }
104
105 static void
test_changed_signal(void)106 test_changed_signal (void)
107 {
108 test_data_t *test = setup_test ();
109 WockyPepService *pep;
110
111 pep = wocky_pep_service_new (TEST_NODE1, FALSE);
112 test_open_both_connections (test);
113
114 g_signal_connect (pep, "changed", G_CALLBACK (test_changed_signal_cb), test);
115
116 wocky_pep_service_start (pep, test->session_out);
117 wocky_porter_start (test->sched_out);
118 wocky_porter_start (test->sched_in);
119
120 /* send events on the right node */
121 event_received = FALSE;
122 send_pep_event (test->sched_in, TEST_NODE1, 0);
123 send_pep_event (test->sched_in, TEST_NODE1, 1);
124 send_pep_event (test->sched_in, TEST_NODE1, 2);
125
126 test->outstanding += 3;
127 test_wait_pending (test);
128 g_assert (event_received);
129 event_received = FALSE;
130
131 /* send event on the wrong node */
132 send_pep_event (test->sched_in, TEST_NODE2, 1);
133
134 g_object_unref (pep);
135
136 /* send event to the right node after the PEP service has been destroyed */
137 send_pep_event (test->sched_in, TEST_NODE1, 1);
138
139 test_close_both_porters (test);
140 teardown_test (test);
141 g_assert (!event_received);
142 }
143
144 /* Test wocky_pep_service_get_async */
145 static void
test_send_query_cb(GObject * source_object,GAsyncResult * res,gpointer user_data)146 test_send_query_cb (GObject *source_object,
147 GAsyncResult *res,
148 gpointer user_data)
149 {
150 test_data_t *test = (test_data_t *) user_data;
151 WockyStanza *reply;
152 WockyNode *item;
153 WockyStanzaType type;
154 WockyStanzaSubType sub_type;
155
156 reply = wocky_pep_service_get_finish (WOCKY_PEP_SERVICE (source_object), res,
157 &item, NULL);
158 g_assert (reply != NULL);
159
160 wocky_stanza_get_type_info (reply, &type, &sub_type);
161 g_assert (type == WOCKY_STANZA_TYPE_IQ);
162 g_assert (sub_type == WOCKY_STANZA_SUB_TYPE_RESULT);
163
164 g_assert (item != NULL);
165 g_assert_cmpstr (item->name, ==, "item");
166 g_assert_cmpstr (wocky_node_get_attribute (item, "id"), ==, "1");
167
168 g_object_unref (reply);
169
170 test->outstanding--;
171 g_main_loop_quit (test->loop);
172 }
173
174 static gboolean
test_send_query_stanza_received_cb(WockyPorter * porter,WockyStanza * stanza,gpointer user_data)175 test_send_query_stanza_received_cb (WockyPorter *porter,
176 WockyStanza *stanza,
177 gpointer user_data)
178 {
179 test_data_t *test = (test_data_t *) user_data;
180 WockyStanza *reply;
181
182 reply = wocky_stanza_build_iq_result (stanza,
183 '(', "pubsub",
184 ':', WOCKY_XMPP_NS_PUBSUB,
185 '(', "items",
186 '@', "node", "node1",
187 '(', "item",
188 '@', "id", "1",
189 '(', "payload", ')',
190 ')',
191 ')',
192 ')',
193 NULL);
194
195 wocky_porter_send (porter, reply);
196 g_object_unref (reply);
197
198 test->outstanding--;
199 g_main_loop_quit (test->loop);
200 return TRUE;
201 }
202
203 static void
test_send_query_failed_cb(GObject * source_object,GAsyncResult * res,gpointer user_data)204 test_send_query_failed_cb (GObject *source_object,
205 GAsyncResult *res,
206 gpointer user_data)
207 {
208 test_data_t *test = (test_data_t *) user_data;
209 WockyStanza *reply;
210 GError *error = NULL;
211
212 reply = wocky_pep_service_get_finish (WOCKY_PEP_SERVICE (source_object), res,
213 NULL, &error);
214 g_assert (reply == NULL);
215 g_assert_error (error, WOCKY_XMPP_CONNECTION_ERROR,
216 WOCKY_XMPP_CONNECTION_ERROR_CLOSED);
217 g_clear_error (&error);
218
219 test->outstanding--;
220 g_main_loop_quit (test->loop);
221 }
222
223 static void
test_get(void)224 test_get (void)
225 {
226 test_data_t *test = setup_test ();
227 WockyPepService *pep;
228 WockyContactFactory *contact_factory;
229 WockyBareContact *contact;
230 guint handler_id;
231
232 pep = wocky_pep_service_new (TEST_NODE1, FALSE);
233 test_open_both_connections (test);
234
235 wocky_pep_service_start (pep, test->session_in);
236 wocky_porter_start (test->sched_out);
237 wocky_porter_start (test->sched_in);
238
239 handler_id = wocky_porter_register_handler_from_anyone (test->sched_out,
240 WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET,
241 WOCKY_PORTER_HANDLER_PRIORITY_MAX,
242 test_send_query_stanza_received_cb, test, NULL);
243
244 contact_factory = wocky_session_get_contact_factory (test->session_in);
245 contact = wocky_contact_factory_ensure_bare_contact (contact_factory,
246 "juliet@example.org");
247
248 wocky_pep_service_get_async (pep, contact, NULL, test_send_query_cb, test);
249
250 test->outstanding += 2;
251 test_wait_pending (test);
252
253 /* Regression test for a bug where wocky_pep_service_get_async's callback
254 * would crash if sending the IQ failed.
255 */
256 wocky_porter_unregister_handler (test->sched_out, handler_id);
257 wocky_pep_service_get_async (pep, contact, NULL, test_send_query_failed_cb,
258 test);
259 test->outstanding += 1;
260 test_close_both_porters (test);
261
262 g_object_unref (contact);
263 g_object_unref (pep);
264 teardown_test (test);
265 }
266
267 /* Test wocky_pep_service_make_publish_stanza */
268 static void
test_make_publish_stanza(void)269 test_make_publish_stanza (void)
270 {
271 WockyPepService *pep;
272 WockyStanza *stanza;
273 WockyNode *item = NULL, *n;
274 WockyStanzaType type;
275 WockyStanzaSubType sub_type;
276
277 pep = wocky_pep_service_new (TEST_NODE1, FALSE);
278
279 stanza = wocky_pep_service_make_publish_stanza (pep, &item);
280
281 g_assert (stanza != NULL);
282
283 wocky_stanza_get_type_info (stanza, &type, &sub_type);
284 g_assert (type == WOCKY_STANZA_TYPE_IQ);
285 g_assert (sub_type == WOCKY_STANZA_SUB_TYPE_SET);
286
287 n = wocky_node_get_child_ns (wocky_stanza_get_top_node (stanza),
288 "pubsub", WOCKY_XMPP_NS_PUBSUB);
289 g_assert (n != NULL);
290
291 n = wocky_node_get_child (n, "publish");
292 g_assert (n != NULL);
293 g_assert (!wocky_strdiff (wocky_node_get_attribute (n, "node"),
294 TEST_NODE1));
295
296 n = wocky_node_get_child (n, "item");
297 g_assert (n != NULL);
298 g_assert (n == item);
299
300 g_object_unref (stanza);
301 g_object_unref (pep);
302 }
303
304 int
main(int argc,char ** argv)305 main (int argc, char **argv)
306 {
307 int result;
308
309 test_init (argc, argv);
310
311 g_test_add_func ("/pep-service/instantiation", test_instantiation);
312 g_test_add_func ("/pep-service/changed-signal", test_changed_signal);
313 g_test_add_func ("/pep-service/get", test_get);
314 g_test_add_func ("/pep-service/make-publish-stanza",
315 test_make_publish_stanza);
316
317 result = g_test_run ();
318 test_deinit ();
319 return result;
320 }
321