/* Tests of TpTextChannel
*
* 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 "config.h"
#include
#include
#include
#include "examples/cm/contactlist/conn.h"
#include "tests/lib/util.h"
typedef struct {
GMainLoop *mainloop;
TpDBusDaemon *dbus;
/* Service side objects */
TpBaseConnection *base_connection;
TpHandleRepoIface *contact_repo;
/* Client side objects */
TpConnection *connection;
TpTextChannel *channel;
TpTextChannel *sms_channel;
GPtrArray *blocked_added;
GPtrArray *blocked_removed;
TpContact *contact;
GError *error /* initialized where needed */;
gint wait;
} Test;
static void
setup (Test *test,
gconstpointer data)
{
gchar *conn_name, *conn_path;
GQuark conn_features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };
test->mainloop = g_main_loop_new (NULL, FALSE);
test->dbus = tp_tests_dbus_daemon_dup_or_die ();
test->error = NULL;
/* Create (service and client sides) connection objects */
test->base_connection = tp_tests_object_new_static_class (
EXAMPLE_TYPE_CONTACT_LIST_CONNECTION,
"account", "me@test.com",
"simulation-delay", 0,
"protocol", "test",
NULL);
g_assert (tp_base_connection_register (test->base_connection, "example",
&conn_name, &conn_path, &test->error));
g_assert_no_error (test->error);
test->connection = tp_connection_new (test->dbus, conn_name, conn_path,
&test->error);
g_assert_no_error (test->error);
test->contact_repo = tp_base_connection_get_handles (test->base_connection,
TP_HANDLE_TYPE_CONTACT);
g_assert (test->contact_repo != NULL);
/* Connect the connection */
tp_cli_connection_call_connect (test->connection, -1, NULL, NULL, NULL, NULL);
tp_tests_proxy_run_until_prepared (test->connection, conn_features);
g_free (conn_name);
g_free (conn_path);
}
static void
teardown (Test *test,
gconstpointer data)
{
g_clear_error (&test->error);
tp_clear_object (&test->dbus);
g_main_loop_unref (test->mainloop);
test->mainloop = NULL;
tp_tests_connection_assert_disconnect_succeeds (test->connection);
g_object_unref (test->connection);
g_object_unref (test->base_connection);
tp_clear_pointer (&test->blocked_added, g_ptr_array_unref);
tp_clear_pointer (&test->blocked_removed, g_ptr_array_unref);
g_clear_object (&test->contact);
}
static void
block_contacts_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
Test *test = user_data;
tp_connection_block_contacts_finish (TP_CONNECTION (source), result,
&test->error);
g_assert_no_error (test->error);
test->wait--;
if (test->wait <= 0)
g_main_loop_quit (test->mainloop);
}
static void
unblock_contacts_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
Test *test = user_data;
tp_connection_unblock_contacts_finish (TP_CONNECTION (source), result,
&test->error);
g_assert_no_error (test->error);
test->wait--;
if (test->wait <= 0)
g_main_loop_quit (test->mainloop);
}
static void
contact_block_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
Test *test = user_data;
tp_contact_block_finish (TP_CONTACT (source), result, &test->error);
g_assert_no_error (test->error);
test->wait--;
if (test->wait <= 0)
g_main_loop_quit (test->mainloop);
}
static void
contact_unblock_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
Test *test = user_data;
tp_contact_unblock_finish (TP_CONTACT (source), result, &test->error);
g_assert_no_error (test->error);
test->wait--;
if (test->wait <= 0)
g_main_loop_quit (test->mainloop);
}
static TpContact *
create_contact (Test *test,
const gchar *id)
{
TpHandle handle;
TpContact *contact;
handle = tp_handle_ensure (test->contact_repo, id, NULL, &test->error);
g_assert_no_error (test->error);
contact = tp_connection_dup_contact_if_possible (test->connection, handle,
id);
g_assert (contact != NULL);
return contact;
}
static void
test_block_unblock (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
TpContact *alice, *bob;
GPtrArray *arr;
alice = create_contact (test, "alice");
bob = create_contact (test, "bob");
arr = g_ptr_array_sized_new (2);
g_ptr_array_add (arr, alice);
g_ptr_array_add (arr, bob);
/* Block contacts */
tp_connection_block_contacts_async (test->connection,
arr->len, (TpContact * const *) arr->pdata, FALSE,
block_contacts_cb, test);
test->wait = 1;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
/* Unblock contacts */
tp_connection_unblock_contacts_async (test->connection,
arr->len, (TpContact * const *) arr->pdata,
unblock_contacts_cb, test);
test->wait = 1;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_object_unref (alice);
g_object_unref (bob);
g_ptr_array_unref (arr);
}
static void
proxy_prepare_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
Test *test = user_data;
tp_proxy_prepare_finish (source, result, &test->error);
test->wait--;
if (test->wait <= 0)
g_main_loop_quit (test->mainloop);
}
static void
test_can_report_abusive (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
GQuark features[] = { TP_CONNECTION_FEATURE_CONTACT_BLOCKING, 0 };
gboolean abuse;
/* Feature is not prepared yet */
g_object_get (test->connection, "can-report-abusive", &abuse, NULL);
g_assert (!abuse);
g_assert (!tp_connection_can_report_abusive (test->connection));
tp_proxy_prepare_async (test->connection, features,
proxy_prepare_cb, test);
test->wait = 1;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (tp_proxy_is_prepared (test->connection,
TP_CONNECTION_FEATURE_CONTACT_BLOCKING));
g_object_get (test->connection, "can-report-abusive", &abuse, NULL);
g_assert (abuse);
g_assert (tp_connection_can_report_abusive (test->connection));
}
static void
blocked_contacts_changed_cb (TpConnection *conn,
GPtrArray *added,
GPtrArray *removed,
Test *test)
{
tp_clear_pointer (&test->blocked_added, g_ptr_array_unref);
tp_clear_pointer (&test->blocked_removed, g_ptr_array_unref);
test->blocked_added = g_ptr_array_ref (added);
test->blocked_removed = g_ptr_array_ref (removed);
test->wait--;
if (test->wait <= 0)
g_main_loop_quit (test->mainloop);
}
static void
test_blocked_contacts (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
GQuark features[] = { TP_CONNECTION_FEATURE_CONTACT_BLOCKING, 0 };
GPtrArray *blocked;
TpContact *alice, *bill, *guillaume, *sjoerd, *steve;
gboolean use_contact_api = GPOINTER_TO_UINT (data);
sjoerd = create_contact (test, "sjoerd@example.com");
steve = create_contact (test, "steve@example.com");
/* Feature is not prepared yet */
g_object_get (test->connection, "blocked-contacts", &blocked, NULL);
g_assert_cmpuint (blocked->len, == , 0);
g_ptr_array_unref (blocked);
blocked = tp_connection_get_blocked_contacts (test->connection);
g_assert_cmpuint (blocked->len, == , 0);
/* Prepare the feature */
tp_proxy_prepare_async (test->connection, features,
proxy_prepare_cb, test);
test->wait = 1;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
/* 2 contacts are already blocked in the CM */
g_object_get (test->connection, "blocked-contacts", &blocked, NULL);
g_assert_cmpuint (blocked->len, == , 2);
g_ptr_array_unref (blocked);
blocked = tp_connection_get_blocked_contacts (test->connection);
g_assert_cmpuint (blocked->len, == , 2);
/* Preparing TP_CONNECTION_FEATURE_CONTACT_BLOCKING gives us
* TP_CONTACT_FEATURE_CONTACT_BLOCKING for free. Test that this works with
* existing and newly created TpContact. */
bill = create_contact (test, "bill@example.com");
guillaume = create_contact (test, "guillaume@example.com");
g_assert (tp_contact_has_feature (sjoerd,
TP_CONTACT_FEATURE_CONTACT_BLOCKING));
g_assert (!tp_contact_is_blocked (sjoerd));
g_assert (tp_contact_has_feature (steve,
TP_CONTACT_FEATURE_CONTACT_BLOCKING));
g_assert (tp_contact_is_blocked (steve));
g_assert (tp_contact_has_feature (bill, TP_CONTACT_FEATURE_CONTACT_BLOCKING));
g_assert (tp_contact_is_blocked (bill));
g_assert (tp_contact_has_feature (guillaume,
TP_CONTACT_FEATURE_CONTACT_BLOCKING));
g_assert (!tp_contact_is_blocked (guillaume));
g_object_unref (steve);
g_object_unref (sjoerd);
g_object_unref (bill);
g_object_unref (guillaume);
/* Let's block another contact */
alice = create_contact (test, "alice");
g_signal_connect (test->connection, "blocked-contacts-changed",
G_CALLBACK (blocked_contacts_changed_cb), test);
if (use_contact_api)
{
tp_contact_block_async (alice, FALSE, contact_block_cb, test);
}
else
{
tp_connection_block_contacts_async (test->connection,
1, &alice, FALSE, block_contacts_cb, test);
}
g_object_unref (alice);
test->wait = 2;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert_cmpuint (test->blocked_added->len, ==, 1);
g_assert_cmpuint (test->blocked_removed->len, ==, 0);
alice = g_ptr_array_index (test->blocked_added, 0);
g_assert (TP_IS_CONTACT (alice));
g_assert_cmpstr (tp_contact_get_identifier (alice), ==, "alice");
blocked = tp_connection_get_blocked_contacts (test->connection);
g_assert_cmpuint (blocked->len, == , 3);
/* Cool, now unblock the poor Alice */
if (use_contact_api)
{
tp_contact_unblock_async (alice, contact_unblock_cb, test);
}
else
{
tp_connection_unblock_contacts_async (test->connection,
1, &alice, unblock_contacts_cb, test);
}
test->wait = 2;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert_cmpuint (test->blocked_added->len, ==, 0);
g_assert_cmpuint (test->blocked_removed->len, ==, 1);
alice = g_ptr_array_index (test->blocked_removed, 0);
g_assert (TP_IS_CONTACT (alice));
g_assert_cmpstr (tp_contact_get_identifier (alice), ==, "alice");
blocked = tp_connection_get_blocked_contacts (test->connection);
g_assert_cmpuint (blocked->len, == , 2);
}
static void
get_contacts_by_id_cb (TpConnection *connection,
guint n_contacts,
TpContact * const *contacts,
const gchar * const *requested_ids,
GHashTable *failed_id_errors,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
Test *test = user_data;
g_clear_object (&test->contact);
if (error != NULL)
{
test->error = g_error_copy (error);
}
else
{
test->contact = g_object_ref (contacts[0]);
}
test->wait--;
if (test->wait <= 0)
g_main_loop_quit (test->mainloop);
}
static void
contact_list_state_change_cb (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
TpConnection *conn = (TpConnection *) object;
Test *test = user_data;
if (tp_connection_get_contact_list_state (conn) !=
TP_CONTACT_LIST_STATE_SUCCESS)
return;
test->wait--;
if (test->wait <= 0)
g_main_loop_quit (test->mainloop);
}
static void
property_change_cb (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
Test *test = user_data;
test->wait--;
if (test->wait <= 0)
g_main_loop_quit (test->mainloop);
}
static void
test_is_blocked (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
const gchar *id = "bill@example.com";
TpContactFeature features[] = { TP_CONTACT_FEATURE_CONTACT_BLOCKING };
GQuark conn_features[] = { TP_CONNECTION_FEATURE_CONTACT_LIST, 0 };
tp_proxy_prepare_async (test->connection, conn_features,
proxy_prepare_cb, test);
test->wait = 1;
/* We have to wait that the ContactList has been fetched by the CM */
if (tp_connection_get_contact_list_state (test->connection) !=
TP_CONTACT_LIST_STATE_SUCCESS)
{
g_signal_connect (test->connection, "notify::contact-list-state",
G_CALLBACK (contact_list_state_change_cb), test);
test->wait++;
}
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
/* Bill is already blocked in the CM */
tp_connection_get_contacts_by_id (test->connection, 1, &id,
G_N_ELEMENTS (features), features, get_contacts_by_id_cb, test,
NULL, NULL);
test->wait = 1;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (TP_IS_CONTACT (test->contact));
g_assert (tp_contact_has_feature (test->contact,
TP_CONTACT_FEATURE_CONTACT_BLOCKING));
g_assert (tp_contact_is_blocked (test->contact));
/* Unblock Bill */
g_signal_connect (test->contact, "notify::is-blocked",
G_CALLBACK (property_change_cb), test);
tp_contact_unblock_async (test->contact, contact_unblock_cb, test);
test->wait = 2;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (!tp_contact_is_blocked (test->contact));
}
static void
test_contact_list_properties (Test *test,
gconstpointer data)
{
gboolean props_only = GPOINTER_TO_UINT (data);
GQuark conn_features[] = { 0, 0 };
GPtrArray *contacts;
if (props_only)
conn_features[0] = TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES;
else
conn_features[0] = TP_CONNECTION_FEATURE_CONTACT_LIST;
/* Feature isn't prepared yet */
g_assert (!tp_proxy_is_prepared (test->connection,
TP_CONNECTION_FEATURE_CONTACT_LIST));
g_assert (!tp_proxy_is_prepared (test->connection,
TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES));
g_assert_cmpuint (tp_connection_get_contact_list_state (test->connection), ==,
TP_CONTACT_LIST_STATE_NONE);
g_assert (!tp_connection_get_contact_list_persists (test->connection));
g_assert (!tp_connection_get_can_change_contact_list (test->connection));
g_assert (!tp_connection_get_request_uses_message (test->connection));
tp_proxy_prepare_async (test->connection, conn_features,
proxy_prepare_cb, test);
test->wait = 1;
g_main_loop_run (test->mainloop);
g_assert_no_error (test->error);
g_assert (tp_proxy_is_prepared (test->connection,
TP_CONNECTION_FEATURE_CONTACT_LIST) == !props_only);
g_assert (tp_proxy_is_prepared (test->connection,
TP_CONNECTION_FEATURE_CONTACT_LIST_PROPERTIES));
g_assert (tp_connection_get_contact_list_persists (test->connection));
g_assert (tp_connection_get_can_change_contact_list (test->connection));
g_assert (tp_connection_get_request_uses_message (test->connection));
contacts = tp_connection_dup_contact_list (test->connection);
if (props_only)
{
/* Contacts haven't be fetched */
g_assert_cmpuint (contacts->len, ==, 0);
}
else
{
g_assert_cmpuint (contacts->len, >, 0);
}
g_ptr_array_unref (contacts);
}
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 ("/contact-list-client/blocking/block-unblock", Test, NULL, setup,
test_block_unblock, teardown);
g_test_add ("/contact-list-client/blocking/can-report-abusive", Test, NULL,
setup, test_can_report_abusive, teardown);
g_test_add ("/contact-list-client/blocking/connection/blocked-contacts", Test,
GUINT_TO_POINTER (FALSE), setup, test_blocked_contacts, teardown);
g_test_add ("/contact-list-client/blocking/contact/blocked-contacts", Test,
GUINT_TO_POINTER (TRUE), setup, test_blocked_contacts, teardown);
g_test_add ("/contact-list-client/blocking/is-blocked", Test, NULL,
setup, test_is_blocked, teardown);
g_test_add ("/contact-list-client/contact-list/properties", Test,
GUINT_TO_POINTER (FALSE), setup, test_contact_list_properties, teardown);
g_test_add ("/contact-list-client/contact-list/properties/props-only", Test,
GUINT_TO_POINTER (TRUE), setup, test_contact_list_properties, teardown);
return tp_tests_run_with_bus ();
}