Add a test in prep for supporting multiple im contacts.
[qtcontacts-tracker:qtcontacts-tracker.git] / tests / ut_qtcontacts_trackerplugin / ut_qtcontacts_trackerplugin.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the Qt Mobility Components.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "ut_qtcontacts_trackerplugin.h"
43
44 #include <QMap>
45 #include <QPair>
46 #include <QUuid>
47
48 #include <QtTracker/Tracker>
49 #include <QtTracker/ontologies/nco.h>
50 #include <QtTracker/ontologies/nie.h>
51 #include <qcontactfilters.h>
52 #include <QContactChangeLogFilter>
53 #include <qtcontacts.h>
54 #include <trackerchangelistener.h>
55 #include <qcontactrelationshipsaverequest.h>
56 #include <qcontactrelationshipfetchrequest.h>
57 #include <qtrackercontactidfetchrequest.h>
58 #include <qcontacttrackerbackend_p.h>
59 #include <qtrackercontactasyncrequest.h>
60
61 #include "contactmanager.h"
62
63 // update this when creating debian package
64 const QString PATH_TO_SPARQL_TESTS("./ut_qtcontacts_trackerplugin_data");
65
66 ut_qtcontacts_trackerplugin::ut_qtcontacts_trackerplugin()
67 {
68
69 }
70
71 void ut_qtcontacts_trackerplugin::initTestCase()
72 {
73     QMap<QString, QString> trackerEngineParams;
74     trackerEngine = new QContactTrackerEngine(trackerEngineParams);
75     errorMap = new QMap<int, QContactManager::Error>();
76 }
77
78 void ut_qtcontacts_trackerplugin::testContacts()
79 {
80     QContact c1;
81     QContact c2;
82
83     trackerEngine->saveContact(&c1, error);
84     trackerEngine->saveContact(&c2, error);
85     QVERIFY2((error == QContactManager::NoError),"Saving contact");
86     QList<QContactLocalId> contacts = trackerEngine->contactIds(queryFilter, sortOrders, error);
87     QVERIFY2(contacts.contains(c1.localId()), "Previously added contact is not found");
88     QVERIFY2(contacts.contains(c2.localId()), "Previously added contact is not found");
89 }
90
91 void ut_qtcontacts_trackerplugin::testContact()
92 {
93     // Test invalid contact id
94     QContact invalidContact = trackerEngine->contact_impl( -1, error);
95     QVERIFY(error != QContactManager::NoError);
96
97     // Add a contact
98     QContact newContact;
99     const QContactLocalId oldid = newContact.localId();
100     QVERIFY( trackerEngine->saveContact( &newContact, error ) );
101
102     QContactLocalId id = newContact.localId();
103     QVERIFY( id != oldid );
104
105     // Find the added contact
106     QContact c = trackerEngine->contact_impl( id, error );
107     QVERIFY( c.localId() == newContact.localId() );
108 }
109
110 void ut_qtcontacts_trackerplugin::testSaveName()
111 {
112     QContact c;
113     QContactLocalId initialId = c.localId();
114     int detailsAdded = 0;
115
116     QMap<QString,QString> nameValues;
117     QContactName name;
118     nameValues.insert(QLatin1String(QContactName::FieldPrefix), "Mr");
119     nameValues.insert(QLatin1String(QContactName::FieldFirst), "John");
120     nameValues.insert(QLatin1String(QContactName::FieldMiddle), "Rupert");
121     nameValues.insert(QLatin1String(QContactName::FieldLast), "Doe");
122 //    nameValues.insert(QContactName::FieldSuffix, "III");
123
124     foreach (QString field, nameValues.keys()) {
125         name.setValue(field, nameValues.value(field));
126     }
127     c.saveDetail(&name);
128
129     QContactNickname nick;
130     nick.setValue(QLatin1String(QContactNickname::FieldNickname), "Johnny");
131     c.saveDetail(&nick);
132
133     QVERIFY(c.detail<QContactName>().prefix() == "Mr");
134     QVERIFY(c.detail<QContactName>().firstName() == "John");
135     QVERIFY(c.detail<QContactName>().middleName() == "Rupert");
136     QVERIFY(c.detail<QContactName>().lastName() == "Doe");
137     QVERIFY(c.detail<QContactNickname>().nickname() == "Johnny");
138
139     detailsAdded++;
140
141     trackerEngine->saveContact(&c, error);
142     QCOMPARE(error,  QContactManager::NoError);
143     QVERIFY(c.localId() != initialId);
144     QContact contact = trackerEngine->contact_impl(c.localId(), error);
145     QList<QContactName> details = contact.details<QContactName>();
146     QList<QContactNickname> details2 = contact.details<QContactNickname>();
147     QCOMPARE(details.count(), detailsAdded);
148     QCOMPARE(details2.count(), detailsAdded);
149     // Name is unique
150     foreach(QString field, nameValues.keys()) {
151         QCOMPARE(details.at(0).value(field), nameValues.value(field));
152     }
153     QCOMPARE(details2.at(0).value(QLatin1String(QContactNickname::FieldNickname)), QString("Johnny"));
154
155     // Try changing the name of the saved contact.
156     {
157         QMap<QString,QString> nameValues;
158         QContactName name = c.detail<QContactName>();
159         nameValues.insert(QLatin1String(QContactName::FieldPrefix), "Mr2");
160         nameValues.insert(QLatin1String(QContactName::FieldFirst), "John2");
161         nameValues.insert(QLatin1String(QContactName::FieldMiddle), "Rupert2");
162         nameValues.insert(QLatin1String(QContactName::FieldLast), "");
163         //    nameValues.insert(QContactName::FieldSuffix, "III");
164
165         foreach (QString field, nameValues.keys()) {
166             name.setValue(field, nameValues.value(field));
167         }
168         c.saveDetail(&name);
169
170         QContactNickname nick = c.detail<QContactNickname>();
171         nick.setValue(QLatin1String(QContactNickname::FieldNickname), "Johnny2");
172         c.saveDetail(&nick);
173
174
175         QVERIFY(trackerEngine->saveContact(&c, error));
176         QCOMPARE(error,  QContactManager::NoError);
177         QVERIFY(c.localId() != initialId);
178
179         QContact contact = trackerEngine->contact_impl(c.localId(), error);
180         QCOMPARE(error,  QContactManager::NoError);
181         QList<QContactName> details = contact.details<QContactName>();
182         QList<QContactNickname> details2 = contact.details<QContactNickname>();
183         QCOMPARE(details.count(), detailsAdded);
184         QCOMPARE(details2.count(), detailsAdded);
185         // Name is unique
186         foreach(QString field, nameValues.keys()) {
187             QCOMPARE(details.at(0).value(field), nameValues.value(field));
188         }
189         QCOMPARE(details2.at(0).value(QLatin1String(QContactNickname::FieldNickname)), QString("Johnny2"));
190
191         // now try to add new name detail fails - this is how currently unique fields are implemented
192         // so cover it in unit tests
193         QContactName name1;
194         name1.setValue(QContactName::FieldFirst, "Something that wont be stored as name is unique");
195         c.saveDetail(&name1);
196         // validate that unique name is not saved
197         QVERIFY(!trackerEngine->saveContact(&c, error));
198         details = contact.details<QContactName>();
199         details2 = contact.details<QContactNickname>();
200         QCOMPARE(details.count(), detailsAdded);
201         QCOMPARE(details2.count(), detailsAdded);
202     }
203 }
204
205 void ut_qtcontacts_trackerplugin::testSavePhoneNumber()
206 {
207     // use the same values for 2 contacts
208     for (int i = 0; i <2; i++ )
209     {
210     QContact c;
211     QContactLocalId initialId = c.localId();
212     int detailsAdded = 0;
213     QContactName name;
214     name.setFirstName("I have phone numbers");
215     name.setLastName("Girl");
216     c.saveDetail(&name);
217
218     // key: phonenumber; value: context,subtype
219     QMap<QString,QPair<QString,QString> > phoneValues;
220
221     phoneValues.insert("(704)486-6472", QPair<QString,QString>(QLatin1String(QContactDetail::ContextHome), QString()));
222     phoneValues.insert("(765)957-1663", QPair<QString,QString>(QLatin1String(QContactDetail::ContextHome), QString()));
223     phoneValues.insert("(999)888-1111", QPair<QString,QString>(QLatin1String(QContactDetail::ContextHome),
224                                                                QLatin1String(QContactPhoneNumber::SubTypeMobile)));
225
226     phoneValues.insert("(792)123-6113", QPair<QString,QString>(QLatin1String(QContactDetail::ContextWork), QString()));
227     phoneValues.insert("(918)491-7361", QPair<QString,QString>(QLatin1String(QContactDetail::ContextWork),
228                                                   QLatin1String(QContactPhoneNumber::SubTypeMobile)));
229     phoneValues.insert("(412)670-1514", QPair<QString,QString>(QLatin1String(QContactDetail::ContextWork),
230                                                   QLatin1String(QContactPhoneNumber::SubTypeCar)));
231     QMap<QString,QPair<QString,QString> > formattedPhoneValues;
232
233
234     foreach (QString number, phoneValues.keys()) {
235         QContactPhoneNumber phone;
236         phone.setNumber(number);
237         // Stripped automatically on saving RFC 3966 visual-separators reg exp "[(|-|.|)| ]"
238         formattedPhoneValues.insert(QString(number).replace( QRegExp("[\\(|" \
239                 "\\-|" \
240                 "\\.|" \
241                 "\\)|" \
242                 " ]"), ""),phoneValues.value(number));
243         if (!phoneValues.value(number).first.isEmpty()) {
244             phone.setContexts(phoneValues.value(number).first);
245         }
246         if (!phoneValues.value(number).second.isEmpty()) {
247             phone.setSubTypes(phoneValues.value(number).second);
248         }
249         c.saveDetail(&phone);
250         detailsAdded++;
251     }
252
253     trackerEngine->saveContact(&c, error);
254     QCOMPARE(error,  QContactManager::NoError);
255     QVERIFY(c.localId() != initialId);
256     // wait for commit transaction to be done, no signals yet
257     for(int i = 0; i < 100; i++)
258     {
259         usleep(10000);
260         QCoreApplication::processEvents();
261     }
262
263
264     // verify with synchronous read too
265     QContact contact = trackerEngine->contact_impl(c.localId(), error);
266     QCOMPARE(error,  QContactManager::NoError);
267     QList<QContactPhoneNumber> details = contact.details<QContactPhoneNumber>();
268
269
270     QCOMPARE(details.count(), detailsAdded);
271
272
273     foreach (QContactPhoneNumber detail, details) {
274         // Verify that the stored values and attributes are the same as given
275         QVERIFY(formattedPhoneValues.contains(detail.number()));
276         QCOMPARE(detail.contexts()[0], formattedPhoneValues.value(detail.number()).first);
277         if( formattedPhoneValues.value(detail.number()).second.isEmpty()) // default empty is voice
278             QCOMPARE(detail.subTypes()[0], QLatin1String(QContactPhoneNumber::SubTypeVoice));
279         else
280             QCOMPARE(detail.subTypes()[0], formattedPhoneValues.value(detail.number()).second);
281     }
282
283     // edit one of numbers . values, context and subtypes and save again
284     QString editedPhoneValue = "+7044866473";
285     QContactPhoneNumber phone = details[0];
286     phone.setNumber(editedPhoneValue);
287     phone.setContexts(QContactDetail::ContextWork);
288     phone.setSubTypes(QContactPhoneNumber::SubTypeMobile);
289     c = contact;
290     c.saveDetail(&phone);
291     trackerEngine->saveContact(&c, error);
292     QCOMPARE(error,  QContactManager::NoError);
293     c = this->contact(c.localId(), QStringList()<<QContactPhoneNumber::DefinitionName);
294     details = c.details<QContactPhoneNumber>();
295     QCOMPARE(details.count(), detailsAdded);
296     bool found = false;
297     foreach (QContactPhoneNumber detail, details) {
298         if(detail.number() == phone.number())
299         {
300             found = true;
301             QVERIFY(detail.subTypes().contains(QContactPhoneNumber::SubTypeMobile));
302             QVERIFY(detail.contexts().contains(QContactPhoneNumber::ContextWork));
303             break;
304         }
305     }
306     QVERIFY(found);
307     }
308 }
309
310 void ut_qtcontacts_trackerplugin::testPhoneNumberContext()
311 {
312     QContact c;
313     QContactPhoneNumber phone;
314     phone.setContexts(QContactDetail::ContextHome);
315     phone.setNumber("555-888");
316     phone.setSubTypes(QContactPhoneNumber::SubTypeMobile);
317     c.saveDetail(&phone);
318     QContact contactToSave = c;
319     // Let's do this all twice, first time save new detail, and next iteration change the context
320     for (int iterations = 0; iterations < 2; iterations++) {
321         QVERIFY(trackerEngine->saveContact(&contactToSave, error));
322         // wait for commit transaction to be done, no signals yet
323         for(int i = 0; i < 100; i++) {
324             usleep(10000);
325             QCoreApplication::processEvents();
326         }
327
328         QContactFetchRequest request;
329         QContactLocalIdFilter filter;
330         QList<QContactLocalId> ids;
331         ids.append(contactToSave.localId());
332         filter.setIds(ids);
333         request.setFilter(filter);
334
335         QStringList details;
336         details << QContactPhoneNumber::DefinitionName;
337         request.setDefinitionRestrictions(details);
338
339         Slots slot;
340         QObject::connect(&request, SIGNAL(resultsAvailable()),
341                 &slot, SLOT(resultsAvailable()));
342
343         trackerEngine->startRequest(&request);
344
345         for(int i = 0; i < 100; i++) {
346             usleep(100000);
347             QCoreApplication::processEvents();
348             if(request.isFinished() )
349                 break;
350         }
351
352         // if it takes more, then something is wrong
353         QVERIFY(request.isFinished());
354         QVERIFY(!slot.contacts.isEmpty());
355
356         QContact contactToTest;
357         foreach (QContact savedContact, slot.contacts) {
358             if (savedContact.localId() == contactToSave.localId()) {
359                 contactToTest = savedContact;
360             }
361         }
362         QVERIFY(contactToTest.localId() == contactToSave.localId()); // Just to be sure we got the saved contact
363         qDebug()<<contactToTest.details<QContactPhoneNumber>().count();
364         
365         QVERIFY(contactToTest.details<QContactPhoneNumber>().count() == 1);
366         if (0 == iterations) {
367             // perform context change
368             QContactPhoneNumber phoneToEdit = contactToTest.detail<QContactPhoneNumber>();
369             phoneToEdit.setContexts(QContactDetail::ContextWork);
370             contactToTest.saveDetail(&phoneToEdit);
371             contactToSave = contactToTest;
372         }
373         QVERIFY(contactToTest.details<QContactPhoneNumber>().count() == 1);
374     }
375 }
376
377 void ut_qtcontacts_trackerplugin::testWritingOnlyWorkMobile()
378 {
379     QContact c;
380     QContactPhoneNumber phone;
381     phone.setContexts(QContactDetail::ContextWork);
382     phone.setNumber("555999");
383     phone.setSubTypes(QContactPhoneNumber::SubTypeMobile);
384     c.saveDetail(&phone);
385     QContact& contactToSave = c;
386     QVERIFY(trackerEngine->saveContact(&contactToSave, error));
387     // wait for commit transaction to be done, no signals yet
388     for(int i = 0; i < 100; i++) {
389         usleep(10000);
390         QCoreApplication::processEvents();
391     }
392
393     QContactFetchRequest request;
394     QContactLocalIdFilter filter;
395     QList<QContactLocalId> ids;
396     ids.append(contactToSave.localId());
397     filter.setIds(ids);
398     request.setFilter(filter);
399     QStringList details;
400     details << QContactPhoneNumber::DefinitionName;
401     request.setDefinitionRestrictions(details);
402
403     Slots slot;
404     QObject::connect(&request, SIGNAL(resultsAvailable()),
405             &slot, SLOT(resultsAvailable()));
406
407     trackerEngine->startRequest(&request);
408
409     for(int i = 0; i < 100; i++) {
410         usleep(100000);
411         QCoreApplication::processEvents();
412         if(request.isFinished() )
413             break;
414     }
415
416     // if it takes more, then something is wrong
417     QVERIFY(request.isFinished());
418     QVERIFY(!slot.contacts.isEmpty());
419
420     QContact contactToTest;
421     foreach (QContact savedContact, slot.contacts) {
422         if (savedContact.localId() == c.localId()) {
423             contactToTest = savedContact;
424         }
425     }
426     QVERIFY(contactToTest.localId() == c.localId()); // Just to be sure we got the saved contact
427     QVERIFY(contactToTest.details<QContactPhoneNumber>().count() == 1);
428     QVERIFY(contactToTest.detail<QContactPhoneNumber>().number() == phone.number());
429     QVERIFY(contactToTest.detail<QContactPhoneNumber>().subTypes() == phone.subTypes());
430     QVERIFY(contactToTest.detail<QContactPhoneNumber>().contexts() == phone.contexts());
431 }
432
433 void ut_qtcontacts_trackerplugin::testSaveAddress()
434 {
435     QContact c;
436     QContactName name;
437     name.setFirstName("Aruba & Barbados");
438     name.setLastName("Girl");
439     c.saveDetail(&name);
440     QContactLocalId initialId = c.localId();
441     int detailsAdded = 0;
442
443     // List of pairs of field-value map and context
444     typedef QMap<QString,QString> typeAddress;
445     typedef QPair<typeAddress,QString> typeAddressWithContext;
446     QList<typeAddressWithContext> addressValues;
447
448     // TODO check status of 137174 and other libqttracker1pre6 bugs before refactoring
449     typeAddress values;
450     values.insert(QLatin1String(QContactAddress::FieldCountry), "Barbados");
451     values.insert(QLatin1String(QContactAddress::FieldPostcode), "55555");
452     values.insert(QLatin1String(QContactAddress::FieldStreet), "Martindales Rd");
453     values.insert(QLatin1String(QContactAddress::FieldRegion), "Bridgetown");
454     addressValues.append(typeAddressWithContext(values, QLatin1String(QContactDetail::ContextHome)));
455     values.clear();
456     values.insert(QLatin1String(QContactAddress::FieldCountry), "Aruba");
457     values.insert(QLatin1String(QContactAddress::FieldPostcode), "44444");
458     values.insert(QLatin1String(QContactAddress::FieldStreet), "Brazilie Straat");
459     values.insert(QLatin1String(QContactAddress::FieldRegion), "Oranjestad");
460     addressValues.append(typeAddressWithContext(values, QLatin1String(QContactDetail::ContextHome)));
461     values.clear();
462     values.insert(QLatin1String(QContactAddress::FieldCountry), "ArubaWork");
463     values.insert(QLatin1String(QContactAddress::FieldPostcode), "44445");
464     values.insert(QLatin1String(QContactAddress::FieldStreet), "Sunset Blvd");
465     values.insert(QLatin1String(QContactAddress::FieldRegion), "Oranjestad");
466     addressValues.append(typeAddressWithContext(values, QLatin1String(QContactDetail::ContextHome)));
467     foreach (typeAddressWithContext addressWithContext, addressValues) {
468         QContactAddress address;
469         foreach (QString field, addressWithContext.first.keys()) {
470             address.setValue(field, addressWithContext.first.value(field));
471         }
472         address.setContexts(addressWithContext.second);
473         c.saveDetail(&address);
474         detailsAdded++;
475     }
476
477     trackerEngine->saveContact(&c, error);
478     QCOMPARE(error,  QContactManager::NoError);
479     QVERIFY(c.localId() != initialId);
480     QContact contact = trackerEngine->contact_impl(c.localId(), error);
481     QList<QContactAddress> details = contact.details<QContactAddress>();
482     QCOMPARE(details.count(), detailsAdded);
483     bool found = false;
484     // Test if inserted values are found in some of the details
485     foreach (typeAddressWithContext addressWithContext, addressValues) {
486         foreach (QContactAddress detail, details) {
487             foreach (QString field, addressWithContext.first.keys()) {
488                 found = (detail.value(field) == addressWithContext.first.value(field));
489                 if (!found)
490                     break;
491             }
492             if (found)
493                 break;
494         }
495         QVERIFY2(found, "Inserted detail was not found in the fetched details");
496     }
497 }
498
499 void ut_qtcontacts_trackerplugin::testSaveEmailAddress()
500 {
501     QContact c;
502     QContactLocalId initialId = c.localId();
503     int detailsAdded = 0;
504
505     QMap<QString,QString> values;
506     values.insert("john.does@hotmail.com", QContactDetail::ContextHome);
507     values.insert("john.doe@gmail.com", QContactDetail::ContextWork);
508     values.insert("john.doe@nokia.com", QContactDetail::ContextWork);
509     values.insert("john.doe@johndoe.com", QContactDetail::ContextHome);
510     foreach(QString address, values.keys()) {
511         QContactEmailAddress emailAddress;
512         emailAddress.setEmailAddress(address);
513         emailAddress.setContexts(values.value(address));
514         c.saveDetail(&emailAddress);
515         detailsAdded++;
516     }
517     QContactName name;
518     name.setFirstName("Jo");
519     name.setLastName("H N Doe");
520     c.saveDetail(&name);
521     trackerEngine->saveContact(&c, error);
522     QCOMPARE(error,  QContactManager::NoError);
523     QVERIFY(c.localId() != initialId);
524     QContact contact = trackerEngine->contact_impl(c.localId(), error);
525     QList<QContactEmailAddress> details = contact.details<QContactEmailAddress>();
526     QCOMPARE(details.count(), detailsAdded);
527     foreach (QContactEmailAddress detail, details) {
528         QString address = detail.value(QContactEmailAddress::FieldEmailAddress);
529         QVERIFY(values.contains(address));
530         QCOMPARE(detail.contexts()[0], values.value(address));
531     }
532 }
533
534 void ut_qtcontacts_trackerplugin::testRemoveContact()
535 {
536     QContact c;
537     QContactPhoneNumber phone;
538     phone.setNumber("+358501234567");
539     c.saveDetail(&phone);
540     QContactEmailAddress email;
541     email.setEmailAddress("super.man@hotmail.com");
542     c.saveDetail(&email);
543     QContactName name;
544     name.setFirstName("Super");
545     name.setLastName("Man");
546     c.saveDetail(&name);
547
548     QVERIFY2(trackerEngine->saveContact(&c, error) && error == QContactManager::NoError, "Saving a contact failed");
549     QVERIFY2(trackerEngine->removeContact(c.localId(), error), "Removing a contact failed");
550     QCOMPARE(error, QContactManager::NoError);
551     QVERIFY2(trackerEngine->contact_impl(c.localId(), error) == QContact(), "Found a contact, which should have been removed");
552 }
553
554 void ut_qtcontacts_trackerplugin::testSaveContacts()
555 {
556     QList<QContact> contacts;
557     for (int i = 0; i < 3; i++) {
558         QContact c;
559         QContactName name;
560         name.setFirstName("John");
561         name.setLastName(QString::number(i,10));
562         c.saveDetail(&name);
563         contacts.append(c);
564     }
565
566     QMap<int, QContactManager::Error>* errorMap;    
567     trackerEngine->saveContacts(&contacts, errorMap, error);
568     QCOMPARE(error, QContactManager::NoError);
569     for (int i = 0; i < contacts.count(); i++) {
570         QVERIFY(contacts[i].localId() != 0);
571         QList<QContactName> details = trackerEngine->contact_impl(contacts[i].localId(), error).details<QContactName>();
572         QVERIFY(details.count());
573         QCOMPARE(details.at(0).lastName(),
574                  QString("%1").arg(QString::number(i,10)));
575     }
576 }
577
578 void ut_qtcontacts_trackerplugin::testRemoveContacts()
579 {
580     QList<QContactLocalId> addedIds;
581     for (int i = 0; i < 5; i++) {
582         QContact c;
583         QContactName name;
584         name.setFirstName(QString("John%1").arg(QString::number(i,10)));
585         c.saveDetail(&name);
586         QVERIFY2(trackerEngine->saveContact(&c, error) && error == QContactManager::NoError, "Saving a contact failed");
587         addedIds.append(c.localId());
588     }
589     QList<QContactLocalId> toApiRemove;
590     toApiRemove.append(addedIds.takeLast());
591     toApiRemove.append(addedIds.takeLast());
592     QList<QContactLocalId> toPluginRemove(addedIds);
593     // Remove all, but last of the added contacts
594     bool success = trackerEngine->removeContacts(&toPluginRemove, errorMap, error);
595     QCOMPARE(success, true);
596     for (int i = 0; i < errorMap->count(); i++) {
597         QVERIFY(toPluginRemove[i] == 0);
598     }
599     QCOMPARE(error, QContactManager::NoError);
600
601     success = ContactManager::instance()->removeContacts(&toApiRemove, errorMap);
602     QCOMPARE(success, true);
603     for (int i = 0; i < errorMap->count(); i++) {
604         QVERIFY(toApiRemove[i] == 0);
605     }
606
607     // Try to remove some previously removed contacts, but one valid contact
608     success = trackerEngine->removeContacts(&addedIds, errorMap, error);
609     QCOMPARE(errorMap->count(), addedIds.count());
610     for (int i = 0; i < errorMap->count() - 1; i++) {
611         QVERIFY2(addedIds[i] != 0, "Manager should not mark id as zero");
612     }
613 }
614
615 void ut_qtcontacts_trackerplugin::testAvatar()
616 {
617     QContact contactWithAvatar;
618     QContactAvatar avatar;
619
620     avatar.setAvatar("file:///home/user/.contacts/avatars/default_avatar.png");
621     contactWithAvatar.saveDetail(&avatar);
622     QContactName name;
623     name.setFirstName("John");name.setLastName("A Frog");
624     contactWithAvatar.saveDetail(&name);
625     QVERIFY(trackerEngine->saveContact( &contactWithAvatar, error));
626
627     QContact c = trackerEngine->contact_impl( contactWithAvatar.localId(), error);
628     QList<QContactAvatar> avatars = c.details<QContactAvatar>();
629     QVERIFY( avatars.size() );
630     QCOMPARE( avatars[0].avatar(), avatar.avatar() );
631 }
632
633 void ut_qtcontacts_trackerplugin::testUrl()
634 {
635
636     //Context home, homepage url
637     QContact contactWithUrl1;
638     QContactUrl url1;
639     url1.setUrl("http://home.homepage");
640     url1.setContexts(QContactDetail::ContextHome);
641     url1.setSubType(QContactUrl::SubTypeHomePage);
642     QContactName name;
643     name.setFirstName("John");name.setLastName("TestUrl1");
644     contactWithUrl1.saveDetail(&name);
645     contactWithUrl1.saveDetail(&url1);
646     QVERIFY(trackerEngine->saveContact(&contactWithUrl1, error));
647
648     //Context work, homepage url
649     QContact contactWithUrl2;
650     QContactUrl url2;
651     url2.setUrl("http://work.homepage");
652     url2.setContexts(QContactDetail::ContextWork);
653     url2.setSubType(QContactUrl::SubTypeHomePage);
654     QContactName name2;
655     name2.setLastName("TestUrl2");
656     contactWithUrl2.saveDetail(&name2);
657     contactWithUrl2.saveDetail(&url2);
658     QVERIFY(trackerEngine->saveContact(&contactWithUrl2, error));
659
660     //Context home, favourite url
661     QContact contactWithUrl3;
662     QContactUrl url3;
663     url3.setUrl("http://home.favourite");
664     url3.setContexts(QContactDetail::ContextHome);
665     url3.setSubType(QContactUrl::SubTypeFavourite);
666
667     name2.setLastName("TestUrl3");
668     contactWithUrl3.saveDetail(&name2);
669     contactWithUrl3.saveDetail(&url3);
670     QVERIFY(trackerEngine->saveContact(&contactWithUrl3, error));
671
672
673     QContactLocalId id1 = contactWithUrl1.localId();
674     QContactLocalId id2 = contactWithUrl2.localId();
675     QContactLocalId id3 = contactWithUrl3.localId();
676     QCOMPARE(trackerEngine->contact_impl(id1, error).detail<QContactUrl>().url(), QString("http://home.homepage"));
677     QCOMPARE(trackerEngine->contact_impl(id2, error).detail<QContactUrl>().url(), QString("http://work.homepage"));
678     QCOMPARE(trackerEngine->contact_impl(id3, error).detail<QContactUrl>().url(), QString("http://home.favourite"));
679
680     QVERIFY(trackerEngine->contact_impl(id1, error).detail<QContactUrl>().contexts()[0] ==
681             QContactDetail::ContextHome );
682     QVERIFY(trackerEngine->contact_impl(id2, error).detail<QContactUrl>().contexts()[0] ==
683             QContactDetail::ContextWork );
684     QVERIFY(trackerEngine->contact_impl(id3, error).detail<QContactUrl>().contexts()[0] ==
685             QContactDetail::ContextHome );
686
687     QVERIFY(trackerEngine->contact_impl(id1, error).detail<QContactUrl>().subType() ==
688             QContactUrl::SubTypeHomePage );
689     QVERIFY(trackerEngine->contact_impl(id2, error).detail<QContactUrl>().subType() ==
690             QContactUrl::SubTypeHomePage );
691     QVERIFY(trackerEngine->contact_impl(id3, error).detail<QContactUrl>().subType() ==
692             QContactUrl::SubTypeFavourite );
693
694 }
695
696 /*
697 void ut_qtcontacts_trackerplugin::testGroups()
698 {
699     qDebug() << "Not implemented";
700     QVERIFY(false);
701 }
702
703 void ut_qtcontacts_trackerplugin::testGroup()
704 {
705     qDebug() << "Not implemented";
706     QVERIFY(false);
707 }
708
709 void ut_qtcontacts_trackerplugin::testSaveGroup()
710 {
711     qDebug() << "Not implemented";
712     QVERIFY(false);
713 }
714
715 void ut_qtcontacts_trackerplugin::testRemoveGroup()
716 {
717     qDebug() << "Not implemented";
718     QVERIFY(false);
719 }
720
721 void ut_qtcontacts_trackerplugin::testDetailDefinitions()
722 {
723     qDebug() << "Not implemented";
724     QVERIFY(false);
725 }
726
727 void ut_qtcontacts_trackerplugin::testDetailDefinition()
728 {
729     qDebug() << "Not implemented";
730     QVERIFY(false);
731 }
732
733 void ut_qtcontacts_trackerplugin::testSaveDetailDefinition()
734 {
735     qDebug() << "Not implemented";
736     QVERIFY(false);
737 }
738
739 void ut_qtcontacts_trackerplugin::testRemoveDetailDefinition()
740 {
741     qDebug() << "Not implemented";
742     QVERIFY(false);
743 }
744 */
745
746 void ut_qtcontacts_trackerplugin::testSyncContactManagerContactsAddedSince()
747 {
748     // FIXME move this code out: not supposed to compile in and load the same code as dll plugin
749     QSKIP("Statically and dinamically linking the same code is not working", SkipAll);
750
751     QDateTime start;
752     QList<QContactLocalId> addedIds;
753     syncContactsAddedSinceHelper(start, addedIds);
754
755     QContactChangeLogFilter filter(QContactChangeLogFilter::EventAdded);
756     filter.setSince(start);
757
758     QList<QContactSortOrder> sortOrder;
759     
760     QList<QContact> contactIds = ContactManager::instance()->contacts( filter, sortOrder, QStringList() );
761     qDebug() << "addedIds" << addedIds.size();
762     qDebug() << "contactIds" << contactIds.size();
763     QVERIFY2( contactIds.size() == addedIds.size(), "Incorrect number of filtered contacts");
764 }
765
766 void ut_qtcontacts_trackerplugin::testSyncTrackerEngineContactsIdsAddedSince()
767 {
768     QDateTime start;
769     QList<QContactLocalId> addedIds;
770     syncContactsAddedSinceHelper(start, addedIds);
771
772     QContactChangeLogFilter filter(QContactChangeLogFilter::EventAdded);
773     filter.setSince(start);
774
775     QList<QContactSortOrder> sortOrder;
776     QContactManager::Error error;
777
778     QList<QContactLocalId> contactIds = trackerEngine->contactIds( filter, sortOrder, error );
779     qDebug() << "addedIds" << addedIds;
780     qDebug() << "contactIds" << contactIds;
781     QVERIFY2( contactIds.size() == addedIds.size(), "Incorrect number of filtered contacts");
782 }
783
784 void ut_qtcontacts_trackerplugin::testSyncContactManagerContactIdsAddedSince()
785 {
786     // FIXME move this code out: not supposed to compile in and load the same code as dll plugin
787     QSKIP("Statically and dinamically linking the same code is not working", SkipAll);
788     QDateTime start;
789     QList<QContactLocalId> addedIds;
790     syncContactsAddedSinceHelper(start, addedIds);
791     QContactChangeLogFilter filter(QContactChangeLogFilter::EventAdded);
792     filter.setSince(start);
793     QList<QContactSortOrder> sortOrder;
794
795
796     QList<QContactLocalId> contactIds = ContactManager::instance()->contactIds(filter, sortOrder);
797     qDebug() << "addedIds" << addedIds;
798     qDebug() << "contactIds" << contactIds;
799     QVERIFY2( contactIds.size() == addedIds.size(), "Incorrect number of filtered contacts");
800 }
801
802
803 void ut_qtcontacts_trackerplugin::syncContactsAddedSinceHelper(QDateTime& start, QList<QContactLocalId>& addedIds)
804 {
805     for (int i = 0; i < 3; i++) {
806         QContact c;
807         QContactName name;
808         name.setFirstName("A"+QString::number(i));
809         QVERIFY2(c.saveDetail(&name), "Failed to save detail");
810         QVERIFY2(trackerEngine->saveContact(&c, error), "Failed to save contact");
811     }
812
813     QTest::qWait(1000);
814     start = QDateTime::currentDateTime();
815
816     for (int i = 0; i < 3; i++) {
817         QContact c;
818         QContactName name;
819         name.setFirstName("B"+QString::number(i));
820         QVERIFY2(c.saveDetail(&name), "Failed to save detail");
821         QVERIFY2(trackerEngine->saveContact(&c, error), "Failed to save contact");
822         addedIds.append(c.localId());
823     }
824 }
825
826 void ut_qtcontacts_trackerplugin::testContactsAddedSince()
827 {
828     QList<QContactLocalId> addedIds;
829     QDateTime start;
830     for (int i = 0; i < 3; i++) {
831         QContact c;
832         QContactName name;
833         name.setFirstName("A"+QString::number(i));
834         QVERIFY2(c.saveDetail(&name), "Failed to save detail");
835         QVERIFY2(trackerEngine->saveContact(&c, error), "Failed to save contact");
836     }
837
838     QTest::qWait(1000);
839     start = QDateTime::currentDateTime();
840
841     for (int i = 0; i < 3; i++) {
842         QContact c;
843         QContactName name;
844         name.setFirstName("B"+QString::number(i));
845         QVERIFY2(c.saveDetail(&name), "Failed to save detail");
846         QVERIFY2(trackerEngine->saveContact(&c, error), "Failed to save contact");
847         addedIds.append(c.localId());
848     }
849
850     // now one asynchronous request to read all the
851     QContactFetchRequest request;
852     QContactChangeLogFilter filter(QContactChangeLogFilter::EventAdded);
853     filter.setSince(start);
854     request.setFilter(filter);
855
856     // here You specify which details are of interest
857     QStringList details;
858     details << QContactAvatar::DefinitionName
859             << QContactBirthday::DefinitionName
860             << QContactAddress::DefinitionName
861             << QContactEmailAddress::DefinitionName
862             << QContactDisplayLabel::DefinitionName
863             << QContactGender::DefinitionName
864             << QContactAnniversary::DefinitionName
865             << QContactName::DefinitionName
866             << QContactOnlineAccount::DefinitionName
867             << QContactOrganization::DefinitionName
868             << QContactPhoneNumber::DefinitionName;
869     request.setDefinitionRestrictions(details);
870
871     Slots slot;
872     QObject::connect(&request, SIGNAL(resultsAvailable()),
873             &slot, SLOT(resultsAvailable()));
874
875     // start. clients should, instead of following use
876     // request.setManager(trackermanagerinstance);
877     // request.start();
878     trackerEngine->startRequest(&request);
879     trackerEngine->waitForRequestFinished(&request, 10000);
880     // if it takes more, then something is wrong
881     QVERIFY(request.isFinished());
882     QCOMPARE(slot.contacts.count(), addedIds.count());
883
884     foreach(QContact cont, slot.contacts) {
885         QVERIFY2(addedIds.contains(cont.localId()), "One of the added contacts was not reported as added");
886     }
887
888     QContactLocalIdFetchRequest idreq;
889     filter.setSince(start);
890     idreq.setFilter(filter);
891
892     Slots slot2;
893     QObject::connect(&idreq, SIGNAL(resultsAvailable()),
894             &slot2, SLOT(idResultsAvailable()));
895     trackerEngine->startRequest(&idreq);
896     trackerEngine->waitForRequestFinished(&idreq, 10000);
897     QVERIFY(idreq.isFinished());
898     QCOMPARE(slot2.ids.count(), addedIds.count());
899     foreach(QContactLocalId id, slot2.ids) {
900         QVERIFY2(addedIds.contains(id), "One of the added contacts was not reported as added");
901     }
902
903 }
904
905 void ut_qtcontacts_trackerplugin::testContactsModifiedSince()
906 {
907     QDateTime start;
908     QList<QContactLocalId> addedIds;
909     QList<QContactLocalId> modified;
910
911     const int contactsToAdd = 5;
912     const int contactsToModify = 3;
913     QVERIFY2(contactsToAdd >= contactsToModify, "Cannot modify more contacts than this test has added");
914     QVERIFY2(contactsToModify+1 <= contactsToAdd, "Cannot modify more contacts than this test has added");
915
916     // Add contacts with only first name and store them to list of added
917     for (int i = 0; i < contactsToAdd; i++) {
918         QContact c;
919         QContactName name;
920         name.setFirstName("A"+QString::number(i));
921         QVERIFY2(c.saveDetail(&name), "Failed to save detail");
922         QVERIFY2(trackerEngine->saveContact(&c, error), "Failed to save contact");
923         addedIds.append(c.localId());
924     }
925
926     QTest::qWait(2000);
927     start = QDateTime::currentDateTime();
928
929    // Modify and save rest of the contacts
930     for (int i = 0; i < contactsToModify; i++) {
931         QContact c = trackerEngine->contact_impl(addedIds[i], error);
932         QContactName name = c.detail<QContactName>();
933         // Modify name
934         name.setFirstName("B"+QString::number(i));
935         QVERIFY2(c.saveDetail(&name), "Failed to save detail");
936         QVERIFY2(trackerEngine->saveContact(&c, error), "Failed to save contact");
937         modified.append(c.localId());
938     }
939     // Set filter
940     QContactChangeLogFilter filter(QContactChangeLogFilter::EventChanged);
941     filter.setSince(start);
942
943     QContactLocalIdFetchRequest idfetch;
944     QContactFetchRequest fetch;
945     idfetch.setFilter(filter);
946     fetch.setFilter(filter);
947     trackerEngine->startRequest(&idfetch);
948     trackerEngine->waitForRequestFinished(&idfetch, 10000);
949     QVERIFY2(idfetch.isFinished(), "Id fetch request did not finish on time");
950     QVERIFY2(idfetch.error() == QContactManager::NoError, "Id fetch request finished with errors");
951     QList<QContactLocalId> actuallyModifiedIds = idfetch.ids();
952     trackerEngine->startRequest(&fetch);
953     trackerEngine->waitForRequestFinished(&fetch, 10000);
954     QVERIFY2(fetch.isFinished(), "Fetch request did not finish on time");
955     QVERIFY2(fetch.error() == QContactManager::NoError, "Fetch request finished with errors");
956     QList<QContact> actuallyModified = fetch.contacts();
957
958     // Num of actually modified should be same as supposedly modified
959     QCOMPARE(actuallyModifiedIds.count(), modified.count());
960     QCOMPARE(actuallyModified.count(), modified.count());
961     // All the ids of the modified contacts should be found in the result list
962     foreach (QContactLocalId id, modified) {
963         QVERIFY2(actuallyModifiedIds.contains(id), "One the modified contacts was not reported as modified");
964     }
965 }
966
967 void ut_qtcontacts_trackerplugin::testContactsRemovedSince()
968 {
969     QDateTime start = QDateTime::currentDateTime();
970     QContactChangeLogFilter filter(QContactChangeLogFilter::EventRemoved);
971     filter.setSince(start);
972     QList<QContactSortOrder> sorts;
973     QList<QContactLocalId> actuallyRemoved = trackerEngine->contactIds(filter, sorts, error);
974     QVERIFY(actuallyRemoved.isEmpty());
975     QVERIFY(error == QContactManager::NotSupportedError);
976 }
977 /*
978 void ut_qtcontacts_trackerplugin::testGroupsAddedSince()
979 {
980     qDebug() << "Not implemented";
981     QVERIFY(false);
982 }
983
984 void ut_qtcontacts_trackerplugin::testGroupsModifiedSince()
985 {
986     qDebug() << "Not implemented";
987     QVERIFY(false);
988 }
989
990 void ut_qtcontacts_trackerplugin::testGroupsRemovedSince()
991 {
992     qDebug() << "Not implemented";
993     QVERIFY(false);
994 }
995 */
996
997 void ut_qtcontacts_trackerplugin::cleanupTestCase()
998 {
999     delete trackerEngine;
1000     delete errorMap;
1001 }
1002
1003 void ut_qtcontacts_trackerplugin::cleanup()
1004 {
1005     foreach (QContactLocalId id, addedContacts) {
1006         trackerEngine->removeContact(id, error);
1007     }
1008     addedContacts.clear();
1009 }
1010
1011
1012 void ut_qtcontacts_trackerplugin::testNcoTypes()
1013 {
1014     using namespace SopranoLive;
1015
1016     QList<QContactLocalId> ids;
1017     RDFVariable RDFContact = RDFVariable::fromType<nco::PersonContact>();
1018     RDFSelect query;
1019
1020     query.addColumn("contact_uri", RDFContact);
1021     query.addColumn("contactId", RDFContact.property<nco::contactUID>());
1022     LiveNodes ncoContacts = ::tracker()->modelQuery(query);
1023     foreach( Live<nco::PersonContact> p, ncoContacts ) {
1024         QVERIFY(p.hasType<nco::Contact>());
1025         QVERIFY(p.hasType<nco::Role>());
1026         QVERIFY(p.hasType<nco::PersonContact>());
1027     }
1028 }
1029
1030 void ut_qtcontacts_trackerplugin::testAsyncReadContacts()
1031 {
1032     addedContacts.clear();
1033     // Add at least one contact to be sure that this doesn't fail because tracker is clean
1034
1035     QStringList firstNames, lastNames;
1036     firstNames << "aa" << "ab" << "ac" << "dd" << "fe";
1037     lastNames << "fe" << "ab" << "dd" << "dd" << "aa";
1038     for (int i = 0; i < firstNames.count(); i++) {
1039         QContact c;
1040         QContactName name;
1041         name.setFirstName(firstNames.at(i));
1042         name.setLastName(lastNames.at(i));
1043         QContactAvatar avatar;
1044         avatar.setAvatar("default_avatar.png");
1045         avatar.setSubType(QContactAvatar::SubTypeImage);
1046         QVERIFY(c.saveDetail(&name));
1047         QVERIFY(c.saveDetail(&avatar));
1048         QVERIFY(trackerEngine->saveContact(&c, error));
1049         addedContacts.append(c.localId());
1050     }
1051     
1052     // Prepare the filter for the request - we really should test only the contact we add here.
1053     QContactLocalIdFilter filter;
1054     filter.setIds(addedContacts);
1055
1056     // this one will get complete contacts
1057
1058     Slots slot;
1059     QContactFetchRequest request;
1060     QList<QContactSortOrder> sorting;
1061     QContactSortOrder sort, sort1;
1062     sort.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldLast);
1063     sort1.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldFirst);
1064     sorting << sort << sort1;
1065     QStringList details; details << QContactName::DefinitionName << QContactAvatar::DefinitionName;
1066     request.setDefinitionRestrictions(details);
1067     request.setSorting(sorting);
1068     request.setFilter(filter);
1069
1070     QObject::connect(&request, SIGNAL(resultsAvailable()),
1071             &slot, SLOT(resultsAvailable()));
1072
1073     // this one only ids
1074     QContactLocalIdFetchRequest request1;
1075     request1.setFilter(filter);
1076     QObject::connect(&request1, SIGNAL(resultsAvailable()),
1077             &slot, SLOT(idResultsAvailable()));
1078
1079     // the purpose is to compare if all contacts are loaded, and
1080     // if optional fields are defined properly in request
1081
1082     // start both at once
1083     trackerEngine->startRequest(&request);
1084     trackerEngine->startRequest(&request1);
1085     trackerEngine->waitForRequestFinished(&request, 10000);
1086     trackerEngine->waitForRequestFinished(&request1, 10000);
1087
1088
1089     // if it takes more, then something is wrong
1090     QVERIFY(request.isFinished());
1091     QVERIFY(request1.isFinished());
1092
1093     // there need1 to be something added to be verified
1094     QVERIFY(!request.contacts().isEmpty());
1095     // now ask for one contact
1096     QVERIFY(!slot.contacts.isEmpty());
1097     // there need to be something added to be verified
1098     QVERIFY(!request1.ids().isEmpty());
1099     // now ask for one contact
1100     QVERIFY(!slot.ids.isEmpty());
1101
1102     QVERIFY2(slot.contacts.count() == slot.ids.count(), "not all contacts were loaded");
1103     QVERIFY(slot.contacts.count() >= firstNames.count());
1104     for( int i = 0; i < slot.contacts.size() -1 ; i++)
1105     {
1106         QContact contact = slot.contacts[i];
1107         QContact contact1 = slot.contacts[i+1];
1108         QString last0 = contact.detail<QContactName>().lastName();
1109         QString first0 = contact.detail<QContactName>().firstName();
1110         QString last1 = contact1.detail<QContactName>().lastName();
1111         QString first1 = contact1.detail<QContactName>().firstName();
1112         // sorting
1113         qDebug() << "contacts:" << contact.localId() << first0 << last0;
1114         bool test = last0 < last1 || (last0 == last1 && first0 <= first1);
1115         if (!test) {
1116             qDebug() << "contacts sort failed. First: " << contact1.localId() << first0 << last1 << "lasts: " << last0 << last1;
1117         }
1118         QVERIFY2(test, "Sorting failed.");
1119     }
1120
1121 }
1122
1123 void ut_qtcontacts_trackerplugin::testFilterContacts()
1124 {
1125     // this one will get complete contacts
1126     QContact c;
1127     QContactName name;
1128     name.setFirstName("Zuba");
1129     name.setLastName("Zub");
1130     c.saveDetail(&name);
1131     QContactPhoneNumber phone;
1132
1133     phone.setNumber("4872444");
1134     c.saveDetail(&phone);
1135
1136     QContactBirthday birthday;
1137     birthday.setDate(QDate(2010, 2, 14));
1138     c.saveDetail(&birthday);
1139
1140     trackerEngine->saveContact(&c, error);
1141
1142     QStringList details;
1143     details << QContactName::DefinitionName << QContactAvatar::DefinitionName
1144             << QContactPhoneNumber::DefinitionName;
1145
1146     QContactFetchRequest request;
1147     QContactDetailFilter filter;
1148     filter.setDetailDefinitionName(QContactPhoneNumber::DefinitionName, QContactPhoneNumber::FieldNumber);
1149
1150     Slots slot;
1151     QObject::connect(&request, SIGNAL(resultsAvailable()),
1152             &slot, SLOT(resultsAvailable()));
1153     filter.setValue(QString("4872444"));
1154     filter.setMatchFlags(QContactFilter::MatchEndsWith);
1155
1156     request.setDefinitionRestrictions(details);
1157     request.setFilter(filter);
1158
1159     trackerEngine->startRequest(&request);
1160
1161     for(int i = 0; i < 100; i++)
1162     {
1163         usleep(100000);
1164         QCoreApplication::processEvents();
1165         if(request.isFinished() )
1166             break;
1167     }
1168
1169     // if it takes more, then something is wrong
1170     QVERIFY(request.isFinished());
1171     QVERIFY(!request.contacts().isEmpty());
1172
1173     QVERIFY(!slot.contacts.isEmpty());
1174
1175     bool containsThisId = false;
1176     foreach(const QContact &contact, slot.contacts)
1177     {
1178         if( contact.localId() == c.localId())
1179             containsThisId = true;
1180         bool containsPhone = false;
1181         foreach(const QContactDetail &detail, contact.details(QContactPhoneNumber::DefinitionName))
1182         {
1183             if(detail.value(QContactPhoneNumber::FieldNumber).contains("4872444"))
1184             {
1185                 containsPhone = true;
1186                 break;
1187             }
1188         }
1189         QVERIFY(containsPhone);
1190     }
1191     QVERIFY(containsThisId);
1192
1193     // filter by birthday range
1194     QContactDetailRangeFilter rangeFilter;
1195     rangeFilter.setDetailDefinitionName(QContactBirthday::DefinitionName, QContactBirthday::FieldBirthday);
1196     // include lower & exclude upper by default
1197     rangeFilter.setRange(QDate(2010, 2, 14), QDate(2010, 2, 15));
1198     QList<QContact> contacts = trackerEngine->contacts(rangeFilter, QList<QContactSortOrder>(), QStringList()<< QContactBirthday::DefinitionName, error);
1199     QVERIFY(!contacts.isEmpty());
1200     bool containsOurContact(false);
1201     foreach(const QContact &cont, contacts)
1202     {
1203         QVERIFY(cont.detail<QContactBirthday>().date() == QDate(2010, 2, 14));
1204         if( c.id() == cont.id() )
1205             containsOurContact = true;
1206     }
1207     QVERIFY(containsOurContact);
1208 }
1209
1210 void ut_qtcontacts_trackerplugin::testFilterContactsEndsWith()
1211 {
1212     QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Nokia", "Trackerplugin");
1213     QString restoreValue = settings.value("phoneNumberMatchDigitCount", "7").toString();
1214
1215     QContact matchingContact;
1216     QContactName name;
1217     name.setFirstName("Zuba");
1218     name.setLastName("Zub");
1219     matchingContact.saveDetail(&name);
1220     QContactPhoneNumber phone;
1221     // TODO doesnt work yet phone.setContexts(QContactPhoneNumber::ContextWork);
1222     phone.setNumber("3210987654321");
1223     matchingContact.saveDetail(&phone);
1224     trackerEngine->saveContact(&matchingContact, error);
1225
1226     QStringList details;
1227     details << QContactName::DefinitionName << QContactAvatar::DefinitionName
1228             << QContactPhoneNumber::DefinitionName;
1229
1230     QContactFetchRequest request;
1231     QContactDetailFilter filter;
1232     filter.setDetailDefinitionName(QContactPhoneNumber::DefinitionName, QContactPhoneNumber::FieldNumber);
1233
1234     Slots slot;
1235     QObject::connect(&request, SIGNAL(resultsAvailable()),
1236             &slot, SLOT(resultsAvailable()));
1237
1238     {
1239         // test matching of 7 last digits
1240         int matchCount = 7;
1241         qDebug() << "Test matching of" << matchCount << "last digits.";
1242         settings.setValue("phoneNumberMatchDigitCount", matchCount);
1243         QString matchValue = "3000007654321";
1244         QContact nonMatchingContact;
1245         nonMatchingContact.saveDetail(&name);
1246         phone.setNumber("3210980654321");
1247         nonMatchingContact.saveDetail(&phone);
1248         trackerEngine->saveContact(&nonMatchingContact, error);
1249
1250         filter.setValue(matchValue);
1251         filter.setMatchFlags(QContactFilter::MatchEndsWith);
1252
1253         request.setDefinitionRestrictions(details);
1254         request.setFilter(filter);
1255
1256         trackerEngine->startRequest(&request);
1257
1258         for(int i = 0; i < 100; i++) {
1259             usleep(100000);
1260             QCoreApplication::processEvents();
1261             if (request.isFinished())
1262                 break;
1263         }
1264         QVERIFY(request.isFinished());
1265         QVERIFY(!slot.contacts.isEmpty());
1266
1267         bool containsMatchingId = false;
1268         bool containsNonMatchingId = false;
1269         foreach(const QContact &contact, slot.contacts) {
1270             if (contact.localId() == nonMatchingContact.localId())
1271                 containsNonMatchingId = true;
1272             if (contact.localId() == matchingContact.localId())
1273                 containsMatchingId = true;
1274             bool containsPhone = false;
1275             foreach(const QContactDetail &detail, contact.details(QContactPhoneNumber::DefinitionName)) {
1276                 if (detail.value(QContactPhoneNumber::FieldNumber).endsWith(matchValue.right(matchCount))) {
1277                     containsPhone = true;
1278                     break;
1279                 }
1280             }
1281             QVERIFY(containsPhone);
1282         }
1283         QVERIFY(containsMatchingId);
1284         QVERIFY(!containsNonMatchingId);
1285     }
1286
1287     {
1288         // test matching of 11 last digits
1289         int matchCount = 11;
1290         qDebug() << "Test matching of" << matchCount << "last digits.";
1291         settings.setValue("phoneNumberMatchDigitCount", matchCount);
1292         QString matchValue = "3010987654321";
1293         QContact nonMatchingContact;
1294         nonMatchingContact.saveDetail(&name);
1295         phone.setNumber("3200987654321");
1296         nonMatchingContact.saveDetail(&phone);
1297         trackerEngine->saveContact(&nonMatchingContact, error);
1298
1299         QContact matchingContactWithShorterNumber;
1300         QContactName name1;
1301         name1.setFirstName("ShortNumber");
1302         name1.setLastName("Zub1");
1303         matchingContactWithShorterNumber.saveDetail(&name1);
1304         QContactPhoneNumber phone1;
1305         phone1.setNumber("54321");
1306         matchingContactWithShorterNumber.saveDetail(&phone1);
1307         trackerEngine->saveContact(&matchingContactWithShorterNumber, error);
1308         QVERIFY(QContactManager::NoError == error);
1309
1310
1311         filter.setValue(matchValue);
1312         filter.setMatchFlags(QContactFilter::MatchEndsWith);
1313
1314         request.setDefinitionRestrictions(details);
1315         request.setFilter(filter);
1316
1317         trackerEngine->startRequest(&request);
1318
1319         for(int i = 0; i < 100; i++) {
1320             usleep(100000);
1321             QCoreApplication::processEvents();
1322             if (request.isFinished())
1323                 break;
1324         }
1325         QVERIFY(request.isFinished());
1326         QVERIFY(!slot.contacts.isEmpty());
1327
1328         bool containsMatchingId = false;
1329         bool containsNonMatchingId = false;
1330         foreach(const QContact &contact, slot.contacts) {
1331             if (contact.localId() == nonMatchingContact.localId())
1332                 containsNonMatchingId = true;
1333             if (contact.localId() == matchingContact.localId())
1334                 containsMatchingId = true;
1335             bool containsPhone = false;
1336             foreach(const QContactDetail &detail, contact.details(QContactPhoneNumber::DefinitionName)) {
1337                 if (detail.value(QContactPhoneNumber::FieldNumber).endsWith(matchValue.right(matchCount))) {
1338                     containsPhone = true;
1339                     break;
1340                 }
1341             }
1342             QVERIFY(containsPhone);
1343         }
1344         QVERIFY(containsMatchingId);
1345         QVERIFY(!containsNonMatchingId);
1346
1347         // now verify with short number
1348         filter.setValue("54321");
1349         filter.setMatchFlags(QContactFilter::MatchEndsWith);
1350
1351         request.setDefinitionRestrictions(details);
1352         request.setFilter(filter);
1353
1354         trackerEngine->startRequest(&request);
1355
1356         for(int i = 0; i < 100; i++) {
1357             usleep(100000);
1358             QCoreApplication::processEvents();
1359             if (request.isFinished())
1360                 break;
1361         }
1362         QVERIFY(request.isFinished());
1363         QVERIFY(!slot.contacts.isEmpty());
1364         bool containsShort = false;
1365         foreach(const QContact &contact, slot.contacts) {
1366             if (contact.localId() == matchingContactWithShorterNumber.localId())
1367                 containsShort = true;
1368         }
1369         QVERIFY(containsShort);
1370     }
1371     settings.setValue("phoneNumberMatchDigitCount", restoreValue);
1372 }
1373
1374 void ut_qtcontacts_trackerplugin::testFilterTwoNameFields()
1375 {
1376     // init test
1377     QMap<QContactLocalId, QContactName> names;
1378     for (int i = 0; i < 3; i++) {
1379         QContact c;
1380         QContactName name;
1381         name.setFirstName(QUuid::createUuid().toString() + QString::number(i));
1382         name.setLastName(QUuid::createUuid().toString() + QString::number(i));
1383         c.saveDetail(&name);
1384         QContactAvatar avatar;
1385         avatar.setAvatar(QUuid::createUuid().toString());
1386         c.saveDetail(&avatar);
1387         QVERIFY(trackerEngine->saveContact(&c, error));        
1388         names.insert(c.localId(), name);
1389         QCOMPARE(error, QContactManager::NoError);
1390         addedContacts.append(c.localId());
1391     }
1392
1393     // Init filter
1394     QContactLocalId searchId = names.keys().at(1);
1395     QString searchFirst = names.value(searchId).firstName();
1396     QString searchLast = names.value(searchId).lastName();
1397     QContactUnionFilter ufilter;
1398     QContactDetailFilter filterFirst;
1399     filterFirst.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldFirst);
1400     filterFirst.setMatchFlags(QContactFilter::MatchExactly);
1401     filterFirst.setValue(searchFirst);
1402     QContactDetailFilter filterLast;
1403     filterLast.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldLast);
1404     filterLast.setMatchFlags(QContactFilter::MatchExactly);
1405     filterLast.setValue(searchLast);
1406     ufilter.setFilters(QList<QContactFilter>() << filterFirst << filterLast);
1407
1408     // Init request
1409     QContactFetchRequest request;
1410     request.setFilter(ufilter);
1411     trackerEngine->startRequest(&request);
1412     trackerEngine->waitForRequestFinished(&request, 10000);
1413
1414
1415     // Test fetch result
1416     QCOMPARE(request.contacts().count(), 1);
1417     QCOMPARE(request.contacts().at(0).localId(), searchId);
1418     QCOMPARE(request.contacts().at(0).detail<QContactName>().firstName(), searchFirst);
1419     QCOMPARE(request.contacts().at(0).detail<QContactName>().lastName(), searchLast);
1420 }
1421
1422 void ut_qtcontacts_trackerplugin::testTrackerUriToUniqueId()
1423 {
1424     QString uri = "contact:1234567";
1425     QContactLocalId id = url2UniqueId( uri );
1426     QCOMPARE( (int)id, 1234567 );
1427 }
1428
1429 void ut_qtcontacts_trackerplugin::testQRelationshipAndMergingContacts()
1430 {
1431     QContact firstContact;
1432     QContactName name;
1433     name.setFirstName("FirstMeta");
1434     firstContact.saveDetail(&name);
1435     QVERIFY(trackerEngine->saveContact(&firstContact, error));
1436
1437     QList<QContactLocalId> secondIds;
1438     QStringList names(QStringList()<<"SecondMeta"<<"ThirdMeta");
1439     foreach (QString firstname, names)
1440     {
1441         QContact secondContact;
1442         QContactName name1;
1443         name1.setFirstName(firstname);
1444         secondContact.saveDetail(&name1);
1445         QVERIFY(trackerEngine->saveContact(&secondContact, error));
1446         secondIds<<secondContact.id().localId();
1447         QContactRelationship rel;
1448         rel.setRelationshipType(QContactRelationship::Is);
1449         rel.setFirst(firstContact.id());
1450         rel.setSecond(secondContact.id());
1451         QContactRelationshipSaveRequest req;
1452         req.setRelationships(QList<QContactRelationship>()<<rel);
1453         QVERIFY(trackerEngine->startRequest(&req));
1454         trackerEngine->waitForRequestFinished(&req, 10000);
1455         // if it takes more, then something is wrong
1456         QVERIFY(req.isFinished());
1457         QVERIFY(QContactManager::NoError == req.error());
1458     }
1459
1460     // once they are merged - that's it - no contacts or relationship track exists
1461     foreach( QContactLocalId mergedId, secondIds)
1462     {
1463         QContact second = contact(mergedId, QStringList()<<QContactName::DefinitionName);
1464         QVERIFY(second.localId() == 0); // as not existing
1465     }
1466     QVERIFY(contact(firstContact.localId(), QStringList()<<QContactName::DefinitionName).localId() != 0);
1467     // TODO check that values from secondids are merged to firstcontact
1468
1469 }
1470
1471 void ut_qtcontacts_trackerplugin::insertContact(const QString& URI, QContactLocalId uid, QString imId, QString imStatus, QString accountPath, QString protocol )
1472 {
1473     QProcess inserter;
1474     QStringList args;
1475     args << URI << QString::number(uid) << imId << accountPath << imStatus << "In Helsinki" << protocol << "Some" << "Guy";
1476     inserter.start( PATH_TO_SPARQL_TESTS+"/insertTpContact.sparql", args );
1477     inserter.waitForFinished();
1478 }
1479
1480 void ut_qtcontacts_trackerplugin::updateIMContactStatus(const QString& uri, QString imStatus)
1481 {
1482     QProcess inserter;
1483     QStringList args;
1484     args << uri << imStatus;
1485     inserter.start( PATH_TO_SPARQL_TESTS+"/updateTpStatus.sparql", args );
1486     inserter.waitForFinished();
1487 }
1488
1489 void ut_qtcontacts_trackerplugin::testMergeTwoOnlineContacts()
1490 {
1491     QList<QContact> contacts;
1492     for( int i = 0; i < 3; i++ )
1493     {
1494         unsigned int contactid = 555+i;
1495         insertContact(QString("contact:") + QString::number(contactid),
1496             contactid, QString::number(contactid)+ "@ovi.com", "nco:presence-status-available", QString("/org/freedesktop/fake/account/%1").arg(contactid),"ovi.com");
1497         QContact c = contact(contactid, QStringList()<<QContactOnlineAccount::DefinitionName);
1498         contacts << c;
1499     }
1500     QContactRelationship rel;
1501     rel.setFirst(contacts.at(0).id());
1502     rel.setSecond(contacts.at(1).id());
1503     QContactRelationship rel2;
1504     rel2.setFirst(contacts.at(0).id());
1505     rel2.setSecond(contacts.at(2).id());
1506     
1507     QContactRelationshipSaveRequest req;
1508     //TODO adding rel2 to the following causes segfault
1509     req.setRelationships(QList<QContactRelationship>()<<rel);
1510     QVERIFY(trackerEngine->startRequest(&req));
1511     trackerEngine->waitForRequestFinished(&req, 1000);
1512     QVERIFY(req.isFinished());
1513     QVERIFY(QContactManager::NoError == req.error());
1514     
1515     QList<QContactOnlineAccount> onlineAccounts = contacts.at(0).details<QContactOnlineAccount>();
1516     qDebug() << onlineAccounts.size();
1517     QEXPECT_FAIL("", "Do net yet support merging multiple im contacts", Continue);
1518     QVERIFY(onlineAccounts.size() == 2);
1519 }
1520
1521 void ut_qtcontacts_trackerplugin::testIMContactsAndMetacontactMasterPresence()
1522 {
1523     if( !QFileInfo(PATH_TO_SPARQL_TESTS).exists() )
1524     {
1525         qWarning()<<Q_FUNC_INFO<<"is disabled - test scripts are not installed";
1526         return;
1527     }
1528     QList<unsigned int> idstomerge;
1529     QContactLocalId masterContactId; // using one master contact later for additional testing
1530     for( int i = 0; i < 2; i++ )
1531     {
1532         unsigned int contactid = 999998+i;
1533         idstomerge << contactid;
1534         insertContact(QString("contact:") + QString::number(999998+i),
1535                 contactid, QString::number(999998 + i)+ "@ovi.com", "nco:presence-status-available", QString("/org/freedesktop/fake/account/%1").arg(999998+i),"ovi.com");
1536         QContact c = contact(contactid, QStringList()<<QContactOnlineAccount::DefinitionName);
1537         QVERIFY(c.localId() == contactid);
1538         QVERIFY(c.detail<QContactOnlineAccount>().serviceProvider() == "ovi.com");
1539         QContact firstContact;
1540         QContactName name;
1541         name.setFirstName("FirstMetaWithIM"+QString::number(contactid));
1542         firstContact.saveDetail(&name);
1543         QVERIFY(trackerEngine->saveContact(&firstContact, error));
1544
1545         // save metarelationship
1546         QContactRelationship rel;
1547         rel.setRelationshipType(QContactRelationship::Is);
1548         rel.setFirst(firstContact.id());
1549         masterContactId = firstContact.localId();
1550         rel.setSecond(c.id());
1551         QContactRelationshipSaveRequest req;
1552         req.setRelationships(QList<QContactRelationship>()<<rel);
1553         QVERIFY(trackerEngine->startRequest(&req));
1554         trackerEngine->waitForRequestFinished(&req, 1000);
1555         QVERIFY(req.isFinished());
1556         QVERIFY(QContactManager::NoError == req.error());
1557     }
1558
1559     // expected behavior - is that master contact contains all details aggregated
1560     {
1561         QList<QContact> cons = contacts(QList<QContactLocalId> ()
1562                 << masterContactId << 999999, QStringList()
1563                 << QContactOnlineAccount::DefinitionName);
1564         QVERIFY(cons.size() == 1);
1565         QVERIFY(cons[0].id().localId() == masterContactId);
1566
1567         bool containDetail = false;
1568         foreach(QContactOnlineAccount det, cons[0].details<QContactOnlineAccount>())
1569             {
1570                 if (det.value("Account") == "999999@ovi.com" // deprecated, going to account URI
1571                         || det.accountUri() == "999999@ovi.com")
1572                 {
1573                     QVERIFY(det.presence() == QContactOnlineAccount::PresenceAvailable);
1574                     containDetail = true;
1575                 }
1576             }
1577         QVERIFY(containDetail);
1578     }
1579     //now update presence to IM Address and check it in contact (TODO and if signal is emitted)
1580     updateIMContactStatus("telepathy:/org/freedesktop/fake/account/999999/999999@ovi.com", "nco:presence-status-offline");
1581     {
1582         QList<QContact> cons = contacts(QList<QContactLocalId> ()
1583                 << masterContactId << 999999, QStringList()
1584                 << QContactOnlineAccount::DefinitionName);
1585         QVERIFY(cons.size() == 1);
1586         QVERIFY(cons[0].id().localId() == masterContactId);
1587
1588         bool containDetail = false;
1589         foreach(QContactOnlineAccount det, cons[0].details<QContactOnlineAccount>())
1590             {
1591                 if (det.value("Account") == "999999@ovi.com" // deprecated, going to account URI
1592                         || det.accountUri() == "999999@ovi.com")
1593                 {
1594                     QVERIFY(det.presence() == QContactOnlineAccount::PresenceOffline);
1595                     containDetail = true;
1596                 }
1597             }
1598         QVERIFY(containDetail);
1599     }
1600
1601     // load contact should load also all merged content from other contacts (that dont exis anymore)
1602     {
1603         QList<QContact> cons = contacts(QList<QContactLocalId> ()
1604                 << masterContactId, QStringList()
1605                 << QContactOnlineAccount::DefinitionName);
1606         QVERIFY(cons.size() == 1);
1607         QVERIFY(cons[0].id().localId() == masterContactId);
1608
1609         bool containDetail = false;
1610         foreach(QContactOnlineAccount det, cons[0].details<QContactOnlineAccount>())
1611             {
1612                 if (det.value("Account") == "999999@ovi.com" // deprecated, going to account URI
1613                         || det.accountUri() == "999999@ovi.com")
1614                 {
1615                     QVERIFY(det.presence() == QContactOnlineAccount::PresenceOffline);
1616                     containDetail = true;
1617                 }
1618             }
1619         QVERIFY(containDetail);
1620     }
1621
1622     // remove them
1623     QVERIFY2(trackerEngine->removeContact(masterContactId, error), "Removing a contact failed");
1624
1625     foreach(unsigned int id, idstomerge)
1626     {
1627         QVERIFY2(!trackerEngine->removeContact(id, error), "Merged contact doesn't exist and removing it shoudl fail");
1628     }
1629 }
1630
1631 void ut_qtcontacts_trackerplugin::testIMContactsFilterring()
1632 {
1633     QList<unsigned int> idstoremove;
1634     QList<QContactLocalId> idsToRetrieveThroughFilter;
1635     for( int i = 0; i < 3; i++ )
1636     {
1637         unsigned int contactid = qHash(QString("/org/freedesktop/fake/account/") + QString::number(999995+i) + "@ovi.com");
1638         idstoremove << contactid;
1639         insertContact(QString("telepathy:/org/freedesktop/fake/account/") + QString::number(999995+i) + "@ovi.com",
1640                 contactid, QString::number(999995 + i)+ "@ovi.com", "nco:presence-status-available",
1641                 QString("/org/freedesktop/fake/account/%1").arg(i/2), QString("ovi%1.com").arg(i/2));
1642         if(!i/2)
1643             idsToRetrieveThroughFilter << contactid;
1644     }
1645
1646     {
1647     // now filter by service provider ovi0.com needs to return 2 contacts, 999995 & 999996
1648     QList<QContactLocalId> ids(idsToRetrieveThroughFilter);
1649
1650     QContactFetchRequest request;
1651     QContactDetailFilter filter;
1652     filter.setDetailDefinitionName(QContactOnlineAccount::DefinitionName, QContactOnlineAccount::FieldServiceProvider);
1653
1654     Slots slot;
1655     QObject::connect(&request, SIGNAL(resultsAvailable()),
1656             &slot, SLOT(resultsAvailable()));
1657     filter.setValue(QString("ovi0.com"));
1658     filter.setMatchFlags(QContactFilter::MatchExactly);
1659
1660     request.setDefinitionRestrictions(QStringList()<<QContactOnlineAccount::DefinitionName);
1661     request.setFilter(filter);
1662
1663     trackerEngine->startRequest(&request);
1664
1665     for(int i = 0; i < 100; i++)
1666     {
1667         usleep(100000);
1668         QCoreApplication::processEvents();
1669         if(request.isFinished() )
1670             break;
1671     }
1672
1673     // if it takes more, then something is wrong
1674     QVERIFY(request.isFinished());
1675     QVERIFY(!request.contacts().isEmpty());
1676
1677     QVERIFY(request.contacts().size() >= 2);
1678     foreach(const QContact &contact, request.contacts())
1679     {
1680         //qDebug() << contact.localId()<< "acc"<<contact.detail<QContactOnlineAccount>().serviceProvider();
1681         QVERIFY(contact.detail<QContactOnlineAccount>().serviceProvider() == "ovi0.com");
1682         ids.removeOne(contact.localId());
1683     }
1684     QVERIFY(ids.isEmpty());
1685     }
1686
1687     // now account path filter
1688     {
1689     // now filter by account path 999995 & 999996
1690     QList<QContactLocalId> ids(idsToRetrieveThroughFilter);
1691
1692     QContactFetchRequest request;
1693     QContactDetailFilter filter;
1694     filter.setDetailDefinitionName(QContactOnlineAccount::DefinitionName, "AccountPath");
1695
1696     Slots slot;
1697     QObject::connect(&request, SIGNAL(resultsAvailable()),
1698             &slot, SLOT(resultsAvailable()));
1699     // see insertTpContact
1700     filter.setValue(QString("/org/freedesktop/fake/account/0"));
1701     filter.setMatchFlags(QContactFilter::MatchExactly);
1702
1703     request.setDefinitionRestrictions(QStringList()<<QContactOnlineAccount::DefinitionName);
1704     request.setFilter(filter);
1705
1706     trackerEngine->startRequest(&request);
1707
1708     for(int i = 0; i < 100; i++)
1709     {
1710         usleep(100000);
1711         QCoreApplication::processEvents();
1712         if(request.isFinished() )
1713             break;
1714     }
1715
1716     // if it takes more, then something is wrong
1717     QVERIFY(request.isFinished());
1718     QVERIFY(!request.contacts().isEmpty());
1719
1720     QVERIFY(request.contacts().size() >= 2);
1721     foreach(const QContact &contact, request.contacts())
1722     {
1723         QVERIFY(contact.detail<QContactOnlineAccount>().serviceProvider() == "ovi0.com");
1724         ids.removeOne(contact.localId());
1725     }
1726     QVERIFY(ids.isEmpty());
1727     }
1728
1729
1730     // remove them
1731     foreach(unsigned int id, idstoremove)
1732     {
1733         QVERIFY2(trackerEngine->removeContact(id, error), "Removing a contact failed");
1734     }
1735
1736 }
1737
1738 void ut_qtcontacts_trackerplugin::testContactsWithoutMeContact() {
1739     QContact c;
1740     QContactName name;
1741     name.setFirstName("Totally");
1742     name.setLastName("Unique");
1743     c.saveDetail(&name);
1744     trackerEngine->saveContact(&c, error);
1745     QContactLocalId id = c.localId();  // Store ID for later removal. 
1746     
1747     // Prepare the filter for the request - we fetch only the one contact saved above.
1748     QList<QContactLocalId> ids;
1749     ids << id;
1750     QContactLocalIdFilter filter;
1751     filter.setIds(ids);
1752     
1753     // Prepare the requst - give filter to it and specify which fields to fetch. We fetch only the name.
1754     QStringList details;
1755     details << QContactName::DefinitionName;
1756
1757     QContactLocalIdFetchRequest nameFetchRequest;
1758     nameFetchRequest.setFilter(filter);
1759
1760     // Start the request and wait for it to finish.
1761     trackerEngine->startRequest(&nameFetchRequest);
1762     trackerEngine->waitForRequestFinished(&nameFetchRequest, 1000);
1763
1764     // Requst finished. Test that only one contact is removed.
1765     QList<QContactLocalId> contacts = nameFetchRequest.ids();
1766     QVERIFY2(contacts.count() < 2, "We expected to get only one contact. Got more.");
1767     QVERIFY2(contacts.count() != 0, "We expected to get one contact. Got none.");
1768     QVERIFY2(contacts.first() == id, "Did not get the requested contact back.");
1769     
1770     // Cleaning up.
1771     trackerEngine->removeContact(id, error);
1772
1773 }
1774
1775 /***************************     Helper functions for unit tests   ***************'*/
1776
1777 QContact ut_qtcontacts_trackerplugin::contact(QContactLocalId id, QStringList details)
1778 {
1779     QList<QContact> conts = contacts(QList<QContactLocalId>()<<id, details);
1780     return conts.size()?conts[0]:QContact();
1781 }
1782
1783 QList<QContact> ut_qtcontacts_trackerplugin::contacts(QList<QContactLocalId> ids, QStringList details)
1784 {
1785     QContactFetchRequest request;
1786     QContactLocalIdFilter filter;
1787     filter.setIds(ids);
1788     request.setFilter(filter);
1789
1790     request.setDefinitionRestrictions(details);
1791
1792     trackerEngine->startRequest(&request);
1793     trackerEngine->waitForRequestFinished(&request, 1000);
1794
1795     return request.contacts();
1796 }
1797
1798 void Slots::idResultsAvailable()
1799 {
1800     QContactLocalIdFetchRequest* self = qobject_cast<QContactLocalIdFetchRequest*>(sender());
1801     ids << self->ids();
1802 }
1803
1804 void Slots::resultsAvailable()
1805 {
1806     QContactFetchRequest* self = qobject_cast<QContactFetchRequest*>(sender());
1807     contacts = self->contacts();
1808     QList<QContactLocalId> idsFromAllContactReq;
1809     foreach( QContact contact, contacts)
1810     {
1811         idsFromAllContactReq << contact.localId();
1812     }
1813 }
1814
1815 QTEST_MAIN(ut_qtcontacts_trackerplugin)