1 /* Tests of TpAccount channel request API
2  *
3  * Copyright © 2010 Collabora Ltd.
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/telepathy-glib.h>
13 
14 #include <telepathy-glib/account-channel-request-internal.h>
15 #include <telepathy-glib/client.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/contacts-conn.h"
21 #include "tests/lib/textchan-null.h"
22 #include "tests/lib/simple-channel-dispatcher.h"
23 #include "tests/lib/simple-channel-request.h"
24 
25 typedef struct {
26     GMainLoop *mainloop;
27     TpDBusDaemon *dbus;
28 
29     /* Service side objects */
30     TpBaseConnection *base_connection;
31     TpTestsSimpleAccount *account_service;
32     TpTestsSimpleChannelDispatcher *cd_service;
33 
34     /* Client side objects */
35     TpConnection *connection;
36     TpAccount *account;
37     TpChannel *channel;
38 
39     GCancellable *cancellable;
40 
41     gint count;
42 
43     GError *error /* initialized where needed */;
44 } Test;
45 
46 #define ACCOUNT_PATH TP_ACCOUNT_OBJECT_PATH_BASE "what/ev/er"
47 
48 static void
setup(Test * test,gconstpointer data)49 setup (Test *test,
50        gconstpointer data)
51 {
52   test->mainloop = g_main_loop_new (NULL, FALSE);
53   test->dbus = tp_tests_dbus_daemon_dup_or_die ();
54 
55   test->cancellable = g_cancellable_new ();
56 
57   test->error = NULL;
58 
59   /* Claim AccountManager bus-name (needed as we're going to export an Account
60    * object). */
61   tp_dbus_daemon_request_name (test->dbus,
62           TP_ACCOUNT_MANAGER_BUS_NAME, FALSE, &test->error);
63   g_assert_no_error (test->error);
64 
65   /* Create service-side Account object */
66   test->account_service = tp_tests_object_new_static_class (
67       TP_TESTS_TYPE_SIMPLE_ACCOUNT, NULL);
68   tp_dbus_daemon_register_object (test->dbus, ACCOUNT_PATH,
69       test->account_service);
70 
71   /* Claim CD bus-name */
72   tp_dbus_daemon_request_name (test->dbus,
73           TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, &test->error);
74   g_assert_no_error (test->error);
75 
76     /* Create client-side Account object */
77   test->account = tp_account_new (test->dbus, ACCOUNT_PATH, NULL);
78   g_assert (test->account != NULL);
79 
80   /* Create (service and client sides) connection objects */
81   tp_tests_create_and_connect_conn (TP_TESTS_TYPE_CONTACTS_CONNECTION,
82       "me@test.com", &test->base_connection, &test->connection);
83 
84   /* Create and register CD */
85   test->cd_service = tp_tests_object_new_static_class (
86       TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER,
87       "connection", test->base_connection,
88       NULL);
89 
90   tp_dbus_daemon_register_object (test->dbus, TP_CHANNEL_DISPATCHER_OBJECT_PATH,
91       test->cd_service);
92 }
93 
94 static void
teardown_channel_invalidated_cb(TpChannel * self,guint domain,gint code,gchar * message,Test * test)95 teardown_channel_invalidated_cb (TpChannel *self,
96   guint domain,
97   gint code,
98   gchar *message,
99   Test *test)
100 {
101   g_main_loop_quit (test->mainloop);
102 }
103 
104 static void
teardown_run_close_channel(Test * test,TpChannel * channel)105 teardown_run_close_channel (Test *test, TpChannel *channel)
106 {
107   if (channel != NULL && tp_proxy_get_invalidated (channel) == NULL)
108     {
109       g_signal_connect (channel, "invalidated",
110           G_CALLBACK (teardown_channel_invalidated_cb), test);
111       tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL);
112       g_main_loop_run (test->mainloop);
113     }
114 }
115 
116 static void
teardown(Test * test,gconstpointer data)117 teardown (Test *test,
118           gconstpointer data)
119 {
120   teardown_run_close_channel (test, test->channel);
121 
122   g_clear_error (&test->error);
123 
124   tp_dbus_daemon_unregister_object (test->dbus, test->account_service);
125   g_object_unref (test->account_service);
126 
127   tp_dbus_daemon_release_name (test->dbus, TP_ACCOUNT_MANAGER_BUS_NAME,
128       &test->error);
129   g_assert_no_error (test->error);
130 
131   tp_dbus_daemon_release_name (test->dbus, TP_CHANNEL_DISPATCHER_BUS_NAME,
132       &test->error);
133   g_assert_no_error (test->error);
134 
135   tp_clear_object (&test->cd_service);
136 
137   tp_clear_object (&test->dbus);
138 
139   g_main_loop_unref (test->mainloop);
140   test->mainloop = NULL;
141 
142   tp_clear_object (&test->account);
143 
144   tp_clear_object (&test->channel);
145 
146   tp_tests_connection_assert_disconnect_succeeds (test->connection);
147   tp_clear_object (&test->connection);
148   tp_clear_object (&test->base_connection);
149 
150   tp_clear_object (&test->cancellable);
151 }
152 
153 /* Request and handle tests */
154 
155 static void
create_and_handle_cb(GObject * source,GAsyncResult * result,gpointer user_data)156 create_and_handle_cb (GObject *source,
157     GAsyncResult *result,
158     gpointer user_data)
159 
160 {
161   Test *test = user_data;
162   TpHandleChannelsContext *context = NULL;
163   TpChannel *channel;
164 
165   channel = tp_account_channel_request_create_and_handle_channel_finish (
166       TP_ACCOUNT_CHANNEL_REQUEST (source), result, &context, &test->error);
167   if (channel == NULL)
168     goto out;
169 
170   g_assert (TP_IS_CHANNEL (channel));
171   g_assert (test->channel == NULL || test->channel == channel);
172   test->channel = channel;
173 
174   g_assert (TP_IS_HANDLE_CHANNELS_CONTEXT (context));
175   g_object_unref (context);
176 
177 out:
178   g_main_loop_quit (test->mainloop);
179 }
180 
181 static GHashTable *
create_request(void)182 create_request (void)
183 {
184   return tp_asv_new (
185       TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
186       TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
187         TP_HANDLE_TYPE_CONTACT,
188       TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, "alice",
189       NULL);
190 }
191 
192 static GVariant *
floating_request(void)193 floating_request (void)
194 {
195   return g_variant_new_parsed (
196       "{ %s: <%s>, %s: <%u>, %s: <%s> }",
197       TP_PROP_CHANNEL_CHANNEL_TYPE, TP_IFACE_CHANNEL_TYPE_TEXT,
198       TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, (guint32) TP_HANDLE_TYPE_CONTACT,
199       TP_PROP_CHANNEL_TARGET_ID, "alice");
200 }
201 
202 static void
test_handle_create_success(Test * test,gconstpointer data G_GNUC_UNUSED)203 test_handle_create_success (Test *test,
204     gconstpointer data G_GNUC_UNUSED)
205 {
206   TpAccountChannelRequest *req;
207   TpChannelRequest *chan_req;
208 
209   req = tp_account_channel_request_new_text (test->account, 0);
210   tp_account_channel_request_set_target_id (req, TP_HANDLE_TYPE_CONTACT,
211       "alice");
212 
213   tp_account_channel_request_set_sms_channel (req, TRUE);
214 
215   /* We didn't start requesting the channel yet, so there is no
216    * ChannelRequest */
217   chan_req = tp_account_channel_request_get_channel_request (req);
218   g_assert (chan_req == NULL);
219 
220   tp_account_channel_request_create_and_handle_channel_async (req,
221       NULL, create_and_handle_cb, test);
222 
223   g_object_unref (req);
224 
225   g_main_loop_run (test->mainloop);
226   g_assert_no_error (test->error);
227 
228   /* The ChannelRequest has been defined */
229   g_object_get (req, "channel-request", &chan_req, NULL);
230   g_assert (TP_IS_CHANNEL_REQUEST (chan_req));
231   g_assert (tp_account_channel_request_get_channel_request (req) == chan_req);
232   g_object_unref (chan_req);
233 
234   /* The request had the properties we wanted */
235   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
236         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_TEXT);
237   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
238         TP_PROP_CHANNEL_TARGET_ID), ==, "alice");
239   g_assert_cmpuint (tp_asv_get_uint32 (test->cd_service->last_request,
240         TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL), ==, TP_HANDLE_TYPE_CONTACT);
241   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 4);
242   g_assert (tp_asv_get_boolean (test->cd_service->last_request,
243         TP_PROP_CHANNEL_INTERFACE_SMS_SMS_CHANNEL, NULL));
244 }
245 
246 /* ChannelDispatcher.CreateChannel() call fails */
247 static void
test_handle_create_fail(Test * test,gconstpointer data G_GNUC_UNUSED)248 test_handle_create_fail (Test *test,
249     gconstpointer data G_GNUC_UNUSED)
250 {
251   TpAccountChannelRequest *req;
252 
253   req = tp_account_channel_request_new_audio_call (test->account, 666);
254   tp_account_channel_request_set_target_id (req, TP_HANDLE_TYPE_CONTACT,
255       "alice");
256   tp_account_channel_request_set_request_property (req, "com.example.Int",
257       g_variant_new_int32 (17));
258   tp_account_channel_request_set_request_property (req, "com.example.String",
259       g_variant_new_string ("ferret"));
260   /* Ask the CD to fail */
261   tp_account_channel_request_set_request_property (req, "CreateChannelFail",
262       g_variant_new_boolean (TRUE));
263 
264   tp_account_channel_request_create_and_handle_channel_async (req,
265       NULL, create_and_handle_cb, test);
266 
267   g_object_unref (req);
268 
269   g_main_loop_run (test->mainloop);
270   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
271   g_assert (test->channel == NULL);
272 
273   /* The request had the properties we wanted */
274   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
275         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_CALL);
276   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
277         TP_PROP_CHANNEL_TARGET_ID), ==, "alice");
278   g_assert_cmpuint (tp_asv_get_uint32 (test->cd_service->last_request,
279         TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL), ==, TP_HANDLE_TYPE_CONTACT);
280   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
281         TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, NULL), ==, TRUE);
282   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
283         "com.example.String"), ==, "ferret");
284   g_assert_cmpuint (tp_asv_get_int32 (test->cd_service->last_request,
285         "com.example.Int", NULL), ==, 17);
286   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
287         "CreateChannelFail", NULL), ==, TRUE);
288   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 7);
289   g_assert_cmpuint (test->cd_service->last_user_action_time, ==, 666);
290 }
291 
292 /* ChannelRequest.Proceed() call fails */
293 static void
test_handle_proceed_fail(Test * test,gconstpointer data G_GNUC_UNUSED)294 test_handle_proceed_fail (Test *test,
295     gconstpointer data G_GNUC_UNUSED)
296 {
297   TpAccountChannelRequest *req;
298 
299   req = tp_account_channel_request_new_audio_video_call (test->account, 0);
300   /* Ask the CD to fail */
301   tp_account_channel_request_set_request_property (req, "ProceedFail",
302       g_variant_new_boolean (TRUE));
303 
304   tp_account_channel_request_create_and_handle_channel_async (req,
305       NULL, create_and_handle_cb, test);
306 
307   g_object_unref (req);
308 
309   g_main_loop_run (test->mainloop);
310   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
311   g_assert (test->channel == NULL);
312 
313   /* The request had the properties we wanted */
314   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
315         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_CALL);
316   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
317         TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, NULL), ==, TRUE);
318   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
319         TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO, NULL), ==, TRUE);
320   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
321         "ProceedFail", NULL), ==, TRUE);
322   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 5);
323 }
324 
325 /* ChannelRequest fire the 'Failed' signal */
326 static void
test_handle_cr_failed(Test * test,gconstpointer data G_GNUC_UNUSED)327 test_handle_cr_failed (Test *test,
328     gconstpointer data G_GNUC_UNUSED)
329 {
330   TpAccountChannelRequest *req;
331 
332   req = tp_account_channel_request_new_file_transfer (test->account,
333       "warez.rar", "application/x-rar", G_GUINT64_CONSTANT (1234567890123), 0);
334 
335   /* Ask to the CR to fire the signal */
336   tp_account_channel_request_set_request_property (req, "FireFailed",
337       g_variant_new_boolean (TRUE));
338 
339   tp_account_channel_request_create_and_handle_channel_async (req,
340       NULL, create_and_handle_cb, test);
341 
342   g_object_unref (req);
343 
344   g_main_loop_run (test->mainloop);
345   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
346   g_assert (test->channel == NULL);
347 
348   /* The request had the properties we wanted */
349   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
350         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER);
351   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
352         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME), ==, "warez.rar");
353   g_assert_cmpuint (tp_asv_get_uint64 (test->cd_service->last_request,
354         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE, NULL), ==,
355       G_GUINT64_CONSTANT (1234567890123));
356   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
357         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_TYPE), ==,
358       "application/x-rar");
359   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
360         "FireFailed", NULL), ==, TRUE);
361   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 6);
362   g_assert_cmpuint (test->cd_service->last_user_action_time, ==, 0);
363 }
364 
365 static void
test_ft_props(Test * test,gconstpointer data G_GNUC_UNUSED)366 test_ft_props (Test *test,
367     gconstpointer data G_GNUC_UNUSED)
368 {
369   TpAccountChannelRequest *req;
370 
371   req = tp_account_channel_request_new_file_transfer (test->account,
372       "warez.rar", "application/x-rar", G_GUINT64_CONSTANT (1234567890123), 0);
373   tp_account_channel_request_set_file_transfer_description (req,
374       "A collection of l33t warez");
375   tp_account_channel_request_set_file_transfer_initial_offset (req,
376       1024 * 1024);
377   tp_account_channel_request_set_file_transfer_timestamp (req,
378       1111222233);
379   tp_account_channel_request_set_file_transfer_uri (req,
380       "file:///home/Downloads/warez.rar");
381   tp_account_channel_request_set_file_transfer_hash (req,
382       TP_FILE_HASH_TYPE_SHA256, "This is not a hash");
383 
384   /* Ask to the CR to fire the signal */
385   tp_account_channel_request_set_request_property (req, "FireFailed",
386       g_variant_new_boolean (TRUE));
387 
388   tp_account_channel_request_create_and_handle_channel_async (req,
389       NULL, create_and_handle_cb, test);
390 
391   g_object_unref (req);
392 
393   g_main_loop_run (test->mainloop);
394   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
395   g_assert (test->channel == NULL);
396 
397   /* The request had the properties we wanted */
398   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
399         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER);
400   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
401         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME), ==, "warez.rar");
402   g_assert_cmpuint (tp_asv_get_uint64 (test->cd_service->last_request,
403         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE, NULL), ==,
404       G_GUINT64_CONSTANT (1234567890123));
405   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
406         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_TYPE), ==,
407       "application/x-rar");
408   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
409         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DESCRIPTION), ==,
410       "A collection of l33t warez");
411   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
412         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_URI), ==,
413       "file:///home/Downloads/warez.rar");
414   g_assert_cmpuint (tp_asv_get_uint64 (test->cd_service->last_request,
415         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_INITIAL_OFFSET, NULL), ==,
416       1024 * 1024);
417   g_assert_cmpuint (tp_asv_get_uint64 (test->cd_service->last_request,
418         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DATE, NULL), ==,
419       1111222233);
420   g_assert_cmpuint (tp_asv_get_uint32 (test->cd_service->last_request,
421         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH_TYPE, NULL), ==,
422       TP_FILE_HASH_TYPE_SHA256);
423   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
424         TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH), ==,
425       "This is not a hash");
426   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
427         "FireFailed", NULL), ==, TRUE);
428   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 12);
429   g_assert_cmpuint (test->cd_service->last_user_action_time, ==, 0);
430 }
431 
432 static void
test_stream_tube_props(Test * test,gconstpointer data G_GNUC_UNUSED)433 test_stream_tube_props (Test *test,
434     gconstpointer data G_GNUC_UNUSED)
435 {
436   TpAccountChannelRequest *req;
437 
438   req = tp_account_channel_request_new_stream_tube (test->account, "daap",
439       0);
440 
441   /* Ask to the CR to fire the signal */
442   tp_account_channel_request_set_request_property (req, "FireFailed",
443       g_variant_new_boolean (TRUE));
444 
445   tp_account_channel_request_create_and_handle_channel_async (req,
446       NULL, create_and_handle_cb, test);
447 
448   g_object_unref (req);
449 
450   g_main_loop_run (test->mainloop);
451   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
452   g_assert (test->channel == NULL);
453 
454   /* The request had the properties we wanted */
455   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
456         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
457   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
458         TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE), ==, "daap");
459   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
460         "FireFailed", NULL), ==, TRUE);
461   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 4);
462   g_assert_cmpuint (test->cd_service->last_user_action_time, ==, 0);
463 }
464 
465 static void
test_dbus_tube_props(Test * test,gconstpointer data G_GNUC_UNUSED)466 test_dbus_tube_props (Test *test,
467     gconstpointer data G_GNUC_UNUSED)
468 {
469   TpAccountChannelRequest *req;
470 
471   req = tp_account_channel_request_new_dbus_tube (test->account,
472       "com.example.ServiceName", 0);
473 
474   /* Ask to the CR to fire the signal */
475   tp_account_channel_request_set_request_property (req, "FireFailed",
476       g_variant_new_boolean (TRUE));
477 
478   tp_account_channel_request_create_and_handle_channel_async (req,
479       NULL, create_and_handle_cb, test);
480 
481   g_object_unref (req);
482 
483   g_main_loop_run (test->mainloop);
484   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
485   g_assert (test->channel == NULL);
486 
487   /* The request had the properties we wanted */
488   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
489         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE);
490   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
491         TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME), ==,
492       "com.example.ServiceName");
493   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
494         "FireFailed", NULL), ==, TRUE);
495   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 4);
496   g_assert_cmpuint (test->cd_service->last_user_action_time, ==, 0);
497 }
498 
499 static void
ensure_and_handle_cb(GObject * source,GAsyncResult * result,gpointer user_data)500 ensure_and_handle_cb (GObject *source,
501     GAsyncResult *result,
502     gpointer user_data)
503 
504 {
505   Test *test = user_data;
506   TpChannel *channel;
507 
508   channel = tp_account_channel_request_ensure_and_handle_channel_finish (
509       TP_ACCOUNT_CHANNEL_REQUEST (source), result, NULL, &test->error);
510   if (channel == NULL)
511     goto out;
512 
513   g_assert (TP_IS_CHANNEL (channel));
514   g_assert (test->channel == NULL || test->channel == channel);
515   test->channel = channel;
516 
517 out:
518   test->count--;
519   if (test->count <= 0)
520     g_main_loop_quit (test->mainloop);
521 }
522 
523 static void
test_handle_ensure_success(Test * test,gconstpointer data G_GNUC_UNUSED)524 test_handle_ensure_success (Test *test,
525     gconstpointer data G_GNUC_UNUSED)
526 {
527   TpAccountChannelRequest *req;
528   TpContact *alice;
529   GHashTable *asv;
530   GVariant *vardict;
531 
532   alice = tp_tests_connection_run_until_contact_by_id (test->connection,
533       "alice", 0, NULL);
534 
535   req = tp_account_channel_request_new_text (test->account, 0);
536   tp_account_channel_request_set_target_contact (req, alice);
537 
538   asv = (GHashTable *) tp_account_channel_request_get_request (req);
539   vardict = tp_account_channel_request_dup_request (req);
540   g_assert_cmpstr (tp_asv_get_string (asv,
541       TP_PROP_CHANNEL_TARGET_ID), ==, "alice");
542   g_assert_cmpstr (tp_vardict_get_string (vardict,
543       TP_PROP_CHANNEL_TARGET_ID), ==, "alice");
544   g_variant_unref (vardict);
545 
546   g_object_get (req,
547       "request", &asv,
548       "request-vardict", &vardict,
549       NULL);
550   g_assert_cmpstr (tp_asv_get_string (asv,
551       TP_PROP_CHANNEL_TARGET_ID), ==, "alice");
552   g_assert_cmpstr (tp_vardict_get_string (vardict,
553       TP_PROP_CHANNEL_TARGET_ID), ==, "alice");
554   g_hash_table_unref (asv);
555   g_variant_unref (vardict);
556 
557   tp_account_channel_request_ensure_and_handle_channel_async (req,
558       NULL, ensure_and_handle_cb, test);
559 
560   g_object_unref (req);
561 
562   g_main_loop_run (test->mainloop);
563   g_assert_no_error (test->error);
564 
565   /* Try again, now it will fail as the channel already exist */
566   req = tp_account_channel_request_new_text (test->account, 0);
567   tp_account_channel_request_set_target_contact (req, alice);
568 
569   tp_account_channel_request_ensure_and_handle_channel_async (req,
570       NULL, ensure_and_handle_cb, test);
571 
572   g_object_unref (req);
573 
574   g_main_loop_run (test->mainloop);
575   g_assert_error (test->error, TP_ERROR, TP_ERROR_NOT_YOURS);
576 
577   g_object_unref (alice);
578 
579   /* The request had the properties we wanted */
580   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
581         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_TEXT);
582   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
583         TP_PROP_CHANNEL_TARGET_ID), ==, "alice");
584   g_assert_cmpuint (tp_asv_get_uint32 (test->cd_service->last_request,
585         TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL), ==, TP_HANDLE_TYPE_CONTACT);
586   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 3);
587 }
588 
589 /* Cancel the operation before starting it */
590 static void
test_handle_cancel_before(Test * test,gconstpointer data G_GNUC_UNUSED)591 test_handle_cancel_before (Test *test,
592     gconstpointer data G_GNUC_UNUSED)
593 {
594   TpAccountChannelRequest *req;
595 
596   req = tp_account_channel_request_new_vardict (test->account,
597       floating_request (), 0);
598 
599   g_cancellable_cancel (test->cancellable);
600 
601   tp_account_channel_request_ensure_and_handle_channel_async (req,
602       test->cancellable, create_and_handle_cb, test);
603 
604   g_object_unref (req);
605 
606   g_main_loop_run (test->mainloop);
607   g_assert_error (test->error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
608 }
609 
610 /* Cancel the operation after the channel request has been created */
611 static void
channel_request_created_cb(TpTestsSimpleChannelDispatcher * dispatcher,TpTestsSimpleChannelRequest * request,Test * test)612 channel_request_created_cb (TpTestsSimpleChannelDispatcher *dispatcher,
613     TpTestsSimpleChannelRequest *request,
614     Test *test)
615 {
616   g_cancellable_cancel (test->cancellable);
617 }
618 
619 static void
test_handle_cancel_after_create(Test * test,gconstpointer data G_GNUC_UNUSED)620 test_handle_cancel_after_create (Test *test,
621     gconstpointer data G_GNUC_UNUSED)
622 {
623   TpAccountChannelRequest *req;
624 
625   req = tp_account_channel_request_new_vardict (test->account,
626       floating_request (), 0);
627 
628   tp_account_channel_request_ensure_and_handle_channel_async (req,
629       test->cancellable, create_and_handle_cb, test);
630 
631   g_signal_connect (test->cd_service, "channel-request-created",
632       G_CALLBACK (channel_request_created_cb), test);
633 
634   g_object_unref (req);
635 
636   g_main_loop_run (test->mainloop);
637   g_assert_error (test->error, TP_ERROR, TP_ERROR_CANCELLED);
638 }
639 
640 /* Test if re-handled is properly fired when a channel is
641  * re-handled */
642 static void
re_handled_cb(TpAccountChannelRequest * req,TpChannel * channel,gint64 timestamp,TpHandleChannelsContext * context,Test * test)643 re_handled_cb (TpAccountChannelRequest *req,
644     TpChannel *channel,
645     gint64 timestamp,
646     TpHandleChannelsContext *context,
647     Test *test)
648 {
649   g_assert (TP_IS_CHANNEL (channel));
650   g_assert_cmpint (timestamp, ==, 666);
651   g_assert (TP_IS_HANDLE_CHANNELS_CONTEXT (context));
652 
653   test->count--;
654   if (test->count <= 0)
655     g_main_loop_quit (test->mainloop);
656 }
657 
658 static void
test_handle_re_handle(Test * test,gconstpointer data G_GNUC_UNUSED)659 test_handle_re_handle (Test *test,
660     gconstpointer data G_GNUC_UNUSED)
661 {
662   TpAccountChannelRequest *req, *req2;
663 
664   req = tp_account_channel_request_new_vardict (test->account,
665       floating_request (), 0);
666 
667   tp_account_channel_request_ensure_and_handle_channel_async (req,
668       NULL, ensure_and_handle_cb, test);
669 
670   g_main_loop_run (test->mainloop);
671   g_assert_no_error (test->error);
672 
673   g_signal_connect (req, "re-handled",
674       G_CALLBACK (re_handled_cb), test);
675 
676   /* Ensure the same channel to re-handle it */
677   req2 = tp_account_channel_request_new_vardict (test->account,
678       floating_request (), 666);
679 
680   tp_account_channel_request_ensure_and_handle_channel_async (req2,
681       NULL, ensure_and_handle_cb, test);
682 
683   /* Wait that the operation finished and the sig has been fired */
684   test->count = 2;
685   g_main_loop_run (test->mainloop);
686 
687   g_object_unref (req);
688   g_object_unref (req2);
689 }
690 
691 static void
create_and_handle_hints_cb(GObject * source,GAsyncResult * result,gpointer user_data)692 create_and_handle_hints_cb (GObject *source,
693     GAsyncResult *result,
694     gpointer user_data)
695 
696 {
697   Test *test = user_data;
698   TpHandleChannelsContext *context = NULL;
699   GList *reqs;
700   const GHashTable *hints;
701   TpChannelRequest *req;
702 
703   test->channel = tp_account_channel_request_create_and_handle_channel_finish (
704       TP_ACCOUNT_CHANNEL_REQUEST (source), result, &context, &test->error);
705   if (test->channel == NULL)
706     goto out;
707 
708   g_assert (TP_IS_CHANNEL (test->channel));
709   tp_clear_object (&test->channel);
710 
711   g_assert (TP_IS_HANDLE_CHANNELS_CONTEXT (context));
712 
713   reqs = tp_handle_channels_context_get_requests (context);
714   g_assert_cmpuint (g_list_length (reqs), ==, 1);
715 
716   req = reqs->data;
717   g_assert (TP_IS_CHANNEL_REQUEST (req));
718 
719   hints = tp_channel_request_get_hints (req);
720   g_assert_cmpuint (g_hash_table_size ((GHashTable *) hints), ==, 1);
721   g_assert_cmpuint (tp_asv_get_uint32 (hints, "Badger", NULL), ==, 42);
722 
723   g_list_foreach (reqs, (GFunc) g_object_unref, NULL);
724   g_list_free (reqs);
725 
726   g_object_unref (context);
727 
728 out:
729   g_main_loop_quit (test->mainloop);
730 }
731 
732 static GHashTable *
create_hints(void)733 create_hints (void)
734 {
735   return tp_asv_new (
736       "Badger", G_TYPE_UINT, 42,
737       NULL);
738 }
739 
740 static void
test_handle_create_success_hints(Test * test,gconstpointer data G_GNUC_UNUSED)741 test_handle_create_success_hints (Test *test,
742     gconstpointer data G_GNUC_UNUSED)
743 {
744   TpAccountChannelRequest *req;
745   GHashTable *hints;
746 
747   req = tp_account_channel_request_new_vardict (test->account,
748       floating_request (), 0);
749 
750   hints = create_hints ();
751   tp_account_channel_request_set_hints (req, hints);
752   g_hash_table_unref (hints);
753 
754   tp_account_channel_request_create_and_handle_channel_async (req,
755       NULL, create_and_handle_hints_cb, test);
756 
757   g_object_unref (req);
758 
759   g_main_loop_run (test->mainloop);
760   g_assert_no_error (test->error);
761 }
762 
763 static void
channel_delegated_cb(TpAccountChannelRequest * req,TpChannel * channel,gpointer user_data)764 channel_delegated_cb (TpAccountChannelRequest *req,
765     TpChannel *channel,
766     gpointer user_data)
767 {
768   Test *test = user_data;
769 
770   g_assert (TP_IS_ACCOUNT_CHANNEL_REQUEST (req));
771 
772   g_assert (TP_IS_CHANNEL (channel));
773   g_assert_cmpstr (tp_proxy_get_object_path (channel), ==,
774       tp_proxy_get_object_path (test->channel));
775 
776   test->count--;
777   if (test->count <= 0)
778     g_main_loop_quit (test->mainloop);
779 }
780 
781 static void
add_channel_to_ptr_array(GPtrArray * arr,TpChannel * channel)782 add_channel_to_ptr_array (GPtrArray *arr,
783     TpChannel *channel)
784 {
785   GValueArray *tmp;
786 
787   g_assert (arr != NULL);
788   g_assert (channel != NULL);
789 
790   tmp = tp_value_array_build (2,
791       DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (channel),
792       TP_HASH_TYPE_STRING_VARIANT_MAP, tp_channel_borrow_immutable_properties (
793         channel),
794       G_TYPE_INVALID);
795 
796   g_ptr_array_add (arr, tmp);
797 }
798 
799 static void
no_return_cb(TpClient * proxy,const GError * error,gpointer user_data,GObject * weak_object)800 no_return_cb (TpClient *proxy,
801     const GError *error,
802     gpointer user_data,
803     GObject *weak_object)
804 {
805   Test *test = user_data;
806 
807   g_clear_error (&test->error);
808 
809   if (error != NULL)
810     {
811       test->error = g_error_copy (error);
812       goto out;
813     }
814 
815 out:
816   test->count--;
817   if (test->count == 0)
818     g_main_loop_quit (test->mainloop);
819 }
820 
821 #define PREFERRED_HANDLER_NAME TP_CLIENT_BUS_NAME_BASE ".Badger"
822 
823 static void
test_handle_delegated(Test * test,gconstpointer data G_GNUC_UNUSED)824 test_handle_delegated (Test *test,
825     gconstpointer data G_GNUC_UNUSED)
826 {
827   TpAccountChannelRequest *req;
828   GPtrArray *requests, *requests_satisified, *channels;
829   GHashTable *hints, *request_props, *info;
830   TpTestsSimpleChannelRequest *cr;
831   TpBaseClient *base_client;
832   TpClient *client;
833 
834   req = tp_account_channel_request_new_vardict (test->account,
835       floating_request (), 0);
836 
837   /* Allow other clients to preempt the channel */
838   tp_account_channel_request_set_delegated_channel_callback (req,
839       channel_delegated_cb, test, NULL);
840 
841   tp_account_channel_request_create_and_handle_channel_async (req,
842       NULL, create_and_handle_cb, test);
843 
844   g_object_unref (req);
845 
846   g_main_loop_run (test->mainloop);
847   g_assert_no_error (test->error);
848 
849   /* Another client asks to dispatch the channel to it */
850   requests = g_ptr_array_new ();
851 
852   hints = tp_asv_new (
853       "org.freedesktop.Telepathy.ChannelRequest.DelegateToPreferredHandler",
854         G_TYPE_BOOLEAN, TRUE,
855       NULL);
856 
857   cr = tp_tests_simple_channel_request_new ("/CR",
858       TP_TESTS_SIMPLE_CONNECTION (test->base_connection),
859       tp_proxy_get_object_path (test->account),
860       TP_USER_ACTION_TIME_CURRENT_TIME, PREFERRED_HANDLER_NAME,
861       requests, hints);
862 
863   requests_satisified = g_ptr_array_sized_new (1);
864   g_ptr_array_add (requests_satisified, "/CR");
865 
866   request_props = g_hash_table_new_full (g_str_hash, g_str_equal,
867       NULL, (GDestroyNotify) g_hash_table_unref);
868 
869   g_hash_table_insert (request_props, "/CR",
870       tp_tests_simple_channel_request_dup_immutable_props (cr));
871 
872   info = tp_asv_new (
873       "request-properties", TP_HASH_TYPE_OBJECT_IMMUTABLE_PROPERTIES_MAP,
874         request_props, NULL);
875 
876   channels = g_ptr_array_sized_new (1);
877   add_channel_to_ptr_array (channels, test->channel);
878 
879   base_client = _tp_account_channel_request_get_client (req);
880   g_assert (TP_IS_BASE_CLIENT (base_client));
881 
882   client = tp_tests_object_new_static_class (TP_TYPE_CLIENT,
883       "dbus-daemon", tp_base_client_get_dbus_daemon (base_client),
884       "bus-name", tp_base_client_get_bus_name (base_client),
885       "object-path",  tp_base_client_get_object_path (base_client),
886       NULL);
887 
888   tp_proxy_add_interface_by_id (TP_PROXY (client),
889       TP_IFACE_QUARK_CLIENT_HANDLER);
890 
891   tp_cli_client_handler_call_handle_channels (client, -1,
892       tp_proxy_get_object_path (test->account),
893       tp_proxy_get_object_path (test->connection),
894       channels, requests_satisified, 0, info,
895       no_return_cb, test, NULL, NULL);
896 
897   test->count = 2;
898   g_main_loop_run (test->mainloop);
899   g_assert_no_error (test->error);
900 
901   g_ptr_array_unref (requests);
902   g_hash_table_unref (hints);
903   g_object_unref (cr);
904   g_ptr_array_unref (requests_satisified);
905   g_ptr_array_unref (channels);
906   g_hash_table_unref (request_props);
907   g_hash_table_unref (info);
908   g_object_unref (client);
909 }
910 
911 /* Request and forget tests */
912 
913 static void
create_cb(GObject * source,GAsyncResult * result,gpointer user_data)914 create_cb (GObject *source,
915     GAsyncResult *result,
916     gpointer user_data)
917 
918 {
919   Test *test = user_data;
920 
921   tp_account_channel_request_create_channel_finish (
922       TP_ACCOUNT_CHANNEL_REQUEST (source), result, &test->error);
923 
924   g_main_loop_quit (test->mainloop);
925 }
926 
927 static void
test_forget_create_success(Test * test,gconstpointer data G_GNUC_UNUSED)928 test_forget_create_success (Test *test,
929     gconstpointer data G_GNUC_UNUSED)
930 {
931   TpAccountChannelRequest *req;
932 
933   req = tp_account_channel_request_new_vardict (test->account,
934       floating_request (), 0);
935 
936   tp_account_channel_request_create_channel_async (req, "Fake", NULL, create_cb,
937       test);
938 
939   g_object_unref (req);
940 
941   g_main_loop_run (test->mainloop);
942   g_assert_no_error (test->error);
943 }
944 
945 static void
ensure_cb(GObject * source,GAsyncResult * result,gpointer user_data)946 ensure_cb (GObject *source,
947     GAsyncResult *result,
948     gpointer user_data)
949 
950 {
951   Test *test = user_data;
952 
953   tp_account_channel_request_ensure_channel_finish (
954       TP_ACCOUNT_CHANNEL_REQUEST (source), result, &test->error);
955 
956   g_main_loop_quit (test->mainloop);
957 }
958 
959 static void
test_forget_ensure_success(Test * test,gconstpointer data G_GNUC_UNUSED)960 test_forget_ensure_success (Test *test,
961     gconstpointer data G_GNUC_UNUSED)
962 {
963   TpAccountChannelRequest *req;
964 
965   req = tp_account_channel_request_new_vardict (test->account,
966       floating_request (), 0);
967 
968   tp_account_channel_request_ensure_channel_async (req, "Fake", NULL, ensure_cb,
969       test);
970 
971   g_object_unref (req);
972 
973   g_main_loop_run (test->mainloop);
974   g_assert_no_error (test->error);
975 }
976 
977 /* ChannelDispatcher.CreateChannel() call fails */
978 static void
test_forget_create_fail(Test * test,gconstpointer data G_GNUC_UNUSED)979 test_forget_create_fail (Test *test,
980     gconstpointer data G_GNUC_UNUSED)
981 {
982   GHashTable *request;
983   TpAccountChannelRequest *req;
984 
985   request = create_request ();
986 
987   /* Ask to the CD to fail */
988   tp_asv_set_boolean (request, "CreateChannelFail", TRUE);
989 
990   req = tp_account_channel_request_new (test->account, request, 0);
991 
992   tp_account_channel_request_create_channel_async (req, "Fake", NULL, create_cb,
993       test);
994 
995   g_hash_table_unref (request);
996   g_object_unref (req);
997 
998   g_main_loop_run (test->mainloop);
999   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
1000   g_assert (test->channel == NULL);
1001 }
1002 
1003 /* ChannelRequest.Proceed() call fails */
1004 static void
test_forget_proceed_fail(Test * test,gconstpointer data G_GNUC_UNUSED)1005 test_forget_proceed_fail (Test *test,
1006     gconstpointer data G_GNUC_UNUSED)
1007 {
1008   GHashTable *request;
1009   TpAccountChannelRequest *req;
1010 
1011   request = create_request ();
1012 
1013   /* Ask to the CD to fail */
1014   tp_asv_set_boolean (request, "ProceedFail", TRUE);
1015 
1016   req = tp_account_channel_request_new (test->account, request, 0);
1017 
1018   tp_account_channel_request_create_channel_async (req, "Fake", NULL, create_cb,
1019       test);
1020 
1021   g_hash_table_unref (request);
1022   g_object_unref (req);
1023 
1024   g_main_loop_run (test->mainloop);
1025   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
1026   g_assert (test->channel == NULL);
1027 }
1028 
1029 /* ChannelRequest fire the 'Failed' signal */
1030 static void
test_forget_cr_failed(Test * test,gconstpointer data G_GNUC_UNUSED)1031 test_forget_cr_failed (Test *test,
1032     gconstpointer data G_GNUC_UNUSED)
1033 {
1034   GHashTable *request;
1035   TpAccountChannelRequest *req;
1036 
1037   request = create_request ();
1038 
1039   /* Ask to the CR to fire the signal */
1040   tp_asv_set_boolean (request, "FireFailed", TRUE);
1041 
1042   req = tp_account_channel_request_new (test->account, request, 0);
1043 
1044   tp_account_channel_request_create_channel_async (req, "Fake", NULL, create_cb,
1045       test);
1046 
1047   g_hash_table_unref (request);
1048   g_object_unref (req);
1049 
1050   g_main_loop_run (test->mainloop);
1051   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
1052   g_assert (test->channel == NULL);
1053 }
1054 
1055 /* Cancel the operation before starting it */
1056 static void
test_forget_cancel_before(Test * test,gconstpointer data G_GNUC_UNUSED)1057 test_forget_cancel_before (Test *test,
1058     gconstpointer data G_GNUC_UNUSED)
1059 {
1060   TpAccountChannelRequest *req;
1061 
1062   req = tp_account_channel_request_new_vardict (test->account,
1063       floating_request (), 0);
1064 
1065   g_cancellable_cancel (test->cancellable);
1066 
1067   tp_account_channel_request_create_channel_async (req, "Fake",
1068       test->cancellable, create_cb, test);
1069 
1070   g_object_unref (req);
1071 
1072   g_main_loop_run (test->mainloop);
1073   g_assert_error (test->error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1074 }
1075 
1076 static void
test_forget_cancel_after_create(Test * test,gconstpointer data G_GNUC_UNUSED)1077 test_forget_cancel_after_create (Test *test,
1078     gconstpointer data G_GNUC_UNUSED)
1079 {
1080   TpAccountChannelRequest *req;
1081 
1082   req = tp_account_channel_request_new_vardict (test->account,
1083       floating_request (), 0);
1084 
1085   tp_account_channel_request_create_channel_async (req, "Fake",
1086       test->cancellable, create_cb, test);
1087 
1088   g_signal_connect (test->cd_service, "channel-request-created",
1089       G_CALLBACK (channel_request_created_cb), test);
1090 
1091   g_object_unref (req);
1092 
1093   g_main_loop_run (test->mainloop);
1094   g_assert_error (test->error, TP_ERROR, TP_ERROR_CANCELLED);
1095 }
1096 
1097 /* Request and observe tests */
1098 static void
create_and_observe_cb(GObject * source,GAsyncResult * result,gpointer user_data)1099 create_and_observe_cb (GObject *source,
1100     GAsyncResult *result,
1101     gpointer user_data)
1102 
1103 {
1104   Test *test = user_data;
1105 
1106   test->channel = tp_account_channel_request_create_and_observe_channel_finish (
1107       TP_ACCOUNT_CHANNEL_REQUEST (source), result, &test->error);
1108   if (test->channel == NULL)
1109     goto out;
1110 
1111   g_assert (TP_IS_CHANNEL (test->channel));
1112   tp_clear_object (&test->channel);
1113 
1114 out:
1115   g_main_loop_quit (test->mainloop);
1116 }
1117 
1118 static void
test_observe_create_success(Test * test,gconstpointer data G_GNUC_UNUSED)1119 test_observe_create_success (Test *test,
1120     gconstpointer data G_GNUC_UNUSED)
1121 {
1122   TpAccountChannelRequest *req;
1123 
1124   req = tp_account_channel_request_new_vardict (test->account,
1125       floating_request (), 0);
1126 
1127   tp_account_channel_request_create_and_observe_channel_async (req, "Fake",
1128       NULL, create_and_observe_cb, test);
1129 
1130   g_object_unref (req);
1131 
1132   g_main_loop_run (test->mainloop);
1133   g_assert_no_error (test->error);
1134 }
1135 
1136 /* ChannelDispatcher.CreateChannel() call fails */
1137 static void
test_observe_create_fail(Test * test,gconstpointer data G_GNUC_UNUSED)1138 test_observe_create_fail (Test *test,
1139     gconstpointer data G_GNUC_UNUSED)
1140 {
1141   GHashTable *request;
1142   TpAccountChannelRequest *req;
1143 
1144   request = create_request ();
1145 
1146   /* Ask to the CD to fail */
1147   tp_asv_set_boolean (request, "CreateChannelFail", TRUE);
1148 
1149   req = tp_account_channel_request_new (test->account, request, 0);
1150 
1151   tp_account_channel_request_create_and_observe_channel_async (req, "Fake",
1152       NULL, create_and_observe_cb, test);
1153 
1154   g_hash_table_unref (request);
1155   g_object_unref (req);
1156 
1157   g_main_loop_run (test->mainloop);
1158   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
1159   g_assert (test->channel == NULL);
1160 }
1161 
1162 /* ChannelRequest.Proceed() call fails */
1163 static void
test_observe_proceed_fail(Test * test,gconstpointer data G_GNUC_UNUSED)1164 test_observe_proceed_fail (Test *test,
1165     gconstpointer data G_GNUC_UNUSED)
1166 {
1167   GHashTable *request;
1168   TpAccountChannelRequest *req;
1169 
1170   request = create_request ();
1171 
1172   /* Ask to the CD to fail */
1173   tp_asv_set_boolean (request, "ProceedFail", TRUE);
1174 
1175   req = tp_account_channel_request_new (test->account, request, 0);
1176 
1177   tp_account_channel_request_create_and_observe_channel_async (req, "Fake",
1178       NULL, create_and_observe_cb, test);
1179 
1180   g_hash_table_unref (request);
1181   g_object_unref (req);
1182 
1183   g_main_loop_run (test->mainloop);
1184   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
1185   g_assert (test->channel == NULL);
1186 }
1187 
1188 /* ChannelRequest fire the 'Failed' signal */
1189 static void
test_observe_cr_failed(Test * test,gconstpointer data G_GNUC_UNUSED)1190 test_observe_cr_failed (Test *test,
1191     gconstpointer data G_GNUC_UNUSED)
1192 {
1193   GHashTable *request;
1194   TpAccountChannelRequest *req;
1195 
1196   request = create_request ();
1197 
1198   /* Ask to the CR to fire the signal */
1199   tp_asv_set_boolean (request, "FireFailed", TRUE);
1200 
1201   req = tp_account_channel_request_new (test->account, request, 0);
1202 
1203   tp_account_channel_request_create_and_observe_channel_async (req, "Fake",
1204       NULL, create_and_observe_cb, test);
1205 
1206   g_hash_table_unref (request);
1207   g_object_unref (req);
1208 
1209   g_main_loop_run (test->mainloop);
1210   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
1211   g_assert (test->channel == NULL);
1212 }
1213 
1214 static void
ensure_and_observe_cb(GObject * source,GAsyncResult * result,gpointer user_data)1215 ensure_and_observe_cb (GObject *source,
1216     GAsyncResult *result,
1217     gpointer user_data)
1218 
1219 {
1220   Test *test = user_data;
1221 
1222   test->channel = tp_account_channel_request_ensure_and_observe_channel_finish (
1223       TP_ACCOUNT_CHANNEL_REQUEST (source), result, &test->error);
1224   if (test->channel == NULL)
1225     goto out;
1226 
1227   g_assert (TP_IS_CHANNEL (test->channel));
1228   tp_clear_object (&test->channel);
1229 
1230 out:
1231   g_main_loop_quit (test->mainloop);
1232 }
1233 
1234 static void
test_observe_ensure_success(Test * test,gconstpointer data G_GNUC_UNUSED)1235 test_observe_ensure_success (Test *test,
1236     gconstpointer data G_GNUC_UNUSED)
1237 {
1238   TpAccountChannelRequest *req;
1239 
1240   req = tp_account_channel_request_new_vardict (test->account,
1241       floating_request (), 0);
1242 
1243   tp_account_channel_request_ensure_and_observe_channel_async (req, "Fake",
1244       NULL, ensure_and_observe_cb, test);
1245 
1246   g_object_unref (req);
1247 
1248   g_main_loop_run (test->mainloop);
1249   g_assert_no_error (test->error);
1250 }
1251 
1252 /* Cancel the operation before starting it */
1253 static void
test_observe_cancel_before(Test * test,gconstpointer data G_GNUC_UNUSED)1254 test_observe_cancel_before (Test *test,
1255     gconstpointer data G_GNUC_UNUSED)
1256 {
1257   TpAccountChannelRequest *req;
1258 
1259   req = tp_account_channel_request_new_vardict (test->account,
1260       floating_request (), 0);
1261 
1262   g_cancellable_cancel (test->cancellable);
1263 
1264   tp_account_channel_request_create_and_observe_channel_async (req, "Fake",
1265       test->cancellable, create_and_observe_cb, test);
1266 
1267   g_object_unref (req);
1268 
1269   g_main_loop_run (test->mainloop);
1270   g_assert_error (test->error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
1271 }
1272 
1273 static void
test_observe_cancel_after_create(Test * test,gconstpointer data G_GNUC_UNUSED)1274 test_observe_cancel_after_create (Test *test,
1275     gconstpointer data G_GNUC_UNUSED)
1276 {
1277   TpAccountChannelRequest *req;
1278 
1279   req = tp_account_channel_request_new_vardict (test->account,
1280       floating_request (), 0);
1281 
1282   tp_account_channel_request_create_and_observe_channel_async (req, "Fake",
1283       test->cancellable, create_and_observe_cb, test);
1284 
1285   g_signal_connect (test->cd_service, "channel-request-created",
1286       G_CALLBACK (channel_request_created_cb), test);
1287 
1288   g_object_unref (req);
1289 
1290   g_main_loop_run (test->mainloop);
1291   g_assert_error (test->error, TP_ERROR, TP_ERROR_CANCELLED);
1292 }
1293 
1294 /* Succeeded is fired but not SucceededWithChannel */
1295 static void
test_observe_no_channel(Test * test,gconstpointer data G_GNUC_UNUSED)1296 test_observe_no_channel (Test *test,
1297     gconstpointer data G_GNUC_UNUSED)
1298 {
1299   TpAccountChannelRequest *req;
1300 
1301   req = tp_account_channel_request_new_vardict (test->account,
1302       floating_request (), 0);
1303 
1304   tp_account_channel_request_create_and_observe_channel_async (req,
1305       "FakeNoChannel", NULL, create_and_observe_cb, test);
1306 
1307   g_object_unref (req);
1308 
1309   g_main_loop_run (test->mainloop);
1310   g_assert_error (test->error, TP_ERROR, TP_ERROR_CONFUSED);
1311 }
1312 
1313 /* Check if TargetHandleType: TP_HANDLE_TYPE_NONE is automatically added if no
1314  * target has been specified by the user. */
1315 static void
test_no_handle_type(Test * test,gconstpointer data G_GNUC_UNUSED)1316 test_no_handle_type (Test *test,
1317     gconstpointer data G_GNUC_UNUSED)
1318 {
1319   TpAccountChannelRequest *req;
1320   gboolean valid;
1321   const gchar * const channels[] = { "/chan1", "/chan2", NULL };
1322   GPtrArray *chans;
1323   const gchar * const invitees[] = { "badger@badger.com",
1324       "snake@badger.com", NULL };
1325   const gchar * const *strv;
1326 
1327   req = tp_account_channel_request_new_text (test->account, 0);
1328 
1329   tp_account_channel_request_set_conference_initial_channels (req, channels);
1330 
1331   tp_account_channel_request_set_initial_invitee_ids (req, invitees);
1332 
1333   /* Ask to the CR to fire the signal */
1334   tp_account_channel_request_set_request_property (req, "FireFailed",
1335       g_variant_new_boolean (TRUE));
1336 
1337   tp_account_channel_request_create_and_handle_channel_async (req,
1338       NULL, create_and_handle_cb, test);
1339 
1340   g_object_unref (req);
1341 
1342   g_main_loop_run (test->mainloop);
1343   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
1344   g_assert (test->channel == NULL);
1345 
1346   /* The request had the properties we wanted */
1347   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
1348         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_TEXT);
1349   g_assert_cmpuint (tp_asv_get_uint32 (test->cd_service->last_request,
1350         TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid), ==, TP_HANDLE_TYPE_NONE);
1351   g_assert (valid);
1352   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
1353         "FireFailed", NULL), ==, TRUE);
1354   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 5);
1355   g_assert_cmpuint (test->cd_service->last_user_action_time, ==, 0);
1356 
1357   chans = tp_asv_get_boxed (test->cd_service->last_request,
1358       TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_CHANNELS,
1359       TP_ARRAY_TYPE_OBJECT_PATH_LIST);
1360   g_assert (chans != NULL);
1361   g_assert_cmpuint (chans->len, ==, 2);
1362   g_assert_cmpstr (g_ptr_array_index (chans, 0), ==, "/chan1");
1363   g_assert_cmpstr (g_ptr_array_index (chans, 1), ==, "/chan2");
1364 
1365   strv = tp_asv_get_boxed (test->cd_service->last_request,
1366       TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_IDS,
1367       G_TYPE_STRV);
1368   g_assert (strv != NULL);
1369   g_assert_cmpuint (g_strv_length ((GStrv) strv), ==, 2);
1370   g_assert (tp_strv_contains (strv, "badger@badger.com"));
1371   g_assert (tp_strv_contains (strv, "snake@badger.com"));
1372 }
1373 
1374 static void
test_initial_invitees(Test * test,gconstpointer data G_GNUC_UNUSED)1375 test_initial_invitees (Test *test,
1376     gconstpointer data G_GNUC_UNUSED)
1377 {
1378   TpAccountChannelRequest *req;
1379   gboolean valid;
1380   GPtrArray *invitees;
1381   TpContact *contact;
1382   const gchar * const *strv;
1383 
1384   req = tp_account_channel_request_new_text (test->account, 0);
1385 
1386   invitees = g_ptr_array_new_with_free_func (g_object_unref);
1387 
1388   contact = tp_tests_connection_run_until_contact_by_id (test->connection,
1389       "badger@badger.com", 0, NULL);
1390   g_ptr_array_add (invitees, contact);
1391   contact = tp_tests_connection_run_until_contact_by_id (test->connection,
1392       "snake@badger.com", 0, NULL);
1393   g_ptr_array_add (invitees, contact);
1394 
1395   tp_account_channel_request_set_initial_invitees (req, invitees);
1396   g_ptr_array_unref (invitees);
1397 
1398   /* Ask to the CR to fire the signal */
1399   tp_account_channel_request_set_request_property (req, "FireFailed",
1400       g_variant_new_boolean (TRUE));
1401 
1402   tp_account_channel_request_create_and_handle_channel_async (req,
1403       NULL, create_and_handle_cb, test);
1404 
1405   g_object_unref (req);
1406 
1407   g_main_loop_run (test->mainloop);
1408   g_assert_error (test->error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT);
1409   g_assert (test->channel == NULL);
1410 
1411   /* The request had the properties we wanted */
1412   g_assert_cmpstr (tp_asv_get_string (test->cd_service->last_request,
1413         TP_PROP_CHANNEL_CHANNEL_TYPE), ==, TP_IFACE_CHANNEL_TYPE_TEXT);
1414   g_assert_cmpuint (tp_asv_get_uint32 (test->cd_service->last_request,
1415         TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, &valid), ==, TP_HANDLE_TYPE_NONE);
1416   g_assert (valid);
1417   g_assert_cmpuint (tp_asv_get_boolean (test->cd_service->last_request,
1418         "FireFailed", NULL), ==, TRUE);
1419   g_assert_cmpuint (tp_asv_size (test->cd_service->last_request), ==, 4);
1420   g_assert_cmpuint (test->cd_service->last_user_action_time, ==, 0);
1421 
1422   strv = tp_asv_get_boxed (test->cd_service->last_request,
1423       TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_IDS,
1424       G_TYPE_STRV);
1425   g_assert (strv != NULL);
1426   g_assert_cmpuint (g_strv_length ((GStrv) strv), ==, 2);
1427   g_assert (tp_strv_contains (strv, "badger@badger.com"));
1428   g_assert (tp_strv_contains (strv, "snake@badger.com"));
1429 }
1430 
1431 int
main(int argc,char ** argv)1432 main (int argc,
1433       char **argv)
1434 {
1435   tp_tests_init (&argc, &argv);
1436   g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id=");
1437 
1438   /* Request and handle tests */
1439   g_test_add ("/account-channels/request-handle/create-success", Test, NULL,
1440       setup, test_handle_create_success, teardown);
1441   g_test_add ("/account-channels/request-handle/create-fail", Test, NULL,
1442       setup, test_handle_create_fail, teardown);
1443   g_test_add ("/account-channels/request-handle/proceed-fail", Test, NULL,
1444       setup, test_handle_proceed_fail, teardown);
1445   g_test_add ("/account-channels/request-handle/cr-failed", Test, NULL,
1446       setup, test_handle_cr_failed, teardown);
1447   g_test_add ("/account-channels/request-handle/ensure-success", Test, NULL,
1448       setup, test_handle_ensure_success, teardown);
1449   g_test_add ("/account-channels/request-handle/cancel-before", Test, NULL,
1450       setup, test_handle_cancel_before, teardown);
1451   g_test_add ("/account-channels/request-handle/after-create", Test, NULL,
1452       setup, test_handle_cancel_after_create, teardown);
1453   g_test_add ("/account-channels/request-handle/re-handle", Test, NULL,
1454       setup, test_handle_re_handle, teardown);
1455   g_test_add ("/account-channels/request-handle/create-success-hints", Test,
1456       NULL, setup, test_handle_create_success_hints, teardown);
1457   g_test_add ("/account-channels/request-handle/delegated", Test, NULL,
1458       setup, test_handle_delegated, teardown);
1459 
1460   /* Request and forget tests */
1461   g_test_add ("/account-channels/request-forget/create-success", Test, NULL,
1462       setup, test_forget_create_success, teardown);
1463   g_test_add ("/account-channels/request-forget/create-fail", Test, NULL,
1464       setup, test_forget_create_fail, teardown);
1465   g_test_add ("/account-channels/request-foget/proceed-fail", Test, NULL,
1466       setup, test_forget_proceed_fail, teardown);
1467   g_test_add ("/account-channels/request-forget/cr-failed", Test, NULL,
1468       setup, test_forget_cr_failed, teardown);
1469   g_test_add ("/account-channels/request-forget/ensure-success", Test, NULL,
1470       setup, test_forget_ensure_success, teardown);
1471   g_test_add ("/account-channels/request-forget/cancel-before", Test, NULL,
1472       setup, test_forget_cancel_before, teardown);
1473   g_test_add ("/account-channels/request-forget/after-create", Test, NULL,
1474       setup, test_forget_cancel_after_create, teardown);
1475 
1476   /* Request and observe tests */
1477   g_test_add ("/account-channels/request-observe/create-success", Test, NULL,
1478       setup, test_observe_create_success, teardown);
1479   g_test_add ("/account-channels/request-observe/create-fail", Test, NULL,
1480       setup, test_observe_create_fail, teardown);
1481   g_test_add ("/account-channels/request-observe/proceed-fail", Test, NULL,
1482       setup, test_observe_proceed_fail, teardown);
1483   g_test_add ("/account-channels/request-observe/cr-failed", Test, NULL,
1484       setup, test_observe_cr_failed, teardown);
1485   g_test_add ("/account-channels/request-observe/ensure-success", Test, NULL,
1486       setup, test_observe_ensure_success, teardown);
1487   g_test_add ("/account-channels/request-observe/cancel-before", Test, NULL,
1488       setup, test_observe_cancel_before, teardown);
1489   g_test_add ("/account-channels/request-observe/after-create", Test, NULL,
1490       setup, test_observe_cancel_after_create, teardown);
1491   g_test_add ("/account-channels/request-observe/no-channel", Test, NULL,
1492       setup, test_observe_no_channel, teardown);
1493 
1494   /* Particular properties of the request */
1495   g_test_add ("/account-channels/test-ft-props", Test, NULL,
1496       setup, test_ft_props, teardown);
1497   g_test_add ("/account-channels/test-stream-tube-props", Test, NULL,
1498       setup, test_stream_tube_props, teardown);
1499   g_test_add ("/account-channels/test-dbus-tube-props", Test, NULL,
1500       setup, test_dbus_tube_props, teardown);
1501   g_test_add ("/account-channels/test-no-handle-type", Test, NULL,
1502       setup, test_no_handle_type, teardown);
1503   g_test_add ("/account-channels/test-initial-invitees", Test, NULL,
1504       setup, test_initial_invitees, teardown);
1505 
1506   return tp_tests_run_with_bus ();
1507 }
1508