4ead527caff5cf70de34d75733e30896deeee1d7
[platform/upstream/folks.git] / tests / tracker / add-persona.vala
1 /*
2  * Copyright (C) 2011 Collabora Ltd.
3  *
4  * This library is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 2.1 of the License, or
7  * (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Authors: Raul Gutierrez Segales <raul.gutierrez.segales@collabora.co.uk>
18  *
19  */
20
21 using Tracker.Sparql;
22 using TrackerTest;
23 using Folks;
24 using Gee;
25
26 public class AddPersonaTests : Folks.TestCase
27 {
28   private GLib.MainLoop _main_loop;
29   private TrackerTest.Backend _tracker_backend;
30   private IndividualAggregator _aggregator;
31   private string _persona_fullname;
32   private string _persona_alias;
33   private string _family_name;
34   private string _given_name;
35   private HashTable<string, bool> _properties_found;
36   private string _persona_iid;
37   private string _file_uri;
38   private string _birthday;
39   private DateTime _bday;
40   private string _email_1;
41   private string _email_2;
42   private string _im_addr_1;
43   private string _im_addr_2;
44   private string _note_1;
45   private string _phone_1;
46   private string _phone_2;
47   private string _title_1;
48   private string _organisation_1;
49   private PostalAddress _address;
50   private string _po_box = "12345";
51   private string _locality = "locality";
52   private string _postal_code = "code";
53   private string _street = "some street";
54   private string _extension = "some extension";
55   private string _country = "some country";
56   private string _region = "some region";
57   private string _url_1 = "http://www-1.example.org";
58   private string _url_2 = "http://www-1.example.org";
59   private Trf.PersonaStore _pstore;
60   private bool _added_persona = false;
61
62   public AddPersonaTests ()
63     {
64       base ("AddPersonaTests");
65
66       this._tracker_backend = new TrackerTest.Backend ();
67
68       this.add_test ("test adding personas to Tracker ", this.test_add_persona);
69     }
70
71   public override void set_up ()
72     {
73     }
74
75   public override void tear_down ()
76     {
77     }
78
79   public void test_add_persona ()
80     {
81       this._main_loop = new GLib.MainLoop (null, false);
82       this._persona_fullname = "persona #1";
83       this._persona_alias = "alias";
84       this._family_name = "family";
85       this._given_name = "given";
86       this._persona_iid = "";
87       this._file_uri = "file:///tmp/some-avatar.jpg";
88       this._birthday = "2001-10-26T20:32:52Z";
89       this._email_1 = "someone-1@example.org";
90       this._email_2 = "someone-2@example.org";
91       this._im_addr_1 = "someone-1@jabber.example.org";
92       this._im_addr_2 = "someone-2@jabber.example.org";
93       this._note_1 = "this is a note";
94       this._phone_1 = "12345";
95       this._phone_2 = "54321";
96       this._title_1 = "CFO";
97       this._organisation_1 = "Example Inc.";
98
99       GLib.List<string> types =  new GLib.List<string> ();
100       this._address = new PostalAddress (this._po_box,
101           this._extension, this._street, this._locality, this._region,
102           this._postal_code, this._country, null, types, null);
103
104       TimeVal t = TimeVal ();
105       t.from_iso8601 (this._birthday);
106       this._bday = new  DateTime.from_timeval_utc (t);
107
108       this._properties_found = new HashTable<string, bool>
109           (str_hash, str_equal);
110       this._properties_found.insert ("full_name", false);
111       this._properties_found.insert ("alias", false);
112       this._properties_found.insert ("is_favourite", false);
113       this._properties_found.insert ("structured_name", false);
114       this._properties_found.insert ("avatar", false);
115       this._properties_found.insert ("birthday", false);
116       this._properties_found.insert ("gender", false);
117       this._properties_found.insert ("email-1", false);
118       this._properties_found.insert ("email-2", false);
119       this._properties_found.insert ("im-addr-1", false);
120       this._properties_found.insert ("im-addr-2", false);
121       this._properties_found.insert ("note-1", false);
122       this._properties_found.insert ("phone-1", false);
123       this._properties_found.insert ("phone-2", false);
124       this._properties_found.insert ("role-1", false);
125       this._properties_found.insert ("postal-address-1", false);
126       this._properties_found.insert ("url-1", false);
127       this._properties_found.insert ("url-2", false);
128
129       this._test_add_persona_async ();
130
131       Timeout.add_seconds (5, () =>
132         {
133           this._main_loop.quit ();
134           assert_not_reached ();
135         });
136
137       this._main_loop.run ();
138
139       foreach (var k in this._properties_found.get_values ())
140         {
141           assert (k);
142         }
143
144       this._tracker_backend.tear_down ();
145     }
146
147   private async void _test_add_persona_async ()
148     {
149       var store = BackendStore.dup ();
150       yield store.prepare ();
151       this._aggregator = new IndividualAggregator ();
152       this._aggregator.individuals_changed.connect
153           (this._individuals_changed_cb);
154       try
155         {
156           yield this._aggregator.prepare ();
157
158           this._pstore = null;
159           foreach (var backend in store.enabled_backends)
160             {
161               this._pstore =
162                 (Trf.PersonaStore) backend.persona_stores.lookup ("tracker");
163               if (this._pstore != null)
164                 break;
165             }
166           assert (this._pstore != null);
167           this._pstore.notify["is-prepared"].connect (this._notify_pstore_cb);
168           this._try_to_add ();
169         }
170       catch (GLib.Error e)
171         {
172           GLib.warning ("Error when calling prepare: %s\n", e.message);
173         }
174     }
175
176   private async void _add_persona ()
177     {
178       HashTable<string, Value?> details = new HashTable<string, Value?>
179           (str_hash, str_equal);
180
181       Value? v1 = Value (typeof (string));
182       v1.set_string (this._persona_fullname);
183       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.FULL_NAME),
184           (owned) v1);
185
186       Value? v2 = Value (typeof (string));
187       v2.set_string (this._persona_alias);
188       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.ALIAS),
189           (owned) v2);
190
191       Value? v3 = Value (typeof (bool));
192       v3.set_boolean (true);
193       details.insert (
194           Folks.PersonaStore.detail_key (PersonaDetail.IS_FAVOURITE),
195           (owned) v3);
196
197       Value? v4 = Value (typeof (StructuredName));
198       StructuredName sname = new StructuredName (this._family_name,
199           this._given_name, null, null, null);
200       v4.set_object (sname);
201       details.insert (
202           Folks.PersonaStore.detail_key (PersonaDetail.STRUCTURED_NAME),
203           (owned) v4);
204
205       Value? v5 = Value (typeof (File));
206       File avatar = File.new_for_uri (this._file_uri);
207       v5.set_object (avatar);
208       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.AVATAR),
209           (owned) v5);
210
211       Value? v6 = Value (typeof (DateTime));
212       TimeVal t = TimeVal ();
213       t.from_iso8601 (this._birthday);
214       DateTime dobj = new  DateTime.from_timeval_utc (t);
215       v6.set_boxed (dobj);
216       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.BIRTHDAY),
217           (owned) v6);
218
219       Value? v7 = Value (typeof (Folks.Gender));
220       v7.set_enum (Folks.Gender.MALE);
221       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.GENDER),
222           (owned) v7);
223
224       Value? v8 = Value (typeof (GLib.List<FieldDetails>));
225       GLib.List<FieldDetails> emails =
226         new GLib.List<FieldDetails> ();
227       var email_1 = new FieldDetails (this._email_1);
228       emails.prepend ((owned) email_1);
229       var email_2 = new FieldDetails (this._email_2);
230       emails.prepend ((owned) email_2);
231       v8.set_pointer (emails);
232       details.insert (
233           Folks.PersonaStore.detail_key (PersonaDetail.EMAIL_ADDRESSES),
234           (owned) v8);
235
236       Value? v9 = Value (typeof (MultiMap<string, string>));
237       var im_addrs = new HashMultiMap<string, string> ();
238       im_addrs.set ("jabber", this._im_addr_1);
239       im_addrs.set ("yahoo", this._im_addr_2);
240       v9.set_object (im_addrs);
241       details.insert (
242           Folks.PersonaStore.detail_key (PersonaDetail.IM_ADDRESSES), v9);
243
244       Value? v10 = Value (typeof (Gee.HashSet<Note>));
245       Gee.HashSet<Note> notes = new Gee.HashSet<Note> ();
246       Note n1 = new Note (this._note_1);
247       notes.add (n1);
248       v10.set_object (notes);
249       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.NOTES),
250           (owned) v10);
251
252       Value? v11 = Value (typeof (GLib.List<FieldDetails>));
253       GLib.List<FieldDetails> phones =
254         new GLib.List<FieldDetails> ();
255       var phone_1 = new FieldDetails (this._phone_1);
256       phones.prepend ((owned) phone_1);
257       var phone_2 = new FieldDetails (this._phone_2);
258       phones.prepend ((owned) phone_2);
259       v11.set_pointer (phones);
260       details.insert (
261           Folks.PersonaStore.detail_key (PersonaDetail.PHONE_NUMBERS),
262           (owned) v11);
263
264       Value? v12 = Value (typeof (Gee.HashSet<Role>));
265       Gee.HashSet<Role> roles = new Gee.HashSet<Role> ();
266       Role r1 = new Role (this._title_1, this._organisation_1);
267       roles.add (r1);
268       v12.set_object (roles);
269       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.ROLES),
270           (owned) v12);
271
272       Value? v13 = Value (typeof (GLib.List<PostalAddress>));
273       GLib.List<PostalAddress> postal_addresses =
274         new GLib.List<PostalAddress> ();
275
276       GLib.List<string> types =  new GLib.List<string> ();
277       PostalAddress postal_a = new PostalAddress (this._po_box,
278           this._extension, this._street, this._locality, this._region,
279           this._postal_code, this._country, null, types, null);
280       postal_addresses.prepend ((owned) postal_a);
281       v13.set_pointer (postal_addresses);
282       details.insert (
283           Folks.PersonaStore.detail_key (PersonaDetail.POSTAL_ADDRESSES),
284           (owned) v13);
285
286       Value? v14 = Value (typeof (GLib.List<FieldDetails>));
287       GLib.List<FieldDetails> urls =
288         new GLib.List<FieldDetails> ();
289       var url_1 = new FieldDetails (this._url_1);
290       urls.prepend ((owned) url_1);
291       var url_2 = new FieldDetails (this._url_2);
292       urls.prepend ((owned) url_2);
293       v14.set_pointer (urls);
294       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.URLS),
295           (owned) v14);
296
297       try
298         {
299           Trf.Persona persona = (Trf. Persona)
300               yield this._aggregator.add_persona_from_details
301                 (null, this._pstore, details);
302           this._persona_iid = persona.iid;
303         }
304       catch (Folks.IndividualAggregatorError e)
305         {
306           GLib.warning ("[AddPersonaError] add_persona_from_details: %s\n",
307               e.message);
308         }
309     }
310
311   private void _individuals_changed_cb
312       (GLib.List<Individual>? added,
313        GLib.List<Individual>? removed,
314        string? message,
315        Persona? actor,
316        GroupDetails.ChangeReason reason)
317     {
318       foreach (unowned Individual i in added)
319         {
320           if (i.is_user == false)
321             {
322               /* NOTE:
323                *   we also listen to the Trf.Persona's structured-name
324                *   because if only one of its property is updated
325                *   Individual won't fire a notification.
326                */
327               unowned Trf.Persona p = (Trf.Persona) i.personas.nth_data (0);
328               if (p.structured_name != null)
329                 {
330                   p.notify["structured-name"].connect
331                     (this._notify_persona_sname);
332                 }
333
334               i.notify["full-name"].connect (this._notify_cb);
335               i.notify["alias"].connect (this._notify_cb);
336               i.notify["avatar"].connect (this._notify_cb);
337               i.notify["is-favourite"].connect (this._notify_cb);
338               i.notify["structured-name"].connect (this._notify_cb);
339               i.notify["family-name"].connect (this._notify_cb);
340               i.notify["given-name"].connect (this._notify_cb);
341               i.notify["avatar"].connect (this._notify_cb);
342               i.notify["birthday"].connect (this._notify_cb);
343               i.notify["gender"].connect (this._notify_cb);
344               i.notify["email-addresses"].connect (this._notify_cb);
345               i.notify["im-addresses"].connect (this._notify_cb);
346               i.notify["notes"].connect (this._notify_cb);
347               i.notify["phone-numbers"].connect (this._notify_cb);
348               i.notify["roles"].connect (this._notify_cb);
349               i.notify["postal-addresses"].connect (this._notify_cb);
350               i.notify["urls"].connect (this._notify_cb);
351
352               this._check_properties (i);
353             }
354         }
355
356       assert (removed == null);
357     }
358
359   private void _notify_cb (Object individual_obj, ParamSpec ps)
360     {
361       Folks.Individual i = (Folks.Individual) individual_obj;
362       this._check_properties (i);
363     }
364
365   private void _notify_persona_sname (Object persona_p, ParamSpec ps)
366     {
367       Trf.Persona persona = (Trf.Persona) persona_p;
368       this._check_sname (persona.structured_name);
369       this._exit_if_all_properties_found ();
370     }
371
372   private void _notify_pstore_cb (Object _pstore, ParamSpec ps)
373     {
374       this._try_to_add ();
375     }
376
377   private void _try_to_add ()
378     {
379       lock (this._added_persona)
380         {
381           if (this._pstore.is_prepared &&
382               this._added_persona == false)
383             {
384               this._added_persona = true;
385               this._add_persona ();
386             }
387         }
388     }
389
390   private void _check_properties (Individual i)
391     {
392       if (i.full_name == this._persona_fullname)
393         this._properties_found.replace ("full_name", true);
394
395       if (i.alias == this._persona_alias)
396         this._properties_found.replace ("alias", true);
397
398       if (i.is_favourite)
399         this._properties_found.replace ("is_favourite", true);
400
401       if (i.structured_name != null)
402         {
403           this._check_sname (i.structured_name);
404         }
405
406       if (i.avatar != null &&
407           i.avatar.get_uri () == this._file_uri)
408         this._properties_found.replace ("avatar", true);
409
410       if (i.birthday != null &&
411           i.birthday.compare (this._bday) == 0)
412         this._properties_found.replace ("birthday", true);
413
414       if (i.gender == Gender.MALE)
415         this._properties_found.replace ("gender", true);
416
417       foreach (unowned FieldDetails e in i.email_addresses)
418         {
419           if (e.value == this._email_1)
420             {
421               this._properties_found.replace ("email-1", true);
422             }
423           else if (e.value == this._email_2)
424             {
425               this._properties_found.replace ("email-2", true);
426             }
427         }
428
429       foreach (var proto in i.im_addresses.get_keys ())
430         {
431           var addrs = i.im_addresses.get (proto);
432           foreach (var a in addrs)
433             {
434               if (a == this._im_addr_1)
435                 this._properties_found.replace ("im-addr-1", true);
436               else if (a == this._im_addr_2)
437                 this._properties_found.replace ("im-addr-2", true);
438             }
439         }
440
441       foreach (var n in i.notes)
442         {
443           if (n.content == this._note_1)
444             {
445               this._properties_found.replace ("note-1", true);
446             }
447         }
448
449       foreach (unowned FieldDetails e in i.phone_numbers)
450         {
451           if (e.value == this._phone_1)
452             {
453               this._properties_found.replace ("phone-1", true);
454             }
455           else if (e.value == this._phone_2)
456             {
457               this._properties_found.replace ("phone-2", true);
458             }
459         }
460
461       foreach (var r in i.roles)
462         {
463           if (r.title == this._title_1 &&
464               r.organisation_name == this._organisation_1)
465             {
466               this._properties_found.replace ("role-1", true);
467             }
468         }
469
470       foreach (var pa in i.postal_addresses)
471         {
472           this._address.uid = pa.uid;
473           if (pa.equal (this._address))
474             this._properties_found.replace ("postal-address-1", true);
475         }
476
477       foreach (var u in i.urls)
478         {
479           if (u.value == this._url_1)
480             this._properties_found.replace ("url-1", true);
481           if (u.value == this._url_2)
482             this._properties_found.replace ("url-2", true);
483         }
484
485       this._exit_if_all_properties_found ();
486     }
487
488   private void _exit_if_all_properties_found ()
489     {
490       foreach (var k in this._properties_found.get_keys ())
491         {
492           var v = this._properties_found.lookup (k);
493           if (v == false)
494             return;
495         }
496       this._main_loop.quit ();
497     }
498
499   private void _check_sname (StructuredName sname)
500     {
501       if (sname.family_name == this._family_name &&
502           sname.given_name == this._given_name)
503         this._properties_found.replace ("structured_name", true);
504     }
505 }
506
507 public int main (string[] args)
508 {
509   Test.init (ref args);
510
511   TestSuite root = TestSuite.get_root ();
512   root.add_suite (new AddPersonaTests ().get_suite ());
513
514   Test.run ();
515
516   return 0;
517 }