1 /* A very basic feature test for TpChannelRequest
2 *
3 * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
4 * Copyright (C) 2009 Nokia Corporation
5 *
6 * Copying and distribution of this file, with or without modification,
7 * are permitted in any medium without royalty provided the copyright
8 * notice and this notice are preserved.
9 */
10
11 #include "config.h"
12
13 #include <telepathy-glib/channel-request.h>
14 #include <telepathy-glib/defs.h>
15 #include <telepathy-glib/debug.h>
16 #include <telepathy-glib/svc-channel-request.h>
17
18 #include <dbus/dbus.h>
19 #include <dbus/dbus-glib.h>
20 #include <dbus/dbus-glib-lowlevel.h>
21
22 #include "tests/lib/simple-conn.h"
23 #include "tests/lib/util.h"
24
25 /* This object implements no methods and no properties - TpChannelRequest
26 * doesn't actually use them yet */
27
28 static GType test_simple_cr_get_type (void);
29
30 typedef struct {
31 GObject parent;
32 } TestSimpleCR;
33
34 typedef struct {
35 GObjectClass parent;
36 } TestSimpleCRClass;
37
38 G_DEFINE_TYPE_WITH_CODE (TestSimpleCR, test_simple_cr, G_TYPE_OBJECT,
39 G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_REQUEST, NULL));
40
41 static void
test_simple_cr_init(TestSimpleCR * self)42 test_simple_cr_init (TestSimpleCR *self)
43 {
44 }
45
46 static void
test_simple_cr_class_init(TestSimpleCRClass * klass)47 test_simple_cr_class_init (TestSimpleCRClass *klass)
48 {
49 }
50
51 typedef struct {
52 GMainLoop *mainloop;
53 TpDBusDaemon *dbus;
54
55 DBusGConnection *private_conn;
56 TpDBusDaemon *private_dbus;
57 GObject *cr_service;
58
59 /* Service side objects */
60 TpBaseConnection *base_connection;
61
62 /* Client side objects */
63 TpConnection *connection;
64 TpChannel *channel;
65 TpChannelRequest *cr;
66
67 GError *error /* initialized where needed */;
68
69 guint succeeded;
70 } Test;
71
72 static void
setup(Test * test,gconstpointer data)73 setup (Test *test,
74 gconstpointer data)
75 {
76 DBusConnection *libdbus;
77
78 tp_debug_set_flags ("all");
79
80 test->mainloop = g_main_loop_new (NULL, FALSE);
81 test->dbus = tp_tests_dbus_daemon_dup_or_die ();
82 g_assert (test->dbus != NULL);
83
84 libdbus = dbus_bus_get_private (DBUS_BUS_STARTER, NULL);
85 g_assert (libdbus != NULL);
86 dbus_connection_setup_with_g_main (libdbus, NULL);
87 dbus_connection_set_exit_on_disconnect (libdbus, FALSE);
88 test->private_conn = dbus_connection_get_g_connection (libdbus);
89 /* transfer ref */
90 dbus_g_connection_ref (test->private_conn);
91 dbus_connection_unref (libdbus);
92 g_assert (test->private_conn != NULL);
93 test->private_dbus = tp_dbus_daemon_new (test->private_conn);
94 g_assert (test->private_dbus != NULL);
95
96 /* Create (service and client sides) connection objects */
97 tp_tests_create_and_connect_conn (TP_TESTS_TYPE_SIMPLE_CONNECTION,
98 "me@test.com", &test->base_connection, &test->connection);
99 test->cr = NULL;
100
101 test->cr_service = tp_tests_object_new_static_class (test_simple_cr_get_type (),
102 NULL);
103 tp_dbus_daemon_register_object (test->private_dbus, "/whatever",
104 test->cr_service);
105 }
106
107 static void
teardown(Test * test,gconstpointer data)108 teardown (Test *test,
109 gconstpointer data)
110 {
111 tp_tests_connection_assert_disconnect_succeeds (test->connection);
112 g_object_unref (test->connection);
113 g_object_unref (test->base_connection);
114
115 if (test->cr != NULL)
116 {
117 g_object_unref (test->cr);
118 test->cr = NULL;
119 }
120
121 if (test->private_dbus != NULL)
122 {
123 tp_dbus_daemon_release_name (test->private_dbus,
124 TP_CHANNEL_DISPATCHER_BUS_NAME, NULL);
125
126 g_object_unref (test->private_dbus);
127 test->private_dbus = NULL;
128 }
129
130 g_object_unref (test->cr_service);
131 test->cr_service = NULL;
132
133 if (test->private_conn != NULL)
134 {
135 dbus_connection_close (dbus_g_connection_get_connection (
136 test->private_conn));
137
138 dbus_g_connection_unref (test->private_conn);
139 test->private_conn = NULL;
140 }
141
142 /* make sure any pending things have happened */
143 tp_tests_proxy_run_until_dbus_queue_processed (test->dbus);
144
145 g_object_unref (test->dbus);
146 test->dbus = NULL;
147
148 g_main_loop_unref (test->mainloop);
149 test->mainloop = NULL;
150 }
151
152 static void
test_new(Test * test,gconstpointer data G_GNUC_UNUSED)153 test_new (Test *test,
154 gconstpointer data G_GNUC_UNUSED)
155 {
156 gboolean ok;
157
158 /* CD not running */
159 test->cr = tp_channel_request_new (test->dbus,
160 "/whatever", NULL, NULL);
161 g_assert (test->cr == NULL);
162
163 ok = tp_dbus_daemon_request_name (test->private_dbus,
164 TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL);
165 g_assert (ok);
166
167 test->cr = tp_channel_request_new (test->dbus,
168 "not even syntactically valid", NULL, NULL);
169 g_assert (test->cr == NULL);
170
171 test->cr = tp_channel_request_new (test->dbus, "/whatever", NULL, NULL);
172 g_assert (test->cr != NULL);
173 }
174
175 static void
test_crash(Test * test,gconstpointer data G_GNUC_UNUSED)176 test_crash (Test *test,
177 gconstpointer data G_GNUC_UNUSED)
178 {
179 gboolean ok;
180
181 ok = tp_dbus_daemon_request_name (test->private_dbus,
182 TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL);
183 g_assert (ok);
184
185 test->cr = tp_channel_request_new (test->dbus, "/whatever", NULL, NULL);
186 g_assert (test->cr != NULL);
187 g_assert (tp_proxy_get_invalidated (test->cr) == NULL);
188
189 tp_dbus_daemon_release_name (test->private_dbus,
190 TP_CHANNEL_DISPATCHER_BUS_NAME, NULL);
191
192 tp_tests_proxy_run_until_dbus_queue_processed (test->cr);
193
194 g_assert (tp_proxy_get_invalidated (test->cr) == NULL);
195
196 dbus_connection_close (dbus_g_connection_get_connection (
197 test->private_conn));
198 dbus_g_connection_unref (test->private_conn);
199 test->private_conn = NULL;
200
201 while (tp_proxy_get_invalidated (test->cr) == NULL)
202 g_main_context_iteration (NULL, TRUE);
203
204 g_assert (tp_proxy_get_invalidated (test->cr)->domain == TP_DBUS_ERRORS);
205 g_assert (tp_proxy_get_invalidated (test->cr)->code ==
206 TP_DBUS_ERROR_NAME_OWNER_LOST);
207 }
208
209 static void
succeeded_cb(Test * test)210 succeeded_cb (Test *test)
211 {
212 test->succeeded++;
213 }
214
215 static void
succeeded_with_channel_cb(TpChannelRequest * request,TpConnection * connection,TpChannel * channel,Test * test)216 succeeded_with_channel_cb (TpChannelRequest *request,
217 TpConnection *connection,
218 TpChannel *channel,
219 Test *test)
220 {
221 g_assert (TP_IS_CONNECTION (connection));
222 g_assert (TP_IS_CHANNEL (channel));
223
224 g_assert_cmpstr (tp_proxy_get_object_path (connection), ==,
225 tp_base_connection_get_object_path (test->base_connection));
226 g_assert_cmpstr (tp_proxy_get_object_path (channel), ==,
227 "/Channel");
228
229 test->succeeded++;
230 }
231
232 static void
test_succeeded(Test * test,gconstpointer data G_GNUC_UNUSED)233 test_succeeded (Test *test,
234 gconstpointer data G_GNUC_UNUSED)
235 {
236 gboolean ok;
237 GHashTable *props;
238
239 ok = tp_dbus_daemon_request_name (test->private_dbus,
240 TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL);
241 g_assert (ok);
242
243 test->cr = tp_channel_request_new (test->dbus, "/whatever", NULL, NULL);
244 g_assert (test->cr != NULL);
245 g_assert (tp_proxy_get_invalidated (test->cr) == NULL);
246
247 g_signal_connect_swapped (test->cr, "succeeded", G_CALLBACK (succeeded_cb),
248 test);
249 g_signal_connect (test->cr, "succeeded-with-channel",
250 G_CALLBACK (succeeded_with_channel_cb), test);
251
252 /* sync up both sockets to ensure that the match rules are in place */
253 tp_tests_proxy_run_until_dbus_queue_processed (test->cr);
254
255 props = g_hash_table_new (NULL, NULL);
256
257 tp_svc_channel_request_emit_succeeded_with_channel (test->cr_service,
258 tp_base_connection_get_object_path (test->base_connection),
259 props, "/Channel", props);
260
261 g_hash_table_unref (props);
262
263 tp_svc_channel_request_emit_succeeded (test->cr_service);
264
265 tp_tests_proxy_run_until_dbus_queue_processed (test->cr);
266
267 g_assert (tp_proxy_get_invalidated (test->cr) != NULL);
268 g_assert (tp_proxy_get_invalidated (test->cr)->domain == TP_DBUS_ERRORS);
269 g_assert (tp_proxy_get_invalidated (test->cr)->code ==
270 TP_DBUS_ERROR_OBJECT_REMOVED);
271 g_assert_cmpuint (test->succeeded, ==, 2);
272
273 g_signal_handlers_disconnect_by_func (test->cr, G_CALLBACK (succeeded_cb),
274 test);
275 }
276
277 static void
test_failed(Test * test,gconstpointer data G_GNUC_UNUSED)278 test_failed (Test *test,
279 gconstpointer data G_GNUC_UNUSED)
280 {
281 gboolean ok;
282
283 ok = tp_dbus_daemon_request_name (test->private_dbus,
284 TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL);
285 g_assert (ok);
286
287 test->cr = tp_channel_request_new (test->dbus, "/whatever", NULL, NULL);
288 g_assert (test->cr != NULL);
289 g_assert (tp_proxy_get_invalidated (test->cr) == NULL);
290
291 g_signal_connect_swapped (test->cr, "succeeded", G_CALLBACK (succeeded_cb),
292 test);
293
294 /* sync up both sockets to ensure that the match rules are in place */
295 tp_tests_proxy_run_until_dbus_queue_processed (test->cr);
296
297 tp_svc_channel_request_emit_failed (test->cr_service,
298 TP_ERROR_STR_NOT_YOURS, "lalala");
299
300 tp_tests_proxy_run_until_dbus_queue_processed (test->cr);
301
302 g_assert (tp_proxy_get_invalidated (test->cr) != NULL);
303 g_assert (tp_proxy_get_invalidated (test->cr)->domain == TP_ERROR);
304 g_assert (tp_proxy_get_invalidated (test->cr)->code == TP_ERROR_NOT_YOURS);
305 g_assert_cmpstr (tp_proxy_get_invalidated (test->cr)->message, ==,
306 "lalala");
307 g_assert_cmpuint (test->succeeded, ==, 0);
308
309 g_signal_handlers_disconnect_by_func (test->cr, G_CALLBACK (succeeded_cb),
310 test);
311 }
312
313 static void
test_immutable_properties(Test * test,gconstpointer data G_GNUC_UNUSED)314 test_immutable_properties (Test *test,
315 gconstpointer data G_GNUC_UNUSED)
316 {
317 gboolean ok;
318 GHashTable *props;
319 GVariant *vardict;
320
321 props = tp_asv_new ("badger", G_TYPE_UINT, 42,
322 NULL);
323
324 ok = tp_dbus_daemon_request_name (test->private_dbus,
325 TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL);
326 g_assert (ok);
327
328 test->cr = tp_channel_request_new (test->dbus, "/whatever", props, NULL);
329 g_assert (test->cr != NULL);
330
331 g_hash_table_unref (props);
332
333 props = (GHashTable *) tp_channel_request_get_immutable_properties (test->cr);
334 g_assert_cmpuint (tp_asv_get_uint32 (props, "badger", NULL), ==, 42);
335
336 g_object_get (test->cr, "immutable-properties", &props, NULL);
337 g_assert_cmpuint (tp_asv_get_uint32 (props, "badger", NULL), ==, 42);
338
339 g_hash_table_unref (props);
340
341 vardict = tp_channel_request_dup_immutable_properties (test->cr);
342 g_assert_cmpuint (tp_vardict_get_uint32 (vardict, "badger", NULL), ==, 42);
343 g_variant_unref (vardict);
344
345 g_object_get (test->cr,
346 "immutable-properties-vardict", &vardict, NULL);
347 g_assert_cmpuint (tp_vardict_get_uint32 (vardict, "badger", NULL), ==, 42);
348 g_variant_unref (vardict);
349 }
350
351 #define ACCOUNT_PATH TP_ACCOUNT_OBJECT_PATH_BASE "a/b/c"
352
353 static void
test_properties(Test * test,gconstpointer data G_GNUC_UNUSED)354 test_properties (Test *test,
355 gconstpointer data G_GNUC_UNUSED)
356 {
357 gboolean ok;
358 GHashTable *props, *hints;
359 TpAccount *account;
360 gint64 user_action_time;
361 const gchar *handler;
362 GVariant *vardict;
363
364 hints = tp_asv_new ("test", G_TYPE_STRING, "hi", NULL);
365
366 props = tp_asv_new (
367 TP_PROP_CHANNEL_REQUEST_ACCOUNT, DBUS_TYPE_G_OBJECT_PATH, ACCOUNT_PATH,
368 TP_PROP_CHANNEL_REQUEST_USER_ACTION_TIME, G_TYPE_INT64, (gint64) 12345,
369 TP_PROP_CHANNEL_REQUEST_PREFERRED_HANDLER, G_TYPE_STRING, "Badger",
370 TP_PROP_CHANNEL_REQUEST_HINTS, TP_HASH_TYPE_STRING_VARIANT_MAP, hints,
371 NULL);
372
373 ok = tp_dbus_daemon_request_name (test->private_dbus,
374 TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL);
375 g_assert (ok);
376
377 test->cr = tp_channel_request_new (test->dbus, "/whatever", props, NULL);
378 g_assert (test->cr != NULL);
379
380 g_hash_table_unref (props);
381 g_hash_table_unref (hints);
382
383 /* Account */
384 account = tp_channel_request_get_account (test->cr);
385 g_assert (TP_IS_ACCOUNT (account));
386 g_assert_cmpstr (tp_proxy_get_object_path (account), ==, ACCOUNT_PATH);
387
388 g_object_get (test->cr, "account", &account, NULL);
389 g_assert (TP_IS_ACCOUNT (account));
390 g_assert_cmpstr (tp_proxy_get_object_path (account), ==, ACCOUNT_PATH);
391 g_object_unref (account);
392
393 /* UserActionTime */
394 user_action_time = tp_channel_request_get_user_action_time (test->cr);
395 g_assert_cmpint (user_action_time, ==, 12345);
396
397 g_object_get (test->cr, "user-action-time", &user_action_time, NULL);
398 g_assert_cmpint (user_action_time, ==, 12345);
399
400 /* PreferredHandler */
401 handler = tp_channel_request_get_preferred_handler (test->cr);
402 g_assert_cmpstr (handler, ==, "Badger");
403
404 g_object_get (test->cr, "preferred-handler", &handler, NULL);
405 g_assert_cmpstr (handler, ==, "Badger");
406
407 /* Hints */
408 hints = (GHashTable *) tp_channel_request_get_hints (test->cr);
409 g_assert_cmpstr (tp_asv_get_string (hints, "test"), ==, "hi");
410
411 g_object_get (test->cr, "hints", &hints, NULL);
412 g_assert_cmpstr (tp_asv_get_string (hints, "test"), ==, "hi");
413
414 g_hash_table_unref (hints);
415
416 vardict = tp_channel_request_dup_hints (test->cr);
417 g_assert_cmpstr (tp_vardict_get_string (vardict, "test"), ==, "hi");
418 g_variant_unref (vardict);
419
420 g_object_get (test->cr,
421 "hints-vardict", &vardict,
422 NULL);
423 g_assert_cmpstr (tp_vardict_get_string (vardict, "test"), ==, "hi");
424 g_variant_unref (vardict);
425 }
426
427 int
main(int argc,char ** argv)428 main (int argc,
429 char **argv)
430 {
431 tp_tests_init (&argc, &argv);
432 g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id=");
433
434 g_test_add ("/cr/new", Test, NULL, setup, test_new, teardown);
435 g_test_add ("/cr/crash", Test, NULL, setup, test_crash, teardown);
436 g_test_add ("/cr/succeeded", Test, NULL, setup, test_succeeded, teardown);
437 g_test_add ("/cr/failed", Test, NULL, setup, test_failed, teardown);
438 g_test_add ("/cr/immutable-properties", Test, NULL, setup,
439 test_immutable_properties, teardown);
440 g_test_add ("/cr/properties", Test, NULL, setup, test_properties, teardown);
441
442 return tp_tests_run_with_bus ();
443 }
444