/* Tests of TpBaseClient
*
* Copyright © 2010 Collabora Ltd.
*
* Copying and distribution of this file, with or without modification,
* are permitted in any medium without royalty provided the copyright
* notice and this notice are preserved.
*/
/* We include -internal headers of context to be able to easily access to
* their semi-private attributes (connection, account, channels, etc). */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "tests/lib/util.h"
#include "tests/lib/simple-account.h"
#include "tests/lib/simple-channel-dispatch-operation.h"
#include "tests/lib/simple-channel-dispatcher.h"
#include "tests/lib/simple-channel-request.h"
#include "tests/lib/simple-client.h"
#include "tests/lib/simple-conn.h"
#include "tests/lib/textchan-null.h"
typedef struct {
GMainLoop *mainloop;
TpDBusDaemon *dbus;
/* Service side objects */
TpBaseClient *base_client;
TpTestsSimpleClient *simple_client;
TpBaseConnection *base_connection;
TpTestsSimpleAccount *account_service;
TpTestsTextChannelNull *text_chan_service;
TpTestsTextChannelNull *text_chan_service_2;
TpTestsSimpleChannelDispatchOperation *cdo_service;
TpTestsSimpleChannelDispatcher *cd_service;
/* Client side objects */
TpAccountManager *account_mgr;
TpClient *client;
TpConnection *connection;
TpAccount *account;
TpChannel *text_chan;
TpChannel *text_chan_2;
GError *error /* initialized where needed */;
GStrv interfaces;
gint wait;
GPtrArray *delegated;
GHashTable *not_delegated;
} Test;
#define ACCOUNT_PATH TP_ACCOUNT_OBJECT_PATH_BASE "what/ev/er"
#define CDO_PATH "/whatever"
static void
setup (Test *test,
gconstpointer data)
{
gchar *chan_path;
TpHandle handle;
TpHandleRepoIface *contact_repo;
test->mainloop = g_main_loop_new (NULL, FALSE);
test->dbus = tp_tests_dbus_daemon_dup_or_die ();
test->error = NULL;
test->interfaces = NULL;
/* The case of a non-shared TpAccountManager is tested in
* simple-approver.c */
test->account_mgr = tp_account_manager_dup ();
g_assert (test->account_mgr != NULL);
/* Claim AccountManager bus-name (needed as we're going to export an Account
* object). */
tp_dbus_daemon_request_name (test->dbus,
TP_ACCOUNT_MANAGER_BUS_NAME, FALSE, &test->error);
g_assert_no_error (test->error);
/* Create service-side Client object */
test->simple_client = tp_tests_simple_client_new (test->dbus, "Test", FALSE);
g_assert (test->simple_client != NULL);
test->base_client = TP_BASE_CLIENT (test->simple_client);
/* Create service-side Account object */
test->account_service = tp_tests_object_new_static_class (
TP_TESTS_TYPE_SIMPLE_ACCOUNT, NULL);
tp_dbus_daemon_register_object (test->dbus, ACCOUNT_PATH,
test->account_service);
/* Create client-side Client object */
test->client = tp_tests_object_new_static_class (TP_TYPE_CLIENT,
"dbus-daemon", test->dbus,
"bus-name", tp_base_client_get_bus_name (test->base_client),
"object-path", tp_base_client_get_object_path (test->base_client),
NULL);
g_assert (test->client != NULL);
/* Create client-side Account object */
test->account = tp_account_manager_ensure_account (test->account_mgr,
ACCOUNT_PATH);
g_assert (test->account != NULL);
g_object_ref (test->account);
/* Create (service and client sides) connection objects */
tp_tests_create_and_connect_conn (TP_TESTS_TYPE_SIMPLE_CONNECTION,
"me@test.com", &test->base_connection, &test->connection);
/* Create service-side text channel object */
chan_path = g_strdup_printf ("%s/Channel",
tp_proxy_get_object_path (test->connection));
contact_repo = tp_base_connection_get_handles (test->base_connection,
TP_HANDLE_TYPE_CONTACT);
g_assert (contact_repo != NULL);
handle = tp_handle_ensure (contact_repo, "bob", NULL, &test->error);
g_assert_no_error (test->error);
test->text_chan_service = TP_TESTS_TEXT_CHANNEL_NULL (
tp_tests_object_new_static_class (
TP_TESTS_TYPE_TEXT_CHANNEL_NULL,
"connection", test->base_connection,
"object-path", chan_path,
"handle", handle,
NULL));
/* Create client-side text channel object */
test->text_chan = tp_channel_new (test->connection, chan_path, NULL,
TP_HANDLE_TYPE_CONTACT, handle, &test->error);
g_assert_no_error (test->error);
tp_handle_unref (contact_repo, handle);
g_free (chan_path);
/* Create a second channel */
chan_path = g_strdup_printf ("%s/Channel2",
tp_proxy_get_object_path (test->connection));
handle = tp_handle_ensure (contact_repo, "alice", NULL, &test->error);
g_assert_no_error (test->error);
test->text_chan_service_2 = TP_TESTS_TEXT_CHANNEL_NULL (
tp_tests_object_new_static_class (
TP_TESTS_TYPE_TEXT_CHANNEL_NULL,
"connection", test->base_connection,
"object-path", chan_path,
"handle", handle,
NULL));
/* Create client-side text channel object */
test->text_chan_2 = tp_channel_new (test->connection, chan_path, NULL,
TP_HANDLE_TYPE_CONTACT, handle, &test->error);
g_assert_no_error (test->error);
tp_handle_unref (contact_repo, handle);
g_free (chan_path);
/* Create Service side ChannelDispatchOperation object */
test->cdo_service = tp_tests_object_new_static_class (
TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION,
NULL);
tp_dbus_daemon_register_object (test->dbus, CDO_PATH, test->cdo_service);
tp_tests_simple_channel_dispatch_operation_set_conn_path (test->cdo_service,
tp_proxy_get_object_path (test->connection));
tp_tests_simple_channel_dispatch_operation_set_account_path (
test->cdo_service, tp_proxy_get_object_path (test->account));
tp_tests_simple_channel_dispatch_operation_add_channel (test->cdo_service,
test->text_chan);
tp_tests_simple_channel_dispatch_operation_add_channel (test->cdo_service,
test->text_chan_2);
g_assert (tp_dbus_daemon_request_name (test->dbus,
TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL));
/* Create and register CD */
test->cd_service = tp_tests_object_new_static_class (
TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER,
"connection", test->base_connection,
NULL);
tp_dbus_daemon_register_object (test->dbus, TP_CHANNEL_DISPATCHER_OBJECT_PATH,
test->cd_service);
}
static void
teardown_channel_invalidated_cb (TpChannel *self,
guint domain,
gint code,
gchar *message,
Test *test)
{
g_main_loop_quit (test->mainloop);
}
static void
teardown_run_close_channel (Test *test, TpChannel *channel)
{
if (channel != NULL && tp_proxy_get_invalidated (channel) == NULL)
{
g_signal_connect (channel, "invalidated",
G_CALLBACK (teardown_channel_invalidated_cb), test);
tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL);
g_main_loop_run (test->mainloop);
}
}
static void
teardown (Test *test,
gconstpointer data)
{
teardown_run_close_channel (test, test->text_chan);
teardown_run_close_channel (test, test->text_chan_2);
g_clear_error (&test->error);
g_strfreev (test->interfaces);
g_object_unref (test->account_mgr);
tp_dbus_daemon_release_name (test->dbus, TP_CHANNEL_DISPATCHER_BUS_NAME,
NULL);
g_object_unref (test->base_client);
g_object_unref (test->client);
tp_dbus_daemon_unregister_object (test->dbus, test->account_service);
g_object_unref (test->account_service);
tp_dbus_daemon_release_name (test->dbus, TP_ACCOUNT_MANAGER_BUS_NAME,
&test->error);
g_assert_no_error (test->error);
g_object_unref (test->dbus);
test->dbus = NULL;
g_main_loop_unref (test->mainloop);
test->mainloop = NULL;
g_object_unref (test->account);
if (test->text_chan_service != NULL)
g_object_unref (test->text_chan_service);
g_object_unref (test->text_chan);
if (test->text_chan_service_2 != NULL)
g_object_unref (test->text_chan_service_2);
g_object_unref (test->text_chan_2);
tp_clear_object (&test->cdo_service);
tp_cli_connection_run_disconnect (test->connection, -1, &test->error, NULL);
g_assert_no_error (test->error);
g_object_unref (test->connection);
g_object_unref (test->base_connection);
tp_clear_object (&test->cd_service);
tp_clear_pointer (&test->delegated, g_ptr_array_unref);
tp_clear_pointer (&test->not_delegated, g_hash_table_unref);
}
/* Test Basis */
static void
test_basics (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
TpAccountManager *account_manager;
TpDBusDaemon *dbus;
gchar *name;
gboolean unique;
g_object_get (test->base_client,
"account-manager", &account_manager,
"dbus-daemon", &dbus,
"name", &name,
"uniquify-name", &unique,
NULL);
g_assert (test->account_mgr == account_manager);
g_assert (test->dbus == dbus);
g_assert_cmpstr ("Test", ==, name);
g_assert (!unique);
g_assert (test->account_mgr == tp_base_client_get_account_manager (
test->base_client));
g_assert (test->dbus == tp_base_client_get_dbus_daemon (test->base_client));
g_assert_cmpstr ("Test", ==, tp_base_client_get_name (test->base_client));
g_assert (!tp_base_client_get_uniquify_name (test->base_client));
g_object_unref (account_manager);
g_object_unref (dbus);
g_free (name);
}
/* Test register */
static void
get_client_prop_cb (TpProxy *proxy,
GHashTable *properties,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
Test *test = user_data;
if (error != NULL)
{
test->error = g_error_copy (error);
goto out;
}
g_assert_cmpint (g_hash_table_size (properties), == , 1);
g_strfreev (test->interfaces);
test->interfaces = g_strdupv ((GStrv) tp_asv_get_strv (
properties, "Interfaces"));
out:
g_main_loop_quit (test->mainloop);
}
static void
test_register (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
tp_base_client_be_a_handler (test->base_client);
/* no-op as the client is not registered yet */
tp_base_client_unregister (test->base_client);
/* Client is not registered yet */
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT, get_client_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_error (test->error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN);
g_error_free (test->error);
test->error = NULL;
/* register the client */
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT, get_client_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
/* unregister the client */
tp_base_client_unregister (test->base_client);
tp_tests_proxy_run_until_dbus_queue_processed (test->client);
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT, get_client_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_error (test->error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN);
g_error_free (test->error);
test->error = NULL;
/* re-register the client */
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT, get_client_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
}
/* Test Observer */
static void
check_filters (GPtrArray *filters)
{
GHashTable *filter;
g_assert (filters != NULL);
g_assert_cmpuint (filters->len, ==, 2);
filter = g_ptr_array_index (filters, 0);
g_assert_cmpuint (g_hash_table_size (filter), ==, 1);
g_assert_cmpstr (tp_asv_get_string (filter, TP_PROP_CHANNEL_CHANNEL_TYPE), ==,
TP_IFACE_CHANNEL_TYPE_TEXT);
filter = g_ptr_array_index (filters, 1);
g_assert_cmpuint (g_hash_table_size (filter), ==, 2);
g_assert_cmpstr (tp_asv_get_string (filter, TP_PROP_CHANNEL_CHANNEL_TYPE), ==,
TP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
g_assert_cmpuint (tp_asv_get_uint32 (filter,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL), ==, TP_HANDLE_TYPE_CONTACT);
}
static void
get_observer_prop_cb (TpProxy *proxy,
GHashTable *properties,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
Test *test = user_data;
GPtrArray *filters;
gboolean recover, delay;
gboolean valid;
if (error != NULL)
{
test->error = g_error_copy (error);
goto out;
}
g_assert_cmpint (g_hash_table_size (properties), == , 3);
filters = tp_asv_get_boxed (properties, "ObserverChannelFilter",
TP_ARRAY_TYPE_CHANNEL_CLASS_LIST);
check_filters (filters);
recover = tp_asv_get_boolean (properties, "Recover", &valid);
g_assert (valid);
g_assert (recover);
delay = tp_asv_get_boolean (properties, "DelayApprovers", &valid);
g_assert (valid);
g_assert (delay);
out:
g_main_loop_quit (test->mainloop);
}
static void
no_return_cb (TpClient *proxy,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
Test *test = user_data;
g_clear_error (&test->error);
if (error != NULL)
{
test->error = g_error_copy (error);
goto out;
}
out:
test->wait--;
if (test->wait == 0)
g_main_loop_quit (test->mainloop);
}
static void
add_channel_to_ptr_array (GPtrArray *arr,
TpChannel *channel)
{
GValueArray *tmp;
g_assert (arr != NULL);
g_assert (channel != NULL);
tmp = tp_value_array_build (2,
DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (channel),
TP_HASH_TYPE_STRING_VARIANT_MAP, tp_channel_borrow_immutable_properties (
channel),
G_TYPE_INVALID);
g_ptr_array_add (arr, tmp);
}
static void
free_channel_details (gpointer data,
gpointer user_data)
{
g_boxed_free (TP_STRUCT_TYPE_CHANNEL_DETAILS, data);
}
static void
test_observer (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
GHashTable *filter;
GPtrArray *channels, *requests_satisified;
GHashTable *info;
TpChannel *chan;
filter = tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
NULL);
tp_base_client_add_observer_filter (test->base_client, filter);
g_hash_table_unref (filter);
tp_base_client_take_observer_filter (test->base_client, tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
TP_HANDLE_TYPE_CONTACT,
NULL));
tp_base_client_set_observer_recover (test->base_client, TRUE);
tp_base_client_set_observer_delay_approvers (test->base_client, TRUE);
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
/* Check Client properties */
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT, get_client_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert_cmpint (g_strv_length (test->interfaces), ==, 1);
g_assert (tp_strv_contains ((const gchar * const *) test->interfaces,
TP_IFACE_CLIENT_OBSERVER));
/* Check Observer properties */
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT_OBSERVER, get_observer_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
/* Call ObserveChannels */
channels = g_ptr_array_sized_new (1);
add_channel_to_ptr_array (channels, test->text_chan);
requests_satisified = g_ptr_array_sized_new (0);
info = tp_asv_new (
"recovering", G_TYPE_BOOLEAN, TRUE,
NULL);
tp_proxy_add_interface_by_id (TP_PROXY (test->client),
TP_IFACE_QUARK_CLIENT_OBSERVER);
tp_cli_client_observer_call_observe_channels (test->client, -1,
tp_proxy_get_object_path (test->account),
tp_proxy_get_object_path (test->connection),
channels, "/", requests_satisified, info,
no_return_cb, test, NULL, NULL);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (test->simple_client->observe_ctx != NULL);
g_assert (tp_observe_channels_context_is_recovering (
test->simple_client->observe_ctx));
g_assert (test->simple_client->observe_ctx->account == test->account);
/* Now call it with an invalid argument */
tp_asv_set_boolean (info, "FAIL", TRUE);
tp_cli_client_observer_call_observe_channels (test->client, -1,
tp_proxy_get_object_path (test->account),
tp_proxy_get_object_path (test->connection),
channels, "/", requests_satisified, info,
no_return_cb, test, NULL, NULL);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_error (test->error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT);
g_clear_error (&test->error);
/* The channel being observed is invalidated while preparing */
g_hash_table_remove (info, "FAIL");
tp_cli_client_observer_call_observe_channels (test->client, -1,
tp_proxy_get_object_path (test->account),
tp_proxy_get_object_path (test->connection),
channels, "/", requests_satisified, info,
no_return_cb, test, NULL, NULL);
tp_tests_text_channel_null_close (test->text_chan_service);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
chan = g_ptr_array_index (test->simple_client->observe_ctx->channels, 0);
g_assert (TP_IS_CHANNEL (chan));
g_assert (tp_proxy_get_invalidated (chan) != NULL);
g_ptr_array_foreach (channels, free_channel_details, NULL);
g_ptr_array_free (channels, TRUE);
g_ptr_array_free (requests_satisified, TRUE);
g_hash_table_unref (info);
}
/* Test Approver */
static void
get_approver_prop_cb (TpProxy *proxy,
GHashTable *properties,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
Test *test = user_data;
GPtrArray *filters;
if (error != NULL)
{
test->error = g_error_copy (error);
goto out;
}
g_assert_cmpint (g_hash_table_size (properties), == , 1);
filters = tp_asv_get_boxed (properties, "ApproverChannelFilter",
TP_ARRAY_TYPE_CHANNEL_CLASS_LIST);
check_filters (filters);
out:
g_main_loop_quit (test->mainloop);
}
static void
test_approver (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
GHashTable *filter;
GPtrArray *channels, *chans;
GHashTable *properties;
static const char *interfaces[] = { NULL };
static const gchar *possible_handlers[] = {
TP_CLIENT_BUS_NAME_BASE ".Badger", NULL, };
guint i;
filter = tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
NULL);
tp_base_client_add_approver_filter (test->base_client, filter);
g_hash_table_unref (filter);
tp_base_client_take_approver_filter (test->base_client, tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
TP_HANDLE_TYPE_CONTACT,
NULL));
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
/* Check Client properties */
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT, get_client_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert_cmpint (g_strv_length (test->interfaces), ==, 1);
g_assert (tp_strv_contains ((const gchar * const *) test->interfaces,
TP_IFACE_CLIENT_APPROVER));
/* Check Approver properties */
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT_APPROVER, get_approver_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
/* Call AddDispatchOperation */
channels = g_ptr_array_sized_new (2);
add_channel_to_ptr_array (channels, test->text_chan);
add_channel_to_ptr_array (channels, test->text_chan_2);
properties = tp_asv_new (
TP_PROP_CHANNEL_DISPATCH_OPERATION_INTERFACES,
G_TYPE_STRV, interfaces,
TP_PROP_CHANNEL_DISPATCH_OPERATION_CONNECTION,
DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (test->connection),
TP_PROP_CHANNEL_DISPATCH_OPERATION_ACCOUNT,
DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (test->account),
TP_PROP_CHANNEL_DISPATCH_OPERATION_POSSIBLE_HANDLERS,
G_TYPE_STRV, possible_handlers,
NULL);
tp_proxy_add_interface_by_id (TP_PROXY (test->client),
TP_IFACE_QUARK_CLIENT_APPROVER);
tp_cli_client_approver_call_add_dispatch_operation (test->client, -1,
channels, CDO_PATH, properties,
no_return_cb, test, NULL, NULL);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (test->simple_client->add_dispatch_ctx != NULL);
chans = tp_channel_dispatch_operation_borrow_channels (
test->simple_client->add_dispatch_ctx->dispatch_operation);
g_assert_cmpuint (chans->len, ==, 2);
/* Check that we reuse existing proxies rather than creating new ones */
g_assert (test->simple_client->add_dispatch_ctx->account == test->account);
g_assert (tp_channel_dispatch_operation_borrow_account (
test->simple_client->add_dispatch_ctx->dispatch_operation) ==
test->account);
g_assert (tp_channel_dispatch_operation_borrow_connection (
test->simple_client->add_dispatch_ctx->dispatch_operation) ==
test->simple_client->add_dispatch_ctx->connection);
g_assert (chans->len == test->simple_client->add_dispatch_ctx->channels->len);
for (i = 0; i < chans->len; i++)
{
g_assert (g_ptr_array_index (chans, i) ==
g_ptr_array_index (test->simple_client->add_dispatch_ctx->channels,
i));
}
/* Another call to AddDispatchOperation, the second channel will be
* invalidated during the call */
tp_cli_client_approver_call_add_dispatch_operation (test->client, -1,
channels, CDO_PATH, properties,
no_return_cb, test, NULL, NULL);
tp_tests_text_channel_null_close (test->text_chan_service_2);
test->wait++;
g_object_unref (test->text_chan_service_2);
test->text_chan_service_2 = NULL;
tp_tests_simple_channel_dispatch_operation_lost_channel (test->cdo_service,
test->text_chan_2);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (test->simple_client->add_dispatch_ctx != NULL);
/* The CDO only contain valid channels */
chans = tp_channel_dispatch_operation_borrow_channels (
test->simple_client->add_dispatch_ctx->dispatch_operation);
g_assert_cmpuint (chans->len, ==, 1);
/* But the context contains both */
g_assert_cmpuint (test->simple_client->add_dispatch_ctx->channels->len,
==, 2);
/* Another call to AddDispatchOperation, the last channel will be
* invalidated during the call */
tp_cli_client_approver_call_add_dispatch_operation (test->client, -1,
channels, CDO_PATH, properties,
no_return_cb, test, NULL, NULL);
tp_tests_text_channel_null_close (test->text_chan_service);
g_object_unref (test->text_chan_service);
test->text_chan_service = NULL;
tp_tests_simple_channel_dispatch_operation_lost_channel (test->cdo_service,
test->text_chan);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_ptr_array_foreach (channels, free_channel_details, NULL);
g_ptr_array_free (channels, TRUE);
g_hash_table_unref (properties);
}
/* Test Handler */
static void
get_handler_prop_cb (TpProxy *proxy,
GHashTable *properties,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
Test *test = user_data;
GPtrArray *filters;
gboolean bypass;
gboolean valid;
const gchar * const * capabilities;
GPtrArray *handled;
if (error != NULL)
{
test->error = g_error_copy (error);
goto out;
}
g_assert_cmpint (g_hash_table_size (properties), == , 4);
filters = tp_asv_get_boxed (properties, "HandlerChannelFilter",
TP_ARRAY_TYPE_CHANNEL_CLASS_LIST);
check_filters (filters);
bypass = tp_asv_get_boolean (properties, "BypassApproval", &valid);
g_assert (valid);
g_assert (bypass);
capabilities = tp_asv_get_strv (properties, "Capabilities");
g_assert_cmpint (g_strv_length ((GStrv) capabilities), ==, 5);
g_assert (tp_strv_contains (capabilities, "badger"));
g_assert (tp_strv_contains (capabilities, "mushroom"));
g_assert (tp_strv_contains (capabilities, "snake"));
g_assert (tp_strv_contains (capabilities, "goat"));
g_assert (tp_strv_contains (capabilities, "pony"));
handled = tp_asv_get_boxed (properties, "HandledChannels",
TP_ARRAY_TYPE_OBJECT_PATH_LIST);
g_assert (handled != NULL);
g_assert_cmpint (handled->len, ==, 0);
out:
g_main_loop_quit (test->mainloop);
}
static void
channel_invalidated_cb (TpChannel *channel,
guint domain,
gint code,
gchar *message,
Test *test)
{
g_main_loop_quit (test->mainloop);
}
static void
test_handler (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
GHashTable *filter;
const gchar *caps[] = { "mushroom", "snake", NULL };
GPtrArray *channels;
GPtrArray *requests_satisified;
GHashTable *info;
GList *chans;
TpTestsSimpleClient *client_2;
filter = tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
NULL);
tp_base_client_add_handler_filter (test->base_client, filter);
g_hash_table_unref (filter);
tp_base_client_take_handler_filter (test->base_client, tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
TP_HANDLE_TYPE_CONTACT,
NULL));
tp_base_client_set_handler_bypass_approval (test->base_client, TRUE);
tp_base_client_add_handler_capability (test->base_client, "badger");
tp_base_client_add_handler_capabilities (test->base_client, caps);
tp_base_client_add_handler_capabilities_varargs (test->base_client,
"goat", "pony", NULL);
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
/* Check Client properties */
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT, get_client_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert_cmpint (g_strv_length (test->interfaces), ==, 1);
g_assert (tp_strv_contains ((const gchar * const *) test->interfaces,
TP_IFACE_CLIENT_HANDLER));
/* Check Handler properties */
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT_HANDLER, get_handler_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (!tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (!tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
/* Call HandleChannels */
channels = g_ptr_array_sized_new (2);
add_channel_to_ptr_array (channels, test->text_chan);
add_channel_to_ptr_array (channels, test->text_chan_2);
requests_satisified = g_ptr_array_sized_new (0);
info = g_hash_table_new (NULL, NULL);
tp_proxy_add_interface_by_id (TP_PROXY (test->client),
TP_IFACE_QUARK_CLIENT_HANDLER);
tp_cli_client_handler_call_handle_channels (test->client, -1,
tp_proxy_get_object_path (test->account),
tp_proxy_get_object_path (test->connection),
channels, requests_satisified, 0, info,
no_return_cb, test, NULL, NULL);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (test->simple_client->handle_channels_ctx != NULL);
g_assert (test->simple_client->handle_channels_ctx->account == test->account);
chans = tp_base_client_get_handled_channels (test->base_client);
g_assert_cmpuint (g_list_length (chans), ==, 2);
g_list_free (chans);
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
/* One of the channel is closed */
g_signal_connect (test->text_chan, "invalidated",
G_CALLBACK (channel_invalidated_cb), test);
tp_tests_text_channel_null_close (test->text_chan_service);
g_main_loop_run (test->mainloop);
chans = tp_base_client_get_handled_channels (test->base_client);
g_assert_cmpuint (g_list_length (chans), ==, 1);
g_list_free (chans);
g_assert (!tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
/* Create another client sharing the same unique name */
client_2 = tp_tests_simple_client_new (test->dbus, "Test", TRUE);
tp_base_client_be_a_handler (TP_BASE_CLIENT (client_2));
tp_base_client_register (TP_BASE_CLIENT (client_2), &test->error);
g_assert_no_error (test->error);
chans = tp_base_client_get_handled_channels (TP_BASE_CLIENT (client_2));
g_assert_cmpuint (g_list_length (chans), ==, 1);
g_list_free (chans);
g_assert (!tp_base_client_is_handling_channel (TP_BASE_CLIENT (client_2),
test->text_chan));
g_assert (tp_base_client_is_handling_channel (TP_BASE_CLIENT (client_2),
test->text_chan_2));
g_object_unref (client_2);
g_ptr_array_foreach (channels, free_channel_details, NULL);
g_ptr_array_free (channels, TRUE);
g_ptr_array_free (requests_satisified, TRUE);
g_hash_table_unref (info);
}
/* Test Requests interface on Handler */
static void
get_requests_prop_cb (TpProxy *proxy,
GHashTable *properties,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
Test *test = user_data;
if (error != NULL)
{
test->error = g_error_copy (error);
goto out;
}
g_assert_cmpint (g_hash_table_size (properties), == , 0);
out:
g_main_loop_quit (test->mainloop);
}
static void
request_added_cb (TpBaseClient *client,
TpAccount *account,
TpChannelRequest *request,
Test *test)
{
GList *requests;
g_assert (TP_IS_CHANNEL_REQUEST (request));
g_assert (TP_IS_ACCOUNT (account));
g_assert (tp_proxy_is_prepared (account, TP_ACCOUNT_FEATURE_CORE));
requests = tp_base_client_get_pending_requests (test->base_client);
g_assert_cmpuint (g_list_length ((GList *) requests), ==, 1);
g_assert (requests->data == request);
g_list_free (requests);
test->wait--;
if (test->wait == 0)
g_main_loop_quit (test->mainloop);
}
static void
request_removed_cb (TpBaseClient *client,
TpChannelRequest *request,
const gchar *error,
const gchar *reason,
Test *test)
{
g_assert (TP_IS_CHANNEL_REQUEST (request));
test->wait--;
if (test->wait == 0)
g_main_loop_quit (test->mainloop);
}
static void
test_handler_requests (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
GHashTable *properties;
GPtrArray *channels;
GPtrArray *requests_satisified;
GHashTable *info;
TpChannelRequest *request;
GList *requests;
tp_base_client_take_handler_filter (test->base_client, tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
TP_IFACE_CHANNEL_TYPE_STREAM_TUBE,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
TP_HANDLE_TYPE_CONTACT,
NULL));
tp_base_client_set_handler_request_notification (test->base_client);
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
/* Check Client properties */
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT, get_client_prop_cb, test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert_cmpint (g_strv_length (test->interfaces), ==, 2);
g_assert (tp_strv_contains ((const gchar * const *) test->interfaces,
TP_IFACE_CLIENT_HANDLER));
g_assert (tp_strv_contains ((const gchar * const *) test->interfaces,
TP_IFACE_CLIENT_INTERFACE_REQUESTS));
/* Check Requests properties */
tp_cli_dbus_properties_call_get_all (test->client, -1,
TP_IFACE_CLIENT_INTERFACE_REQUESTS, get_requests_prop_cb,
test, NULL, NULL);
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (tp_base_client_get_pending_requests (test->base_client) == NULL);
/* Call AddRequest */
properties = tp_asv_new (
TP_PROP_CHANNEL_REQUEST_ACCOUNT, DBUS_TYPE_G_OBJECT_PATH, ACCOUNT_PATH,
NULL);
tp_proxy_add_interface_by_id (TP_PROXY (test->client),
TP_IFACE_QUARK_CLIENT_INTERFACE_REQUESTS);
g_signal_connect (test->base_client, "request-added",
G_CALLBACK (request_added_cb), test);
tp_cli_client_interface_requests_call_add_request (test->client, -1,
"/Request", properties,
no_return_cb, test, NULL, NULL);
test->wait = 2;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
requests = tp_base_client_get_pending_requests (test->base_client);
g_assert (requests != NULL);
g_list_free (requests);
/* Call HandleChannels */
channels = g_ptr_array_sized_new (2);
add_channel_to_ptr_array (channels, test->text_chan);
requests_satisified = g_ptr_array_sized_new (1);
g_ptr_array_add (requests_satisified, "/Request");
info = g_hash_table_new (NULL, NULL);
tp_proxy_add_interface_by_id (TP_PROXY (test->client),
TP_IFACE_QUARK_CLIENT_HANDLER);
tp_cli_client_handler_call_handle_channels (test->client, -1,
tp_proxy_get_object_path (test->account),
tp_proxy_get_object_path (test->connection),
channels, requests_satisified, 0, info,
no_return_cb, test, NULL, NULL);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (test->simple_client->handle_channels_ctx != NULL);
g_assert_cmpint (
test->simple_client->handle_channels_ctx->requests_satisfied->len, ==, 1);
request = g_ptr_array_index (
test->simple_client->handle_channels_ctx->requests_satisfied, 0);
requests = tp_base_client_get_pending_requests (test->base_client);
g_assert (requests->data == request);
g_list_free (requests);
/* Call RemoveRequest */
g_signal_connect (test->base_client, "request-removed",
G_CALLBACK (request_removed_cb), test);
tp_cli_client_interface_requests_call_remove_request (test->client, -1,
"/Request", "Badger", "snake",
no_return_cb, test, NULL, NULL);
test->wait = 2;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (tp_base_client_get_pending_requests (test->base_client) == NULL);
g_hash_table_unref (properties);
g_ptr_array_foreach (channels, free_channel_details, NULL);
g_ptr_array_free (channels, TRUE);
g_ptr_array_free (requests_satisified, TRUE);
g_hash_table_unref (info);
}
static void
claim_with_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
Test *test = user_data;
tp_channel_dispatch_operation_claim_with_finish (
TP_CHANNEL_DISPATCH_OPERATION (source), result, &test->error);
test->wait--;
if (test->wait == 0)
g_main_loop_quit (test->mainloop);
}
static void
cdo_finished_cb (TpTestsSimpleChannelDispatchOperation *cdo,
Test *test)
{
tp_clear_object (&test->cdo_service);
}
static void
test_channel_dispatch_operation_claim_with_async (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
GPtrArray *channels;
GHashTable *properties;
static const char *interfaces[] = { NULL };
static const gchar *possible_handlers[] = {
TP_CLIENT_BUS_NAME_BASE ".Badger", NULL, };
TpChannelDispatchOperation *cdo;
GList *handled;
/* Register an Approver and Handler */
tp_base_client_take_approver_filter (test->base_client, tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
TP_IFACE_CHANNEL_TYPE_TEXT,
NULL));
tp_base_client_take_handler_filter (test->base_client, tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
TP_IFACE_CHANNEL_TYPE_TEXT,
NULL));
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
/* Call AddDispatchOperation */
channels = g_ptr_array_sized_new (2);
add_channel_to_ptr_array (channels, test->text_chan);
add_channel_to_ptr_array (channels, test->text_chan_2);
properties = tp_asv_new (
TP_PROP_CHANNEL_DISPATCH_OPERATION_INTERFACES,
G_TYPE_STRV, interfaces,
TP_PROP_CHANNEL_DISPATCH_OPERATION_CONNECTION,
DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (test->connection),
TP_PROP_CHANNEL_DISPATCH_OPERATION_ACCOUNT,
DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (test->account),
TP_PROP_CHANNEL_DISPATCH_OPERATION_POSSIBLE_HANDLERS,
G_TYPE_STRV, possible_handlers,
NULL);
tp_proxy_add_interface_by_id (TP_PROXY (test->client),
TP_IFACE_QUARK_CLIENT_APPROVER);
tp_cli_client_approver_call_add_dispatch_operation (test->client, -1,
channels, CDO_PATH, properties,
no_return_cb, test, NULL, NULL);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
cdo = test->simple_client->add_dispatch_ctx->dispatch_operation;
g_assert (TP_IS_CHANNEL_DISPATCH_OPERATION (cdo));
handled = tp_base_client_get_handled_channels (test->base_client);
g_assert (handled == NULL);
/* Connect to CDO's Finished signal so we can remove it from the bus when
* it's claimed as MC would do. */
g_signal_connect (test->cdo_service, "finished",
G_CALLBACK (cdo_finished_cb), test);
/* Claim the CDO, as the client is also a Handler, it is now handling the
* channels */
tp_channel_dispatch_operation_claim_with_async (cdo, test->base_client,
claim_with_cb, test);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
handled = tp_base_client_get_handled_channels (test->base_client);
g_assert_cmpuint (g_list_length (handled), ==, 2);
g_list_free (handled);
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
g_ptr_array_foreach (channels, free_channel_details, NULL);
g_ptr_array_free (channels, TRUE);
g_hash_table_unref (properties);
}
static void
delegate_channels_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
Test *test = user_data;
tp_base_client_delegate_channels_finish (
TP_BASE_CLIENT (source), result, &test->delegated, &test->not_delegated,
&test->error);
test->wait--;
if (test->wait == 0)
g_main_loop_quit (test->mainloop);
}
static void
test_delegate_channels (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
GPtrArray *channels;
GPtrArray *requests_satisified;
GHashTable *info;
GList *chans;
GError *error = NULL;
tp_base_client_be_a_handler (test->base_client);
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
/* Call HandleChannels */
channels = g_ptr_array_sized_new (2);
add_channel_to_ptr_array (channels, test->text_chan);
add_channel_to_ptr_array (channels, test->text_chan_2);
requests_satisified = g_ptr_array_sized_new (0);
info = g_hash_table_new (NULL, NULL);
tp_proxy_add_interface_by_id (TP_PROXY (test->client),
TP_IFACE_QUARK_CLIENT_HANDLER);
tp_cli_client_handler_call_handle_channels (test->client, -1,
tp_proxy_get_object_path (test->account),
tp_proxy_get_object_path (test->connection),
channels, requests_satisified, 0, info,
no_return_cb, test, NULL, NULL);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
/* The client is handling the 2 channels */
chans = tp_base_client_get_handled_channels (test->base_client);
g_assert_cmpuint (g_list_length (chans), ==, 2);
g_list_free (chans);
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
/* Try to delegate the first one */
chans = g_list_append (NULL, test->text_chan);
tp_base_client_delegate_channels_async (test->base_client,
chans, TP_USER_ACTION_TIME_CURRENT_TIME, NULL,
delegate_channels_cb, test);
g_list_free (chans);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert_cmpuint (test->delegated->len, ==, 1);
g_assert (g_ptr_array_index (test->delegated, 0) == test->text_chan);
g_assert_cmpuint (g_hash_table_size (test->not_delegated), ==, 0);
/* Client is not handling the channel any more */
chans = tp_base_client_get_handled_channels (test->base_client);
g_assert_cmpuint (g_list_length (chans), ==, 1);
g_list_free (chans);
g_assert (!tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
/* Try delegating the second channel, but MC refuses */
test->cd_service->refuse_delegate = TRUE;
chans = g_list_append (NULL, test->text_chan_2);
tp_base_client_delegate_channels_async (test->base_client,
chans, TP_USER_ACTION_TIME_CURRENT_TIME, NULL,
delegate_channels_cb, test);
g_list_free (chans);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert_cmpuint (test->delegated->len, ==, 0);
g_assert_cmpuint (g_hash_table_size (test->not_delegated), ==, 1);
error = g_hash_table_lookup (test->not_delegated, test->text_chan_2);
g_assert_error (error, TP_ERRORS, TP_ERROR_BUSY);
/* Client is still handling the channel */
chans = tp_base_client_get_handled_channels (test->base_client);
g_assert_cmpuint (g_list_length (chans), ==, 1);
g_list_free (chans);
g_assert (!tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
g_ptr_array_foreach (channels, free_channel_details, NULL);
g_ptr_array_free (channels, TRUE);
g_ptr_array_free (requests_satisified, TRUE);
g_hash_table_unref (info);
}
static void
present_channel_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
Test *test = user_data;
tp_channel_dispatcher_present_channel_finish (
TP_CHANNEL_DISPATCHER (source), result, &test->error);
test->wait--;
if (test->wait == 0)
g_main_loop_quit (test->mainloop);
}
static void
test_present_channel (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
TpChannelDispatcher *cd;
cd = tp_channel_dispatcher_new (test->dbus);
tp_channel_dispatcher_present_channel_async (cd, test->text_chan,
TP_USER_ACTION_TIME_CURRENT_TIME, present_channel_cb, test);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_object_unref (cd);
}
#define PREFERRED_HANDLER_NAME TP_CLIENT_BUS_NAME_BASE ".Badger"
static gboolean
channel_in_array (GPtrArray *array,
TpChannel *channel)
{
guint i;
for (i = 0; i < array->len; i++)
{
TpChannel *c = g_ptr_array_index (array, i);
if (!tp_strdiff (tp_proxy_get_object_path (channel),
tp_proxy_get_object_path (c)))
return TRUE;
}
return FALSE;
}
static void
delegated_channels_cb (TpBaseClient *client,
GPtrArray *channels,
gpointer user_data)
{
Test *test = user_data;
g_assert_cmpuint (channels->len, ==, 2);
g_assert (channel_in_array (channels, test->text_chan));
g_assert (channel_in_array (channels, test->text_chan_2));
test->wait--;
if (test->wait == 0)
g_main_loop_quit (test->mainloop);
}
static void
delegate_to_preferred_handler (Test *test,
gboolean supported)
{
GPtrArray *channels;
GPtrArray *requests_satisified;
GPtrArray *requests;
GHashTable *request_props;
GHashTable *info;
TpTestsSimpleChannelRequest *cr;
GHashTable *hints;
tp_base_client_be_a_handler (test->base_client);
if (supported)
{
tp_base_client_set_delegated_channels_callback (test->base_client,
delegated_channels_cb, test, NULL);
}
tp_base_client_register (test->base_client, &test->error);
g_assert_no_error (test->error);
/* Call HandleChannels */
channels = g_ptr_array_sized_new (2);
add_channel_to_ptr_array (channels, test->text_chan);
add_channel_to_ptr_array (channels, test->text_chan_2);
requests_satisified = g_ptr_array_sized_new (0);
info = g_hash_table_new (NULL, NULL);
tp_proxy_add_interface_by_id (TP_PROXY (test->client),
TP_IFACE_QUARK_CLIENT_HANDLER);
tp_cli_client_handler_call_handle_channels (test->client, -1,
tp_proxy_get_object_path (test->account),
tp_proxy_get_object_path (test->connection),
channels, requests_satisified, 0, info,
no_return_cb, test, NULL, NULL);
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
/* The client is handling the 2 channels */
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
/* Another client asks to dispatch the channel to it */
requests = g_ptr_array_new ();
hints = tp_asv_new (
"org.freedesktop.Telepathy.ChannelRequest.DelegateToPreferredHandler",
G_TYPE_BOOLEAN, TRUE,
NULL);
cr = tp_tests_simple_channel_request_new ("/CR",
TP_TESTS_SIMPLE_CONNECTION (test->base_connection), ACCOUNT_PATH,
TP_USER_ACTION_TIME_CURRENT_TIME, PREFERRED_HANDLER_NAME,
requests, hints);
g_ptr_array_add (requests_satisified, "/CR");
request_props = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, (GDestroyNotify) g_hash_table_unref);
g_hash_table_insert (request_props, "/CR",
tp_tests_simple_channel_request_dup_immutable_props (cr));
tp_asv_set_boxed (info,
"request-properties", TP_HASH_TYPE_OBJECT_IMMUTABLE_PROPERTIES_MAP,
request_props);
tp_cli_client_handler_call_handle_channels (test->client, -1,
tp_proxy_get_object_path (test->account),
tp_proxy_get_object_path (test->connection),
channels, requests_satisified, 0, info,
no_return_cb, test, NULL, NULL);
test->wait = 1;
/* If we support the DelegateToPreferredHandler hint, we wait for
* delegated_channels_cb to be called */
if (supported)
test->wait++;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
if (supported)
{
/* We are not handling the channels any more */
g_assert (!tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (!tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
}
else
{
/* We are still handling the channels */
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan));
g_assert (tp_base_client_is_handling_channel (test->base_client,
test->text_chan_2));
}
tp_base_client_unregister (test->base_client);
g_object_unref (cr);
g_ptr_array_foreach (channels, free_channel_details, NULL);
g_ptr_array_free (channels, TRUE);
g_ptr_array_free (requests_satisified, TRUE);
g_ptr_array_free (requests, TRUE);
g_hash_table_unref (info);
g_hash_table_unref (hints);
g_hash_table_unref (request_props);
}
static void
test_delegate_to_preferred_handler_not_supported (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
delegate_to_preferred_handler (test, FALSE);
}
static void
test_delegate_to_preferred_handler_supported (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
delegate_to_preferred_handler (test, TRUE);
}
int
main (int argc,
char **argv)
{
tp_tests_init (&argc, &argv);
g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id=");
g_test_add ("/base-client/basics", Test, NULL, setup, test_basics, teardown);
g_test_add ("/base-client/register", Test, NULL, setup, test_register,
teardown);
g_test_add ("/base-client/observer", Test, NULL, setup, test_observer,
teardown);
g_test_add ("/base-client/approver", Test, NULL, setup, test_approver,
teardown);
g_test_add ("/base-client/handler", Test, NULL, setup, test_handler,
teardown);
g_test_add ("/base-client/handler-requests", Test, NULL, setup,
test_handler_requests, teardown);
g_test_add ("/cdo/claim_with", Test, NULL, setup,
test_channel_dispatch_operation_claim_with_async, teardown);
g_test_add ("/base-client/delegate-channels", Test, NULL, setup,
test_delegate_channels, teardown);
g_test_add ("/cd/present-channel", Test, NULL, setup,
test_present_channel, teardown);
g_test_add ("/cd/delegate-to-preferred-handler/not-supported", Test, NULL,
setup, test_delegate_to_preferred_handler_not_supported, teardown);
g_test_add ("/cd/delegate-to-preferred-handler/supported", Test, NULL,
setup, test_delegate_to_preferred_handler_supported, teardown);
return g_test_run ();
}