/* Tests of TpSimpleApprover
*
* 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.
*/
#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-conn.h"
#include "tests/lib/textchan-null.h"
typedef struct {
GMainLoop *mainloop;
TpDBusDaemon *dbus;
/* Service side objects */
TpBaseClient *simple_approver;
TpBaseConnection *base_connection;
TpTestsSimpleAccount *account_service;
TpTestsTextChannelNull *text_chan_service;
TpTestsSimpleChannelDispatchOperation *cdo_service;
/* Client side objects */
TpClient *client;
TpConnection *connection;
TpAccount *account;
TpAccountManager *account_manager;
TpChannel *text_chan;
GError *error /* initialized where needed */;
} 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;
/* 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 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);
test->account_manager = tp_account_manager_new (test->dbus);
g_assert (test->account_manager != NULL);
/* Create client-side Account object */
test->account = tp_account_manager_ensure_account (test->account_manager,
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 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);
g_assert (tp_dbus_daemon_request_name (test->dbus,
TP_CHANNEL_DISPATCHER_BUS_NAME, FALSE, NULL));
}
static void
teardown (Test *test,
gconstpointer data)
{
g_clear_error (&test->error);
tp_dbus_daemon_release_name (test->dbus, TP_CHANNEL_DISPATCHER_BUS_NAME,
NULL);
g_object_unref (test->simple_approver);
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);
g_object_unref (test->text_chan_service);
g_object_unref (test->text_chan);
g_object_unref (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);
}
static void
create_simple_approver (Test *test,
TpSimpleApproverAddDispatchOperationImpl impl)
{
/* Create service-side Client object */
test->simple_approver = tp_simple_approver_new_with_am (
test->account_manager, "MySimpleApprover", FALSE, impl, test, NULL);
g_assert (test->simple_approver != NULL);
/* 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->simple_approver),
"object-path", tp_base_client_get_object_path (test->simple_approver),
NULL);
g_assert (test->client != NULL);
}
static void
get_client_prop_cb (TpProxy *proxy,
GHashTable *properties,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
Test *test = user_data;
const gchar * const *interfaces;
if (error != NULL)
{
test->error = g_error_copy (error);
goto out;
}
g_assert_cmpint (g_hash_table_size (properties), == , 1);
interfaces = tp_asv_get_strv (properties, "Interfaces");
g_assert_cmpint (g_strv_length ((GStrv) interfaces), ==, 1);
g_assert (tp_strv_contains (interfaces, TP_IFACE_CLIENT_APPROVER));
out:
g_main_loop_quit (test->mainloop);
}
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_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
add_dispatch_success (
TpSimpleApprover *approver,
TpAccount *account,
TpConnection *connection,
GList *channels,
TpChannelDispatchOperation *dispatch_operation,
TpAddDispatchOperationContext *context,
gpointer user_data)
{
tp_add_dispatch_operation_context_accept (context);
}
static void
test_properties (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
create_simple_approver (test, add_dispatch_success);
tp_base_client_take_approver_filter (test->simple_approver, tp_asv_new (
TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
NULL));
tp_base_client_take_approver_filter (test->simple_approver, 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->simple_approver, &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);
/* 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);
}
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:
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
call_add_dispatch (Test *test)
{
GPtrArray *channels;
GHashTable *properties;
static const char *interfaces[] = { NULL };
static const gchar *possible_handlers[] = {
TP_CLIENT_BUS_NAME_BASE ".Badger", NULL, };
channels = g_ptr_array_sized_new (1);
add_channel_to_ptr_array (channels, test->text_chan);
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);
g_main_loop_run (test->mainloop);
g_ptr_array_foreach (channels, free_channel_details, NULL);
g_ptr_array_free (channels, TRUE);
g_hash_table_unref (properties);
}
/* AddDispatchOperation returns immediately */
static void
test_success (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
create_simple_approver (test, add_dispatch_success);
tp_base_client_take_approver_filter (test->simple_approver,
g_hash_table_new (NULL, NULL));
tp_base_client_register (test->simple_approver, &test->error);
g_assert_no_error (test->error);
call_add_dispatch (test);
g_assert_no_error (test->error);
}
/* AddDispatchOperation returns in an async way */
static gboolean
accept_idle_cb (gpointer data)
{
TpAddDispatchOperationContext *context = data;
tp_add_dispatch_operation_context_accept (context);
g_object_unref (context);
return FALSE;
}
static void
add_dispatch_async (
TpSimpleApprover *approver,
TpAccount *account,
TpConnection *connection,
GList *channels,
TpChannelDispatchOperation *dispatch_operation,
TpAddDispatchOperationContext *context,
gpointer user_data)
{
Test *test = user_data;
g_idle_add (accept_idle_cb, g_object_ref (context));
g_assert (account == test->account);
tp_add_dispatch_operation_context_delay (context);
}
static void
test_delayed (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
create_simple_approver (test, add_dispatch_async);
tp_base_client_take_approver_filter (test->simple_approver,
g_hash_table_new (NULL, NULL));
tp_base_client_register (test->simple_approver, &test->error);
g_assert_no_error (test->error);
call_add_dispatch (test);
g_assert_no_error (test->error);
}
/* AddDispatchOperation fails */
static void
add_dispatch_fail (
TpSimpleApprover *approver,
TpAccount *account,
TpConnection *connection,
GList *channels,
TpChannelDispatchOperation *dispatch_operation,
TpAddDispatchOperationContext *context,
gpointer user_data)
{
GError error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
"No AddDispatchOperation for you!" };
tp_add_dispatch_operation_context_fail (context, &error);
}
static void
test_fail (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
create_simple_approver (test, add_dispatch_fail);
tp_base_client_take_approver_filter (test->simple_approver,
g_hash_table_new (NULL, NULL));
tp_base_client_register (test->simple_approver, &test->error);
g_assert_no_error (test->error);
call_add_dispatch (test);
g_assert_error (test->error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE);
}
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 ("/simple-/properties", Test, NULL, setup, test_properties,
teardown);
g_test_add ("/simple-approver/success", Test, NULL, setup, test_success,
teardown);
g_test_add ("/simple-approver/delayed", Test, NULL, setup, test_delayed,
teardown);
g_test_add ("/simple-approver/fail", Test, NULL, setup, test_fail,
teardown);
return g_test_run ();
}