eds test: ensure changes to linkable properties aggregate Personas together
authorTravis Reitter <travis.reitter@collabora.co.uk>
Sun, 30 Dec 2012 20:08:49 +0000 (12:08 -0800)
committerTravis Reitter <travis.reitter@collabora.co.uk>
Sun, 6 Jan 2013 01:29:12 +0000 (17:29 -0800)
tests/eds/linkable-properties.vala

index 68fcf5c..c5b396d 100644 (file)
@@ -31,16 +31,33 @@ public class LinkablePropertiesTests : Folks.TestCase
   private bool _found_before_update;
   private bool _found_after_update;
 
+  /* NOTE: each full name must remain unique. Likewise for email. */
+  private const string _full_name_1 = "bernie h. innocenti";
+  private const string _email_1 = "bernie@example.org";
+  private const string _phone_1 = "5551234";
+  private const string _full_name_2 = "Clyde McPoyle";
+  private const string _email_2 = "clyde@example.org";
+  private const string _phone_2 = "987654321";
+  private Individual _ind_1;
+  private Individual _ind_2;
+
+  /* In general, these tests are meant to check basic behavior so we don't need
+   * to sprinkle that throughout (and potentially revise) within unrelated tests
+   */
   public LinkablePropertiesTests ()
     {
       base ("LinkableProperties");
 
       this.add_test ("expected behavior from linkable properties",
           this.test_linkable_properties_excess_individuals);
+      this.add_test ("correct aggregation after linkable property change",
+          this.test_linkable_properties_aggregate_after_change);
     }
 
   public override void set_up ()
     {
+      this._found_before_update = false;
+      this._found_after_update = false;
       this._eds_backend = new EdsTest.Backend ();
       this._eds_backend.set_up ();
 
@@ -160,6 +177,166 @@ public class LinkablePropertiesTests : Folks.TestCase
             }
         }
     }
+
+  /* Check that two unaggregated Personas get aggregated after one changes its
+   * linkable property to match the other's (ie, they get linked).
+   *
+   * FIXME: this test should be moved to tests/folks and rebased upon the Dummy
+   * backend once bgo#648811 is fixed.
+   */
+  void test_linkable_properties_aggregate_after_change ()
+    {
+      Gee.HashMap<string, Value?> c;
+      this._main_loop = new GLib.MainLoop (null, false);
+      Value? v;
+
+      this._found_before_update = false;
+      this._found_after_update = false;
+
+      this._eds_backend.reset ();
+
+      c = new Gee.HashMap<string, Value?> ();
+      v = Value (typeof (string));
+      v.set_string (_full_name_1);
+      c.set ("full_name", (owned) v);
+      v = Value (typeof (string));
+      v.set_string (_email_1);
+      c.set ("email_1", (owned) v);
+      v = Value (typeof (string));
+      v.set_string (_phone_1);
+      c.set ("home_phone", (owned) v);
+      this._eds_backend.add_contact (c);
+
+      c = new Gee.HashMap<string, Value?> ();
+      v = Value (typeof (string));
+      v.set_string (_full_name_2);
+      c.set ("full_name", (owned) v);
+      v = Value (typeof (string));
+      v.set_string (_email_2);
+      c.set ("email_1", (owned) v);
+      v = Value (typeof (string));
+      v.set_string (_phone_2);
+      c.set ("mobile_phone", (owned) v);
+      this._eds_backend.add_contact (c);
+
+      this._test_linkable_properties_aggregate_after_change_async.begin ();
+
+      Timeout.add_seconds (5, () =>
+        {
+          this._main_loop.quit ();
+          stderr.printf ("Personas failed to be aggregated after being given " +
+            "the same linkable properties\n");
+          assert_not_reached ();
+        });
+
+      this._main_loop.run ();
+
+      assert (this._found_before_update);
+      assert (this._found_after_update);
+    }
+
+  private async void _test_linkable_properties_aggregate_after_change_async ()
+    {
+      yield this._eds_backend.commit_contacts_to_addressbook ();
+
+      var store = BackendStore.dup ();
+      yield store.prepare ();
+      this._aggregator = new IndividualAggregator ();
+      this._aggregator.individuals_changed_detailed.connect
+          (this._individuals_changed_aggregate_after_change_cb);
+      try
+        {
+          yield this._aggregator.prepare ();
+        }
+      catch (GLib.Error e)
+        {
+          GLib.warning ("Error when calling prepare: %s\n", e.message);
+        }
+    }
+
+  private void _individuals_changed_aggregate_after_change_cb (
+       MultiMap<Individual?, Individual?> changes)
+    {
+      var added = changes.get_values ();
+
+      if (!this._found_before_update)
+        {
+          foreach (Individual i in added)
+            {
+              assert (i != null);
+
+              var name = (Folks.NameDetails) i;
+
+              if (name.full_name == _full_name_1)
+                {
+                  this._ind_1 = i;
+                }
+              /* Change the second Persona's email address to match the first so
+               * they should get aggregated */
+              else if (name.full_name == _full_name_2)
+                {
+                  this._ind_2 = i;
+                  this._found_before_update = true;
+
+                  foreach (var p in i.personas)
+                    {
+                      var emails = new HashSet<EmailFieldDetails> (
+                          (GLib.HashFunc) EmailFieldDetails.hash,
+                          (GLib.EqualFunc) EmailFieldDetails.equal);
+                      var email_1 = new EmailFieldDetails (_email_1);
+                      email_1.set_parameter (AbstractFieldDetails.PARAM_TYPE,
+                          AbstractFieldDetails.PARAM_TYPE_OTHER);
+                      emails.add (email_1);
+                      ((EmailDetails) p).email_addresses = emails;
+                    }
+                }
+            }
+        }
+      else
+        {
+          Individual replaced;
+
+          if (changes.contains (this._ind_1))
+            {
+              replaced = this._ind_1;
+            }
+          else if (changes.contains (this._ind_2))
+            {
+              replaced = this._ind_2;
+            }
+          else
+            {
+              return;
+            }
+
+          var replacements = changes.get (replaced);
+          foreach (var r in replacements)
+            {
+              var phone_fd_1 = new PhoneFieldDetails (_phone_1);
+              var phone_fd_2 = new PhoneFieldDetails (_phone_1);
+              var num_equal_1 = false;
+              var num_equal_2 = false;
+
+              if (r.personas.size == 2)
+                {
+                  foreach (var num in r.phone_numbers)
+                    {
+                      if (num.values_equal (phone_fd_1))
+                        num_equal_1 = true;
+
+                      if (num.values_equal (phone_fd_2))
+                        num_equal_2 = true;
+                    }
+
+                  if (num_equal_1 && num_equal_2)
+                    {
+                      this._found_after_update = true;
+                      this._main_loop.quit ();
+                    }
+                }
+            }
+        }
+    }
 }
 
 public int main (string[] args)