1 /* A very basic feature test for TpAccountManager
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/account-manager.h>
14 #include <telepathy-glib/debug.h>
15 #include <telepathy-glib/defs.h>
16 
17 #include "tests/lib/simple-account.h"
18 #include "tests/lib/simple-account-manager.h"
19 #include "tests/lib/util.h"
20 
21 #define ACCOUNT1_PATH TP_ACCOUNT_OBJECT_PATH_BASE "badger/musher/account1"
22 #define ACCOUNT2_PATH TP_ACCOUNT_OBJECT_PATH_BASE "badger/musher/account2"
23 
24 typedef struct {
25     GFunc action;
26     gpointer user_data;
27 } ScriptAction;
28 
29 typedef struct {
30     GMainLoop *mainloop;
31     TpDBusDaemon *dbus;
32 
33     TpTestsSimpleAccountManager *service /* initialized in prepare_service */;
34     TpAccountManager *am;
35     TpAccount *account;
36     gboolean prepared /* The result of prepare_finish */;
37     guint timeout_id;
38     GQueue *script /* A list of GAsyncReadyCallback */;
39 
40     TpTestsSimpleAccount *account1_service;
41     TpTestsSimpleAccount *account2_service;
42 
43     TpAccount *account1;
44     TpAccount *account2;
45 
46     GError *error /* initialized where needed */;
47 } Test;
48 
49 /**
50   * Functions for manipulating scripts follow this comment.
51   * In order to be generally useful, the script should probably be stored in its
52   * own data structure, rather than passed around with the test, and the
53   * user_data argument would need to be the test or something. As it is, these
54   * library-like functions rely on being defined after the Test struct.
55   */
56 static ScriptAction *
script_action_new(GFunc action,gpointer data)57 script_action_new (GFunc action,
58     gpointer data)
59 {
60   ScriptAction *script_action = g_new (ScriptAction, 1);
61   script_action->action = action;
62   script_action->user_data = data;
63   return script_action;
64 }
65 
66 static void
script_action_free(ScriptAction * action)67 script_action_free (ScriptAction *action)
68 {
69   g_free (action);
70 }
71 
72 /**
73   * If data is passed in, you are responsible for freeing it. This will not be
74   * done for you.
75   */
76 static void
script_append_action(Test * test,GFunc action,gpointer data)77 script_append_action (Test *test,
78     GFunc action,
79     gpointer data)
80 {
81   g_queue_push_tail (test->script, script_action_new (action, data));
82 }
83 
84 static void
script_continue(gpointer script_data)85 script_continue (gpointer script_data)
86 {
87   Test *test = (Test *) script_data;
88   ScriptAction *action;
89   /* pop the next action */
90   action = (ScriptAction *) g_queue_pop_head (test->script);
91   action->action (script_data, action->user_data);
92   script_action_free (action);
93 }
94 
95 static gboolean
test_timed_out(gpointer data)96 test_timed_out (gpointer data)
97 {
98   Test *test = (Test *) data;
99   g_assert_not_reached ();
100   test->prepared = FALSE;
101   /* Note that this is a completely bogus error, but it only gets returned if
102    * you comment out the g_assert_not_reached() above. */
103   test->error = g_error_new_literal (TP_ERROR, TP_DBUS_ERROR_INCONSISTENT,
104                                      "timeout");
105   g_print ("about to quit");
106   g_main_loop_quit (test->mainloop);
107   g_print ("just quit");
108   return FALSE;
109 }
110 
111 static void
quit_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)112 quit_action (gpointer script_data,
113     gpointer user_data G_GNUC_UNUSED)
114 {
115   Test *test = (Test *) script_data;
116   g_main_loop_quit (test->mainloop);
117 }
118 
119 static void
script_start_with_deadline(Test * test,guint timeout)120 script_start_with_deadline (Test *test,
121     guint timeout)
122 {
123   script_append_action (test, quit_action, NULL);
124   test->timeout_id = g_timeout_add (timeout, test_timed_out, test);
125   script_continue (test);
126   g_main_loop_run (test->mainloop);
127 }
128 
129 /**
130   * Setup and teardown functions follow this comment.
131   */
132 
133 static void
setup(Test * test,gconstpointer data)134 setup (Test *test,
135     gconstpointer data)
136 {
137   tp_debug_set_flags ("all");
138 
139   test->mainloop = g_main_loop_new (NULL, FALSE);
140 
141   test->dbus = tp_tests_dbus_daemon_dup_or_die ();
142 
143   test->am = NULL;
144   test->timeout_id = 0;
145   test->script = g_queue_new ();
146 }
147 
148 static void
setup_service(Test * test,gconstpointer data)149 setup_service (Test *test,
150     gconstpointer data)
151 {
152   setup (test, data);
153 
154   g_assert (tp_dbus_daemon_request_name (test->dbus,
155           TP_ACCOUNT_MANAGER_BUS_NAME, FALSE, &test->error));
156 
157   test->service = tp_tests_object_new_static_class (
158       TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER, NULL);
159   tp_dbus_daemon_register_object (test->dbus, TP_ACCOUNT_MANAGER_OBJECT_PATH,
160       test->service);
161 
162   test->account1_service = tp_tests_object_new_static_class (
163       TP_TESTS_TYPE_SIMPLE_ACCOUNT, NULL);
164   tp_dbus_daemon_register_object (test->dbus, ACCOUNT1_PATH,
165       test->account1_service);
166 
167   test->account2_service = tp_tests_object_new_static_class (
168       TP_TESTS_TYPE_SIMPLE_ACCOUNT, NULL);
169   tp_dbus_daemon_register_object (test->dbus, ACCOUNT2_PATH,
170       test->account2_service);
171 }
172 
173 static void
teardown(Test * test,gconstpointer data)174 teardown (Test *test,
175     gconstpointer data)
176 {
177   if (test->am != NULL)
178     {
179       g_object_unref (test->am);
180       test->am = NULL;
181     }
182   if (test->timeout_id != 0)
183     {
184       g_source_remove (test->timeout_id);
185       test->timeout_id = 0;
186     }
187   g_queue_free (test->script);
188   test->script = NULL;
189 
190   /* make sure any pending things have happened */
191   tp_tests_proxy_run_until_dbus_queue_processed (test->dbus);
192 
193   g_object_unref (test->dbus);
194   test->dbus = NULL;
195   g_main_loop_unref (test->mainloop);
196   test->mainloop = NULL;
197 }
198 
199 static void
teardown_service(Test * test,gconstpointer data)200 teardown_service (Test *test,
201     gconstpointer data)
202 {
203   script_start_with_deadline (test, 1000);
204   g_assert (
205       tp_dbus_daemon_release_name (test->dbus, TP_ACCOUNT_MANAGER_BUS_NAME,
206                                &test->error));
207   tp_dbus_daemon_unregister_object (test->dbus, test->service);
208   g_object_unref (test->service);
209 
210   tp_dbus_daemon_unregister_object (test->dbus, test->account1_service);
211   g_object_unref (test->account1_service);
212   tp_dbus_daemon_unregister_object (test->dbus, test->account2_service);
213   g_object_unref (test->account2_service);
214 
215   g_clear_object (&test->account1);
216   g_clear_object (&test->account2);
217 
218   test->service = NULL;
219   teardown (test, data);
220 }
221 
222 /**
223   * Non-dbus tests follow this comment
224   */
225 
226 static void
test_new(Test * test,gconstpointer data G_GNUC_UNUSED)227 test_new (Test *test,
228     gconstpointer data G_GNUC_UNUSED)
229 {
230   test->am = tp_account_manager_new (test->dbus);
231 }
232 
233 static void
test_dup(Test * test,gconstpointer data G_GNUC_UNUSED)234 test_dup (Test *test,
235     gconstpointer data G_GNUC_UNUSED)
236 {
237   TpAccountManager *one, *two;
238   TpDBusDaemon *dbus_one, *dbus_two;
239 
240   one = tp_account_manager_dup ();
241   two = tp_account_manager_dup ();
242 
243   g_assert (one == two);
244 
245   dbus_one = tp_dbus_daemon_dup (NULL);
246   dbus_two = tp_proxy_get_dbus_daemon (one);
247 
248   g_assert (dbus_one == dbus_two);
249 
250   g_object_unref (dbus_one);
251   g_object_unref (two);
252   g_object_unref (one);
253 }
254 
255 /**
256   * Actions for use with script_append_action() follow this comment. They are
257   * used in tests which involve asyncronous actions.
258   */
259 
260 static void
noop_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)261 noop_action (gpointer script_data,
262     gpointer user_data G_GNUC_UNUSED)
263 {
264   script_continue (script_data);
265 }
266 
267 static void
finish_prepare_action(GObject * source_object,GAsyncResult * res,gpointer user_data)268 finish_prepare_action (GObject *source_object,
269     GAsyncResult *res,
270     gpointer user_data)
271 {
272   Test *test = (Test *) user_data;
273   gboolean is_prepared_reply;
274   TpAccountManager *am = TP_ACCOUNT_MANAGER (source_object);
275 
276   g_assert (test->am == am);
277   test->prepared = tp_account_manager_prepare_finish (am, res, &test->error);
278   is_prepared_reply = tp_proxy_is_prepared (test->am,
279       TP_ACCOUNT_MANAGER_FEATURE_CORE);
280   g_assert_cmpint (is_prepared_reply, ==, test->prepared);
281   script_continue (test);
282 }
283 
284 static void
prepare_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)285 prepare_action (gpointer script_data,
286     gpointer user_data G_GNUC_UNUSED)
287 {
288   Test *test = (Test *) script_data;
289 
290   tp_account_manager_prepare_async (test->am, NULL, finish_prepare_action, test);
291 }
292 
293 static void
manager_new_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)294 manager_new_action (gpointer script_data,
295     gpointer user_data G_GNUC_UNUSED)
296 {
297   Test *test = (Test *) script_data;
298 
299   test->am = tp_account_manager_new (test->dbus);
300   script_continue (test);
301 }
302 
303 /* We really don't want to have MC being launched during this test */
304 static void
finish_assert_am_not_activatable_action(TpDBusDaemon * proxy,const gchar * const * names,const GError * error,gpointer user_data,GObject * weak_object)305 finish_assert_am_not_activatable_action (TpDBusDaemon *proxy,
306     const gchar * const *names,
307     const GError *error,
308     gpointer user_data,
309     GObject *weak_object)
310 {
311   guint i;
312 
313   g_assert (error == NULL);
314 
315   for (i=0; names[i] != NULL; i++)
316     {
317       g_assert_cmpstr (names[i], !=, TP_ACCOUNT_MANAGER_BUS_NAME);
318       g_assert_cmpstr (names[i], !=, "org.freedesktop.Telepathy.MissionControl5");
319     }
320 
321   script_continue (user_data);
322 }
323 
324 static void
assert_am_not_activatable_action(gpointer script_data,gpointer user_data)325 assert_am_not_activatable_action (gpointer script_data,
326     gpointer user_data)
327 {
328   Test *test = (Test *) script_data;
329 
330   tp_dbus_daemon_list_activatable_names (test->dbus, 500,
331       finish_assert_am_not_activatable_action, test, NULL, NULL);
332 }
333 
334 static void
assert_core_not_ready_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)335 assert_core_not_ready_action (gpointer script_data,
336     gpointer user_data G_GNUC_UNUSED)
337 {
338   Test *test = (Test *) script_data;
339 
340   g_assert (!tp_proxy_is_prepared (test->am,
341       TP_ACCOUNT_MANAGER_FEATURE_CORE));
342 
343   script_continue (script_data);
344 }
345 
346 static void
assert_feature_not_ready_action(gpointer script_data,gpointer user_data)347 assert_feature_not_ready_action (gpointer script_data,
348     gpointer user_data)
349 {
350   Test *test = (Test *) script_data;
351 
352   g_assert (!tp_proxy_is_prepared (test->am,
353       g_quark_from_string ((gchar *) user_data)));
354 
355   g_free (user_data);
356   script_continue (script_data);
357 }
358 
359 static void
prepare_feature_action(gpointer script_data,gpointer user_data)360 prepare_feature_action (gpointer script_data,
361     gpointer user_data)
362 {
363   Test *test = (Test *) script_data;
364   GQuark features[3];
365 
366   features[0] = TP_ACCOUNT_MANAGER_FEATURE_CORE;
367   features[1] = g_quark_from_string ((gchar *) user_data);
368   features[2] = 0;
369 
370   tp_account_manager_prepare_async (test->am, features, finish_prepare_action, test);
371 
372   g_free (user_data);
373 }
374 
375 static void
assert_ok_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)376 assert_ok_action (gpointer script_data,
377     gpointer user_data G_GNUC_UNUSED)
378 {
379   Test *test = (Test *) script_data;
380 
381   g_assert_no_error (test->error);
382   g_assert (test->prepared);
383 
384   script_continue (script_data);
385 }
386 
387 static void
assert_failed_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)388 assert_failed_action (gpointer script_data,
389     gpointer user_data G_GNUC_UNUSED)
390 {
391   Test *test = (Test *) script_data;
392 
393   g_assert (test->error != NULL);
394   g_error_free (test->error);
395   test->error = NULL;
396 
397   script_continue (script_data);
398 }
399 
400 /**
401   * account related functions below this comment
402   */
403 
404 static void
ensure_action(gpointer script_data,gpointer user_data)405 ensure_action (gpointer script_data,
406     gpointer user_data)
407 {
408   char *path = (char *) user_data;
409   Test *test = (Test *) script_data;
410   g_assert (test != NULL);
411   g_assert (test->am != NULL);
412   g_assert (tp_proxy_is_prepared (test->am, TP_ACCOUNT_MANAGER_FEATURE_CORE));
413   test->account = tp_account_manager_ensure_account (test->am,
414       path);
415 
416   script_continue (script_data);
417 }
418 
419 static void
assert_account_ok_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)420 assert_account_ok_action (gpointer script_data,
421     gpointer user_data G_GNUC_UNUSED)
422 {
423   Test *test = (Test *) script_data;
424   g_assert (test->account != NULL);
425 
426   script_continue (script_data);
427 }
428 
429 static void
finish_account_prepare_action(GObject * source_object,GAsyncResult * res,gpointer user_data)430 finish_account_prepare_action (GObject *source_object,
431     GAsyncResult *res,
432     gpointer user_data)
433 {
434   Test *test = (Test *) user_data;
435   TpAccount *account = TP_ACCOUNT (source_object);
436 
437   g_assert (test->account == account);
438   test->prepared = tp_account_prepare_finish (account, res, &test->error);
439   g_assert (test->prepared == tp_proxy_is_prepared (account, TP_ACCOUNT_FEATURE_CORE));
440 
441   script_continue (test);
442 }
443 
444 static void
account_prepare_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)445 account_prepare_action (gpointer script_data,
446     gpointer user_data G_GNUC_UNUSED)
447 {
448   Test *test = (Test *) script_data;
449 
450   tp_account_prepare_async (test->account, NULL, finish_account_prepare_action, test);
451 }
452 
453 static void
register_service_action(gpointer script_data,gpointer user_data G_GNUC_UNUSED)454 register_service_action (gpointer script_data,
455     gpointer user_data G_GNUC_UNUSED)
456 {
457   Test *test = (Test *) script_data;
458 
459   tp_dbus_daemon_register_object (test->dbus, TP_ACCOUNT_MANAGER_OBJECT_PATH,
460       test->service);
461 
462   script_continue (test);
463 }
464 
465 /**
466   * Asyncronous tests below this comment. Tests append action functions and
467   * arguments to a script. Once the test function has returned, the teardown
468   * function is responsible for running the script, and quitting the mainloop
469   * afterwards.
470   * Action functions are each responsible for ensuring that the next action is
471   * called.
472   */
473 
474 static void
test_prepare(Test * test,gconstpointer data G_GNUC_UNUSED)475 test_prepare (Test *test,
476     gconstpointer data G_GNUC_UNUSED)
477 {
478   script_append_action (test, assert_am_not_activatable_action, NULL);
479   script_append_action (test, manager_new_action, NULL);
480   script_append_action (test, assert_core_not_ready_action, NULL);
481   script_append_action (test, prepare_action, NULL);
482   script_append_action (test, noop_action, NULL);
483 }
484 
485 /**
486  * Tests the usual case where prepare succeeds.
487  */
488 static void
test_prepare_success(Test * test,gconstpointer data G_GNUC_UNUSED)489 test_prepare_success (Test *test,
490     gconstpointer data G_GNUC_UNUSED)
491 {
492   test_prepare (test, data);
493   script_append_action (test, assert_ok_action, NULL);
494 }
495 
496 /**
497  * Tests the case where the well-known name is not provided.
498  * This should be run with setup rather than setup_service to make this the case.
499  * TODO: use g_assert_error (err, dom, c) to fix the domain and code.
500  */
501 static void
test_prepare_no_name(Test * test,gconstpointer data G_GNUC_UNUSED)502 test_prepare_no_name (Test *test,
503     gconstpointer data G_GNUC_UNUSED)
504 {
505   test_prepare (test, data);
506 
507   script_append_action (test, assert_failed_action, NULL);
508   /* Since we are using teardown rather than teardown_service, we need to
509    * run the script ourselves */
510   script_start_with_deadline (test, 1000);
511 }
512 
513 /**
514  * Tests the case where the object has been destroyed.
515  * TODO: use g_assert_error (err, dom, c) to fix the domain and code.
516  */
517 static void
test_prepare_destroyed(Test * test,gconstpointer data G_GNUC_UNUSED)518 test_prepare_destroyed (Test *test,
519     gconstpointer data G_GNUC_UNUSED)
520 {
521   tp_dbus_daemon_unregister_object (test->dbus, test->service);
522   test_prepare (test, data);
523   script_append_action (test, assert_failed_action, NULL);
524   script_append_action (test, register_service_action, NULL);
525 }
526 
527 /**
528  * Calling prepare with unknown features should succeed, but is_prepared()
529  * on an unknown feature should return FALSE.
530  */
531 static void
test_prepare_unknown_features(Test * test,gconstpointer data G_GNUC_UNUSED)532 test_prepare_unknown_features (Test *test,
533     gconstpointer data G_GNUC_UNUSED)
534 {
535   test_prepare_success (test, data);
536   script_append_action (test, prepare_feature_action, g_strdup ("fake-feature"));
537   script_append_action (test, assert_ok_action, NULL);
538   script_append_action (test, assert_feature_not_ready_action, g_strdup ("fake-feature"));
539 }
540 
541 static void
test_ensure(Test * test,gconstpointer data G_GNUC_UNUSED)542 test_ensure (Test *test,
543     gconstpointer data G_GNUC_UNUSED)
544 {
545   test_prepare (test, data);
546   script_append_action (test, assert_ok_action, NULL);
547 
548   script_append_action (test, ensure_action,
549                         TP_ACCOUNT_OBJECT_PATH_BASE "fakecm/fakeproto/account");
550   script_append_action (test, assert_account_ok_action, NULL);
551   script_append_action (test, account_prepare_action, NULL);
552   script_append_action (test, assert_failed_action, NULL);
553 }
554 
555 /* tp_account_manager_get_most_available_presence() tests */
556 static void
create_tp_accounts(gpointer script_data,gpointer user_data G_GNUC_UNUSED)557 create_tp_accounts (gpointer script_data,
558     gpointer user_data G_GNUC_UNUSED)
559 {
560   Test *test = (Test *) script_data;
561 
562   test->account1 = tp_account_manager_ensure_account (test->am, ACCOUNT1_PATH);
563   g_object_ref (test->account1);
564 
565   test->account2 = tp_account_manager_ensure_account (test->am, ACCOUNT2_PATH);
566   g_object_ref (test->account2);
567 
568   script_continue (test);
569 }
570 
571 static void
test_prepare_most_available(Test * test,gconstpointer data,guint nb_accounts)572 test_prepare_most_available (Test *test,
573     gconstpointer data,
574     guint nb_accounts)
575 {
576   if (nb_accounts >= 1)
577     tp_tests_simple_account_manager_add_account (test->service, ACCOUNT1_PATH,
578         TRUE);
579 
580   if (nb_accounts >= 2)
581     tp_tests_simple_account_manager_add_account (test->service, ACCOUNT2_PATH,
582         TRUE);
583 
584   test_prepare (test, data);
585   script_append_action (test, manager_new_action, NULL);
586   script_append_action (test, prepare_action, NULL);
587   script_append_action (test, create_tp_accounts, NULL);
588 }
589 
590 typedef struct
591 {
592   TpConnectionPresenceType presence;
593   gchar *status;
594   gchar *message;
595 } Presence;
596 
597 static Presence *
presence_new(TpConnectionPresenceType presence,const gchar * status,const gchar * message)598 presence_new (TpConnectionPresenceType presence,
599     const gchar *status,
600     const gchar *message)
601 {
602   Presence *p = g_slice_new (Presence);
603 
604   p->presence = presence;
605   p->status = g_strdup (status);
606   p->message = g_strdup (message);
607   return p;
608 }
609 
610 static void
presence_free(Presence * p)611 presence_free (Presence *p)
612 {
613   g_free (p->status);
614   g_free (p->message);
615   g_slice_free (Presence, p);
616 }
617 
618 static void
check_presence_action(gpointer script_data,gpointer user_data)619 check_presence_action (gpointer script_data,
620     gpointer user_data)
621 {
622   Test *test = script_data;
623   Presence *p = user_data;
624   TpConnectionPresenceType presence;
625   gchar *status, *message;
626 
627   presence = tp_account_manager_get_most_available_presence (test->am,
628       &status, &message);
629 
630   g_assert_cmpuint (presence, ==, p->presence);
631   g_assert_cmpstr (status, ==, p->status);
632   g_assert_cmpstr (message, ==, p->message);
633 
634   presence_free (p);
635   g_free (status);
636   g_free (message);
637 
638   script_continue (script_data);
639 }
640 
641 static void
account_presence_changed(TpAccount * account,TpConnectionPresenceType presence,const gchar * status,const gchar * message,Test * test)642 account_presence_changed (TpAccount *account,
643     TpConnectionPresenceType presence,
644     const gchar *status,
645     const gchar *message,
646     Test *test)
647 {
648   g_signal_handlers_disconnect_by_func (account,
649       account_presence_changed, test);
650 
651   script_continue (test);
652 }
653 
654 static void
change_account_presence(Test * test,TpTestsSimpleAccount * service,TpAccount * account,gpointer user_data)655 change_account_presence (Test *test,
656     TpTestsSimpleAccount *service,
657     TpAccount *account,
658     gpointer user_data)
659 {
660   Presence *p = user_data;
661 
662   tp_tests_simple_account_set_presence (service,
663       p->presence, p->status, p->message);
664 
665   presence_free (p);
666 
667   /* Wait for the presence change notification */
668   g_signal_connect (account, "presence-changed",
669       G_CALLBACK (account_presence_changed), test);
670 }
671 
672 static void
change_account1_presence(gpointer script_data,gpointer user_data)673 change_account1_presence (gpointer script_data,
674     gpointer user_data)
675 {
676   Test *test = script_data;
677 
678   change_account_presence (test, test->account1_service,
679       test->account1, user_data);
680 }
681 
682 static void
change_account2_presence(gpointer script_data,gpointer user_data)683 change_account2_presence (gpointer script_data,
684     gpointer user_data)
685 {
686   Test *test = script_data;
687 
688   change_account_presence (test, test->account2_service,
689       test->account2, user_data);
690 }
691 
692 static void
test_most_available_no_account(Test * test,gconstpointer data G_GNUC_UNUSED)693 test_most_available_no_account (Test *test,
694     gconstpointer data G_GNUC_UNUSED)
695 {
696   test_prepare_most_available (test, data, 0);
697 
698   script_append_action (test, check_presence_action,
699       presence_new (TP_CONNECTION_PRESENCE_TYPE_OFFLINE, "offline", ""));
700 }
701 
702 static void
test_most_available_one_account(Test * test,gconstpointer data G_GNUC_UNUSED)703 test_most_available_one_account (Test *test,
704     gconstpointer data G_GNUC_UNUSED)
705 {
706   test_prepare_most_available (test, data, 1);
707 
708   script_append_action (test, change_account1_presence,
709       presence_new (TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, "available", ""));
710   script_append_action (test, check_presence_action,
711       presence_new (TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, "available", ""));
712 }
713 
714 static void
test_most_available_two_account(Test * test,gconstpointer data G_GNUC_UNUSED)715 test_most_available_two_account (Test *test,
716     gconstpointer data G_GNUC_UNUSED)
717 {
718   test_prepare_most_available (test, data, 2);
719 
720   script_append_action (test, change_account1_presence,
721       presence_new (TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, "available", ""));
722   script_append_action (test, change_account2_presence,
723       presence_new (TP_CONNECTION_PRESENCE_TYPE_AWAY, "away", ""));
724 
725   script_append_action (test, check_presence_action,
726       presence_new (TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, "available", ""));
727 
728   /* account1 disconnects */
729   script_append_action (test, change_account1_presence,
730       presence_new (TP_CONNECTION_PRESENCE_TYPE_OFFLINE, "offline", ""));
731 
732   script_append_action (test, check_presence_action,
733       presence_new (TP_CONNECTION_PRESENCE_TYPE_AWAY, "away", ""));
734 }
735 
736 static void
test_most_available_one_unset(Test * test,gconstpointer data G_GNUC_UNUSED)737 test_most_available_one_unset (Test *test,
738     gconstpointer data G_GNUC_UNUSED)
739 {
740   test_prepare_most_available (test, data, 1);
741 
742   script_append_action (test, change_account1_presence,
743       presence_new (TP_CONNECTION_PRESENCE_TYPE_UNSET, "unset", ""));
744 
745   /* Pretend that we are available */
746   script_append_action (test, check_presence_action,
747       presence_new (TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, "available", ""));
748 }
749 
750 static void
test_most_available_two_unset(Test * test,gconstpointer data G_GNUC_UNUSED)751 test_most_available_two_unset (Test *test,
752     gconstpointer data G_GNUC_UNUSED)
753 {
754   test_prepare_most_available (test, data, 2);
755 
756   script_append_action (test, change_account1_presence,
757       presence_new (TP_CONNECTION_PRESENCE_TYPE_UNSET, "unset", ""));
758   script_append_action (test, change_account2_presence,
759       presence_new (TP_CONNECTION_PRESENCE_TYPE_AWAY, "away", ""));
760 
761   /* Use account2 away presence */
762   script_append_action (test, check_presence_action,
763       presence_new (TP_CONNECTION_PRESENCE_TYPE_AWAY, "away", ""));
764 
765   /* account2 disconnects */
766   script_append_action (test, change_account2_presence,
767       presence_new (TP_CONNECTION_PRESENCE_TYPE_OFFLINE, "offline", ""));
768 
769   /* Pretent that we are available */
770   script_append_action (test, check_presence_action,
771       presence_new (TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, "available", ""));
772 
773   /* account2 reconnects with busy */
774   script_append_action (test, change_account2_presence,
775       presence_new (TP_CONNECTION_PRESENCE_TYPE_BUSY, "busy", ""));
776 
777   script_append_action (test, check_presence_action,
778       presence_new (TP_CONNECTION_PRESENCE_TYPE_BUSY, "busy", ""));
779 }
780 
781 int
main(int argc,char ** argv)782 main (int argc,
783     char **argv)
784 {
785   tp_tests_abort_after (10);
786   g_test_init (&argc, &argv, NULL);
787   g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id=");
788 
789   g_test_add ("/am/new", Test, NULL, setup, test_new, teardown);
790   g_test_add ("/am/dup", Test, NULL, setup, test_dup, teardown);
791 
792   g_test_add ("/am/prepare/success", Test, NULL, setup_service,
793               test_prepare_success, teardown_service);
794   g_test_add ("/am/prepare/destroyed", Test, NULL, setup_service,
795               test_prepare_destroyed, teardown_service);
796   /* WARNING: This test is run using setup/teardown rather than setup_service*/
797   g_test_add ("/am/prepare/name-not-provided", Test, NULL, setup,
798               test_prepare_no_name, teardown);
799   g_test_add ("/am/prepare/unknown_features", Test, NULL, setup_service,
800               test_prepare_unknown_features, teardown_service);
801 
802   g_test_add ("/am/ensure", Test, NULL, setup_service,
803               test_ensure, teardown_service);
804 
805   g_test_add ("/am/most-available/no-account", Test, NULL, setup_service,
806               test_most_available_no_account, teardown_service);
807   g_test_add ("/am/most-available/one-account", Test, NULL, setup_service,
808               test_most_available_one_account, teardown_service);
809   g_test_add ("/am/most-available/two-account", Test, NULL, setup_service,
810               test_most_available_two_account, teardown_service);
811   g_test_add ("/am/most-available/one-unset", Test, NULL, setup_service,
812               test_most_available_one_unset, teardown_service);
813   g_test_add ("/am/most-available/two-unset", Test, NULL, setup_service,
814               test_most_available_two_unset, teardown_service);
815   return tp_tests_run_with_bus ();
816 }
817