1 /* Tests of TpSimpleApprover
2 *
3 * Copyright © 2010 Collabora Ltd. <http://www.collabora.co.uk/>
4 *
5 * Copying and distribution of this file, with or without modification,
6 * are permitted in any medium without royalty provided the copyright
7 * notice and this notice are preserved.
8 */
9
10 #include "config.h"
11
12 #include <telepathy-glib/simple-approver.h>
13 #include <telepathy-glib/client.h>
14 #include <telepathy-glib/debug.h>
15 #include <telepathy-glib/defs.h>
16 #include <telepathy-glib/proxy-subclass.h>
17
18 #include "tests/lib/util.h"
19 #include "tests/lib/simple-account.h"
20 #include "tests/lib/simple-channel-dispatch-operation.h"
21 #include "tests/lib/simple-conn.h"
22 #include "tests/lib/textchan-null.h"
23
24 typedef struct {
25 GMainLoop *mainloop;
26 TpDBusDaemon *dbus;
27
28 /* Service side objects */
29 TpBaseClient *simple_approver;
30 TpBaseConnection *base_connection;
31 TpTestsSimpleAccount *account_service;
32 TpTestsTextChannelNull *text_chan_service;
33 TpTestsSimpleChannelDispatchOperation *cdo_service;
34
35 /* Client side objects */
36 TpClient *client;
37 TpConnection *connection;
38 TpAccount *account;
39 TpAccountManager *account_manager;
40 TpChannel *text_chan;
41
42 GError *error /* initialized where needed */;
43 } Test;
44
45 #define ACCOUNT_PATH TP_ACCOUNT_OBJECT_PATH_BASE "what/ev/er"
46 #define CDO_PATH "/whatever"
47
48 static void
setup(Test * test,gconstpointer data)49 setup (Test *test,
50 gconstpointer data)
51 {
52 gchar *chan_path;
53 TpHandle handle;
54 TpHandleRepoIface *contact_repo;
55
56 test->mainloop = g_main_loop_new (NULL, FALSE);
57 test->dbus = tp_tests_dbus_daemon_dup_or_die ();
58
59 test->error = NULL;
60
61 /* Claim AccountManager bus-name (needed as we're going to export an Account
62 * object). */
63 tp_dbus_daemon_request_name (test->dbus,
64 TP_ACCOUNT_MANAGER_BUS_NAME, FALSE, &test->error);
65 g_assert_no_error (test->error);
66
67 /* Create service-side Account object */
68 test->account_service = tp_tests_object_new_static_class (
69 TP_TESTS_TYPE_SIMPLE_ACCOUNT, NULL);
70 tp_dbus_daemon_register_object (test->dbus, ACCOUNT_PATH,
71 test->account_service);
72
73 test->account_manager = tp_account_manager_new (test->dbus);
74 g_assert (test->account_manager != NULL);
75
76 /* Create client-side Account object */
77 test->account = tp_account_manager_ensure_account (test->account_manager,
78 ACCOUNT_PATH);
79 g_assert (test->account != NULL);
80 g_object_ref (test->account);
81
82 /* Create (service and client sides) connection objects */
83 tp_tests_create_and_connect_conn (TP_TESTS_TYPE_SIMPLE_CONNECTION,
84 "me@test.com", &test->base_connection, &test->connection);
85
86 /* Create service-side text channel object */
87 chan_path = g_strdup_printf ("%s/Channel",
88 tp_proxy_get_object_path (test->connection));
89
90 contact_repo = tp_base_connection_get_handles (test->base_connection,
91 TP_HANDLE_TYPE_CONTACT);
92 g_assert (contact_repo != NULL);
93
94 handle = tp_handle_ensure (contact_repo, "bob", NULL, &test->error);
95 g_assert_no_error (test->error);
96
97 test->text_chan_service = TP_TESTS_TEXT_CHANNEL_NULL (
98 tp_tests_object_new_static_class (
99 TP_TESTS_TYPE_TEXT_CHANNEL_NULL,
100 "connection", test->base_connection,
101 "object-path", chan_path,
102 "handle", handle,
103 NULL));
104
105 /* Create client-side text channel object */
106 test->text_chan = tp_channel_new (test->connection, chan_path, NULL,
107 TP_HANDLE_TYPE_CONTACT, handle, &test->error);
108 g_assert_no_error (test->error);
109
110 tp_handle_unref (contact_repo, handle);
111
112 g_free (chan_path);
113
114 /* Create Service side ChannelDispatchOperation object */
115 test->cdo_service = tp_tests_object_new_static_class (
116 TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION,
117 NULL);
118 tp_dbus_daemon_register_object (test->dbus, CDO_PATH, test->cdo_service);
119
120 tp_tests_simple_channel_dispatch_operation_set_conn_path (test->cdo_service,
121 tp_proxy_get_object_path (test->connection));
122
123 tp_tests_simple_channel_dispatch_operation_set_account_path (
124 test->cdo_service, tp_proxy_get_object_path (test->account));
125
126 tp_tests_simple_channel_dispatch_operation_add_channel (test->cdo_service,
127 test->text_chan);
128
129 g_assert (tp_dbus_daemon_request_name (test->dbus,
130 TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL));
131 }
132
133 static void
teardown(Test * test,gconstpointer data)134 teardown (Test *test,
135 gconstpointer data)
136 {
137 g_clear_error (&test->error);
138
139 tp_dbus_daemon_release_name (test->dbus, TP_CHANNEL_DISPATCHER_BUS_NAME,
140 NULL);
141
142 g_object_unref (test->simple_approver);
143 g_object_unref (test->client);
144
145 tp_dbus_daemon_unregister_object (test->dbus, test->account_service);
146 g_object_unref (test->account_service);
147
148 tp_dbus_daemon_release_name (test->dbus, TP_ACCOUNT_MANAGER_BUS_NAME,
149 &test->error);
150 g_assert_no_error (test->error);
151
152 g_object_unref (test->dbus);
153 test->dbus = NULL;
154 g_main_loop_unref (test->mainloop);
155 test->mainloop = NULL;
156
157 g_object_unref (test->account);
158
159 g_object_unref (test->text_chan_service);
160 g_object_unref (test->text_chan);
161
162 g_object_unref (test->cdo_service);
163
164 tp_tests_connection_assert_disconnect_succeeds (test->connection);
165 g_object_unref (test->connection);
166 g_object_unref (test->base_connection);
167 }
168
169 static void
create_simple_approver(Test * test,TpSimpleApproverAddDispatchOperationImpl impl)170 create_simple_approver (Test *test,
171 TpSimpleApproverAddDispatchOperationImpl impl)
172 {
173 /* Create service-side Client object */
174 test->simple_approver = tp_simple_approver_new_with_am (
175 test->account_manager, "MySimpleApprover", FALSE, impl, test, NULL);
176 g_assert (test->simple_approver != NULL);
177
178 /* Create client-side Client object */
179 test->client = tp_tests_object_new_static_class (TP_TYPE_CLIENT,
180 "dbus-daemon", test->dbus,
181 "bus-name", tp_base_client_get_bus_name (test->simple_approver),
182 "object-path", tp_base_client_get_object_path (test->simple_approver),
183 NULL);
184
185 g_assert (test->client != NULL);
186 }
187
188 static void
get_client_prop_cb(TpProxy * proxy,GHashTable * properties,const GError * error,gpointer user_data,GObject * weak_object)189 get_client_prop_cb (TpProxy *proxy,
190 GHashTable *properties,
191 const GError *error,
192 gpointer user_data,
193 GObject *weak_object)
194 {
195 Test *test = user_data;
196 const gchar * const *interfaces;
197
198 if (error != NULL)
199 {
200 test->error = g_error_copy (error);
201 goto out;
202 }
203
204 g_assert_cmpint (g_hash_table_size (properties), == , 1);
205
206 interfaces = tp_asv_get_strv (properties, "Interfaces");
207 g_assert_cmpint (g_strv_length ((GStrv) interfaces), ==, 1);
208 g_assert (tp_strv_contains (interfaces, TP_IFACE_CLIENT_APPROVER));
209
210 out:
211 g_main_loop_quit (test->mainloop);
212 }
213
214 static void
check_filters(GPtrArray * filters)215 check_filters (GPtrArray *filters)
216 {
217 GHashTable *filter;
218
219 g_assert (filters != NULL);
220 g_assert_cmpuint (filters->len, ==, 2);
221
222 filter = g_ptr_array_index (filters, 0);
223 g_assert_cmpuint (g_hash_table_size (filter), ==, 1);
224 g_assert_cmpstr (tp_asv_get_string (filter, TP_PROP_CHANNEL_CHANNEL_TYPE), ==,
225 TP_IFACE_CHANNEL_TYPE_TEXT);
226
227 filter = g_ptr_array_index (filters, 1);
228 g_assert_cmpuint (g_hash_table_size (filter), ==, 2);
229 g_assert_cmpstr (tp_asv_get_string (filter, TP_PROP_CHANNEL_CHANNEL_TYPE), ==,
230 TP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
231 g_assert_cmpuint (tp_asv_get_uint32 (filter,
232 TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL), ==, TP_HANDLE_TYPE_CONTACT);
233 }
234
235 static void
get_approver_prop_cb(TpProxy * proxy,GHashTable * properties,const GError * error,gpointer user_data,GObject * weak_object)236 get_approver_prop_cb (TpProxy *proxy,
237 GHashTable *properties,
238 const GError *error,
239 gpointer user_data,
240 GObject *weak_object)
241 {
242 Test *test = user_data;
243 GPtrArray *filters;
244
245 if (error != NULL)
246 {
247 test->error = g_error_copy (error);
248 goto out;
249 }
250
251 g_assert_cmpint (g_hash_table_size (properties), == , 1);
252
253 filters = tp_asv_get_boxed (properties, "ApproverChannelFilter",
254 TP_ARRAY_TYPE_CHANNEL_CLASS_LIST);
255 check_filters (filters);
256
257 out:
258 g_main_loop_quit (test->mainloop);
259 }
260
261 static void
add_dispatch_success(TpSimpleApprover * approver,TpAccount * account,TpConnection * connection,GList * channels,TpChannelDispatchOperation * dispatch_operation,TpAddDispatchOperationContext * context,gpointer user_data)262 add_dispatch_success (
263 TpSimpleApprover *approver,
264 TpAccount *account,
265 TpConnection *connection,
266 GList *channels,
267 TpChannelDispatchOperation *dispatch_operation,
268 TpAddDispatchOperationContext *context,
269 gpointer user_data)
270 {
271 tp_add_dispatch_operation_context_accept (context);
272 }
273
274 static void
test_properties(Test * test,gconstpointer data G_GNUC_UNUSED)275 test_properties (Test *test,
276 gconstpointer data G_GNUC_UNUSED)
277 {
278 create_simple_approver (test, add_dispatch_success);
279
280 tp_base_client_add_approver_filter_vardict (test->simple_approver,
281 g_variant_new_parsed ("{ %s: <%s> }",
282 TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_TEXT));
283
284 tp_base_client_add_approver_filter_vardict (test->simple_approver,
285 g_variant_new_parsed ("{ %s: <%s>, %s: <%u> }",
286 TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
287 TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, (guint32) TP_HANDLE_TYPE_CONTACT));
288
289 tp_base_client_register (test->simple_approver, &test->error);
290 g_assert_no_error (test->error);
291
292 /* Check Client properties */
293 tp_cli_dbus_properties_call_get_all (test->client, -1,
294 TP_IFACE_CLIENT, get_client_prop_cb, test, NULL, NULL);
295
296 g_main_loop_run (test->mainloop);
297 g_assert_no_error (test->error);
298
299 /* Check Approver properties */
300 tp_cli_dbus_properties_call_get_all (test->client, -1,
301 TP_IFACE_CLIENT_APPROVER, get_approver_prop_cb, test, NULL, NULL);
302
303 g_main_loop_run (test->mainloop);
304 g_assert_no_error (test->error);
305 }
306
307 static void
no_return_cb(TpClient * proxy,const GError * error,gpointer user_data,GObject * weak_object)308 no_return_cb (TpClient *proxy,
309 const GError *error,
310 gpointer user_data,
311 GObject *weak_object)
312 {
313 Test *test = user_data;
314
315 g_clear_error (&test->error);
316
317 if (error != NULL)
318 {
319 test->error = g_error_copy (error);
320 goto out;
321 }
322
323 out:
324 g_main_loop_quit (test->mainloop);
325 }
326
327 static void
add_channel_to_ptr_array(GPtrArray * arr,TpChannel * channel)328 add_channel_to_ptr_array (GPtrArray *arr,
329 TpChannel *channel)
330 {
331 GValueArray *tmp;
332
333 g_assert (arr != NULL);
334 g_assert (channel != NULL);
335
336 tmp = tp_value_array_build (2,
337 DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (channel),
338 TP_HASH_TYPE_STRING_VARIANT_MAP, tp_channel_borrow_immutable_properties (
339 channel),
340 G_TYPE_INVALID);
341
342 g_ptr_array_add (arr, tmp);
343 }
344
345 static void
free_channel_details(gpointer data,gpointer user_data)346 free_channel_details (gpointer data,
347 gpointer user_data)
348 {
349 g_boxed_free (TP_STRUCT_TYPE_CHANNEL_DETAILS, data);
350 }
351
352 static void
call_add_dispatch(Test * test)353 call_add_dispatch (Test *test)
354 {
355 GPtrArray *channels;
356 GHashTable *properties;
357 static const char *interfaces[] = { NULL };
358 static const gchar *possible_handlers[] = {
359 TP_CLIENT_BUS_NAME_BASE ".Badger", NULL, };
360
361 channels = g_ptr_array_sized_new (1);
362 add_channel_to_ptr_array (channels, test->text_chan);
363
364 properties = tp_asv_new (
365 TP_PROP_CHANNEL_DISPATCH_OPERATION_INTERFACES,
366 G_TYPE_STRV, interfaces,
367 TP_PROP_CHANNEL_DISPATCH_OPERATION_CONNECTION,
368 DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (test->connection),
369 TP_PROP_CHANNEL_DISPATCH_OPERATION_ACCOUNT,
370 DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (test->account),
371 TP_PROP_CHANNEL_DISPATCH_OPERATION_POSSIBLE_HANDLERS,
372 G_TYPE_STRV, possible_handlers,
373 NULL);
374
375 tp_proxy_add_interface_by_id (TP_PROXY (test->client),
376 TP_IFACE_QUARK_CLIENT_APPROVER);
377
378 tp_cli_client_approver_call_add_dispatch_operation (test->client, -1,
379 channels, CDO_PATH, properties, no_return_cb, test, NULL, NULL);
380
381 g_main_loop_run (test->mainloop);
382
383 g_ptr_array_foreach (channels, free_channel_details, NULL);
384 g_ptr_array_unref (channels);
385 g_hash_table_unref (properties);
386 }
387
388 /* AddDispatchOperation returns immediately */
389 static void
test_success(Test * test,gconstpointer data G_GNUC_UNUSED)390 test_success (Test *test,
391 gconstpointer data G_GNUC_UNUSED)
392 {
393 create_simple_approver (test, add_dispatch_success);
394
395 tp_base_client_add_approver_filter_vardict (test->simple_approver,
396 g_variant_new_parsed ("@a{sv} {}"));
397
398 tp_base_client_register (test->simple_approver, &test->error);
399 g_assert_no_error (test->error);
400
401 call_add_dispatch (test);
402 g_assert_no_error (test->error);
403 }
404
405 /* AddDispatchOperation returns in an async way */
406 static gboolean
accept_idle_cb(gpointer data)407 accept_idle_cb (gpointer data)
408 {
409 TpAddDispatchOperationContext *context = data;
410
411 tp_add_dispatch_operation_context_accept (context);
412 g_object_unref (context);
413 return FALSE;
414 }
415
416 static void
add_dispatch_async(TpSimpleApprover * approver,TpAccount * account,TpConnection * connection,GList * channels,TpChannelDispatchOperation * dispatch_operation,TpAddDispatchOperationContext * context,gpointer user_data)417 add_dispatch_async (
418 TpSimpleApprover *approver,
419 TpAccount *account,
420 TpConnection *connection,
421 GList *channels,
422 TpChannelDispatchOperation *dispatch_operation,
423 TpAddDispatchOperationContext *context,
424 gpointer user_data)
425 {
426 Test *test = user_data;
427
428 g_idle_add (accept_idle_cb, g_object_ref (context));
429
430 g_assert (account == test->account);
431
432 tp_add_dispatch_operation_context_delay (context);
433 }
434
435 static void
test_delayed(Test * test,gconstpointer data G_GNUC_UNUSED)436 test_delayed (Test *test,
437 gconstpointer data G_GNUC_UNUSED)
438 {
439 create_simple_approver (test, add_dispatch_async);
440
441 tp_base_client_add_approver_filter_vardict (test->simple_approver,
442 g_variant_new_parsed ("@a{sv} {}"));
443
444 tp_base_client_register (test->simple_approver, &test->error);
445 g_assert_no_error (test->error);
446
447 call_add_dispatch (test);
448 g_assert_no_error (test->error);
449 }
450
451 /* AddDispatchOperation fails */
452 static void
add_dispatch_fail(TpSimpleApprover * approver,TpAccount * account,TpConnection * connection,GList * channels,TpChannelDispatchOperation * dispatch_operation,TpAddDispatchOperationContext * context,gpointer user_data)453 add_dispatch_fail (
454 TpSimpleApprover *approver,
455 TpAccount *account,
456 TpConnection *connection,
457 GList *channels,
458 TpChannelDispatchOperation *dispatch_operation,
459 TpAddDispatchOperationContext *context,
460 gpointer user_data)
461 {
462 GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE,
463 "No AddDispatchOperation for you!" };
464
465 tp_add_dispatch_operation_context_fail (context, &error);
466 }
467
468 static void
test_fail(Test * test,gconstpointer data G_GNUC_UNUSED)469 test_fail (Test *test,
470 gconstpointer data G_GNUC_UNUSED)
471 {
472 create_simple_approver (test, add_dispatch_fail);
473
474 tp_base_client_add_approver_filter_vardict (test->simple_approver,
475 g_variant_new_parsed ("@a{sv} {}"));
476
477 tp_base_client_register (test->simple_approver, &test->error);
478 g_assert_no_error (test->error);
479
480 call_add_dispatch (test);
481 g_assert_error (test->error, TP_ERROR, TP_ERROR_NOT_AVAILABLE);
482 }
483
484 int
main(int argc,char ** argv)485 main (int argc,
486 char **argv)
487 {
488 tp_tests_init (&argc, &argv);
489 g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id=");
490
491 g_test_add ("/simple-/properties", Test, NULL, setup, test_properties,
492 teardown);
493 g_test_add ("/simple-approver/success", Test, NULL, setup, test_success,
494 teardown);
495 g_test_add ("/simple-approver/delayed", Test, NULL, setup, test_delayed,
496 teardown);
497 g_test_add ("/simple-approver/fail", Test, NULL, setup, test_fail,
498 teardown);
499
500 return tp_tests_run_with_bus ();
501 }
502