3c6fb36049b94974722f863cead822ac8f8e5ff3
[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_nickname;
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_nickname = "nickname";
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       var types =  new HashSet<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 ("nickname", 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.values)
160             {
161               this._pstore =
162                 (Trf.PersonaStore) backend.persona_stores.get ("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_nickname);
188       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.NICKNAME),
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 (Set<FieldDetails>));
225       var emails = new HashSet<FieldDetails> ();
226       var email_1 = new FieldDetails (this._email_1);
227       emails.add (email_1);
228       var email_2 = new FieldDetails (this._email_2);
229       emails.add (email_2);
230       v8.set_object (emails);
231       details.insert (
232           Folks.PersonaStore.detail_key (PersonaDetail.EMAIL_ADDRESSES),
233           (owned) v8);
234
235       Value? v9 = Value (typeof (MultiMap<string, string>));
236       var im_addrs = new HashMultiMap<string, string> ();
237       im_addrs.set ("jabber", this._im_addr_1);
238       im_addrs.set ("yahoo", this._im_addr_2);
239       v9.set_object (im_addrs);
240       details.insert (
241           Folks.PersonaStore.detail_key (PersonaDetail.IM_ADDRESSES), v9);
242
243       Value? v10 = Value (typeof (Set<Note>));
244       var notes = new HashSet<Note> ();
245       Note n1 = new Note (this._note_1);
246       notes.add (n1);
247       v10.set_object (notes);
248       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.NOTES),
249           (owned) v10);
250
251       Value? v11 = Value (typeof (Set<FieldDetails>));
252       var phones = new HashSet<FieldDetails> ();
253       var phone_1 = new FieldDetails (this._phone_1);
254       phones.add (phone_1);
255       var phone_2 = new FieldDetails (this._phone_2);
256       phones.add (phone_2);
257       v11.set_object (phones);
258       details.insert (
259           Folks.PersonaStore.detail_key (PersonaDetail.PHONE_NUMBERS),
260           (owned) v11);
261
262       Value? v12 = Value (typeof (Set<Role>));
263       var roles = new HashSet<Role> ();
264       Role r1 = new Role (this._title_1, this._organisation_1);
265       roles.add (r1);
266       v12.set_object (roles);
267       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.ROLES),
268           (owned) v12);
269
270       Value? v13 = Value (typeof (Set<PostalAddress>));
271       var postal_addresses = new HashSet<PostalAddress> ();
272
273       var types =  new HashSet<string> ();
274       PostalAddress postal_a = new PostalAddress (this._po_box,
275           this._extension, this._street, this._locality, this._region,
276           this._postal_code, this._country, null, types, null);
277       postal_addresses.add (postal_a);
278       v13.set_object (postal_addresses);
279       details.insert (
280           Folks.PersonaStore.detail_key (PersonaDetail.POSTAL_ADDRESSES),
281           (owned) v13);
282
283       Value? v14 = Value (typeof (Set<FieldDetails>));
284       var urls = new HashSet<FieldDetails> ();
285       var url_1 = new FieldDetails (this._url_1);
286       urls.add (url_1);
287       var url_2 = new FieldDetails (this._url_2);
288       urls.add (url_2);
289       v14.set_object (urls);
290       details.insert (Folks.PersonaStore.detail_key (PersonaDetail.URLS),
291           (owned) v14);
292
293       try
294         {
295           Trf.Persona persona = (Trf. Persona)
296               yield this._aggregator.add_persona_from_details
297                 (null, this._pstore, details);
298           this._persona_iid = persona.iid;
299         }
300       catch (Folks.IndividualAggregatorError e)
301         {
302           GLib.warning ("[AddPersonaError] add_persona_from_details: %s\n",
303               e.message);
304         }
305     }
306
307   private void _individuals_changed_cb
308       (Set<Individual> added,
309        Set<Individual> removed,
310        string? message,
311        Persona? actor,
312        GroupDetails.ChangeReason reason)
313     {
314       foreach (var i in added)
315         {
316           if (i.is_user == false)
317             {
318               /* NOTE:
319                *   we also listen to the Trf.Persona's structured-name
320                *   because if only one of its property is updated
321                *   Individual won't fire a notification.
322                */
323               foreach (var p in i.personas)
324                 {
325                   if (p is NameDetails &&
326                       ((NameDetails) p).structured_name != null)
327                     {
328                       p.notify["structured-name"].connect
329                         (this._notify_persona_sname);
330                     }
331                 }
332
333               i.notify["full-name"].connect (this._notify_cb);
334               i.notify["nickname"].connect (this._notify_cb);
335               i.notify["avatar"].connect (this._notify_cb);
336               i.notify["is-favourite"].connect (this._notify_cb);
337               i.notify["structured-name"].connect (this._notify_cb);
338               i.notify["family-name"].connect (this._notify_cb);
339               i.notify["given-name"].connect (this._notify_cb);
340               i.notify["avatar"].connect (this._notify_cb);
341               i.notify["birthday"].connect (this._notify_cb);
342               i.notify["gender"].connect (this._notify_cb);
343               i.notify["email-addresses"].connect (this._notify_cb);
344               i.notify["im-addresses"].connect (this._notify_cb);
345               i.notify["notes"].connect (this._notify_cb);
346               i.notify["phone-numbers"].connect (this._notify_cb);
347               i.notify["roles"].connect (this._notify_cb);
348               i.notify["postal-addresses"].connect (this._notify_cb);
349               i.notify["urls"].connect (this._notify_cb);
350
351               this._check_properties (i);
352             }
353         }
354
355       assert (removed.size == 0);
356     }
357
358   private void _notify_cb (Object individual_obj, ParamSpec ps)
359     {
360       Folks.Individual i = (Folks.Individual) individual_obj;
361       this._check_properties (i);
362     }
363
364   private void _notify_persona_sname (Object persona_p, ParamSpec ps)
365     {
366       Trf.Persona persona = (Trf.Persona) persona_p;
367       this._check_sname (persona.structured_name);
368       this._exit_if_all_properties_found ();
369     }
370
371   private void _notify_pstore_cb (Object _pstore, ParamSpec ps)
372     {
373       this._try_to_add ();
374     }
375
376   private void _try_to_add ()
377     {
378       lock (this._added_persona)
379         {
380           if (this._pstore.is_prepared &&
381               this._added_persona == false)
382             {
383               this._added_persona = true;
384               this._add_persona ();
385             }
386         }
387     }
388
389   private void _check_properties (Individual i)
390     {
391       if (i.full_name == this._persona_fullname)
392         this._properties_found.replace ("full_name", true);
393
394       if (i.nickname == this._persona_nickname)
395         this._properties_found.replace ("nickname", true);
396
397       if (i.is_favourite)
398         this._properties_found.replace ("is_favourite", true);
399
400       if (i.structured_name != null)
401         {
402           this._check_sname (i.structured_name);
403         }
404
405       if (i.avatar != null &&
406           i.avatar.get_uri () == this._file_uri)
407         this._properties_found.replace ("avatar", true);
408
409       if (i.birthday != null &&
410           i.birthday.compare (this._bday) == 0)
411         this._properties_found.replace ("birthday", true);
412
413       if (i.gender == Gender.MALE)
414         this._properties_found.replace ("gender", true);
415
416       foreach (var e in i.email_addresses)
417         {
418           if (e.value == this._email_1)
419             {
420               this._properties_found.replace ("email-1", true);
421             }
422           else if (e.value == this._email_2)
423             {
424               this._properties_found.replace ("email-2", true);
425             }
426         }
427
428       foreach (var proto in i.im_addresses.get_keys ())
429         {
430           var addrs = i.im_addresses.get (proto);
431           foreach (var a in addrs)
432             {
433               if (a == this._im_addr_1)
434                 this._properties_found.replace ("im-addr-1", true);
435               else if (a == this._im_addr_2)
436                 this._properties_found.replace ("im-addr-2", true);
437             }
438         }
439
440       foreach (var n in i.notes)
441         {
442           if (n.content == this._note_1)
443             {
444               this._properties_found.replace ("note-1", true);
445             }
446         }
447
448       foreach (var e in i.phone_numbers)
449         {
450           if (e.value == this._phone_1)
451             {
452               this._properties_found.replace ("phone-1", true);
453             }
454           else if (e.value == this._phone_2)
455             {
456               this._properties_found.replace ("phone-2", true);
457             }
458         }
459
460       foreach (var r in i.roles)
461         {
462           if (r.title == this._title_1 &&
463               r.organisation_name == this._organisation_1)
464             {
465               this._properties_found.replace ("role-1", true);
466             }
467         }
468
469       foreach (var pa in i.postal_addresses)
470         {
471           this._address.uid = pa.uid;
472           if (pa.equal (this._address))
473             this._properties_found.replace ("postal-address-1", true);
474         }
475
476       foreach (var u in i.urls)
477         {
478           if (u.value == this._url_1)
479             this._properties_found.replace ("url-1", true);
480           if (u.value == this._url_2)
481             this._properties_found.replace ("url-2", true);
482         }
483
484       this._exit_if_all_properties_found ();
485     }
486
487   private void _exit_if_all_properties_found ()
488     {
489       foreach (var k in this._properties_found.get_keys ())
490         {
491           var v = this._properties_found.lookup (k);
492           if (v == false)
493             return;
494         }
495       this._main_loop.quit ();
496     }
497
498   private void _check_sname (StructuredName sname)
499     {
500       if (sname.family_name == this._family_name &&
501           sname.given_name == this._given_name)
502         this._properties_found.replace ("structured_name", true);
503     }
504 }
505
506 public int main (string[] args)
507 {
508   Test.init (ref args);
509
510   TestSuite root = TestSuite.get_root ();
511   root.add_suite (new AddPersonaTests ().get_suite ());
512
513   Test.run ();
514
515   return 0;
516 }