From a3fb94d88c8c8093fa163195ab091ac724639f74 Mon Sep 17 00:00:00 2001 From: Travis Reitter Date: Mon, 4 Oct 2010 09:00:54 -0700 Subject: [PATCH] Add the PersonaStore:can-add-personas property. Helps bgo#626179. --- backends/key-file/kf-persona-store.vala | 12 ++ backends/telepathy/lib/tpf-persona-store.vala | 52 ++++++ folks/persona-store.vala | 7 + tests/telepathy/Makefile.am | 5 + tests/telepathy/persona-store-capabilities.vala | 225 ++++++++++++++++++++++++ 5 files changed, 301 insertions(+) create mode 100644 tests/telepathy/persona-store-capabilities.vala diff --git a/backends/key-file/kf-persona-store.vala b/backends/key-file/kf-persona-store.vala index 6407eee..fe52a6b 100644 --- a/backends/key-file/kf-persona-store.vala +++ b/backends/key-file/kf-persona-store.vala @@ -54,6 +54,18 @@ public class Folks.Backends.Kf.PersonaStore : Folks.PersonaStore public override string id { get; private set; } /** + * Whether this PersonaStore can add {@link Folks.Persona}s. + * + * See {@link Folks.PersonaStore.can_add_personas}. + * + * @since 0.3.1 + */ + public override MaybeBool can_add_personas + { + get { return MaybeBool.TRUE; } + } + + /** * Whether this PersonaStore has been prepared. * * See {@link Folks.PersonaStore.is_prepared}. diff --git a/backends/telepathy/lib/tpf-persona-store.vala b/backends/telepathy/lib/tpf-persona-store.vala index c0e566e..442120e 100644 --- a/backends/telepathy/lib/tpf-persona-store.vala +++ b/backends/telepathy/lib/tpf-persona-store.vala @@ -65,6 +65,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore private AccountManager account_manager; private Logger logger; private Contact self_contact; + private MaybeBool _can_add_personas = MaybeBool.UNSET; private bool _is_prepared = false; internal signal void group_members_changed (string group, @@ -102,6 +103,18 @@ public class Tpf.PersonaStore : Folks.PersonaStore public override string id { get; private set; } /** + * Whether this PersonaStore can add {@link Folks.Persona}s. + * + * See {@link Folks.PersonaStore.can_add_personas}. + * + * @since 0.3.1 + */ + public override MaybeBool can_add_personas + { + get { return this._can_add_personas; } + } + + /** * Whether this PersonaStore has been prepared. * * See {@link Folks.PersonaStore.is_prepared}. @@ -570,6 +583,12 @@ public class Tpf.PersonaStore : Folks.PersonaStore c.group_members_changed_detailed.connect ( this.subscribe_channel_group_members_changed_detailed_cb); + + c.group_flags_changed.connect ( + this.subscribe_channel_group_flags_changed_cb); + + this.subscribe_channel_group_flags_changed_cb (c, + c.group_get_flags (), 0); } this.standard_channels_unready.unset (name); @@ -625,6 +644,39 @@ public class Tpf.PersonaStore : Folks.PersonaStore this.ignore_by_handle_if_needed (handle, details); } } + + private void subscribe_channel_group_flags_changed_cb ( + Channel? channel, + uint added, + uint removed) + { + this.update_capability ((ChannelGroupFlags) added, + (ChannelGroupFlags) removed, ChannelGroupFlags.CAN_ADD, + ref this._can_add_personas, "can-add-personas"); + } + + private void update_capability ( + ChannelGroupFlags added, + ChannelGroupFlags removed, + ChannelGroupFlags tp_flag, + ref MaybeBool private_member, + string prop_name) + { + var new_value = private_member; + + if ((added & tp_flag) != 0) + new_value = MaybeBool.TRUE; + + if ((removed & tp_flag) != 0) + new_value = MaybeBool.FALSE; + + if (new_value != private_member) + { + private_member = new_value; + this.notify_property (prop_name); + } + } + private void subscribe_channel_group_members_changed_detailed_cb ( Channel channel, /* FIXME: Array => Array; parser bug */ diff --git a/folks/persona-store.vala b/folks/persona-store.vala index a04c60c..37507af 100644 --- a/folks/persona-store.vala +++ b/folks/persona-store.vala @@ -176,6 +176,13 @@ public abstract class Folks.PersonaStore : Object public abstract HashTable personas { get; } /** + * Whether this {@link PersonaStore} can add {@link Persona}s. + * + * @since 0.3.1 + */ + public abstract MaybeBool can_add_personas { get; default = MaybeBool.UNSET; } + + /** * Whether {@link PersonaStore.prepare} has successfully completed for this * store. * diff --git a/tests/telepathy/Makefile.am b/tests/telepathy/Makefile.am index b71cf65..06beae5 100644 --- a/tests/telepathy/Makefile.am +++ b/tests/telepathy/Makefile.am @@ -43,12 +43,17 @@ VALAFLAGS += \ # in order from least to most complex noinst_PROGRAMS = \ + persona-store-capabilities \ contact-retrieval \ contact-properties \ $(NULL) TESTS = $(addprefix test-,$(noinst_PROGRAMS)) +persona_store_capabilities_SOURCES = \ + persona-store-capabilities.vala \ + $(NULL) + contact_retrieval_SOURCES = \ contact-retrieval.vala \ $(NULL) diff --git a/tests/telepathy/persona-store-capabilities.vala b/tests/telepathy/persona-store-capabilities.vala new file mode 100644 index 0000000..46dd5e2 --- /dev/null +++ b/tests/telepathy/persona-store-capabilities.vala @@ -0,0 +1,225 @@ +using DBus; +using TelepathyGLib; +using TpTest; +using Tpf; +using Folks; +using Gee; + +public class PersonaStoreCapabilitiesTests : Folks.TestCase +{ + private DBusDaemon daemon; + private TpTest.Account account; + private TpTest.AccountManager account_manager; + private TpTest.ContactListConnection conn; + private MainLoop main_loop; + private string bus_name; + private string object_path; + private bool got_group_flags; + + public PersonaStoreCapabilitiesTests () + { + base ("PersonaStoreCapabilities"); + + this.add_test ("persona store capabilities", + this.test_persona_store_capabilities); + } + + public override void set_up () + { + this.got_group_flags = false; + + this.main_loop = new GLib.MainLoop (null, false); + + try + { + this.daemon = DBusDaemon.dup (); + } + catch (GLib.Error e) + { + error ("Couldn't get D-Bus daemon: %s", e.message); + } + + /* Set up a contact list connection */ + this.conn = new TpTest.ContactListConnection ("me@example.com", + "protocol", 0, 0); + + try + { + this.conn.register ("cm", out this.bus_name, out this.object_path); + } + catch (GLib.Error e) + { + error ("Failed to register connection %p.", this.conn); + } + + var handle_repo = this.conn.get_handles (HandleType.CONTACT); + Handle self_handle = 0; + try + { + self_handle = TelepathyGLib.handle_ensure (handle_repo, + "me@example.com", null); + } + catch (GLib.Error e) + { + error ("Couldn't ensure self handle '%s': %s", "me@example.com", + e.message); + } + + this.conn.set_self_handle (self_handle); + this.conn.change_status (ConnectionStatus.CONNECTED, + ConnectionStatusReason.REQUESTED); + + /* Create an account */ + this.account = new TpTest.Account (this.object_path); + this.daemon.register_object ( + TelepathyGLib.ACCOUNT_OBJECT_PATH_BASE + "cm/protocol/account", + this.account); + + /* Create an account manager */ + try + { + this.daemon.request_name (TelepathyGLib.ACCOUNT_MANAGER_BUS_NAME, + false); + } + catch (GLib.Error e) + { + error ("Couldn't request account manager bus name '%s': %s", + TelepathyGLib.ACCOUNT_MANAGER_BUS_NAME, e.message); + } + + this.account_manager = new TpTest.AccountManager (); + this.daemon.register_object (TelepathyGLib.ACCOUNT_MANAGER_OBJECT_PATH, + this.account_manager); + } + + public override void tear_down () + { + this.conn.change_status (ConnectionStatus.DISCONNECTED, + ConnectionStatusReason.REQUESTED); + + this.daemon.unregister_object (this.account_manager); + this.account_manager = null; + + try + { + this.daemon.release_name (TelepathyGLib.ACCOUNT_MANAGER_BUS_NAME); + } + catch (GLib.Error e) + { + error ("Couldn't release account manager bus name '%s': %s", + TelepathyGLib.ACCOUNT_MANAGER_BUS_NAME, e.message); + } + + this.daemon.unregister_object (this.account); + this.account = null; + + this.conn = null; + this.daemon = null; + this.bus_name = null; + this.object_path = null; + + Timeout.add_seconds (5, () => + { + this.main_loop.quit (); + this.main_loop = null; + return false; + }); + + /* Run the main loop to process the carnage and destruction */ + this.main_loop.run (); + } + + public void test_persona_store_capabilities () + { + var main_loop = new GLib.MainLoop (null, false); + + /* Ignore the error caused by not running the logger */ + Test.log_set_fatal_handler ((d, l, m) => + { + return !m.has_suffix ("couldn't get list of favourite contacts: " + + "The name org.freedesktop.Telepathy.Logger was not provided by " + + "any .service files"); + }); + + var backend_store = BackendStore.dup (); + backend_store.backend_available.connect ((b) => + { + if (b.name == "telepathy") + { + b.persona_store_added.connect ((ps) => + { + this.set_up_persona_store (ps); + }); + + foreach (var store in b.persona_stores.get_values ()) + { + this.set_up_persona_store (store); + } + + } + + }); + + backend_store.load_backends (); + + Timeout.add_seconds (3, () => + { + main_loop.quit (); + return false; + }); + + main_loop.run (); + + assert (this.got_group_flags); + } + + private void set_up_persona_store (Folks.PersonaStore store) + { + store.prepare.begin ((obj, result) => + { + try + { + store.prepare.end (result); + + if (store.can_add_personas != MaybeBool.UNSET) + can_add_personas_cb (store, null); + else + store.notify["can-add-personas"].connect ( + this.can_add_personas_cb); + } + catch (GLib.Error e) + { + warning ("Error preparing PersonaStore type: %s, id: %s: " + + "'%s'", store.type_id, store.id, e.message); + } + }); + } + + private void can_add_personas_cb (GLib.Object s, ParamSpec? p) + { + assert (s is Tpf.PersonaStore); + var store = (Tpf.PersonaStore) s; + + if (store.can_add_personas != MaybeBool.UNSET) + { + assert (store.can_add_personas == MaybeBool.TRUE); + + this.got_group_flags = true; + + store.notify["can-add-personas"].disconnect ( + this.can_add_personas_cb); + } + } +} + +public int main (string[] args) +{ + Test.init (ref args); + + TestSuite root = TestSuite.get_root (); + root.add_suite (new PersonaStoreCapabilitiesTests ().get_suite ()); + + Test.run (); + + return 0; +} -- 2.7.4