summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/lib/Makefile.am4
-rw-r--r--tests/lib/room-list-chan.c253
-rw-r--r--tests/lib/room-list-chan.h50
-rw-r--r--tests/lib/simple-conn.c172
-rw-r--r--tests/lib/simple-conn.h5
-rw-r--r--tests/lib/textchan-null.c15
-rw-r--r--tests/lib/util.c340
-rw-r--r--tests/lib/util.h36
8 files changed, 777 insertions, 98 deletions
diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am
index e0b7940..faae79a 100644
--- a/tests/lib/Makefile.am
+++ b/tests/lib/Makefile.am
@@ -3,6 +3,8 @@ noinst_LTLIBRARIES = libtp-logger-tests.la
libtp_logger_tests_la_SOURCES = \
contacts-conn.c \
contacts-conn.h \
+ room-list-chan.c \
+ room-list-chan.h \
simple-account.c \
simple-account.h \
simple-account-manager.c \
@@ -23,4 +25,4 @@ AM_CFLAGS = \
$(TPL_CFLAGS)\
$(NULL)
-libtp_logger_tests_la_LIBADD = $(TPL_LIBS) \ No newline at end of file
+libtp_logger_tests_la_LIBADD = $(TPL_LIBS)
diff --git a/tests/lib/room-list-chan.c b/tests/lib/room-list-chan.c
new file mode 100644
index 0000000..49ed291
--- /dev/null
+++ b/tests/lib/room-list-chan.c
@@ -0,0 +1,253 @@
+
+#include "config.h"
+
+#include "room-list-chan.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/channel-iface.h>
+#include <telepathy-glib/svc-channel.h>
+
+static void room_list_iface_init (gpointer iface,
+ gpointer data);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsRoomListChan, tp_tests_room_list_chan, TP_TYPE_BASE_CHANNEL,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_ROOM_LIST, room_list_iface_init))
+
+enum {
+ PROP_SERVER = 1,
+ LAST_PROPERTY,
+};
+
+/*
+enum {
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+*/
+
+struct _TpTestsRoomListChanPriv {
+ gchar *server;
+ gboolean listing;
+};
+
+static void
+tp_tests_room_list_chan_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsRoomListChan *self = TP_TESTS_ROOM_LIST_CHAN (object);
+
+ switch (property_id)
+ {
+ case PROP_SERVER:
+ g_value_set_string (value, self->priv->server);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+tp_tests_room_list_chan_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsRoomListChan *self = TP_TESTS_ROOM_LIST_CHAN (object);
+
+ switch (property_id)
+ {
+ case PROP_SERVER:
+ g_assert (self->priv->server == NULL); /* construct only */
+ self->priv->server = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+tp_tests_room_list_chan_constructed (GObject *object)
+{
+ TpTestsRoomListChan *self = TP_TESTS_ROOM_LIST_CHAN (object);
+ void (*chain_up) (GObject *) =
+ ((GObjectClass *) tp_tests_room_list_chan_parent_class)->constructed;
+
+ if (chain_up != NULL)
+ chain_up (object);
+
+ tp_base_channel_register (TP_BASE_CHANNEL (self));
+}
+
+static void
+tp_tests_room_list_chan_finalize (GObject *object)
+{
+ TpTestsRoomListChan *self = TP_TESTS_ROOM_LIST_CHAN (object);
+ void (*chain_up) (GObject *) =
+ ((GObjectClass *) tp_tests_room_list_chan_parent_class)->finalize;
+
+ g_free (self->priv->server);
+
+ if (chain_up != NULL)
+ chain_up (object);
+}
+
+static void
+fill_immutable_properties (TpBaseChannel *chan,
+ GHashTable *properties)
+{
+ TpBaseChannelClass *klass = TP_BASE_CHANNEL_CLASS (
+ tp_tests_room_list_chan_parent_class);
+
+ klass->fill_immutable_properties (chan, properties);
+
+ tp_dbus_properties_mixin_fill_properties_hash (
+ G_OBJECT (chan), properties,
+ TP_IFACE_CHANNEL_TYPE_ROOM_LIST, "Server",
+ NULL);
+}
+
+static void
+room_list_chan_close (TpBaseChannel *channel)
+{
+ tp_base_channel_destroyed (channel);
+}
+
+static void
+tp_tests_room_list_chan_class_init (
+ TpTestsRoomListChanClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+ TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+ GParamSpec *spec;
+ static TpDBusPropertiesMixinPropImpl room_list_props[] = {
+ { "Server", "server", NULL, },
+ { NULL }
+ };
+
+ oclass->get_property = tp_tests_room_list_chan_get_property;
+ oclass->set_property = tp_tests_room_list_chan_set_property;
+ oclass->constructed = tp_tests_room_list_chan_constructed;
+ oclass->finalize = tp_tests_room_list_chan_finalize;
+
+ base_class->channel_type = TP_IFACE_CHANNEL_TYPE_ROOM_LIST;
+ base_class->target_handle_type = TP_HANDLE_TYPE_NONE;
+ base_class->fill_immutable_properties = fill_immutable_properties;
+ base_class->close = room_list_chan_close;
+
+ spec = g_param_spec_string ("server", "server",
+ "Server",
+ "",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (oclass, PROP_SERVER, spec);
+
+ tp_dbus_properties_mixin_implement_interface (oclass,
+ TP_IFACE_QUARK_CHANNEL_TYPE_ROOM_LIST,
+ tp_dbus_properties_mixin_getter_gobject_properties, NULL,
+ room_list_props);
+
+ g_type_class_add_private (klass, sizeof (TpTestsRoomListChanPriv));
+}
+
+static void
+tp_tests_room_list_chan_init (TpTestsRoomListChan *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ TP_TESTS_TYPE_ROOM_LIST_CHAN, TpTestsRoomListChanPriv);
+}
+
+static void
+add_room (GPtrArray *rooms)
+{
+ GHashTable *hash;
+
+ hash = tp_asv_new (
+ "handle-name", G_TYPE_STRING, "the handle name",
+ "name", G_TYPE_STRING, "the name",
+ "description", G_TYPE_STRING, "the description",
+ "subject", G_TYPE_STRING, "the subject",
+ "members", G_TYPE_UINT, 10,
+ "password", G_TYPE_BOOLEAN, TRUE,
+ "invite-only", G_TYPE_BOOLEAN, TRUE,
+ "room-id", G_TYPE_STRING, "the room id",
+ "server", G_TYPE_STRING, "the server",
+ NULL);
+
+ g_ptr_array_add (rooms, tp_value_array_build (3,
+ G_TYPE_UINT, 0,
+ G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
+ TP_HASH_TYPE_STRING_VARIANT_MAP, hash,
+ G_TYPE_INVALID));
+
+ g_hash_table_unref (hash);
+}
+
+static gboolean
+find_rooms (gpointer data)
+{
+ TpTestsRoomListChan *self = TP_TESTS_ROOM_LIST_CHAN (data);
+ GPtrArray *rooms;
+
+ rooms = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free);
+
+ /* Find 2 rooms */
+ add_room (rooms);
+ add_room (rooms);
+ tp_svc_channel_type_room_list_emit_got_rooms (self, rooms);
+ g_ptr_array_set_size (rooms, 0);
+
+ /* Find 1 room */
+ add_room (rooms);
+ tp_svc_channel_type_room_list_emit_got_rooms (self, rooms);
+ g_ptr_array_unref (rooms);
+
+ return FALSE;
+}
+
+static void
+room_list_list_rooms (TpSvcChannelTypeRoomList *chan,
+ DBusGMethodInvocation *context)
+{
+ TpTestsRoomListChan *self = TP_TESTS_ROOM_LIST_CHAN (chan);
+
+ if (self->priv->listing)
+ {
+ GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Already listing" };
+
+ dbus_g_method_return_error (context, &error);
+ return;
+ }
+
+ if (!tp_strdiff (self->priv->server, "ListRoomsFail"))
+ {
+ GError error = { TP_ERROR, TP_ERROR_SERVICE_CONFUSED,
+ "Computer says no" };
+
+ dbus_g_method_return_error (context, &error);
+ return;
+ }
+
+ self->priv->listing = TRUE;
+ tp_svc_channel_type_room_list_emit_listing_rooms (self, TRUE);
+
+ g_idle_add (find_rooms, self);
+
+ tp_svc_channel_type_room_list_return_from_list_rooms (context);
+}
+
+static void
+room_list_iface_init (gpointer iface,
+ gpointer data)
+{
+ TpSvcChannelTypeRoomListClass *klass = iface;
+
+#define IMPLEMENT(x) \
+ tp_svc_channel_type_room_list_implement_##x (klass, room_list_##x)
+ IMPLEMENT(list_rooms);
+#undef IMPLEMENT
+}
diff --git a/tests/lib/room-list-chan.h b/tests/lib/room-list-chan.h
new file mode 100644
index 0000000..b41be27
--- /dev/null
+++ b/tests/lib/room-list-chan.h
@@ -0,0 +1,50 @@
+
+#ifndef __TP_TESTS_ROOM_LIST_CHAN_H__
+#define __TP_TESTS_ROOM_LIST_CHAN_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/base-channel.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsRoomListChan TpTestsRoomListChan;
+typedef struct _TpTestsRoomListChanClass TpTestsRoomListChanClass;
+typedef struct _TpTestsRoomListChanPriv TpTestsRoomListChanPriv;
+
+struct _TpTestsRoomListChanClass {
+ TpBaseChannelClass parent_class;
+ TpDBusPropertiesMixinClass dbus_properties_class;
+};
+
+struct _TpTestsRoomListChan {
+ TpBaseChannel parent;
+ TpTestsRoomListChanPriv *priv;
+};
+
+GType tp_tests_room_list_chan_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_ROOM_LIST_CHAN \
+ (tp_tests_room_list_chan_get_type ())
+#define TP_TESTS_ROOM_LIST_CHAN(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ TP_TESTS_TYPE_ROOM_LIST_CHAN, \
+ TpTestsRoomListChan))
+#define TP_TESTS_ROOM_LIST_CHAN_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ TP_TESTS_TYPE_ROOM_LIST_CHAN, \
+ TpTestsRoomListChanClass))
+#define TP_TESTS_IS_ROOM_LIST_CHAN(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+ TP_TESTS_TYPE_ROOM_LIST_CHAN))
+#define TP_TESTS_IS_ROOM_LIST_CHAN_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), \
+ TP_TESTS_TYPE_ROOM_LIST_CHAN))
+#define TP_TESTS_ROOM_LIST_CHAN_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ TP_TESTS_TYPE_ROOM_LIST_CHAN, \
+ TpTestsRoomListChanClass))
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_ROOM_LIST_CHAN_H__*/
diff --git a/tests/lib/simple-conn.c b/tests/lib/simple-conn.c
index 11cc7f5..c78e127 100644
--- a/tests/lib/simple-conn.c
+++ b/tests/lib/simple-conn.c
@@ -18,6 +18,7 @@
#include <dbus/dbus-glib.h>
#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/dbus-properties-mixin.h>
#include <telepathy-glib/errors.h>
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/handle-repo-dynamic.h>
@@ -25,12 +26,15 @@
#include <telepathy-glib/util.h>
#include "textchan-null.h"
+#include "room-list-chan.h"
#include "util.h"
+static void props_iface_init (TpSvcDBusPropertiesClass *);
static void conn_iface_init (TpSvcConnectionClass *);
G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleConnection, tp_tests_simple_connection,
TP_TYPE_BASE_CONNECTION,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, props_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION, conn_iface_init))
/* type definition stuff */
@@ -38,12 +42,15 @@ G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleConnection, tp_tests_simple_connection,
enum
{
PROP_ACCOUNT = 1,
+ PROP_BREAK_PROPS = 2,
+ PROP_DBUS_STATUS = 3,
N_PROPS
};
enum
{
SIGNAL_GOT_SELF_HANDLE,
+ SIGNAL_GOT_ALL,
N_SIGNALS
};
@@ -54,9 +61,11 @@ struct _TpTestsSimpleConnectionPrivate
gchar *account;
guint connect_source;
guint disconnect_source;
+ gboolean break_fastpath_props;
/* TpHandle => reffed TpTestsTextChannelNull */
- GHashTable *channels;
+ GHashTable *text_channels;
+ TpTestsRoomListChan *room_list_chan;
GError *get_self_handle_error /* initially NULL */ ;
};
@@ -67,7 +76,7 @@ tp_tests_simple_connection_init (TpTestsSimpleConnection *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
TP_TESTS_TYPE_SIMPLE_CONNECTION, TpTestsSimpleConnectionPrivate);
- self->priv->channels = g_hash_table_new_full (NULL, NULL, NULL,
+ self->priv->text_channels = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) g_object_unref);
}
@@ -83,6 +92,21 @@ get_property (GObject *object,
case PROP_ACCOUNT:
g_value_set_string (value, self->priv->account);
break;
+ case PROP_BREAK_PROPS:
+ g_value_set_boolean (value, self->priv->break_fastpath_props);
+ break;
+ case PROP_DBUS_STATUS:
+ if (self->priv->break_fastpath_props)
+ {
+ g_debug ("returning broken value for Connection.Status");
+ g_value_set_uint (value, 0xdeadbeefU);
+ }
+ else
+ {
+ g_value_set_uint (value,
+ tp_base_connection_get_status (TP_BASE_CONNECTION (self)));
+ }
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
}
@@ -101,6 +125,9 @@ set_property (GObject *object,
g_free (self->priv->account);
self->priv->account = g_utf8_strdown (g_value_get_string (value), -1);
break;
+ case PROP_BREAK_PROPS:
+ self->priv->break_fastpath_props = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
}
@@ -111,7 +138,8 @@ dispose (GObject *object)
{
TpTestsSimpleConnection *self = TP_TESTS_SIMPLE_CONNECTION (object);
- g_hash_table_unref (self->priv->channels);
+ g_hash_table_unref (self->priv->text_channels);
+ g_clear_object (&self->priv->room_list_chan);
G_OBJECT_CLASS (tp_tests_simple_connection_parent_class)->dispose (object);
}
@@ -170,7 +198,7 @@ tp_tests_simple_normalize_contact (TpHandleRepoIface *repo,
static void
create_handle_repos (TpBaseConnection *conn,
- TpHandleRepoIface *repos[NUM_TP_HANDLE_TYPES])
+ TpHandleRepoIface *repos[TP_NUM_HANDLE_TYPES])
{
repos[TP_HANDLE_TYPE_CONTACT] = tp_dynamic_handle_repo_new
(TP_HANDLE_TYPE_CONTACT, tp_tests_simple_normalize_contact, NULL);
@@ -199,11 +227,13 @@ pretend_connected (gpointer data)
TpBaseConnection *conn = (TpBaseConnection *) self;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
TP_HANDLE_TYPE_CONTACT);
+ TpHandle self_handle;
- conn->self_handle = tp_handle_ensure (contact_repo, self->priv->account,
+ self_handle = tp_handle_ensure (contact_repo, self->priv->account,
NULL, NULL);
+ tp_base_connection_set_self_handle (conn, self_handle);
- if (conn->status == TP_CONNECTION_STATUS_CONNECTING)
+ if (tp_base_connection_get_status (conn) == TP_CONNECTION_STATUS_CONNECTING)
{
tp_base_connection_change_status (conn, TP_CONNECTION_STATUS_CONNECTED,
TP_CONNECTION_STATUS_REASON_REQUESTED);
@@ -237,7 +267,8 @@ pretend_disconnected (gpointer data)
TpTestsSimpleConnection *self = TP_TESTS_SIMPLE_CONNECTION (data);
/* We are disconnected, all our channels are invalidated */
- g_hash_table_remove_all (self->priv->channels);
+ g_hash_table_remove_all (self->priv->text_channels);
+ g_clear_object (&self->priv->room_list_chan);
tp_base_connection_finish_shutdown (TP_BASE_CONNECTION (data));
self->priv->disconnect_source = 0;
@@ -257,6 +288,19 @@ shut_down (TpBaseConnection *conn)
conn);
}
+static GPtrArray *
+get_interfaces_always_present (TpBaseConnection *base)
+{
+ GPtrArray *interfaces;
+
+ interfaces = TP_BASE_CONNECTION_CLASS (
+ tp_tests_simple_connection_parent_class)->get_interfaces_always_present (base);
+
+ g_ptr_array_add (interfaces, TP_IFACE_CONNECTION_INTERFACE_REQUESTS);
+
+ return interfaces;
+}
+
static void
tp_tests_simple_connection_class_init (TpTestsSimpleConnectionClass *klass)
{
@@ -264,8 +308,6 @@ tp_tests_simple_connection_class_init (TpTestsSimpleConnectionClass *klass)
(TpBaseConnectionClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
- static const gchar *interfaces_always_present[] = {
- TP_IFACE_CONNECTION_INTERFACE_REQUESTS, NULL };
object_class->get_property = get_property;
object_class->set_property = set_property;
@@ -279,20 +321,39 @@ tp_tests_simple_connection_class_init (TpTestsSimpleConnectionClass *klass)
base_class->start_connecting = start_connecting;
base_class->shut_down = shut_down;
- base_class->interfaces_always_present = interfaces_always_present;
+ base_class->get_interfaces_always_present = get_interfaces_always_present;
param_spec = g_param_spec_string ("account", "Account name",
"The username of this user", NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB);
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_ACCOUNT, param_spec);
+ param_spec = g_param_spec_boolean ("break-0192-properties",
+ "Break 0.19.2 properties",
+ "Break Connection D-Bus properties introduced in spec 0.19.2", FALSE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_BREAK_PROPS, param_spec);
+
+ param_spec = g_param_spec_uint ("dbus-status",
+ "Connection.Status",
+ "The connection status as visible on D-Bus (overridden so can break it)",
+ TP_CONNECTION_STATUS_CONNECTED, G_MAXUINT,
+ TP_CONNECTION_STATUS_DISCONNECTED,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_DBUS_STATUS, param_spec);
+
signals[SIGNAL_GOT_SELF_HANDLE] = g_signal_new ("got-self-handle",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
+
+ signals[SIGNAL_GOT_ALL] = g_signal_new ("got-all",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ 0,
+ NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
@@ -309,7 +370,6 @@ tp_tests_simple_connection_set_identifier (TpTestsSimpleConnection *self,
g_return_if_fail (handle != 0);
tp_base_connection_set_self_handle (conn, handle);
- tp_handle_unref (contact_repo, handle);
}
TpTestsSimpleConnection *
@@ -342,7 +402,8 @@ tp_tests_simple_connection_ensure_text_chan (TpTestsSimpleConnection *self,
handle = tp_handle_ensure (contact_repo, target_id, NULL, NULL);
- chan = g_hash_table_lookup (self->priv->channels, GUINT_TO_POINTER (handle));
+ chan = g_hash_table_lookup (self->priv->text_channels,
+ GUINT_TO_POINTER (handle));
if (chan != NULL)
{
/* Channel already exist, reuse it */
@@ -350,8 +411,8 @@ tp_tests_simple_connection_ensure_text_chan (TpTestsSimpleConnection *self,
}
else
{
- chan_path = g_strdup_printf ("%s/Channel%u", base_conn->object_path,
- count++);
+ chan_path = g_strdup_printf ("%s/Channel%u",
+ tp_base_connection_get_object_path (base_conn), count++);
chan = TP_TESTS_TEXT_CHANNEL_NULL (
tp_tests_object_new_static_class (
@@ -361,18 +422,61 @@ tp_tests_simple_connection_ensure_text_chan (TpTestsSimpleConnection *self,
"handle", handle,
NULL));
- g_hash_table_insert (self->priv->channels, GUINT_TO_POINTER (handle),
+ g_hash_table_insert (self->priv->text_channels, GUINT_TO_POINTER (handle),
chan);
}
- tp_handle_unref (contact_repo, handle);
-
if (props != NULL)
*props = tp_tests_text_channel_get_props (chan);
return chan_path;
}
+static void
+room_list_chan_closed_cb (TpBaseChannel *channel,
+ TpTestsSimpleConnection *self)
+{
+ g_clear_object (&self->priv->room_list_chan);
+}
+
+gchar *
+tp_tests_simple_connection_ensure_room_list_chan (TpTestsSimpleConnection *self,
+ const gchar *server,
+ GHashTable **props)
+{
+ gchar *chan_path;
+ TpBaseConnection *base_conn = (TpBaseConnection *) self;
+
+ if (self->priv->room_list_chan != NULL)
+ {
+ /* Channel already exist, reuse it */
+ g_object_get (self->priv->room_list_chan,
+ "object-path", &chan_path, NULL);
+ }
+ else
+ {
+ chan_path = g_strdup_printf ("%s/RoomListChannel",
+ tp_base_connection_get_object_path (base_conn));
+
+ self->priv->room_list_chan = TP_TESTS_ROOM_LIST_CHAN (
+ tp_tests_object_new_static_class (
+ TP_TESTS_TYPE_ROOM_LIST_CHAN,
+ "connection", self,
+ "object-path", chan_path,
+ "server", server ? server : "",
+ NULL));
+
+ g_signal_connect (self->priv->room_list_chan, "closed",
+ G_CALLBACK (room_list_chan_closed_cb), self);
+ }
+
+ if (props != NULL)
+ g_object_get (self->priv->room_list_chan,
+ "channel-properties", props, NULL);
+
+ return chan_path;
+}
+
void
tp_tests_simple_connection_set_get_self_handle_error (
TpTestsSimpleConnection *self,
@@ -401,7 +505,8 @@ get_self_handle (TpSvcConnection *iface,
return;
}
- tp_svc_connection_return_from_get_self_handle (context, base->self_handle);
+ tp_svc_connection_return_from_get_self_handle (context,
+ tp_base_connection_get_self_handle (base));
g_signal_emit (self, signals[SIGNAL_GOT_SELF_HANDLE], 0);
}
@@ -413,3 +518,26 @@ conn_iface_init (TpSvcConnectionClass *iface)
IMPLEMENT(,get_self_handle);
#undef IMPLEMENT
}
+
+static void
+get_all (TpSvcDBusProperties *iface,
+ const gchar *interface_name,
+ DBusGMethodInvocation *context)
+{
+ GHashTable *values = tp_dbus_properties_mixin_dup_all (G_OBJECT (iface),
+ interface_name);
+
+ tp_svc_dbus_properties_return_from_get_all (context, values);
+ g_hash_table_unref (values);
+ g_signal_emit (iface, signals[SIGNAL_GOT_ALL],
+ g_quark_from_string (interface_name));
+}
+
+static void
+props_iface_init (TpSvcDBusPropertiesClass *iface)
+{
+#define IMPLEMENT(x) \
+ tp_svc_dbus_properties_implement_##x (iface, x)
+ IMPLEMENT (get_all);
+#undef IMPLEMENT
+}
diff --git a/tests/lib/simple-conn.h b/tests/lib/simple-conn.h
index 6322f4b..837400b 100644
--- a/tests/lib/simple-conn.h
+++ b/tests/lib/simple-conn.h
@@ -72,6 +72,11 @@ void tp_tests_simple_connection_set_get_self_handle_error (
gint code,
const gchar *message);
+gchar * tp_tests_simple_connection_ensure_room_list_chan (
+ TpTestsSimpleConnection *self,
+ const gchar *server,
+ GHashTable **props);
+
G_END_DECLS
#endif /* #ifndef __TP_TESTS_SIMPLE_CONN_H__ */
diff --git a/tests/lib/textchan-null.c b/tests/lib/textchan-null.c
index 01efb4f..bbeb0c7 100644
--- a/tests/lib/textchan-null.c
+++ b/tests/lib/textchan-null.c
@@ -21,6 +21,10 @@
#include <telepathy-glib/svc-channel.h>
#include <telepathy-glib/svc-generic.h>
+/* This is for text-mixin unit tests, others should be using ExampleEcho2Channel
+ * which uses newer TpMessageMixin */
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+
static void text_iface_init (gpointer iface, gpointer data);
static void channel_iface_init (gpointer iface, gpointer data);
@@ -150,7 +154,8 @@ get_property (GObject *object,
g_value_set_boolean (value, TRUE);
break;
case PROP_INITIATOR_HANDLE:
- g_value_set_uint (value, self->priv->conn->self_handle);
+ g_value_set_uint (value, tp_base_connection_get_self_handle (
+ self->priv->conn));
break;
case PROP_INITIATOR_ID:
{
@@ -158,7 +163,8 @@ get_property (GObject *object,
self->priv->conn, TP_HANDLE_TYPE_CONTACT);
g_value_set_string (value,
- tp_handle_inspect (contact_repo, self->priv->conn->self_handle));
+ tp_handle_inspect (contact_repo,
+ tp_base_connection_get_self_handle (self->priv->conn)));
}
break;
case PROP_INTERFACES:
@@ -273,8 +279,7 @@ tp_tests_text_channel_null_class_init (TpTestsTextChannelNullClass *klass)
param_spec = g_param_spec_object ("connection", "TpBaseConnection object",
"Connection object that owns this channel",
TP_TYPE_BASE_CONNECTION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
@@ -570,3 +575,5 @@ tp_tests_text_channel_get_props (TpTestsTextChannelNull *self)
g_strfreev (interfaces);
return props;
}
+
+G_GNUC_END_IGNORE_DEPRECATIONS
diff --git a/tests/lib/util.c b/tests/lib/util.c
index b58227e..1e8c402 100644
--- a/tests/lib/util.c
+++ b/tests/lib/util.c
@@ -12,11 +12,21 @@
#include "util.h"
+#include <telepathy-glib/connection.h>
+
+#include <glib/gstdio.h>
+#include <string.h>
#include <stdlib.h>
+
#ifdef G_OS_UNIX
# include <unistd.h> /* for alarm() */
#endif
+#ifdef HAVE_GIO_UNIX
+#include <gio/gunixsocketaddress.h>
+#include <gio/gunixconnection.h>
+#endif
+
void
tp_tests_proxy_run_until_prepared (gpointer proxy,
const GQuark *features)
@@ -105,50 +115,6 @@ tp_tests_proxy_run_until_dbus_queue_processed (gpointer proxy)
g_main_loop_unref (loop);
}
-typedef struct {
- GMainLoop *loop;
- TpHandle handle;
-} HandleRequestResult;
-
-static void
-handles_requested_cb (TpConnection *connection G_GNUC_UNUSED,
- TpHandleType handle_type G_GNUC_UNUSED,
- guint n_handles,
- const TpHandle *handles,
- const gchar * const *ids G_GNUC_UNUSED,
- const GError *error,
- gpointer user_data,
- GObject *weak_object G_GNUC_UNUSED)
-{
- HandleRequestResult *result = user_data;
-
- g_assert_no_error ((GError *) error);
- g_assert_cmpuint (n_handles, ==, 1);
- result->handle = handles[0];
-}
-
-static void
-handle_request_result_finish (gpointer r)
-{
- HandleRequestResult *result = r;
-
- g_main_loop_quit (result->loop);
-}
-
-TpHandle
-tp_tests_connection_run_request_contact_handle (TpConnection *connection,
- const gchar *id)
-{
- HandleRequestResult result = { g_main_loop_new (NULL, FALSE), 0 };
- const gchar * const ids[] = { id, NULL };
-
- tp_connection_request_handles (connection, -1, TP_HANDLE_TYPE_CONTACT, ids,
- handles_requested_cb, &result, handle_request_result_finish, NULL);
- g_main_loop_run (result.loop);
- g_main_loop_unref (result.loop);
- return result.handle;
-}
-
void
_test_assert_empty_strv (const char *file,
int line,
@@ -211,41 +177,43 @@ _tp_tests_assert_strv_equals (const char *file,
}
void
-tp_tests_copy_dir (const gchar *from_dir, const gchar *to_dir)
+_tp_tests_assert_bytes_equal (const gchar *file, int line,
+ GBytes *actual, gconstpointer expected_data,
+ gsize expected_length)
{
- gchar *command;
-
- // If destination directory exist erase it
- command = g_strdup_printf ("rm -rf %s", to_dir);
- g_assert (system (command) == 0);
- g_free (command);
-
- command = g_strdup_printf ("cp -r %s %s", from_dir, to_dir);
- g_assert (system (command) == 0);
- g_free (command);
-
- // In distcheck mode the files and directory are read-only, fix that
- command = g_strdup_printf ("chmod -R +w %s", to_dir);
- g_assert (system (command) == 0);
- g_free (command);
+ if (expected_length != g_bytes_get_size (actual))
+ {
+ g_error ("%s:%d: assertion failed: expected %"G_GSIZE_FORMAT
+ " bytes, got %"G_GSIZE_FORMAT,
+ file, line, expected_length, g_bytes_get_size (actual));
+ }
+ else if (memcmp (g_bytes_get_data (actual, NULL),
+ expected_data, expected_length) != 0)
+ {
+ g_error (
+ "%s:%d: assertion failed: expected data didn't match the actual data",
+ file, line);
+ }
}
void
-tp_tests_create_and_connect_conn (GType conn_type,
+tp_tests_create_conn (GType conn_type,
const gchar *account,
+ gboolean connect,
TpBaseConnection **service_conn,
TpConnection **client_conn)
{
TpDBusDaemon *dbus;
+ TpSimpleClientFactory *factory;
gchar *name;
gchar *conn_path;
GError *error = NULL;
- GQuark conn_features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };
g_assert (service_conn != NULL);
g_assert (client_conn != NULL);
dbus = tp_tests_dbus_daemon_dup_or_die ();
+ factory = (TpSimpleClientFactory *) tp_automatic_client_factory_new (dbus);
*service_conn = tp_tests_object_new_static_class (
conn_type,
@@ -258,18 +226,33 @@ tp_tests_create_and_connect_conn (GType conn_type,
&name, &conn_path, &error));
g_assert_no_error (error);
- *client_conn = tp_connection_new (dbus, name, conn_path,
- &error);
+ *client_conn = tp_simple_client_factory_ensure_connection (factory,
+ conn_path, NULL, &error);
g_assert (*client_conn != NULL);
g_assert_no_error (error);
- tp_cli_connection_call_connect (*client_conn, -1, NULL, NULL, NULL, NULL);
- tp_tests_proxy_run_until_prepared (*client_conn, conn_features);
+ if (connect)
+ {
+ GQuark conn_features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };
+
+ tp_cli_connection_call_connect (*client_conn, -1, NULL, NULL, NULL, NULL);
+ tp_tests_proxy_run_until_prepared (*client_conn, conn_features);
+ }
g_free (name);
g_free (conn_path);
g_object_unref (dbus);
+ g_object_unref (factory);
+}
+
+void
+tp_tests_create_and_connect_conn (GType conn_type,
+ const gchar *account,
+ TpBaseConnection **service_conn,
+ TpConnection **client_conn)
+{
+ tp_tests_create_conn (conn_type, account, TRUE, service_conn, client_conn);
}
/* This object exists solely so that tests/tests.supp can ignore "leaked"
@@ -300,7 +283,27 @@ time_out (gpointer nil G_GNUC_UNUSED)
void
tp_tests_abort_after (guint sec)
{
- if (g_getenv ("TP_TESTS_NO_TIMEOUT") != NULL)
+ gboolean debugger = FALSE;
+ gchar *contents;
+
+ if (g_file_get_contents ("/proc/self/status", &contents, NULL, NULL))
+ {
+/* http://www.youtube.com/watch?v=SXmv8quf_xM */
+#define TRACER_T "\nTracerPid:\t"
+ gchar *line = strstr (contents, TRACER_T);
+
+ if (line != NULL)
+ {
+ gchar *value = line + strlen (TRACER_T);
+
+ if (value[0] != '0' || value[1] != '\n')
+ debugger = TRUE;
+ }
+
+ g_free (contents);
+ }
+
+ if (g_getenv ("TP_TESTS_NO_TIMEOUT") != NULL || debugger)
return;
g_timeout_add_seconds (sec, time_out, NULL);
@@ -312,3 +315,206 @@ tp_tests_abort_after (guint sec)
alarm (sec + 2);
#endif
}
+
+void
+tp_tests_init (int *argc,
+ char ***argv)
+{
+ g_type_init ();
+ tp_tests_abort_after (10);
+ tp_debug_set_flags ("all");
+
+ g_test_init (argc, argv, NULL);
+}
+
+void
+_tp_destroy_socket_control_list (gpointer data)
+{
+ GArray *tab = data;
+ g_array_unref (tab);
+}
+
+GValue *
+_tp_create_local_socket (TpSocketAddressType address_type,
+ TpSocketAccessControl access_control,
+ GSocketService **service,
+ gchar **unix_address,
+ gchar **unix_tmpdir,
+ GError **error)
+{
+ gboolean success;
+ GSocketAddress *address, *effective_address;
+ GValue *address_gvalue;
+
+ g_assert (service != NULL);
+ g_assert (unix_address != NULL);
+
+ switch (access_control)
+ {
+ case TP_SOCKET_ACCESS_CONTROL_LOCALHOST:
+ case TP_SOCKET_ACCESS_CONTROL_CREDENTIALS:
+ case TP_SOCKET_ACCESS_CONTROL_PORT:
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ switch (address_type)
+ {
+#ifdef HAVE_GIO_UNIX
+ case TP_SOCKET_ADDRESS_TYPE_UNIX:
+ {
+ GError *e = NULL;
+ gchar *dir = g_dir_make_tmp ("tp-glib-tests.XXXXXX", &e);
+ gchar *name;
+
+ g_assert_no_error (e);
+
+ name = g_build_filename (dir, "s", NULL);
+ address = g_unix_socket_address_new (name);
+ g_free (name);
+
+ if (unix_tmpdir != NULL)
+ *unix_tmpdir = dir;
+ else
+ g_free (dir);
+ break;
+ }
+#endif
+
+ case TP_SOCKET_ADDRESS_TYPE_IPV4:
+ case TP_SOCKET_ADDRESS_TYPE_IPV6:
+ {
+ GInetAddress *localhost;
+
+ localhost = g_inet_address_new_loopback (
+ address_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ?
+ G_SOCKET_FAMILY_IPV4 : G_SOCKET_FAMILY_IPV6);
+ address = g_inet_socket_address_new (localhost, 0);
+
+ g_object_unref (localhost);
+ break;
+ }
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ *service = g_socket_service_new ();
+
+ success = g_socket_listener_add_address (
+ G_SOCKET_LISTENER (*service),
+ address, G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_DEFAULT,
+ NULL, &effective_address, NULL);
+ g_assert (success);
+
+ switch (address_type)
+ {
+#ifdef HAVE_GIO_UNIX
+ case TP_SOCKET_ADDRESS_TYPE_UNIX:
+ *unix_address = g_strdup (g_unix_socket_address_get_path (
+ G_UNIX_SOCKET_ADDRESS (effective_address)));
+ address_gvalue = tp_g_value_slice_new_bytes (
+ g_unix_socket_address_get_path_len (
+ G_UNIX_SOCKET_ADDRESS (effective_address)),
+ g_unix_socket_address_get_path (
+ G_UNIX_SOCKET_ADDRESS (effective_address)));
+ break;
+#endif
+
+ case TP_SOCKET_ADDRESS_TYPE_IPV4:
+ case TP_SOCKET_ADDRESS_TYPE_IPV6:
+ *unix_address = NULL;
+
+ address_gvalue = tp_g_value_slice_new_take_boxed (
+ TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4,
+ dbus_g_type_specialized_construct (
+ TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4));
+
+ dbus_g_type_struct_set (address_gvalue,
+ 0, address_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ?
+ "127.0.0.1" : "::1",
+ 1, g_inet_socket_address_get_port (
+ G_INET_SOCKET_ADDRESS (effective_address)),
+ G_MAXUINT);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_object_unref (address);
+ g_object_unref (effective_address);
+ return address_gvalue;
+}
+
+void
+tp_tests_connection_assert_disconnect_succeeds (TpConnection *connection)
+{
+ GAsyncResult *result = NULL;
+ GError *error = NULL;
+ gboolean ok;
+
+ tp_connection_disconnect_async (connection, tp_tests_result_ready_cb,
+ &result);
+ tp_tests_run_until_result (&result);
+ ok = tp_connection_disconnect_finish (connection, result, &error);
+ g_assert_no_error (error);
+ g_assert (ok);
+ g_object_unref (result);
+}
+
+static void
+one_contact_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ TpConnection *connection = (TpConnection *) object;
+ TpContact **contact_loc = user_data;
+ GError *error = NULL;
+
+ *contact_loc = tp_connection_dup_contact_by_id_finish (connection, result,
+ &error);
+
+ g_assert_no_error (error);
+ g_assert (TP_IS_CONTACT (*contact_loc));
+}
+
+TpContact *
+tp_tests_connection_run_until_contact_by_id (TpConnection *connection,
+ const gchar *id,
+ guint n_features,
+ const TpContactFeature *features)
+{
+ TpContact *contact = NULL;
+
+ tp_connection_dup_contact_by_id_async (connection, id, n_features, features,
+ one_contact_cb, &contact);
+
+ while (contact == NULL)
+ g_main_context_iteration (NULL, TRUE);
+
+ return contact;
+}
+
+void
+tp_tests_copy_dir (const gchar *from_dir, const gchar *to_dir)
+{
+ gchar *command;
+
+ // If destination directory exist erase it
+ command = g_strdup_printf ("rm -rf %s", to_dir);
+ g_assert (system (command) == 0);
+ g_free (command);
+
+ command = g_strdup_printf ("cp -r %s %s", from_dir, to_dir);
+ g_assert (system (command) == 0);
+ g_free (command);
+
+ // In distcheck mode the files and directory are read-only, fix that
+ command = g_strdup_printf ("chmod -R +w %s", to_dir);
+ g_assert (system (command) == 0);
+ g_free (command);
+}
diff --git a/tests/lib/util.h b/tests/lib/util.h
index ba96c7b..42c9489 100644
--- a/tests/lib/util.h
+++ b/tests/lib/util.h
@@ -18,10 +18,6 @@ TpDBusDaemon *tp_tests_dbus_daemon_dup_or_die (void);
void tp_tests_proxy_run_until_dbus_queue_processed (gpointer proxy);
-TpHandle tp_tests_connection_run_request_contact_handle (
- TpConnection *connection,
- const gchar *id);
-
void tp_tests_proxy_run_until_prepared (gpointer proxy,
const GQuark *features);
gboolean tp_tests_proxy_run_until_prepared_or_failed (gpointer proxy,
@@ -40,6 +36,18 @@ void _tp_tests_assert_strv_equals (const char *file, int line,
const char *actual_desc, gconstpointer actual_strv,
const char *expected_desc, gconstpointer expected_strv);
+#define tp_tests_assert_bytes_equals(actual, expected, expected_length) \
+ _tp_tests_assert_bytes_equal (__FILE__, __LINE__, \
+ actual, expected, expected_length)
+void _tp_tests_assert_bytes_equal (const gchar *file, int line,
+ GBytes *actual, gconstpointer expected_data, gsize expected_length);
+
+void tp_tests_create_conn (GType conn_type,
+ const gchar *account,
+ gboolean connect,
+ TpBaseConnection **service_conn,
+ TpConnection **client_conn);
+
void tp_tests_create_and_connect_conn (GType conn_type,
const gchar *account,
TpBaseConnection **service_conn,
@@ -54,6 +62,26 @@ void tp_tests_result_ready_cb (GObject *object,
void tp_tests_abort_after (guint sec);
+void tp_tests_init (int *argc,
+ char ***argv);
+
+GValue *_tp_create_local_socket (TpSocketAddressType address_type,
+ TpSocketAccessControl access_control,
+ GSocketService **service,
+ gchar **unix_address,
+ gchar **unix_tmpdir,
+ GError **error);
+
+void _tp_destroy_socket_control_list (gpointer data);
+
+void tp_tests_connection_assert_disconnect_succeeds (TpConnection *connection);
+
+TpContact *tp_tests_connection_run_until_contact_by_id (
+ TpConnection *connection,
+ const gchar *id,
+ guint n_features,
+ const TpContactFeature *features);
+
void tp_tests_copy_dir (const gchar *from_dir, const gchar *to_dir);
#endif /* #ifndef __TP_TESTS_LIB_UTIL_H__ */