[folks] Add a test for adding Personas.



commit 4967acd0c235dc3eb0149cfa737443926339d08c
Author: Travis Reitter <travis reitter collabora co uk>
Date:   Mon Sep 6 13:37:53 2010 -0700

    Add a test for adding Personas.
    
    Fixes bgo#629008.

 NEWS                                   |    1 +
 tests/telepathy/Makefile.am            |    3 +
 tests/telepathy/contact-retrieval.vala |  181 ++++++++++++++++++++++++++++++++
 3 files changed, 185 insertions(+), 0 deletions(-)
---
diff --git a/NEWS b/NEWS
index 4986937..efd9ce3 100644
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,7 @@ Bugs fixed:
   attempts
 * Bug 629331 â?? BackendStore.load_backends and the prepare() functions should
   be idempotent.
+* Bug 629008 â?? Add a test for Persona additions
 
 Overview of changes from libfolks 0.1.16 to libfolks 0.1.17
 ===========================================================
diff --git a/tests/telepathy/Makefile.am b/tests/telepathy/Makefile.am
index 258dc00..57b37a6 100644
--- a/tests/telepathy/Makefile.am
+++ b/tests/telepathy/Makefile.am
@@ -4,6 +4,7 @@ AM_CPPFLAGS = \
 	$(TP_GLIB_CFLAGS) \
 	-I$(top_srcdir)/folks \
 	-I$(top_srcdir)/backends/telepathy \
+	-I$(top_srcdir)/backends/telepathy/lib \
 	-I$(top_srcdir)/tests/lib/telepathy/contactlist \
 	-include $(CONFIG_HEADER) \
 	$(NULL)
@@ -12,6 +13,7 @@ LDADD = \
 	$(GLIB_LIBS) \
 	$(GEE_LIBS) \
 	$(TP_GLIB_LIBS) \
+	-L$(top_srcdir)/backends/telepathy/lib \
 	$(NULL)
 
 RUN_WITH_PRIVATE_BUS = $(top_srcdir)/tests/tools/with-session-bus.sh
@@ -47,6 +49,7 @@ contact_retrieval_SOURCES = \
 
 contact_retrieval_LDADD = \
 	$(top_builddir)/tests/lib/telepathy/contactlist/libtp-test-contactlist.la \
+	$(top_builddir)/backends/telepathy/lib/libfolks-telepathy.la \
 	$(top_builddir)/folks/libfolks.la
 
 CLEANFILES = \
diff --git a/tests/telepathy/contact-retrieval.vala b/tests/telepathy/contact-retrieval.vala
index eb01896..c6b668e 100644
--- a/tests/telepathy/contact-retrieval.vala
+++ b/tests/telepathy/contact-retrieval.vala
@@ -35,6 +35,7 @@ public class ContactRetrievalTests : Folks.TestCase
       default_individuals.add (prefix + "geraldine example com");
 
       this.add_test ("aggregator", this.test_aggregator);
+      this.add_test ("aggregator:add", this.test_aggregator_add);
       this.add_test ("individual properties",
           this.test_individual_properties);
     }
@@ -206,6 +207,186 @@ public class ContactRetrievalTests : Folks.TestCase
       aggregator = null;
     }
 
+  public void test_aggregator_add ()
+    {
+      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");
+        });
+
+      HashSet<string> added_individuals = new HashSet<string> ();
+      added_individuals.add ("master shake example com");
+      added_individuals.add ("2wycked example com");
+      added_individuals.add ("carl-brutananadilewski example com");
+
+      /* Set up the aggregator */
+      var aggregator = new IndividualAggregator ();
+
+      aggregator.individuals_changed.connect ((added, removed, m, a, r) =>
+        {
+          /* implicitly ignore the default Individuals, since that's covered in
+           * other test(s) */
+          foreach (Individual i in added)
+            {
+              /* If the Individual contains a Persona with an ID we provided,
+               * mark it as recieved.
+               * This intentionally avoids assuming that the Individual's ID is
+               * necessarily related to the ID of any of its Persona(s) */
+              foreach (Folks.Persona p in i.personas)
+                {
+                  if (p is Tpf.Persona)
+                    if (added_individuals.remove (((Tpf.Persona) p).display_id))
+                      break;
+                }
+            }
+
+          assert (removed == null);
+        });
+
+      /* Kill the main loop after a few seconds. If there are still individuals
+       * in the set of expected individuals, the aggregator has either failed or
+       * been too slow (which we can consider to be failure). */
+      Timeout.add_seconds (3, () =>
+        {
+          main_loop.quit ();
+          return false;
+        });
+
+      Idle.add (() =>
+        {
+          aggregator.prepare.begin ((s,r) =>
+            {
+              try
+                {
+                  aggregator.prepare.end (r);
+                }
+              catch (GLib.Error e1)
+                {
+                  GLib.critical ("failed to prepare aggregator: %s",
+                    e1.message);
+                  assert_not_reached ();
+                }
+
+              /* at this point, all the backends are prepared */
+
+              /* FIXME: the fact that this is so awkward means this is a point
+               * of improvement in the API */
+
+              var adding_done = false;
+
+              /* once we see a valid Tpf.PersonaStore, add our new personas */
+              var backend_store = BackendStore.dup ();
+              foreach (var backend in backend_store.enabled_backends)
+                {
+                  /* PersonaStores can be added after the backend is prepared */
+                  backend.persona_store_added.connect ((store) =>
+                    {
+                      if (store is Tpf.PersonaStore && !adding_done)
+                        {
+                          this.add_personas.begin ((Tpf.PersonaStore) store,
+                            added_individuals);
+                          adding_done = true;
+                        }
+                    });
+
+                  foreach (var store in
+                      backend.persona_stores.get_values ())
+                    {
+                      if (store is Tpf.PersonaStore && !adding_done)
+                        {
+                          this.add_personas.begin ((Tpf.PersonaStore) store,
+                            added_individuals);
+                          adding_done = true;
+                        }
+                    }
+                }
+            });
+
+          return false;
+        });
+
+      main_loop.run ();
+
+      /* We should have received (and removed) the individuals in the set */
+      assert (added_individuals.size == 0);
+
+      /* necessary to reset the aggregator for the next test */
+      aggregator = null;
+    }
+
+  private async void add_personas (Tpf.PersonaStore store,
+      HashSet<string>? ids_add)
+    {
+      try
+        {
+          yield store.prepare ();
+
+          /* track which IDs have been successfully added, since
+           * add_persona_from_details can temporarily fail with
+           * PersonaStoreError.STORE_OFFLINE (in which case, we just need to try
+           * again later) */
+          var ids_remaining = new HashSet<string> (str_hash, str_equal);
+          foreach (var contact_id in ids_add)
+            ids_remaining.add (contact_id);
+
+          Idle.add (() =>
+            {
+              var try_again = false;
+
+              foreach (var id in ids_remaining)
+                {
+                  var details = new HashTable<string, GLib.Value?> (str_hash,
+                      str_equal);
+                  details.insert ("contact", id);
+
+                  /* we can end up adding the same ID twice, since this async
+                   * function can be called a second time before the first
+                   * completes. But add_persona_from_details() is idempotent, so
+                   * this is acceptable (and not worth the extra code) */
+                  store.add_persona_from_details.begin (details, (s2, res) =>
+                      {
+                        try
+                          {
+                            store.add_persona_from_details.end (res);
+
+                            var id_added_value = details.lookup ("contact");
+                            var id_added = id_added_value.get_string ();
+                            if (id_added != null)
+                              ids_remaining.remove (id_added);
+                          }
+                        catch (GLib.Error e1)
+                          {
+                            /* STORE_OFFLINE is acceptable -- see above */
+                            if (!(e1 is PersonaStoreError.STORE_OFFLINE))
+                              {
+                                GLib.critical ("failed to add persona: %s",
+                                  e1.message);
+                                assert_not_reached ();
+                              }
+                          }
+                      });
+
+                  try_again = (ids_remaining.size > 0);
+                  if (try_again)
+                    break;
+                }
+
+              return try_again;
+            });
+        }
+      catch (GLib.Error e2)
+        {
+          warning ("Error preparing PersonaStore '%s': %s", store.id,
+              e2.message);
+          assert_not_reached ();
+        }
+    }
+
   public void test_individual_properties ()
     {
       var main_loop = new GLib.MainLoop (null, false);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]