From 6c84b3bab620888fd9eeaaf2868db8af74c44418 Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Thu, 26 Sep 2013 12:30:47 +0200 Subject: [PATCH 1/3] tests/lib: sync with tp-glib master Adds a few new files used by the new version of the files we are using. --- tests/lib/Makefile.am | 2 + tests/lib/contact-list-manager.c | 906 +++++++++++++++++++++++++++++++++++++ tests/lib/contact-list-manager.h | 71 +++ tests/lib/contacts-conn.c | 286 ++++++++++-- tests/lib/contacts-conn.h | 10 +- tests/lib/debug.h | 3 + tests/lib/room-list-chan.c | 2 - tests/lib/room-list-chan.h | 2 +- tests/lib/simple-account-manager.c | 122 +++-- tests/lib/simple-account-manager.h | 18 +- tests/lib/simple-account.c | 342 +++++++++++--- tests/lib/simple-account.h | 19 +- tests/lib/simple-conn.c | 9 +- tests/lib/simple-conn.h | 2 +- tests/lib/textchan-null.c | 9 +- tests/lib/textchan-null.h | 4 +- tests/lib/util.c | 2 +- tests/lib/util.h | 1 - 18 files changed, 1630 insertions(+), 180 deletions(-) create mode 100644 tests/lib/contact-list-manager.c create mode 100644 tests/lib/contact-list-manager.h create mode 100644 tests/lib/debug.h diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index faae79a..0f7fc28 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 \ + contact-list-manager.c \ + contact-list-manager.h \ room-list-chan.c \ room-list-chan.h \ simple-account.c \ diff --git a/tests/lib/contact-list-manager.c b/tests/lib/contact-list-manager.c new file mode 100644 index 0000000..b816673 --- /dev/null +++ b/tests/lib/contact-list-manager.c @@ -0,0 +1,906 @@ +/* + * Example channel manager for contact lists + * + * Copyright © 2007-2010 Collabora Ltd. + * Copyright © 2007-2010 Nokia Corporation + * + * 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 "contact-list-manager.h" + +#include +#include + +struct _TpTestsContactListManagerPrivate +{ + TpBaseConnection *conn; + + gulong status_changed_id; + + /* TpHandle => ContactDetails */ + GHashTable *contact_details; + + TpHandleRepoIface *contact_repo; + TpHandleRepoIface *group_repo; + TpHandleSet *groups; +}; + +static void contact_groups_iface_init (TpContactGroupListInterface *iface); +static void mutable_contact_groups_iface_init ( + TpMutableContactGroupListInterface *iface); +static void mutable_iface_init ( + TpMutableContactListInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (TpTestsContactListManager, tp_tests_contact_list_manager, + TP_TYPE_BASE_CONTACT_LIST, + G_IMPLEMENT_INTERFACE (TP_TYPE_CONTACT_GROUP_LIST, + contact_groups_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_MUTABLE_CONTACT_GROUP_LIST, + mutable_contact_groups_iface_init) + G_IMPLEMENT_INTERFACE (TP_TYPE_MUTABLE_CONTACT_LIST, + mutable_iface_init)) + +typedef struct { + TpSubscriptionState subscribe; + TpSubscriptionState publish; + gchar *publish_request; + TpHandleSet *groups; + + TpHandle handle; + TpHandleRepoIface *contact_repo; +} ContactDetails; + +static void +contact_detail_destroy (gpointer p) +{ + ContactDetails *d = p; + + g_free (d->publish_request); + tp_handle_set_destroy (d->groups); + + g_slice_free (ContactDetails, d); +} + +static ContactDetails * +lookup_contact (TpTestsContactListManager *self, + TpHandle handle) +{ + return g_hash_table_lookup (self->priv->contact_details, + GUINT_TO_POINTER (handle)); +} + +static ContactDetails * +ensure_contact (TpTestsContactListManager *self, + TpHandle handle) +{ + ContactDetails *d = lookup_contact (self, handle); + + if (d == NULL) + { + d = g_slice_new0 (ContactDetails); + d->subscribe = TP_SUBSCRIPTION_STATE_NO; + d->publish = TP_SUBSCRIPTION_STATE_NO; + d->publish_request = NULL; + d->groups = tp_handle_set_new (self->priv->group_repo); + d->handle = handle; + d->contact_repo = self->priv->contact_repo; + + g_hash_table_insert (self->priv->contact_details, + GUINT_TO_POINTER (handle), d); + } + + return d; +} + +static void +tp_tests_contact_list_manager_init (TpTestsContactListManager *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + TP_TESTS_TYPE_CONTACT_LIST_MANAGER, TpTestsContactListManagerPrivate); + + self->priv->contact_details = g_hash_table_new_full (g_direct_hash, + g_direct_equal, NULL, contact_detail_destroy); +} + +static void +close_all (TpTestsContactListManager *self) +{ + if (self->priv->status_changed_id != 0) + { + g_signal_handler_disconnect (self->priv->conn, + self->priv->status_changed_id); + self->priv->status_changed_id = 0; + } + tp_clear_pointer (&self->priv->contact_details, g_hash_table_unref); + tp_clear_pointer (&self->priv->groups, tp_handle_set_destroy); +} + +static void +dispose (GObject *object) +{ + TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (object); + + close_all (self); + + ((GObjectClass *) tp_tests_contact_list_manager_parent_class)->dispose ( + object); +} + +static TpHandleSet * +contact_list_dup_contacts (TpBaseContactList *base) +{ + TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (base); + TpHandleSet *set; + GHashTableIter iter; + gpointer k, v; + + set = tp_handle_set_new (self->priv->contact_repo); + + g_hash_table_iter_init (&iter, self->priv->contact_details); + while (g_hash_table_iter_next (&iter, &k, &v)) + { + ContactDetails *d = v; + + /* add all the interesting items */ + if (d->subscribe != TP_SUBSCRIPTION_STATE_NO || + d->publish != TP_SUBSCRIPTION_STATE_NO) + tp_handle_set_add (set, GPOINTER_TO_UINT (k)); + } + + return set; +} + +static void +contact_list_dup_states (TpBaseContactList *base, + TpHandle contact, + TpSubscriptionState *subscribe, + TpSubscriptionState *publish, + gchar **publish_request) +{ + TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (base); + ContactDetails *d = lookup_contact (self, contact); + + if (d == NULL) + { + if (subscribe != NULL) + *subscribe = TP_SUBSCRIPTION_STATE_NO; + + if (publish != NULL) + *publish = TP_SUBSCRIPTION_STATE_NO; + + if (publish_request != NULL) + *publish_request = NULL; + } + else + { + if (subscribe != NULL) + *subscribe = d->subscribe; + + if (publish != NULL) + *publish = d->publish; + + if (publish_request != NULL) + *publish_request = g_strdup (d->publish_request); + } +} + +static GStrv +contact_list_dup_groups (TpBaseContactList *base) +{ + TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (base); + GPtrArray *ret; + + if (self->priv->groups != NULL) + { + TpIntsetFastIter iter; + TpHandle group; + + ret = g_ptr_array_sized_new (tp_handle_set_size (self->priv->groups) + 1); + + tp_intset_fast_iter_init (&iter, tp_handle_set_peek (self->priv->groups)); + while (tp_intset_fast_iter_next (&iter, &group)) + { + g_ptr_array_add (ret, g_strdup (tp_handle_inspect ( + self->priv->group_repo, group))); + } + } + else + { + ret = g_ptr_array_sized_new (1); + } + + g_ptr_array_add (ret, NULL); + + return (GStrv) g_ptr_array_free (ret, FALSE); +} + +static GStrv +contact_list_dup_contact_groups (TpBaseContactList *base, + TpHandle contact) +{ + TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (base); + ContactDetails *d = lookup_contact (self, contact); + GPtrArray *ret; + + if (d != NULL && d->groups != NULL) + { + TpIntsetFastIter iter; + TpHandle group; + + ret = g_ptr_array_sized_new (tp_handle_set_size (d->groups) + 1); + + tp_intset_fast_iter_init (&iter, tp_handle_set_peek (d->groups)); + while (tp_intset_fast_iter_next (&iter, &group)) + { + g_ptr_array_add (ret, g_strdup (tp_handle_inspect ( + self->priv->group_repo, group))); + } + } + else + { + ret = g_ptr_array_sized_new (1); + } + + g_ptr_array_add (ret, NULL); + + return (GStrv) g_ptr_array_free (ret, FALSE); +} + +static TpHandleSet * +contact_list_dup_group_members (TpBaseContactList *base, + const gchar *group) +{ + TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (base); + TpHandleSet *set; + TpHandle group_handle; + GHashTableIter iter; + gpointer k, v; + + set = tp_handle_set_new (self->priv->contact_repo); + group_handle = tp_handle_lookup (self->priv->group_repo, group, NULL, NULL); + if (G_UNLIKELY (group_handle == 0)) + { + /* clearly it doesn't have members */ + return set; + } + + g_hash_table_iter_init (&iter, self->priv->contact_details); + while (g_hash_table_iter_next (&iter, &k, &v)) + { + ContactDetails *d = v; + + if (d->groups != NULL && + tp_handle_set_is_member (d->groups, group_handle)) + tp_handle_set_add (set, GPOINTER_TO_UINT (k)); + } + + return set; +} + +static void +contact_list_set_contact_groups_async (TpBaseContactList *base, + TpHandle contact, + const gchar * const *names, + gsize n, + GAsyncReadyCallback callback, + gpointer user_data) +{ + TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (base); + ContactDetails *d; + TpIntset *set, *added_set, *removed_set; + GPtrArray *added_names, *removed_names; + GPtrArray *new_groups; + TpIntsetFastIter iter; + TpHandle group_handle; + guint i; + + d = ensure_contact (self, contact); + + new_groups = g_ptr_array_new (); + set = tp_intset_new (); + for (i = 0; i < n; i++) + { + group_handle = tp_handle_ensure (self->priv->group_repo, names[i], NULL, NULL); + tp_intset_add (set, group_handle); + + if (!tp_handle_set_is_member (self->priv->groups, group_handle)) + { + tp_handle_set_add (self->priv->groups, group_handle); + g_ptr_array_add (new_groups, (gchar *) names[i]); + } + } + + if (new_groups->len > 0) + { + tp_base_contact_list_groups_created ((TpBaseContactList *) self, + (const gchar * const *) new_groups->pdata, new_groups->len); + } + + added_set = tp_intset_difference (set, tp_handle_set_peek (d->groups)); + added_names = g_ptr_array_sized_new (tp_intset_size (added_set)); + tp_intset_fast_iter_init (&iter, added_set); + while (tp_intset_fast_iter_next (&iter, &group_handle)) + { + g_ptr_array_add (added_names, (gchar *) tp_handle_inspect ( + self->priv->group_repo, group_handle)); + } + tp_intset_destroy (added_set); + + removed_set = tp_intset_difference (tp_handle_set_peek (d->groups), set); + removed_names = g_ptr_array_sized_new (tp_intset_size (removed_set)); + tp_intset_fast_iter_init (&iter, removed_set); + while (tp_intset_fast_iter_next (&iter, &group_handle)) + { + g_ptr_array_add (removed_names, (gchar *) tp_handle_inspect ( + self->priv->group_repo, group_handle)); + } + tp_intset_destroy (removed_set); + + tp_handle_set_destroy (d->groups); + d->groups = tp_handle_set_new_from_intset (self->priv->group_repo, set); + tp_intset_destroy (set); + + if (added_names->len > 0 || removed_names->len > 0) + { + tp_base_contact_list_one_contact_groups_changed (base, contact, + (const gchar * const *) added_names->pdata, added_names->len, + (const gchar * const *) removed_names->pdata, removed_names->len); + } + + tp_simple_async_report_success_in_idle ((GObject *) self, callback, + user_data, contact_list_set_contact_groups_async); + + g_ptr_array_unref (added_names); + g_ptr_array_unref (removed_names); + g_ptr_array_unref (new_groups); +} + +static void +contact_list_set_group_members_async (TpBaseContactList *base, + const gchar *normalized_group, + TpHandleSet *contacts, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new_error ((GObject *) base, callback, + user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Not implemented"); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + +static void +contact_list_add_to_group_async (TpBaseContactList *base, + const gchar *group, + TpHandleSet *contacts, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new_error ((GObject *) base, callback, + user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Not implemented"); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + +static void +contact_list_remove_from_group_async (TpBaseContactList *base, + const gchar *group, + TpHandleSet *contacts, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new_error ((GObject *) base, callback, + user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Not implemented"); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + +static void +contact_list_remove_group_async (TpBaseContactList *base, + const gchar *group, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new_error ((GObject *) base, callback, + user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Not implemented"); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + +static void +contact_list_request_subscription_async (TpBaseContactList *self, + TpHandleSet *contacts, + const gchar *message, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GArray *handles; + + handles = tp_handle_set_to_array (contacts); + tp_tests_contact_list_manager_request_subscription ( + (TpTestsContactListManager *) self, + handles->len, (TpHandle *) handles->data, message); + g_array_unref (handles); + + tp_simple_async_report_success_in_idle ((GObject *) self, callback, + user_data, contact_list_request_subscription_async); +} + +static void +contact_list_authorize_publication_async (TpBaseContactList *self, + TpHandleSet *contacts, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GArray *handles; + + handles = tp_handle_set_to_array (contacts); + tp_tests_contact_list_manager_authorize_publication ( + (TpTestsContactListManager *) self, + handles->len, (TpHandle *) handles->data); + g_array_unref (handles); + + tp_simple_async_report_success_in_idle ((GObject *) self, callback, + user_data, contact_list_authorize_publication_async); +} + +static void +contact_list_remove_contacts_async (TpBaseContactList *self, + TpHandleSet *contacts, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GArray *handles; + + handles = tp_handle_set_to_array (contacts); + tp_tests_contact_list_manager_remove ( + (TpTestsContactListManager *) self, + handles->len, (TpHandle *) handles->data); + g_array_unref (handles); + + tp_simple_async_report_success_in_idle ((GObject *) self, callback, + user_data, contact_list_remove_contacts_async); +} + +static void +contact_list_unsubscribe_async (TpBaseContactList *self, + TpHandleSet *contacts, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GArray *handles; + + handles = tp_handle_set_to_array (contacts); + tp_tests_contact_list_manager_unsubscribe ( + (TpTestsContactListManager *) self, + handles->len, (TpHandle *) handles->data); + g_array_unref (handles); + + tp_simple_async_report_success_in_idle ((GObject *) self, callback, + user_data, contact_list_unsubscribe_async); +} + +static void +contact_list_unpublish_async (TpBaseContactList *self, + TpHandleSet *contacts, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GArray *handles; + + handles = tp_handle_set_to_array (contacts); + tp_tests_contact_list_manager_unpublish ( + (TpTestsContactListManager *) self, + handles->len, (TpHandle *) handles->data); + g_array_unref (handles); + + tp_simple_async_report_success_in_idle ((GObject *) self, callback, + user_data, contact_list_unpublish_async); +} + +static void +status_changed_cb (TpBaseConnection *conn, + guint status, + guint reason, + TpTestsContactListManager *self) +{ + switch (status) + { + case TP_CONNECTION_STATUS_CONNECTED: + { + tp_base_contact_list_set_list_received (TP_BASE_CONTACT_LIST (self)); + } + break; + + case TP_CONNECTION_STATUS_DISCONNECTED: + { + close_all (self); + } + break; + } +} + +static void +constructed (GObject *object) +{ + TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (object); + void (*chain_up) (GObject *) = + ((GObjectClass *) tp_tests_contact_list_manager_parent_class)->constructed; + + if (chain_up != NULL) + { + chain_up (object); + } + + self->priv->conn = tp_base_contact_list_get_connection ( + TP_BASE_CONTACT_LIST (self), NULL); + self->priv->status_changed_id = g_signal_connect (self->priv->conn, + "status-changed", G_CALLBACK (status_changed_cb), self); + + self->priv->contact_repo = tp_base_connection_get_handles (self->priv->conn, + TP_HANDLE_TYPE_CONTACT); + self->priv->group_repo = tp_base_connection_get_handles (self->priv->conn, + TP_HANDLE_TYPE_GROUP); + self->priv->groups = tp_handle_set_new (self->priv->group_repo); +} + +static void +contact_groups_iface_init (TpContactGroupListInterface *iface) +{ + iface->dup_groups = contact_list_dup_groups; + iface->dup_contact_groups = contact_list_dup_contact_groups; + iface->dup_group_members = contact_list_dup_group_members; +} + +static void +mutable_contact_groups_iface_init ( + TpMutableContactGroupListInterface *iface) +{ + iface->set_contact_groups_async = contact_list_set_contact_groups_async; + iface->set_group_members_async = contact_list_set_group_members_async; + iface->add_to_group_async = contact_list_add_to_group_async; + iface->remove_from_group_async = contact_list_remove_from_group_async; + iface->remove_group_async = contact_list_remove_group_async; +} + +static void +mutable_iface_init (TpMutableContactListInterface *iface) +{ + iface->request_subscription_async = contact_list_request_subscription_async; + iface->authorize_publication_async = contact_list_authorize_publication_async; + iface->remove_contacts_async = contact_list_remove_contacts_async; + iface->unsubscribe_async = contact_list_unsubscribe_async; + iface->unpublish_async = contact_list_unpublish_async; +} + +static void +tp_tests_contact_list_manager_class_init (TpTestsContactListManagerClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + TpBaseContactListClass *base_class =(TpBaseContactListClass *) klass; + + g_type_class_add_private (klass, sizeof (TpTestsContactListManagerPrivate)); + + object_class->constructed = constructed; + object_class->dispose = dispose; + + base_class->dup_states = contact_list_dup_states; + base_class->dup_contacts = contact_list_dup_contacts; +} + +void +tp_tests_contact_list_manager_add_to_group (TpTestsContactListManager *self, + const gchar *group_name, TpHandle member) +{ + TpBaseContactList *base = TP_BASE_CONTACT_LIST (self); + ContactDetails *d = ensure_contact (self, member); + TpHandle group_handle; + + group_handle = tp_handle_ensure (self->priv->group_repo, + group_name, NULL, NULL); + + if (!tp_handle_set_is_member (self->priv->groups, group_handle)) + { + tp_handle_set_add (self->priv->groups, group_handle); + tp_base_contact_list_groups_created ((TpBaseContactList *) self, + &group_name, 1); + } + + tp_handle_set_add (d->groups, group_handle); + tp_base_contact_list_one_contact_groups_changed (base, member, + &group_name, 1, NULL, 0); +} + +void +tp_tests_contact_list_manager_remove_from_group (TpTestsContactListManager *self, + const gchar *group_name, TpHandle member) +{ + TpBaseContactList *base = TP_BASE_CONTACT_LIST (self); + ContactDetails *d = lookup_contact (self, member); + TpHandle group_handle; + + if (d == NULL) + return; + + group_handle = tp_handle_ensure (self->priv->group_repo, group_name, NULL, NULL); + + tp_handle_set_remove (d->groups, group_handle); + tp_base_contact_list_one_contact_groups_changed (base, member, + NULL, 0, &group_name, 1); +} + +typedef struct { + TpTestsContactListManager *self; + TpHandleSet *handles; +} SelfAndContact; + +static SelfAndContact * +self_and_contact_new (TpTestsContactListManager *self, + TpHandleSet *handles) +{ + SelfAndContact *ret = g_slice_new0 (SelfAndContact); + + ret->self = g_object_ref (self); + ret->handles = tp_handle_set_copy (handles); + + return ret; +} + +static void +self_and_contact_destroy (gpointer p) +{ + SelfAndContact *s = p; + + tp_handle_set_destroy (s->handles); + g_object_unref (s->self); + g_slice_free (SelfAndContact, s); +} + +static gboolean +receive_authorized (gpointer p) +{ + SelfAndContact *s = p; + GArray *handles_array; + guint i; + + handles_array = tp_handle_set_to_array (s->handles); + for (i = 0; i < handles_array->len; i++) + { + ContactDetails *d = lookup_contact (s->self, + g_array_index (handles_array, TpHandle, i)); + + if (d == NULL) + continue; + + d->subscribe = TP_SUBSCRIPTION_STATE_YES; + + /* if we're not publishing to them, also pretend they have asked us to do so */ + if (d->publish != TP_SUBSCRIPTION_STATE_YES) + { + d->publish = TP_SUBSCRIPTION_STATE_ASK; + tp_clear_pointer (&d->publish_request, g_free); + d->publish_request = g_strdup ("automatic publish request"); + } + } + g_array_unref (handles_array); + + tp_base_contact_list_contacts_changed (TP_BASE_CONTACT_LIST (s->self), + s->handles, NULL); + + return FALSE; +} + +static gboolean +receive_unauthorized (gpointer p) +{ + SelfAndContact *s = p; + GArray *handles_array; + guint i; + + handles_array = tp_handle_set_to_array (s->handles); + for (i = 0; i < handles_array->len; i++) + { + ContactDetails *d = lookup_contact (s->self, + g_array_index (handles_array, TpHandle, i)); + + if (d == NULL) + continue; + + d->subscribe = TP_SUBSCRIPTION_STATE_REMOVED_REMOTELY; + } + g_array_unref (handles_array); + + tp_base_contact_list_contacts_changed (TP_BASE_CONTACT_LIST (s->self), + s->handles, NULL); + + return FALSE; +} + +void +tp_tests_contact_list_manager_request_subscription (TpTestsContactListManager *self, + guint n_members, TpHandle *members, const gchar *message) +{ + TpHandleSet *handles; + guint i; + gchar *message_lc; + + handles = tp_handle_set_new (self->priv->contact_repo); + for (i = 0; i < n_members; i++) + { + ContactDetails *d = ensure_contact (self, members[i]); + + if (d->subscribe == TP_SUBSCRIPTION_STATE_YES) + continue; + + d->subscribe = TP_SUBSCRIPTION_STATE_ASK; + tp_handle_set_add (handles, members[i]); + } + + tp_base_contact_list_contacts_changed (TP_BASE_CONTACT_LIST (self), handles, + NULL); + + message_lc = g_ascii_strdown (message, -1); + if (strstr (message_lc, "please") != NULL) + { + g_idle_add_full (G_PRIORITY_DEFAULT, + receive_authorized, + self_and_contact_new (self, handles), + self_and_contact_destroy); + } + else if (strstr (message_lc, "no") != NULL) + { + g_idle_add_full (G_PRIORITY_DEFAULT, + receive_unauthorized, + self_and_contact_new (self, handles), + self_and_contact_destroy); + } + + g_free (message_lc); + tp_handle_set_destroy (handles); +} + +void +tp_tests_contact_list_manager_unsubscribe (TpTestsContactListManager *self, + guint n_members, TpHandle *members) +{ + TpHandleSet *handles; + guint i; + + handles = tp_handle_set_new (self->priv->contact_repo); + for (i = 0; i < n_members; i++) + { + ContactDetails *d = lookup_contact (self, members[i]); + + if (d == NULL || d->subscribe == TP_SUBSCRIPTION_STATE_NO) + continue; + + d->subscribe = TP_SUBSCRIPTION_STATE_NO; + tp_handle_set_add (handles, members[i]); + } + + tp_base_contact_list_contacts_changed (TP_BASE_CONTACT_LIST (self), handles, + NULL); + + tp_handle_set_destroy (handles); +} + +void +tp_tests_contact_list_manager_authorize_publication (TpTestsContactListManager *self, + guint n_members, TpHandle *members) +{ + TpHandleSet *handles; + guint i; + + handles = tp_handle_set_new (self->priv->contact_repo); + for (i = 0; i < n_members; i++) + { + ContactDetails *d = lookup_contact (self, members[i]); + + if (d == NULL || d->publish != TP_SUBSCRIPTION_STATE_ASK) + continue; + + d->publish = TP_SUBSCRIPTION_STATE_YES; + tp_clear_pointer (&d->publish_request, g_free); + tp_handle_set_add (handles, members[i]); + } + + tp_base_contact_list_contacts_changed (TP_BASE_CONTACT_LIST (self), handles, + NULL); + + tp_handle_set_destroy (handles); +} + +void +tp_tests_contact_list_manager_unpublish (TpTestsContactListManager *self, + guint n_members, TpHandle *members) +{ + TpHandleSet *handles; + guint i; + + handles = tp_handle_set_new (self->priv->contact_repo); + for (i = 0; i < n_members; i++) + { + ContactDetails *d = lookup_contact (self, members[i]); + + if (d == NULL || d->publish == TP_SUBSCRIPTION_STATE_NO) + continue; + + d->publish = TP_SUBSCRIPTION_STATE_NO; + tp_clear_pointer (&d->publish_request, g_free); + tp_handle_set_add (handles, members[i]); + } + + tp_base_contact_list_contacts_changed (TP_BASE_CONTACT_LIST (self), handles, + NULL); + + tp_handle_set_destroy (handles); +} + +void +tp_tests_contact_list_manager_remove (TpTestsContactListManager *self, + guint n_members, TpHandle *members) +{ + TpHandleSet *handles; + guint i; + + handles = tp_handle_set_new (self->priv->contact_repo); + for (i = 0; i < n_members; i++) + { + ContactDetails *d = lookup_contact (self, members[i]); + + if (d == NULL) + continue; + + g_hash_table_remove (self->priv->contact_details, + GUINT_TO_POINTER (members[i])); + tp_handle_set_add (handles, members[i]); + } + + tp_base_contact_list_contacts_changed (TP_BASE_CONTACT_LIST (self), NULL, + handles); + + tp_handle_set_destroy (handles); +} + +void +tp_tests_contact_list_manager_add_initial_contacts (TpTestsContactListManager *self, + guint n_members, TpHandle *members) +{ + TpHandleSet *handles; + guint i; + + g_assert_cmpint (tp_base_connection_get_status (self->priv->conn), ==, + TP_CONNECTION_STATUS_DISCONNECTED); + g_assert (!tp_base_connection_is_destroyed (self->priv->conn)); + + handles = tp_handle_set_new (self->priv->contact_repo); + for (i = 0; i < n_members; i++) + { + ContactDetails *d; + + g_assert (lookup_contact (self, members[i]) == NULL); + d = ensure_contact (self, members[i]); + + d->subscribe = TP_SUBSCRIPTION_STATE_YES; + d->publish = TP_SUBSCRIPTION_STATE_YES; + + tp_handle_set_add (handles, members[i]); + } + + tp_base_contact_list_contacts_changed (TP_BASE_CONTACT_LIST (self), handles, + NULL); + + tp_handle_set_destroy (handles); +} diff --git a/tests/lib/contact-list-manager.h b/tests/lib/contact-list-manager.h new file mode 100644 index 0000000..bc44863 --- /dev/null +++ b/tests/lib/contact-list-manager.h @@ -0,0 +1,71 @@ +/* + * Example channel manager for contact lists + * + * Copyright © 2007-2010 Collabora Ltd. + * Copyright © 2007-2010 Nokia Corporation + * + * 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. + */ + +#ifndef __TP_TESTS_CONTACT_LIST_MANAGER_H__ +#define __TP_TESTS_CONTACT_LIST_MANAGER_H__ + +#include + +G_BEGIN_DECLS + +#define TP_TESTS_TYPE_CONTACT_LIST_MANAGER \ + (tp_tests_contact_list_manager_get_type ()) +#define TP_TESTS_CONTACT_LIST_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_CONTACT_LIST_MANAGER, \ + TpTestsContactListManager)) +#define TP_TESTS_CONTACT_LIST_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_CONTACT_LIST_MANAGER, \ + TpTestsContactListManagerClass)) +#define TP_TESTS_IS_CONTACT_LIST_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_CONTACT_LIST_MANAGER)) +#define TP_TESTS_IS_CONTACT_LIST_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_CONTACT_LIST_MANAGER)) +#define TP_TESTS_CONTACT_LIST_MANAGER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_CONTACT_LIST_MANAGER, \ + TpTestsContactListManagerClass)) + +typedef struct _TpTestsContactListManager TpTestsContactListManager; +typedef struct _TpTestsContactListManagerClass TpTestsContactListManagerClass; +typedef struct _TpTestsContactListManagerPrivate TpTestsContactListManagerPrivate; + +struct _TpTestsContactListManagerClass { + TpBaseContactListClass parent_class; +}; + +struct _TpTestsContactListManager { + TpBaseContactList parent; + + TpTestsContactListManagerPrivate *priv; +}; + +GType tp_tests_contact_list_manager_get_type (void); + +void tp_tests_contact_list_manager_add_to_group (TpTestsContactListManager *self, + const gchar *group_name, TpHandle member); +void tp_tests_contact_list_manager_remove_from_group (TpTestsContactListManager *self, + const gchar *group_name, TpHandle member); + +void tp_tests_contact_list_manager_request_subscription (TpTestsContactListManager *self, + guint n_members, TpHandle *members, const gchar *message); +void tp_tests_contact_list_manager_unsubscribe (TpTestsContactListManager *self, + guint n_members, TpHandle *members); +void tp_tests_contact_list_manager_authorize_publication (TpTestsContactListManager *self, + guint n_members, TpHandle *members); +void tp_tests_contact_list_manager_unpublish (TpTestsContactListManager *self, + guint n_members, TpHandle *members); +void tp_tests_contact_list_manager_remove (TpTestsContactListManager *self, + guint n_members, TpHandle *members); +void tp_tests_contact_list_manager_add_initial_contacts (TpTestsContactListManager *self, + guint n_members, TpHandle *members); + +G_END_DECLS + +#endif diff --git a/tests/lib/contacts-conn.c b/tests/lib/contacts-conn.c index 3b25172..6cca69f 100644 --- a/tests/lib/contacts-conn.c +++ b/tests/lib/contacts-conn.c @@ -8,18 +8,17 @@ * are permitted in any medium without royalty provided the copyright * notice and this notice are preserved. */ + #include "config.h" #include "contacts-conn.h" #include -#include -#include -#include -#include -#include -#include +#include +#include + +#include "debug.h" static void init_aliasing (gpointer, gpointer); static void init_avatars (gpointer, gpointer); @@ -36,8 +35,6 @@ G_DEFINE_TYPE_WITH_CODE (TpTestsContactsConnection, init_aliasing); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_AVATARS, init_avatars); - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS, - tp_contacts_mixin_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_PRESENCE, tp_presence_mixin_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_SIMPLE_PRESENCE, @@ -49,6 +46,14 @@ G_DEFINE_TYPE_WITH_CODE (TpTestsContactsConnection, init_contact_caps) G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_INFO, init_contact_info) + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS, + tp_contacts_mixin_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_LIST, + tp_base_contact_list_mixin_list_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_GROUPS, + tp_base_contact_list_mixin_groups_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CLIENT_TYPES, + NULL); ); /* type definition stuff */ @@ -89,6 +94,8 @@ struct _TpTestsContactsConnectionPrivate /* TpHandle => GPtrArray * */ GHashTable *contact_info; GPtrArray *default_contact_info; + + TpTestsContactListManager *list_manager; }; typedef struct @@ -319,11 +326,40 @@ conn_contact_info_properties_getter (GObject *object, if (supported_fields == NULL) { supported_fields = g_ptr_array_new (); + g_ptr_array_add (supported_fields, tp_value_array_build (4, - G_TYPE_STRING, "n", + G_TYPE_STRING, "bday", G_TYPE_STRV, NULL, G_TYPE_UINT, 0, + G_TYPE_UINT, 1, + G_TYPE_INVALID)); + + g_ptr_array_add (supported_fields, tp_value_array_build (4, + G_TYPE_STRING, "email", + G_TYPE_STRV, NULL, + G_TYPE_UINT, 0, + G_TYPE_UINT, G_MAXUINT32, + G_TYPE_INVALID)); + + g_ptr_array_add (supported_fields, tp_value_array_build (4, + G_TYPE_STRING, "fn", + G_TYPE_STRV, NULL, G_TYPE_UINT, 0, + G_TYPE_UINT, 1, + G_TYPE_INVALID)); + + g_ptr_array_add (supported_fields, tp_value_array_build (4, + G_TYPE_STRING, "tel", + G_TYPE_STRV, NULL, + G_TYPE_UINT, 0, + G_TYPE_UINT, G_MAXUINT32, + G_TYPE_INVALID)); + + g_ptr_array_add (supported_fields, tp_value_array_build (4, + G_TYPE_STRING, "url", + G_TYPE_STRV, NULL, + G_TYPE_UINT, 0, + G_TYPE_UINT, G_MAXUINT32, G_TYPE_INVALID)); } g_value_set_boxed (value, supported_fields); @@ -335,8 +371,26 @@ conn_contact_info_properties_getter (GObject *object, } static void +client_types_fill_contact_attributes ( + GObject *object, + const GArray *contacts, + GHashTable *attributes) +{ + TpTestsContactsConnectionClass *klass = + TP_TESTS_CONTACTS_CONNECTION_GET_CLASS (object); + + if (klass->fill_client_types != NULL) + klass->fill_client_types (object, contacts, attributes); + /* …else do nothing: a no-op implementation is valid, relatively speaking. + * The spec sez the /client-types attribute should be “omitted from the + * result if the contact's client types are not known.” + */ +} + +static void constructed (GObject *object) { + TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object); TpBaseConnection *base = TP_BASE_CONNECTION (object); void (*parent_impl) (GObject *) = G_OBJECT_CLASS (tp_tests_contacts_connection_parent_class)->constructed; @@ -347,6 +401,8 @@ constructed (GObject *object) tp_contacts_mixin_init (object, G_STRUCT_OFFSET (TpTestsContactsConnection, contacts_mixin)); tp_base_connection_register_with_contacts_mixin (base); + if (self->priv->list_manager) + tp_base_contact_list_mixin_register_with_contacts_mixin (base); tp_contacts_mixin_add_contact_attributes_iface (object, TP_IFACE_CONNECTION_INTERFACE_ALIASING, aliasing_fill_contact_attributes); @@ -362,6 +418,9 @@ constructed (GObject *object) tp_contacts_mixin_add_contact_attributes_iface (object, TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO, contact_info_fill_contact_attributes); + tp_contacts_mixin_add_contact_attributes_iface (object, + TP_IFACE_CONNECTION_INTERFACE_CLIENT_TYPES, + client_types_fill_contact_attributes); tp_presence_mixin_init (object, G_STRUCT_OFFSET (TpTestsContactsConnection, presence_mixin)); @@ -391,10 +450,7 @@ my_status_available (GObject *object, { TpBaseConnection *base = TP_BASE_CONNECTION (object); - if (base->status != TP_CONNECTION_STATUS_CONNECTED) - return FALSE; - - return TRUE; + return tp_base_connection_check_connected (base, NULL); } static GHashTable * @@ -424,7 +480,7 @@ my_get_contact_statuses (GObject *object, g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); if (presence_message != NULL) - g_hash_table_insert (parameters, "message", + g_hash_table_insert (parameters, (gpointer) "message", tp_g_value_slice_new_string (presence_message)); g_hash_table_insert (result, key, @@ -443,6 +499,7 @@ my_set_own_status (GObject *object, TpBaseConnection *base_conn = TP_BASE_CONNECTION (object); TpTestsContactsConnectionPresenceStatusIndex index = status->index; const gchar *message = ""; + TpHandle self_handle; if (status->optional_arguments != NULL) { @@ -452,29 +509,68 @@ my_set_own_status (GObject *object, message = ""; } + self_handle = tp_base_connection_get_self_handle (base_conn); tp_tests_contacts_connection_change_presences (TP_TESTS_CONTACTS_CONNECTION (object), - 1, &(base_conn->self_handle), &index, &message); + 1, &self_handle, &index, &message); return TRUE; } -static void -tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass) +static guint +my_get_maximum_status_message_length_cb (GObject *obj) { - TpBaseConnectionClass *base_class = - (TpBaseConnectionClass *) klass; - GObjectClass *object_class = (GObjectClass *) klass; + return 512; +} + +static GPtrArray * +create_channel_managers (TpBaseConnection *conn) +{ + TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (conn); + GPtrArray *ret = g_ptr_array_sized_new (1); + + self->priv->list_manager = g_object_new (TP_TESTS_TYPE_CONTACT_LIST_MANAGER, + "connection", conn, NULL); + + g_ptr_array_add (ret, self->priv->list_manager); + + return ret; +} + +static GPtrArray * +tp_tests_contacts_get_interfaces_always_present (TpBaseConnection *base) +{ + GPtrArray *interfaces; static const gchar *interfaces_always_present[] = { TP_IFACE_CONNECTION_INTERFACE_ALIASING, TP_IFACE_CONNECTION_INTERFACE_AVATARS, TP_IFACE_CONNECTION_INTERFACE_CONTACTS, + TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST, + TP_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS, TP_IFACE_CONNECTION_INTERFACE_PRESENCE, TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE, TP_IFACE_CONNECTION_INTERFACE_LOCATION, + TP_IFACE_CONNECTION_INTERFACE_CLIENT_TYPES, TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES, TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO, - TP_IFACE_CONNECTION_INTERFACE_REQUESTS, NULL }; + guint i; + + interfaces = TP_BASE_CONNECTION_CLASS ( + tp_tests_contacts_connection_parent_class)->get_interfaces_always_present (base); + + for (i = 0; interfaces_always_present[i] != NULL; i++) + g_ptr_array_add (interfaces, (gchar *) interfaces_always_present[i]); + + return interfaces; +} + +static void +tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass) +{ + TpBaseConnectionClass *base_class = + (TpBaseConnectionClass *) klass; + GObjectClass *object_class = (GObjectClass *) klass; + TpPresenceMixinClass *mixin_class; static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { { TP_IFACE_CONNECTION_INTERFACE_AVATARS, conn_avatars_properties_getter, @@ -493,7 +589,8 @@ tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass) object_class->finalize = finalize; g_type_class_add_private (klass, sizeof (TpTestsContactsConnectionPrivate)); - base_class->interfaces_always_present = interfaces_always_present; + base_class->get_interfaces_always_present = tp_tests_contacts_get_interfaces_always_present; + base_class->create_channel_managers = create_channel_managers; tp_contacts_mixin_class_init (object_class, G_STRUCT_OFFSET (TpTestsContactsConnectionClass, contacts_mixin)); @@ -502,14 +599,34 @@ tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass) G_STRUCT_OFFSET (TpTestsContactsConnectionClass, presence_mixin), my_status_available, my_get_contact_statuses, my_set_own_status, my_statuses); + mixin_class = TP_PRESENCE_MIXIN_CLASS(klass); + mixin_class->get_maximum_status_message_length = + my_get_maximum_status_message_length_cb; tp_presence_mixin_simple_presence_init_dbus_properties (object_class); klass->properties_class.interfaces = prop_interfaces; tp_dbus_properties_mixin_class_init (object_class, G_STRUCT_OFFSET (TpTestsContactsConnectionClass, properties_class)); + + tp_base_contact_list_mixin_class_init (base_class); +} + +TpTestsContactListManager * +tp_tests_contacts_connection_get_contact_list_manager ( + TpTestsContactsConnection *self) +{ + return self->priv->list_manager; } +/** + * tp_tests_contacts_connection_change_aliases: + * @self: a #TpTestsContactsConnection + * @n: the number of handles + * @handles: (array length=n): the handles + * @aliases: (array length=n): aliases + * + */ void tp_tests_contacts_connection_change_aliases (TpTestsContactsConnection *self, guint n, @@ -523,6 +640,8 @@ tp_tests_contacts_connection_change_aliases (TpTestsContactsConnection *self, { GValueArray *pair = g_value_array_new (2); + DEBUG ("contact#%u -> %s", handles[i], aliases[i]); + g_hash_table_insert (self->priv->aliases, GUINT_TO_POINTER (handles[i]), g_strdup (aliases[i])); @@ -561,6 +680,9 @@ tp_tests_contacts_connection_change_presences ( GHashTable *parameters; gpointer key = GUINT_TO_POINTER (handles[i]); + DEBUG ("contact#%u -> %s \"%s\"", handles[i], + my_statuses[indexes[i]].name, messages[i]); + g_hash_table_insert (self->priv->presence_statuses, key, GUINT_TO_POINTER (indexes[i])); g_hash_table_insert (self->priv->presence_messages, key, @@ -570,7 +692,7 @@ tp_tests_contacts_connection_change_presences ( g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); if (messages[i] != NULL && messages[i][0] != '\0') - g_hash_table_insert (parameters, "message", + g_hash_table_insert (parameters, (gpointer) "message", tp_g_value_slice_new_string (messages[i])); g_hash_table_insert (presences, key, tp_presence_status_new (indexes[i], @@ -593,6 +715,7 @@ tp_tests_contacts_connection_change_avatar_tokens (TpTestsContactsConnection *se for (i = 0; i < n; i++) { + DEBUG ("contact#%u -> %s", handles[i], tokens[i]); g_hash_table_insert (self->priv->avatars, GUINT_TO_POINTER (handles[i]), avatar_data_new (NULL, NULL, tokens[i])); tp_svc_connection_interface_avatars_emit_avatar_updated (self, @@ -625,6 +748,7 @@ tp_tests_contacts_connection_change_locations (TpTestsContactsConnection *self, for (i = 0; i < n; i++) { + DEBUG ("contact#%u ->", handles[i]); tp_asv_dump (locations[i]); g_hash_table_insert (self->priv->locations, GUINT_TO_POINTER (handles[i]), g_hash_table_ref (locations[i])); @@ -686,7 +810,7 @@ my_get_alias_flags (TpSvcConnectionInterfaceAliasing *aliasing, TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context); tp_svc_connection_interface_aliasing_return_from_get_alias_flags (context, - 0); + TP_CONNECTION_ALIAS_FLAG_USER_SET); } static void @@ -778,6 +902,57 @@ my_request_aliases (TpSvcConnectionInterfaceAliasing *aliasing, } static void +my_set_aliases (TpSvcConnectionInterfaceAliasing *aliasing, + GHashTable *table, + DBusGMethodInvocation *context) +{ + TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (aliasing); + TpBaseConnection *base = TP_BASE_CONNECTION (aliasing); + TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base, + TP_HANDLE_TYPE_CONTACT); + guint n; + GArray *handles; + GPtrArray *aliases; + GHashTableIter iter; + gpointer key, value; + GError *error = NULL; + + /* Convert the hash table to arrays of handles and aliases */ + n = g_hash_table_size (table); + handles = g_array_sized_new (FALSE, FALSE, sizeof (TpHandle), n); + aliases = g_ptr_array_sized_new (n); + g_hash_table_iter_init (&iter, table); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + TpHandle handle = GPOINTER_TO_UINT (key); + + g_array_append_val (handles, handle); + g_ptr_array_add (aliases, value); + } + g_assert_cmpuint (handles->len, ==, n); + g_assert_cmpuint (aliases->len, ==, n); + + /* Verify all handles are valid */ + if (!tp_handles_are_valid (contact_repo, handles, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_clear_error (&error); + goto out; + } + + /* Change aliases */ + tp_tests_contacts_connection_change_aliases (self, n, + (const TpHandle *) handles->data, + (const gchar * const *) aliases->pdata); + + tp_svc_connection_interface_aliasing_return_from_set_aliases (context); + +out: + g_array_unref (handles); + g_ptr_array_unref (aliases); +} + +static void init_aliasing (gpointer g_iface, gpointer iface_data) { @@ -788,7 +963,7 @@ init_aliasing (gpointer g_iface, IMPLEMENT(get_alias_flags); IMPLEMENT(request_aliases); IMPLEMENT(get_aliases); - /* IMPLEMENT(set_aliases); */ + IMPLEMENT(set_aliases); #undef IMPLEMENT } @@ -1077,7 +1252,10 @@ lookup_contact_info (TpTestsContactsConnection *self, g_ptr_array_ref (ret)); } - return ret; + if (ret == NULL) + return g_ptr_array_new (); + + return g_ptr_array_ref (ret); } static void @@ -1108,6 +1286,7 @@ my_refresh_contact_info (TpSvcConnectionInterfaceContactInfo *obj, tp_svc_connection_interface_contact_info_emit_contact_info_changed (self, handle, arr); + g_ptr_array_unref (arr); } tp_svc_connection_interface_contact_info_return_from_refresh_contact_info ( @@ -1139,6 +1318,8 @@ my_request_contact_info (TpSvcConnectionInterfaceContactInfo *obj, tp_svc_connection_interface_contact_info_return_from_request_contact_info ( context, ret); + + g_ptr_array_unref (ret); } static void @@ -1160,8 +1341,8 @@ my_set_contact_info (TpSvcConnectionInterfaceContactInfo *obj, g_ptr_array_add (copy, g_value_array_copy (g_ptr_array_index (info, i))); self_handle = tp_base_connection_get_self_handle (base); - g_hash_table_insert (self->priv->contact_info, GUINT_TO_POINTER (self_handle), - copy); + tp_tests_contacts_connection_change_contact_info (self, self_handle, copy); + g_ptr_array_unref (copy); tp_svc_connection_interface_contact_info_return_from_set_contact_info ( context); @@ -1215,27 +1396,33 @@ tp_tests_legacy_contacts_connection_init (TpTestsLegacyContactsConnection *self) { } +static GPtrArray * +tp_tests_legacy_contacts_get_interfaces_always_present (TpBaseConnection *base) +{ + GPtrArray *interfaces; + + interfaces = TP_BASE_CONNECTION_CLASS ( + tp_tests_legacy_contacts_connection_parent_class)->get_interfaces_always_present (base); + + g_ptr_array_remove (interfaces, TP_IFACE_CONNECTION_INTERFACE_CONTACTS); + g_ptr_array_remove (interfaces, TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES); + + return interfaces; +} + static void tp_tests_legacy_contacts_connection_class_init ( TpTestsLegacyContactsConnectionClass *klass) { /* Leave Contacts out of the interfaces we say are present, so clients * won't use it */ - static const gchar *interfaces_always_present[] = { - TP_IFACE_CONNECTION_INTERFACE_ALIASING, - TP_IFACE_CONNECTION_INTERFACE_AVATARS, - TP_IFACE_CONNECTION_INTERFACE_PRESENCE, - TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE, - TP_IFACE_CONNECTION_INTERFACE_LOCATION, - TP_IFACE_CONNECTION_INTERFACE_REQUESTS, - NULL }; TpBaseConnectionClass *base_class = (TpBaseConnectionClass *) klass; GObjectClass *object_class = (GObjectClass *) klass; object_class->get_property = legacy_contacts_connection_get_property; - base_class->interfaces_always_present = interfaces_always_present; + base_class->get_interfaces_always_present = tp_tests_legacy_contacts_get_interfaces_always_present; g_object_class_override_property (object_class, LEGACY_PROP_HAS_IMMORTAL_HANDLES, "has-immortal-handles"); @@ -1251,20 +1438,27 @@ tp_tests_no_requests_connection_init (TpTestsNoRequestsConnection *self) { } +static GPtrArray * +tp_tests_no_requests_get_interfaces_always_present (TpBaseConnection *base) +{ + GPtrArray *interfaces; + + interfaces = TP_BASE_CONNECTION_CLASS ( + tp_tests_no_requests_connection_parent_class)->get_interfaces_always_present (base); + + g_ptr_array_remove (interfaces, TP_IFACE_CONNECTION_INTERFACE_REQUESTS); + g_ptr_array_remove (interfaces, TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES); + + return interfaces; +} + static void tp_tests_no_requests_connection_class_init ( TpTestsNoRequestsConnectionClass *klass) { - static const gchar *interfaces_always_present[] = { - TP_IFACE_CONNECTION_INTERFACE_ALIASING, - TP_IFACE_CONNECTION_INTERFACE_AVATARS, - TP_IFACE_CONNECTION_INTERFACE_CONTACTS, - TP_IFACE_CONNECTION_INTERFACE_PRESENCE, - TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE, - TP_IFACE_CONNECTION_INTERFACE_LOCATION, - NULL }; TpBaseConnectionClass *base_class = (TpBaseConnectionClass *) klass; - base_class->interfaces_always_present = interfaces_always_present; + base_class->get_interfaces_always_present = tp_tests_no_requests_get_interfaces_always_present; + base_class->create_channel_managers = NULL; } diff --git a/tests/lib/contacts-conn.h b/tests/lib/contacts-conn.h index baab460..c596e3e 100644 --- a/tests/lib/contacts-conn.h +++ b/tests/lib/contacts-conn.h @@ -13,11 +13,10 @@ #define __TP_TESTS_CONTACTS_CONN_H__ #include -#include -#include -#include +#include #include "simple-conn.h" +#include "contact-list-manager.h" G_BEGIN_DECLS @@ -31,6 +30,8 @@ struct _TpTestsContactsConnectionClass { TpPresenceMixinClass presence_mixin; TpContactsMixinClass contacts_mixin; TpDBusPropertiesMixinClass properties_class; + + TpContactsMixinFillContactAttributesFunc fill_client_types; }; struct _TpTestsContactsConnection { @@ -71,6 +72,9 @@ typedef enum { (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_CONTACTS_CONNECTION, \ TpTestsContactsConnectionClass)) +TpTestsContactListManager *tp_tests_contacts_connection_get_contact_list_manager ( + TpTestsContactsConnection *self); + void tp_tests_contacts_connection_change_aliases ( TpTestsContactsConnection *self, guint n, const TpHandle *handles, const gchar * const *aliases); diff --git a/tests/lib/debug.h b/tests/lib/debug.h new file mode 100644 index 0000000..60e070b --- /dev/null +++ b/tests/lib/debug.h @@ -0,0 +1,3 @@ +#undef DEBUG +#define DEBUG(format, ...) \ + g_debug ("%s: " format, G_STRFUNC, ##__VA_ARGS__) diff --git a/tests/lib/room-list-chan.c b/tests/lib/room-list-chan.c index 49ed291..e6134a3 100644 --- a/tests/lib/room-list-chan.c +++ b/tests/lib/room-list-chan.c @@ -4,8 +4,6 @@ #include "room-list-chan.h" #include -#include -#include static void room_list_iface_init (gpointer iface, gpointer data); diff --git a/tests/lib/room-list-chan.h b/tests/lib/room-list-chan.h index b41be27..52dbd2e 100644 --- a/tests/lib/room-list-chan.h +++ b/tests/lib/room-list-chan.h @@ -3,7 +3,7 @@ #define __TP_TESTS_ROOM_LIST_CHAN_H__ #include -#include +#include G_BEGIN_DECLS diff --git a/tests/lib/simple-account-manager.c b/tests/lib/simple-account-manager.c index 33e70f6..c38132c 100644 --- a/tests/lib/simple-account-manager.c +++ b/tests/lib/simple-account-manager.c @@ -1,7 +1,7 @@ /* * simple-account-manager.c - a simple account manager service. * - * Copyright (C) 2007-2009 Collabora Ltd. + * Copyright (C) 2007-2012 Collabora Ltd. * Copyright (C) 2007-2008 Nokia Corporation * * Copying and distribution of this file, with or without modification, @@ -13,10 +13,8 @@ #include "simple-account-manager.h" -#include -#include -#include -#include +#include +#include static void account_manager_iface_init (gpointer, gpointer); @@ -33,14 +31,6 @@ G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleAccountManager, /* TP_IFACE_ACCOUNT_MANAGER is implied */ static const char *ACCOUNT_MANAGER_INTERFACES[] = { NULL }; -static gchar *VALID_ACCOUNTS[] = { - "/org/freedesktop/Telepathy/Account/fakecm/fakeproto/validaccount", - NULL }; - -static gchar *INVALID_ACCOUNTS[] = { - "/org/freedesktop/Telepathy/Account/fakecm/fakeproto/invalidaccount", - NULL }; - enum { PROP_0, @@ -51,11 +41,12 @@ enum struct _TpTestsSimpleAccountManagerPrivate { - int dummy; + GPtrArray *valid_accounts; + GPtrArray *invalid_accounts; }; static void -tp_tests_simple_account_manager_create_account (TpSvcAccountManager *self, +tp_tests_simple_account_manager_create_account (TpSvcAccountManager *svc, const gchar *in_Connection_Manager, const gchar *in_Protocol, const gchar *in_Display_Name, @@ -63,9 +54,24 @@ tp_tests_simple_account_manager_create_account (TpSvcAccountManager *self, GHashTable *in_Properties, DBusGMethodInvocation *context) { - const gchar *out_Account = "/some/fake/account/i/think"; - - tp_svc_account_manager_return_from_create_account (context, out_Account); + TpTestsSimpleAccountManager *self = (TpTestsSimpleAccountManager *) svc; + const gchar *out = TP_ACCOUNT_OBJECT_PATH_BASE "gabble/jabber/lospolloshermanos"; + + /* if we have fail=yes as a parameter, make the call fail */ + if (!tp_strdiff (tp_asv_get_string (in_Parameters, "fail"), "yes")) + { + GError e = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "loldongs" }; + dbus_g_method_return_error (context, &e); + return; + } + + self->create_cm = g_strdup (in_Connection_Manager); + self->create_protocol = g_strdup (in_Protocol); + self->create_display_name = g_strdup (in_Display_Name); + self->create_parameters = g_hash_table_ref (in_Parameters); + self->create_properties = g_hash_table_ref (in_Properties); + + tp_svc_account_manager_return_from_create_account (context, out); } static void @@ -84,6 +90,9 @@ tp_tests_simple_account_manager_init (TpTestsSimpleAccountManager *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER, TpTestsSimpleAccountManagerPrivate); + + self->priv->valid_accounts = g_ptr_array_new_with_free_func (g_free); + self->priv->invalid_accounts = g_ptr_array_new_with_free_func (g_free); } static void @@ -92,8 +101,7 @@ tp_tests_simple_account_manager_get_property (GObject *object, GValue *value, GParamSpec *spec) { - GPtrArray *accounts; - guint i = 0; + TpTestsSimpleAccountManager *self = SIMPLE_ACCOUNT_MANAGER (object); switch (property_id) { case PROP_INTERFACES: @@ -101,21 +109,11 @@ tp_tests_simple_account_manager_get_property (GObject *object, break; case PROP_VALID_ACCOUNTS: - accounts = g_ptr_array_new (); - - for (i=0; VALID_ACCOUNTS[i] != NULL; i++) - g_ptr_array_add (accounts, g_strdup (VALID_ACCOUNTS[i])); - - g_value_take_boxed (value, accounts); + g_value_set_boxed (value, self->priv->valid_accounts); break; case PROP_INVALID_ACCOUNTS: - accounts = g_ptr_array_new (); - - for (i=0; INVALID_ACCOUNTS[i] != NULL; i++) - g_ptr_array_add (accounts, g_strdup (VALID_ACCOUNTS[i])); - - g_value_take_boxed (value, accounts); + g_value_set_boxed (value, self->priv->invalid_accounts); break; default: @@ -124,6 +122,24 @@ tp_tests_simple_account_manager_get_property (GObject *object, } } +static void +tp_tests_simple_account_manager_finalize (GObject *object) +{ + TpTestsSimpleAccountManager *self = SIMPLE_ACCOUNT_MANAGER (object); + + g_ptr_array_unref (self->priv->valid_accounts); + g_ptr_array_unref (self->priv->invalid_accounts); + + tp_clear_pointer (&self->create_cm, g_free); + tp_clear_pointer (&self->create_protocol, g_free); + tp_clear_pointer (&self->create_display_name, g_free); + tp_clear_pointer (&self->create_parameters, g_hash_table_unref); + tp_clear_pointer (&self->create_properties, g_hash_table_unref); + + G_OBJECT_CLASS (tp_tests_simple_account_manager_parent_class)->finalize ( + object); +} + /** * This class currently only provides the minimum for * tp_account_manager_prepare to succeed. This turns out to be only a working @@ -158,6 +174,7 @@ tp_tests_simple_account_manager_class_init ( }; g_type_class_add_private (klass, sizeof (TpTestsSimpleAccountManagerPrivate)); + object_class->finalize = tp_tests_simple_account_manager_finalize; object_class->get_property = tp_tests_simple_account_manager_get_property; param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces", @@ -180,3 +197,44 @@ tp_tests_simple_account_manager_class_init ( tp_dbus_properties_mixin_class_init (object_class, G_STRUCT_OFFSET (TpTestsSimpleAccountManagerClass, dbus_props_class)); } + +static void +remove_from_array (GPtrArray *array, const gchar *str) +{ + guint i; + + for (i = 0; i < array->len; i++) + if (!tp_strdiff (str, g_ptr_array_index (array, i))) + { + g_ptr_array_remove_index_fast (array, i); + return; + } +} + +void +tp_tests_simple_account_manager_add_account ( + TpTestsSimpleAccountManager *self, + const gchar *object_path, + gboolean valid) +{ + remove_from_array (self->priv->valid_accounts, object_path); + remove_from_array (self->priv->valid_accounts, object_path); + + if (valid) + g_ptr_array_add (self->priv->valid_accounts, g_strdup (object_path)); + else + g_ptr_array_add (self->priv->invalid_accounts, g_strdup (object_path)); + + tp_svc_account_manager_emit_account_validity_changed (self, object_path, valid); +} + +void +tp_tests_simple_account_manager_remove_account ( + TpTestsSimpleAccountManager *self, + const gchar *object_path) +{ + remove_from_array (self->priv->valid_accounts, object_path); + remove_from_array (self->priv->valid_accounts, object_path); + + tp_svc_account_manager_emit_account_removed (self, object_path); +} diff --git a/tests/lib/simple-account-manager.h b/tests/lib/simple-account-manager.h index b4f787c..94a60cd 100644 --- a/tests/lib/simple-account-manager.h +++ b/tests/lib/simple-account-manager.h @@ -1,7 +1,7 @@ /* * simple-account-manager.h - header for a simple account manager service. * - * Copyright (C) 2007-2009 Collabora Ltd. + * Copyright (C) 2007-2012 Collabora Ltd. * Copyright (C) 2007-2008 Nokia Corporation * * Copying and distribution of this file, with or without modification, @@ -13,7 +13,7 @@ #define __TP_TESTS_SIMPLE_ACCOUNT_MANAGER_H__ #include -#include +#include G_BEGIN_DECLS @@ -30,6 +30,12 @@ struct _TpTestsSimpleAccountManagerClass { struct _TpTestsSimpleAccountManager { GObject parent; + gchar *create_cm; + gchar *create_protocol; + gchar *create_display_name; + GHashTable *create_parameters; + GHashTable *create_properties; + TpTestsSimpleAccountManagerPrivate *priv; }; @@ -52,6 +58,14 @@ GType tp_tests_simple_account_manager_get_type (void); (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER, \ TpTestsSimpleAccountManagerClass)) +void tp_tests_simple_account_manager_add_account ( + TpTestsSimpleAccountManager *self, + const gchar *object_path, + gboolean valid); + +void tp_tests_simple_account_manager_remove_account ( + TpTestsSimpleAccountManager *self, + const gchar *object_path); G_END_DECLS diff --git a/tests/lib/simple-account.c b/tests/lib/simple-account.c index 6761c06..eeead16 100644 --- a/tests/lib/simple-account.c +++ b/tests/lib/simple-account.c @@ -1,7 +1,7 @@ /* * simple-account.c - a simple account service. * - * Copyright (C) 2010 Collabora Ltd. + * Copyright (C) 2010-2012 Collabora Ltd. * * Copying and distribution of this file, with or without modification, * are permitted in any medium without royalty provided the copyright @@ -12,14 +12,8 @@ #include "simple-account.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include static void account_iface_init (gpointer, gpointer); @@ -28,6 +22,10 @@ G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleAccount, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_ACCOUNT, account_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_ACCOUNT_INTERFACE_AVATAR, + NULL); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_ACCOUNT_INTERFACE_ADDRESSING, + NULL); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_ACCOUNT_INTERFACE_STORAGE, NULL); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, @@ -36,6 +34,7 @@ G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleAccount, /* TP_IFACE_ACCOUNT is implied */ static const char *ACCOUNT_INTERFACES[] = { + TP_IFACE_ACCOUNT_INTERFACE_ADDRESSING, TP_IFACE_ACCOUNT_INTERFACE_STORAGE, NULL }; @@ -58,91 +57,97 @@ enum PROP_REQUESTED_PRESENCE, PROP_NORMALIZED_NAME, PROP_HAS_BEEN_ONLINE, + PROP_URI_SCHEMES, PROP_STORAGE_PROVIDER, PROP_STORAGE_IDENTIFIER, PROP_STORAGE_SPECIFIC_INFORMATION, - PROP_STORAGE_RESTRICTIONS + PROP_STORAGE_RESTRICTIONS, + PROP_AVATAR, + PROP_SUPERSEDES, + N_PROPS }; struct _TpTestsSimpleAccountPrivate { - gpointer unused; - GHashTable *parameters; + TpConnectionPresenceType presence; + gchar *presence_status; + gchar *presence_msg; + gchar *connection_path; + gboolean enabled; + GPtrArray *uri_schemes; }; static void +tp_tests_simple_account_update_parameters (TpSvcAccount *svc, + GHashTable *parameters, + const gchar **unset_parameters, + DBusGMethodInvocation *context) +{ + GPtrArray *reconnect_required = g_ptr_array_new (); + GHashTableIter iter; + gpointer k; + guint i; + + /* We don't actually store any parameters, but for the purposes + * of this method we pretend that every parameter provided is + * valid and requires reconnection. */ + + g_hash_table_iter_init (&iter, parameters); + + while (g_hash_table_iter_next (&iter, &k, NULL)) + g_ptr_array_add (reconnect_required, k); + + for (i = 0; unset_parameters != NULL && unset_parameters[i] != NULL; i++) + g_ptr_array_add (reconnect_required, (gchar *) unset_parameters[i]); + + g_ptr_array_add (reconnect_required, NULL); + + tp_svc_account_return_from_update_parameters (context, + (const gchar **) reconnect_required->pdata); + g_ptr_array_unref (reconnect_required); +} + +static void account_iface_init (gpointer klass, gpointer unused G_GNUC_UNUSED) { #define IMPLEMENT(x) tp_svc_account_implement_##x (\ klass, tp_tests_simple_account_##x) - /* TODO */ + IMPLEMENT (update_parameters); #undef IMPLEMENT } +/* you may have noticed this is not entirely realistic */ +static const gchar * const uri_schemes[] = { "about", "telnet", NULL }; static void tp_tests_simple_account_init (TpTestsSimpleAccount *self) { + guint i; + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TESTS_TYPE_SIMPLE_ACCOUNT, TpTestsSimpleAccountPrivate); - self->priv->parameters = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, (GDestroyNotify) tp_g_value_slice_free); -} - -static gpointer -_parameters_hash_copy_key (gpointer boxed) -{ - return g_strdup (boxed); -} - -static gpointer -_parameters_hash_copy_value (gpointer boxed) -{ - GValue *ret = tp_g_value_slice_new (G_TYPE_STRING); - g_value_copy (boxed, ret); - return ret; -} - - -static void -tp_tests_simple_account_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - TpTestsSimpleAccount *self = TP_TESTS_SIMPLE_ACCOUNT (object); + self->priv->presence = TP_CONNECTION_PRESENCE_TYPE_AWAY; + self->priv->presence_status = g_strdup ("currently-away"); + self->priv->presence_msg = g_strdup ("this is my CurrentPresence"); + self->priv->connection_path = g_strdup ("/"); + self->priv->enabled = TRUE; - switch (param_id) { - case PROP_PARAMETERS: - tp_g_hash_table_update (self->priv->parameters, - g_value_get_boxed (value), _parameters_hash_copy_key, - _parameters_hash_copy_value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } + self->priv->uri_schemes = g_ptr_array_new_with_free_func (g_free); + for (i = 0; uri_schemes[i] != NULL; i++) + g_ptr_array_add (self->priv->uri_schemes, g_strdup (uri_schemes[i])); } - static void tp_tests_simple_account_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *spec) + guint property_id, + GValue *value, + GParamSpec *spec) { TpTestsSimpleAccount *self = TP_TESTS_SIMPLE_ACCOUNT (object); - GValueArray *presence; GValue identifier = { 0, }; - presence = tp_value_array_build (3, - G_TYPE_UINT, TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, - G_TYPE_STRING, "available", - G_TYPE_STRING, "", - G_TYPE_INVALID); - g_value_init (&identifier, G_TYPE_STRING); g_value_set_string (&identifier, "unique-identifier"); @@ -160,22 +165,26 @@ tp_tests_simple_account_get_property (GObject *object, g_value_set_boolean (value, TRUE); break; case PROP_ENABLED: - g_value_set_boolean (value, TRUE); + g_value_set_boolean (value, self->priv->enabled); break; case PROP_NICKNAME: g_value_set_string (value, "badger"); break; case PROP_PARAMETERS: - g_value_set_boxed (value, self->priv->parameters); + g_value_take_boxed (value, g_hash_table_new (NULL, NULL)); break; case PROP_AUTOMATIC_PRESENCE: - g_value_set_boxed (value, presence); + g_value_take_boxed (value, tp_value_array_build (3, + G_TYPE_UINT, TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, + G_TYPE_STRING, "automatically-available", + G_TYPE_STRING, "this is my AutomaticPresence", + G_TYPE_INVALID)); break; case PROP_CONNECT_AUTO: g_value_set_boolean (value, FALSE); break; case PROP_CONNECTION: - g_value_set_boxed (value, "/"); + g_value_set_boxed (value, self->priv->connection_path); break; case PROP_CONNECTION_STATUS: g_value_set_uint (value, TP_CONNECTION_STATUS_CONNECTED); @@ -184,13 +193,21 @@ tp_tests_simple_account_get_property (GObject *object, g_value_set_uint (value, TP_CONNECTION_STATUS_REASON_REQUESTED); break; case PROP_CURRENT_PRESENCE: - g_value_set_boxed (value, presence); + g_value_take_boxed (value, tp_value_array_build (3, + G_TYPE_UINT, self->priv->presence, + G_TYPE_STRING, self->priv->presence_status, + G_TYPE_STRING, self->priv->presence_msg, + G_TYPE_INVALID)); break; case PROP_REQUESTED_PRESENCE: - g_value_set_boxed (value, presence); + g_value_take_boxed (value, tp_value_array_build (3, + G_TYPE_UINT, TP_CONNECTION_PRESENCE_TYPE_BUSY, + G_TYPE_STRING, "requesting", + G_TYPE_STRING, "this is my RequestedPresence", + G_TYPE_INVALID)); break; case PROP_NORMALIZED_NAME: - g_value_set_string (value, ""); + g_value_set_string (value, "bob.mcbadgers@example.com"); break; case PROP_HAS_BEEN_ONLINE: g_value_set_boolean (value, TRUE); @@ -213,15 +230,67 @@ tp_tests_simple_account_get_property (GObject *object, TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED | TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PARAMETERS); break; + case PROP_URI_SCHEMES: + { + GPtrArray *arr; + guint i; + + arr = g_ptr_array_sized_new (self->priv->uri_schemes->len + 1); + for (i = 0; i < self->priv->uri_schemes->len; i++) + g_ptr_array_add (arr, + g_ptr_array_index (self->priv->uri_schemes, i)); + g_ptr_array_add (arr, NULL); + + g_value_set_boxed (value, arr->pdata); + g_ptr_array_unref (arr); + } + break; + case PROP_AVATAR: + { + GArray *arr = g_array_new (FALSE, FALSE, sizeof (char)); + + /* includes NUL for simplicity */ + g_array_append_vals (arr, ":-)", 4); + + g_value_take_boxed (value, + tp_value_array_build (2, + TP_TYPE_UCHAR_ARRAY, arr, + G_TYPE_STRING, "text/plain", + G_TYPE_INVALID)); + g_array_unref (arr); + } + break; + case PROP_SUPERSEDES: + { + GPtrArray *arr = g_ptr_array_new (); + + g_ptr_array_add (arr, + g_strdup (TP_ACCOUNT_OBJECT_PATH_BASE "super/seded/whatever")); + g_value_take_boxed (value, arr); + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec); break; } - g_boxed_free (TP_STRUCT_TYPE_SIMPLE_PRESENCE, presence); g_value_unset (&identifier); } +static void +tp_tests_simple_account_finalize (GObject *object) +{ + TpTestsSimpleAccount *self = TP_TESTS_SIMPLE_ACCOUNT (object); + + g_free (self->priv->presence_status); + g_free (self->priv->presence_msg); + g_free (self->priv->connection_path); + + g_ptr_array_unref (self->priv->uri_schemes); + + G_OBJECT_CLASS (tp_tests_simple_account_parent_class)->finalize (object); +} + /** * This class currently only provides the minimum for * tp_account_prepare to succeed. This turns out to be only a working @@ -250,6 +319,7 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass) { "RequestedPresence", "requested-presence", NULL }, { "NormalizedName", "normalized-name", NULL }, { "HasBeenOnline", "has-been-online", NULL }, + { "Supersedes", "supersedes", NULL }, { NULL } }; @@ -261,6 +331,16 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass) { NULL }, }; + static TpDBusPropertiesMixinPropImpl aia_props[] = { + { "URISchemes", "uri-schemes", NULL }, + { NULL }, + }; + + static TpDBusPropertiesMixinPropImpl avatar_props[] = { + { "Avatar", "avatar", NULL }, + { NULL }, + }; + static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { { TP_IFACE_ACCOUNT, tp_dbus_properties_mixin_getter_gobject_properties, @@ -273,12 +353,23 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass) NULL, ais_props }, + { + TP_IFACE_ACCOUNT_INTERFACE_ADDRESSING, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + aia_props + }, + { TP_IFACE_ACCOUNT_INTERFACE_AVATAR, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + avatar_props + }, { NULL }, }; g_type_class_add_private (klass, sizeof (TpTestsSimpleAccountPrivate)); object_class->get_property = tp_tests_simple_account_get_property; - object_class->set_property = tp_tests_simple_account_set_property; + object_class->finalize = tp_tests_simple_account_finalize; param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces", "In this case we only implement Account, so none.", @@ -319,7 +410,7 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass) param_spec = g_param_spec_boxed ("parameters", "parameters", "Parameters property", TP_HASH_TYPE_STRING_VARIANT_MAP, - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_PARAMETERS, param_spec); param_spec = g_param_spec_boxed ("automatic-presence", "automatic presence", @@ -343,14 +434,14 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass) param_spec = g_param_spec_uint ("connection-status", "connection status", "ConnectionStatus property", - 0, NUM_TP_CONNECTION_STATUSES, TP_CONNECTION_STATUS_DISCONNECTED, + 0, TP_NUM_CONNECTION_STATUSES, TP_CONNECTION_STATUS_DISCONNECTED, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_CONNECTION_STATUS, param_spec); param_spec = g_param_spec_uint ("connection-status-reason", "connection status reason", "ConnectionStatusReason property", - 0, NUM_TP_CONNECTION_STATUS_REASONS, + 0, TP_NUM_CONNECTION_STATUS_REASONS, TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_CONNECTION_STATUS_REASON, @@ -412,7 +503,114 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass) g_object_class_install_property (object_class, PROP_STORAGE_RESTRICTIONS, param_spec); + param_spec = g_param_spec_boxed ("uri-schemes", "URI schemes", + "Some URI schemes", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_URI_SCHEMES, param_spec); + + param_spec = g_param_spec_boxed ("avatar", + "Avatar", "Avatar", + TP_STRUCT_TYPE_AVATAR, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + PROP_AVATAR, param_spec); + + param_spec = g_param_spec_boxed ("supersedes", + "Supersedes", "List of superseded accounts", + TP_ARRAY_TYPE_OBJECT_PATH_LIST, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + PROP_SUPERSEDES, param_spec); + klass->dbus_props_class.interfaces = prop_interfaces; tp_dbus_properties_mixin_class_init (object_class, G_STRUCT_OFFSET (TpTestsSimpleAccountClass, dbus_props_class)); } + +void +tp_tests_simple_account_set_presence (TpTestsSimpleAccount *self, + TpConnectionPresenceType presence, + const gchar *status, + const gchar *message) +{ + GHashTable *props; + GValueArray *v; + + g_free (self->priv->presence_status); + g_free (self->priv->presence_msg); + + self->priv->presence = presence; + self->priv->presence_status = g_strdup (status); + self->priv->presence_msg = g_strdup (message); + + g_object_get (self, "current-presence", &v, NULL); + + props = tp_asv_new ( + "CurrentPresence", TP_STRUCT_TYPE_SIMPLE_PRESENCE, v, + NULL); + + tp_svc_account_emit_account_property_changed (self, props); + + g_boxed_free (TP_STRUCT_TYPE_SIMPLE_PRESENCE, v); +} + +void +tp_tests_simple_account_set_connection (TpTestsSimpleAccount *self, + const gchar *object_path) +{ + GHashTable *change; + + if (object_path == NULL) + object_path = "/"; + + g_free (self->priv->connection_path); + self->priv->connection_path = g_strdup (object_path); + + change = tp_asv_new (NULL, NULL); + tp_asv_set_string (change, "Connection", object_path); + tp_svc_account_emit_account_property_changed (self, change); + g_hash_table_unref (change); +} + +void +tp_tests_simple_account_removed (TpTestsSimpleAccount *self) +{ + tp_svc_account_emit_removed (self); +} + +void +tp_tests_simple_account_set_enabled (TpTestsSimpleAccount *self, + gboolean enabled) +{ + GHashTable *change; + + self->priv->enabled = enabled; + + change = tp_asv_new (NULL, NULL); + tp_asv_set_boolean (change, "Enabled", enabled); + tp_svc_account_emit_account_property_changed (self, change); + g_hash_table_unref (change); +} + +void +tp_tests_simple_account_add_uri_scheme (TpTestsSimpleAccount *self, + const gchar *uri_scheme) +{ + GHashTable *changed; + GStrv schemes; + + g_ptr_array_add (self->priv->uri_schemes, g_strdup (uri_scheme)); + + g_object_get (self, "uri-schemes", &schemes, NULL); + + changed = tp_asv_new ( + "URISchemes", G_TYPE_STRV, schemes, + NULL); + + tp_svc_dbus_properties_emit_properties_changed (self, + TP_IFACE_ACCOUNT_INTERFACE_ADDRESSING, changed, NULL); + + g_strfreev (schemes); + g_hash_table_unref (changed); +} diff --git a/tests/lib/simple-account.h b/tests/lib/simple-account.h index 7af263d..351c6cc 100644 --- a/tests/lib/simple-account.h +++ b/tests/lib/simple-account.h @@ -1,7 +1,7 @@ /* * simple-account.h - header for a simple account service. * - * Copyright (C) 2010 Collabora Ltd. + * Copyright (C) 2010-2012 Collabora Ltd. * * Copying and distribution of this file, with or without modification, * are permitted in any medium without royalty provided the copyright @@ -12,8 +12,8 @@ #define __TP_TESTS_SIMPLE_ACCOUNT_H__ #include -#include +#include G_BEGIN_DECLS @@ -51,6 +51,21 @@ GType tp_tests_simple_account_get_type (void); (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_ACCOUNT, \ TpTestsSimpleAccountClass)) +void tp_tests_simple_account_set_presence (TpTestsSimpleAccount *self, + TpConnectionPresenceType presence, + const gchar *status, + const gchar *message); + +void tp_tests_simple_account_set_connection (TpTestsSimpleAccount *self, + const gchar *object_path); + +void tp_tests_simple_account_removed (TpTestsSimpleAccount *self); +void tp_tests_simple_account_set_enabled (TpTestsSimpleAccount *self, + gboolean enabled); + +void tp_tests_simple_account_add_uri_scheme (TpTestsSimpleAccount *self, + const gchar * uri_scheme); + G_END_DECLS #endif /* #ifndef __TP_TESTS_SIMPLE_ACCOUNT_H__ */ diff --git a/tests/lib/simple-conn.c b/tests/lib/simple-conn.c index c78e127..6cdc6b0 100644 --- a/tests/lib/simple-conn.c +++ b/tests/lib/simple-conn.c @@ -17,13 +17,8 @@ #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include "textchan-null.h" #include "room-list-chan.h" diff --git a/tests/lib/simple-conn.h b/tests/lib/simple-conn.h index 837400b..14d2275 100644 --- a/tests/lib/simple-conn.h +++ b/tests/lib/simple-conn.h @@ -13,7 +13,7 @@ #define __TP_TESTS_SIMPLE_CONN_H__ #include -#include +#include G_BEGIN_DECLS diff --git a/tests/lib/textchan-null.c b/tests/lib/textchan-null.c index bbeb0c7..c426acf 100644 --- a/tests/lib/textchan-null.c +++ b/tests/lib/textchan-null.c @@ -13,13 +13,8 @@ #include "textchan-null.h" -#include -#include -#include -#include -#include -#include -#include +#include +#include /* This is for text-mixin unit tests, others should be using ExampleEcho2Channel * which uses newer TpMessageMixin */ diff --git a/tests/lib/textchan-null.h b/tests/lib/textchan-null.h index 583bec5..076defb 100644 --- a/tests/lib/textchan-null.h +++ b/tests/lib/textchan-null.h @@ -13,9 +13,7 @@ #define __TP_TESTS_TEXT_CHANNEL_NULL_H__ #include -#include -#include -#include +#include G_BEGIN_DECLS diff --git a/tests/lib/util.c b/tests/lib/util.c index 1e8c402..8d5a7ea 100644 --- a/tests/lib/util.c +++ b/tests/lib/util.c @@ -12,7 +12,7 @@ #include "util.h" -#include +#include #include #include diff --git a/tests/lib/util.h b/tests/lib/util.h index 42c9489..1c40f42 100644 --- a/tests/lib/util.h +++ b/tests/lib/util.h @@ -12,7 +12,6 @@ #define __TP_TESTS_LIB_UTIL_H__ #include -#include TpDBusDaemon *tp_tests_dbus_daemon_dup_or_die (void); -- 1.8.3.1