qtmobility/tests/auto/qcontactmanager/tst_qcontactmanager.cpp
changeset 5 453da2cfceef
parent 4 90517678cc4f
child 11 06b8e2af4411
equal deleted inserted replaced
4:90517678cc4f 5:453da2cfceef
   106 /* A class that no backend can support */
   106 /* A class that no backend can support */
   107 class UnsupportedMetatype {
   107 class UnsupportedMetatype {
   108     int foo;
   108     int foo;
   109 };
   109 };
   110 Q_DECLARE_METATYPE(UnsupportedMetatype)
   110 Q_DECLARE_METATYPE(UnsupportedMetatype)
       
   111 Q_DECLARE_METATYPE(QContact)
       
   112 Q_DECLARE_METATYPE(QContactManager::Error)
   111 
   113 
   112 class tst_QContactManager : public QObject
   114 class tst_QContactManager : public QObject
   113 {
   115 {
   114 Q_OBJECT
   116 Q_OBJECT
   115 
   117 
   125     QList<QContactDetail> removeAllDefaultDetails(const QList<QContactDetail>& details);
   127     QList<QContactDetail> removeAllDefaultDetails(const QList<QContactDetail>& details);
   126     void addManagers(); // add standard managers to the data
   128     void addManagers(); // add standard managers to the data
   127     QContact createContact(QContactDetailDefinition nameDef, QString firstName, QString lastName, QString phoneNumber);
   129     QContact createContact(QContactDetailDefinition nameDef, QString firstName, QString lastName, QString phoneNumber);
   128     void saveContactName(QContact *contact, QContactDetailDefinition nameDef, QContactName *contactName, const QString &name) const;
   130     void saveContactName(QContact *contact, QContactDetailDefinition nameDef, QContactName *contactName, const QString &name) const;
   129 
   131 
   130     QContactManagerDataHolder managerDataHolder;
   132     QScopedPointer<QContactManagerDataHolder> managerDataHolder;
   131 
   133 
   132 public slots:
   134 public slots:
   133     void init();
   135     void initTestCase();
   134     void cleanup();
   136     void cleanupTestCase();
   135 private slots:
   137 private slots:
   136 
   138 
   137     void doDump();
   139     void doDump();
   138     void doDump_data() {addManagers();}
   140     void doDump_data() {addManagers();}
   139 
   141 
   141     void doDumpSchema_data() {addManagers();}
   143     void doDumpSchema_data() {addManagers();}
   142 
   144 
   143     /* Special test with special data */
   145     /* Special test with special data */
   144     void uriParsing();
   146     void uriParsing();
   145     void nameSynthesis();
   147     void nameSynthesis();
       
   148     void compatibleContact();
   146 
   149 
   147     /* Tests that are run on all managers */
   150     /* Tests that are run on all managers */
   148     void metadata();
   151     void metadata();
   149     void nullIdOperations();
   152     void nullIdOperations();
   150     void add();
   153     void add();
   165     void errorStayingPut();
   168     void errorStayingPut();
   166     void ctors();
   169     void ctors();
   167     void invalidManager();
   170     void invalidManager();
   168     void memoryManager();
   171     void memoryManager();
   169     void changeSet();
   172     void changeSet();
   170 
   173     void fetchHint();
   171     /* data providers (mostly all engines) */
   174 
   172     void uriParsing_data(); // Special data
   175     /* Special test with special data */
   173     void nameSynthesis_data(); // Special data
   176     void uriParsing_data();
       
   177     void nameSynthesis_data();
       
   178     void compatibleContact_data();
       
   179     /* Tests that are run on all managers */
   174     void metadata_data() {addManagers();}
   180     void metadata_data() {addManagers();}
   175     void nullIdOperations_data() {addManagers();}
   181     void nullIdOperations_data() {addManagers();}
   176     void add_data() {addManagers();}
   182     void add_data() {addManagers();}
   177     void update_data() {addManagers();}
   183     void update_data() {addManagers();}
   178     void remove_data() {addManagers();}
   184     void remove_data() {addManagers();}
   193 
   199 
   194 tst_QContactManager::~tst_QContactManager()
   200 tst_QContactManager::~tst_QContactManager()
   195 {
   201 {
   196 }
   202 }
   197 
   203 
   198 void tst_QContactManager::init()
   204 void tst_QContactManager::initTestCase()
   199 {
   205 {
       
   206     managerDataHolder.reset(new QContactManagerDataHolder());
       
   207 
   200     /* Make sure these other test plugins are NOT loaded by default */
   208     /* Make sure these other test plugins are NOT loaded by default */
   201     // These are now removed from the list of managers in addManagers()
   209     // These are now removed from the list of managers in addManagers()
   202     //QVERIFY(!QContactManager::availableManagers().contains("testdummy"));
   210     //QVERIFY(!QContactManager::availableManagers().contains("testdummy"));
   203     //QVERIFY(!QContactManager::availableManagers().contains("teststaticdummy"));
   211     //QVERIFY(!QContactManager::availableManagers().contains("teststaticdummy"));
   204     //QVERIFY(!QContactManager::availableManagers().contains("maliciousplugin"));
   212     //QVERIFY(!QContactManager::availableManagers().contains("maliciousplugin"));
   205 }
   213 }
   206 
   214 
   207 void tst_QContactManager::cleanup()
   215 void tst_QContactManager::cleanupTestCase()
   208 {
   216 {
       
   217     managerDataHolder.reset(0);
   209 }
   218 }
   210 
   219 
   211 void tst_QContactManager::dumpContactDifferences(const QContact& ca, const QContact& cb)
   220 void tst_QContactManager::dumpContactDifferences(const QContact& ca, const QContact& cb)
   212 {
   221 {
   213     // Try to narrow down the differences
   222     // Try to narrow down the differences
   291                 break;
   300                 break;
   292             }
   301             }
   293         }
   302         }
   294     }
   303     }
   295 
   304 
       
   305     // Second remove any superset matches (eg, backend adds a field)
       
   306     aDetails = a.details();
       
   307     bDetails = b.details();
       
   308     foreach (QContactDetail d, aDetails) {
       
   309         foreach (QContactDetail d2, bDetails) {
       
   310             if (d.definitionName() == d2.definitionName()) {
       
   311                 bool canRemove = true;
       
   312                 QMap<QString, QVariant> d2map = d2.variantValues();
       
   313                 foreach (QString key, d2map.keys()) {
       
   314                     if (d.value(key) != d2.value(key)) {
       
   315                         // d can have _more_ keys than d2,
       
   316                         // but not _less_; and it cannot
       
   317                         // change the value.
       
   318                         canRemove = false;
       
   319                     }
       
   320                 }
       
   321 
       
   322                 if (canRemove) {
       
   323                     // if we get to here, we can remove the details.
       
   324                     a.removeDetail(&d);
       
   325                     b.removeDetail(&d2);
       
   326                     break;
       
   327                 }
       
   328             }
       
   329         }
       
   330     }
       
   331 
   296     // check for contact type updates
   332     // check for contact type updates
   297     if (!a.type().isEmpty())
   333     if (!a.type().isEmpty())
   298         if (!b.type().isEmpty())
   334         if (!b.type().isEmpty())
   299             if (a.type() != b.type())
   335             if (a.type() != b.type())
   300                 return false; // nonempty type is different.
   336                 return false; // nonempty type is different.
   309 }
   345 }
   310 
   346 
   311 void tst_QContactManager::dumpContact(const QContact& contact)
   347 void tst_QContactManager::dumpContact(const QContact& contact)
   312 {
   348 {
   313     QContactManager m;
   349     QContactManager m;
   314     qDebug() << "Contact: " << contact.id().localId() << "(" << m.synthesizedDisplayLabel(contact) << ")";
   350     qDebug() << "Contact: " << contact.id().localId() << "(" << m.synthesizedContactDisplayLabel(contact) << ")";
   315     QList<QContactDetail> details = contact.details();
   351     QList<QContactDetail> details = contact.details();
   316     foreach(QContactDetail d, details) {
   352     foreach(QContactDetail d, details) {
   317         qDebug() << "  " << d.definitionName() << ":";
   353         qDebug() << "  " << d.definitionName() << ":";
   318         qDebug() << "    Vals:" << d.variantValues();
   354         qDebug() << "    Vals:" << d.variantValues();
   319     }
   355     }
   701     QContact alice = createContact(nameDef, "Alice", "inWonderland", "1234567");
   737     QContact alice = createContact(nameDef, "Alice", "inWonderland", "1234567");
   702     int currCount = cm->contactIds().count();
   738     int currCount = cm->contactIds().count();
   703     QVERIFY(cm->saveContact(&alice));
   739     QVERIFY(cm->saveContact(&alice));
   704     QVERIFY(cm->error() == QContactManager::NoError);
   740     QVERIFY(cm->error() == QContactManager::NoError);
   705 
   741 
   706     QVERIFY(alice.id() != QContactId());
   742     QVERIFY(!alice.id().managerUri().isEmpty());
       
   743     QVERIFY(alice.id().localId() != 0);
   707     QCOMPARE(cm->contactIds().count(), currCount+1);
   744     QCOMPARE(cm->contactIds().count(), currCount+1);
   708 
   745 
   709     QContact added = cm->contact(alice.id().localId());
   746     QContact added = cm->contact(alice.id().localId());
   710     QVERIFY(added.id() != QContactId());
       
   711     QVERIFY(added.id() == alice.id());
   747     QVERIFY(added.id() == alice.id());
   712     
   748     
   713     if (!isSuperset(added, alice)) {
   749     if (!isSuperset(added, alice)) {
   714         dumpContacts(cm.data());
   750         dumpContacts(cm.data());
   715         dumpContactDifferences(added, alice);
   751         dumpContactDifferences(added, alice);
   746         // XXX FIXME: access constraint reporting as moved to the detail itself
   782         // XXX FIXME: access constraint reporting as moved to the detail itself
   747         //if (def.accessConstraint() == QContactDetailDefinition::ReadOnly) {
   783         //if (def.accessConstraint() == QContactDetailDefinition::ReadOnly) {
   748         //    continue;
   784         //    continue;
   749         //}
   785         //}
   750 
   786 
       
   787         if (cm->managerName() == "maemo5") {
       
   788             // The maemo5 backend only supports reading of Guid and QCOA
       
   789             if (def.name() == QContactGuid::DefinitionName)
       
   790                 continue;
       
   791             if (def.name() == QContactOnlineAccount::DefinitionName)
       
   792                 continue;
       
   793         }
       
   794 
       
   795         // This is probably read-only
       
   796         if (def.name() == QContactTimestamp::DefinitionName)
       
   797             continue;
       
   798 
   751         // otherwise, create a new detail of the given type and save it to the contact
   799         // otherwise, create a new detail of the given type and save it to the contact
   752         QContactDetail det(def.name());
   800         QContactDetail det(def.name());
   753         QMap<QString, QContactDetailFieldDefinition> fieldmap = def.fields();
   801         QMap<QString, QContactDetailFieldDefinition> fieldmap = def.fields();
   754         QStringList fieldKeys = fieldmap.keys();
   802         QStringList fieldKeys = fieldmap.keys();
   755         foreach (const QString& fieldKey, fieldKeys) {
   803         foreach (const QString& fieldKey, fieldKeys) {
   756             // get the field, and check to see that it's not constrained.
   804             // get the field, and check to see that it's not constrained.
   757             QContactDetailFieldDefinition currentField = fieldmap.value(fieldKey);
   805             QContactDetailFieldDefinition currentField = fieldmap.value(fieldKey);
   758             
   806             
       
   807             // Don't test detail uris as these are manager specific
       
   808             if (fieldKey == QContactDetail::FieldDetailUri)
       
   809                 continue;
       
   810 
   759             // Special case: phone number.
   811             // Special case: phone number.
   760             if (def.name() == QContactPhoneNumber::DefinitionName &&
   812             if (def.name() == QContactPhoneNumber::DefinitionName &&
   761                 fieldKey == QContactPhoneNumber::FieldNumber) {
   813                 fieldKey == QContactPhoneNumber::FieldNumber) {
   762                 det.setValue(fieldKey, "+3581234567890");
   814                 det.setValue(fieldKey, "+3581234567890");
   763                 continue;
   815                 continue;
   808                 }
   860                 }
   809 
   861 
   810                 // if we get here, we don't know what sort of value can be saved...
   862                 // if we get here, we don't know what sort of value can be saved...
   811             }
   863             }
   812         }
   864         }
   813         megacontact.saveDetail(&det);
   865         if (!det.isEmpty())
       
   866             megacontact.saveDetail(&det);
   814     }
   867     }
   815 
   868 
   816     QVERIFY(cm->saveContact(&megacontact)); // must be able to save since built from definitions.
   869     QVERIFY(cm->saveContact(&megacontact)); // must be able to save since built from definitions.
   817     QContact retrievedMegacontact = cm->contact(megacontact.id().localId());
   870     QContact retrievedMegacontact = cm->contact(megacontact.id().localId());
   818     if (retrievedMegacontact != megacontact) {
   871     if (!isSuperset(retrievedMegacontact, megacontact)) {
   819         dumpContactDifferences(megacontact, retrievedMegacontact);
   872         dumpContactDifferences(megacontact, retrievedMegacontact);
   820         QEXPECT_FAIL("mgr='wince'", "Address Display Label mismatch", Continue);
   873         QEXPECT_FAIL("mgr='wince'", "Address Display Label mismatch", Continue);
   821         QCOMPARE(megacontact, retrievedMegacontact);
   874         QCOMPARE(megacontact, retrievedMegacontact);
   822     }
   875     }
   823 
   876 
   843     else {
   896     else {
   844         QVERIFY(cm->saveContact(&veryContactable));
   897         QVERIFY(cm->saveContact(&veryContactable));
   845         
   898         
   846         // verify save
   899         // verify save
   847         QContact retrievedContactable = cm->contact(veryContactable.id().localId());
   900         QContact retrievedContactable = cm->contact(veryContactable.id().localId());
   848         if (retrievedContactable != veryContactable) {
   901         if (!isSuperset(retrievedContactable, veryContactable)) {
   849             dumpContactDifferences(veryContactable, retrievedContactable);
   902             dumpContactDifferences(veryContactable, retrievedContactable);
   850             QEXPECT_FAIL("mgr='wince'", "Number of phones supported mismatch", Continue);
   903             QEXPECT_FAIL("mgr='wince'", "Number of phones supported mismatch", Continue);
   851             QCOMPARE(veryContactable, retrievedContactable);
   904             QCOMPARE(veryContactable, retrievedContactable);
   852         }
   905         }
   853     }
   906     }
  1144     QContact foo;
  1197     QContact foo;
  1145     QContactName nf;
  1198     QContactName nf;
  1146     nf.setLastName("Lastname");
  1199     nf.setLastName("Lastname");
  1147     foo.saveDetail(&nf);
  1200     foo.saveDetail(&nf);
  1148 
  1201 
  1149     QVERIFY(manager.synthesizedDisplayLabel(foo).isEmpty());
  1202     QVERIFY(manager.synthesizedContactDisplayLabel(foo).isEmpty());
  1150     QVERIFY(manager.error() == QContactManager::NotSupportedError);
  1203     QVERIFY(manager.error() == QContactManager::NotSupportedError);
  1151 
  1204 
  1152     QVERIFY(manager.saveContact(&foo) == false);
  1205     QVERIFY(manager.saveContact(&foo) == false);
  1153     QVERIFY(manager.error() == QContactManager::NotSupportedError);
  1206     QVERIFY(manager.error() == QContactManager::NotSupportedError);
  1154     QVERIFY(foo.id() == QContactId());
  1207     QVERIFY(foo.id() == QContactId());
  1592         c.saveDetail(&org);
  1645         c.saveDetail(&org);
  1593     if (addcompany2)
  1646     if (addcompany2)
  1594         c.saveDetail(&org2);
  1647         c.saveDetail(&org2);
  1595 
  1648 
  1596     // Finally!
  1649     // Finally!
  1597     QCOMPARE(cm.synthesizedDisplayLabel(c), expected);
  1650     QCOMPARE(cm.synthesizedContactDisplayLabel(c), expected);
       
  1651 }
       
  1652 
       
  1653 void tst_QContactManager::compatibleContact_data()
       
  1654 {
       
  1655     QTest::addColumn<QContact>("input");
       
  1656     QTest::addColumn<QContact>("expected");
       
  1657     QTest::addColumn<QContactManager::Error>("error");
       
  1658 
       
  1659     QContact baseContact;
       
  1660     QContactName name;
       
  1661     name.setFirstName(QLatin1String("First"));
       
  1662     baseContact.saveDetail(&name);
       
  1663 
       
  1664     {
       
  1665         QTest::newRow("already compatible") << baseContact << baseContact << QContactManager::NoError;
       
  1666     }
       
  1667 
       
  1668     {
       
  1669         QContact contact(baseContact);
       
  1670         QContactDetail detail("UnknownDetail");
       
  1671         detail.setValue("Key", QLatin1String("Value"));
       
  1672         contact.saveDetail(&detail);
       
  1673         QTest::newRow("unknown detail") << contact << baseContact << QContactManager::NoError;
       
  1674     }
       
  1675 
       
  1676     {
       
  1677         QContact contact(baseContact);
       
  1678         QContactType type1;
       
  1679         type1.setType(QContactType::TypeContact);
       
  1680         contact.saveDetail(&type1);
       
  1681         QContactType type2;
       
  1682         type2.setType(QContactType::TypeGroup);
       
  1683         contact.saveDetail(&type2);
       
  1684         QContact expected(baseContact);
       
  1685         expected.saveDetail(&type2);
       
  1686         QTest::newRow("duplicate unique field") << contact << expected << QContactManager::NoError;
       
  1687     }
       
  1688 
       
  1689     {
       
  1690         QContact contact(baseContact);
       
  1691         QContactPhoneNumber phoneNumber;
       
  1692         phoneNumber.setValue("UnknownKey", "Value");
       
  1693         contact.saveDetail(&phoneNumber);
       
  1694         QTest::newRow("unknown field") << contact << baseContact << QContactManager::NoError;
       
  1695     }
       
  1696 
       
  1697     {
       
  1698         QContact contact(baseContact);
       
  1699         QContactDisplayLabel displayLabel;
       
  1700         displayLabel.setValue(QContactDisplayLabel::FieldLabel, QStringList("Value"));
       
  1701         contact.saveDetail(&displayLabel);
       
  1702         QTest::newRow("wrong type") << contact << baseContact << QContactManager::NoError;
       
  1703     }
       
  1704 
       
  1705     {
       
  1706         QContact contact(baseContact);
       
  1707         QContactPhoneNumber phoneNumber1;
       
  1708         phoneNumber1.setNumber(QLatin1String("1234"));
       
  1709         phoneNumber1.setSubTypes(QStringList()
       
  1710                                 << QContactPhoneNumber::SubTypeMobile
       
  1711                                 << QContactPhoneNumber::SubTypeVoice
       
  1712                                 << QLatin1String("InvalidSubtype"));
       
  1713         contact.saveDetail(&phoneNumber1);
       
  1714         QContact expected(baseContact);
       
  1715         QContactPhoneNumber phoneNumber2;
       
  1716         phoneNumber2.setNumber(QLatin1String("1234"));
       
  1717         phoneNumber2.setSubTypes(QStringList()
       
  1718                                 << QContactPhoneNumber::SubTypeMobile
       
  1719                                 << QContactPhoneNumber::SubTypeVoice);
       
  1720         expected.saveDetail(&phoneNumber2);
       
  1721         QTest::newRow("bad value (list)") << contact << expected << QContactManager::NoError;
       
  1722     }
       
  1723 
       
  1724     {
       
  1725         QContact contact(baseContact);
       
  1726         QContactPhoneNumber phoneNumber1;
       
  1727         phoneNumber1.setNumber(QLatin1String("1234"));
       
  1728         phoneNumber1.setSubTypes(QStringList(QLatin1String("InvalidSubtype")));
       
  1729         contact.saveDetail(&phoneNumber1);
       
  1730         QContact expected(baseContact);
       
  1731         QContactPhoneNumber phoneNumber2;
       
  1732         phoneNumber2.setNumber(QLatin1String("1234"));
       
  1733         expected.saveDetail(&phoneNumber2);
       
  1734         QTest::newRow("all bad value (list)") << contact << expected << QContactManager::NoError;
       
  1735     }
       
  1736 
       
  1737     {
       
  1738         QContact contact(baseContact);
       
  1739         QContactGender gender;
       
  1740         gender.setGender(QLatin1String("UnknownGender"));
       
  1741         contact.saveDetail(&gender);
       
  1742         QTest::newRow("bad value (string)") << contact << baseContact << QContactManager::NoError;
       
  1743     }
       
  1744 
       
  1745     {
       
  1746         QContact contact;
       
  1747         QContactGender gender;
       
  1748         gender.setGender(QLatin1String("UnknownGender"));
       
  1749         contact.saveDetail(&gender);
       
  1750         QTest::newRow("bad value (string)") << contact << QContact() << QContactManager::DoesNotExistError;
       
  1751     }
       
  1752 }
       
  1753 
       
  1754 void tst_QContactManager::compatibleContact()
       
  1755 {
       
  1756     QContactManager cm("memory");
       
  1757 
       
  1758     QFETCH(QContact, input);
       
  1759     QFETCH(QContact, expected);
       
  1760     QFETCH(QContactManager::Error, error);
       
  1761     QCOMPARE(cm.compatibleContact(input), expected);
       
  1762     QCOMPARE(cm.error(), error);
  1598 }
  1763 }
  1599 
  1764 
  1600 void tst_QContactManager::contactValidation()
  1765 void tst_QContactManager::contactValidation()
  1601 {
  1766 {
  1602     /* Use the memory engine as a reference (validation is not engine specific) */
  1767     /* Use the memory engine as a reference (validation is not engine specific) */
  1698     c.removeDetail(&d7);
  1863     c.removeDetail(&d7);
  1699 }
  1864 }
  1700 
  1865 
  1701 void tst_QContactManager::signalEmission()
  1866 void tst_QContactManager::signalEmission()
  1702 {
  1867 {
       
  1868     QTest::qWait(500); // clear the signal queue
  1703     QFETCH(QString, uri);
  1869     QFETCH(QString, uri);
  1704     QScopedPointer<QContactManager> m1(QContactManager::fromUri(uri));
  1870     QScopedPointer<QContactManager> m1(QContactManager::fromUri(uri));
  1705     QScopedPointer<QContactManager> m2(QContactManager::fromUri(uri));
       
  1706 
       
  1707     QVERIFY(m1->hasFeature(QContactManager::Anonymous) ==
       
  1708         m2->hasFeature(QContactManager::Anonymous));
       
  1709 
  1871 
  1710     qRegisterMetaType<QContactLocalId>("QContactLocalId");
  1872     qRegisterMetaType<QContactLocalId>("QContactLocalId");
  1711     qRegisterMetaType<QList<QContactLocalId> >("QList<QContactLocalId>");
  1873     qRegisterMetaType<QList<QContactLocalId> >("QList<QContactLocalId>");
  1712     QSignalSpy spyCA(m1.data(), SIGNAL(contactsAdded(QList<QContactLocalId>)));
  1874     QSignalSpy spyCA(m1.data(), SIGNAL(contactsAdded(QList<QContactLocalId>)));
  1713     QSignalSpy spyCM(m1.data(), SIGNAL(contactsChanged(QList<QContactLocalId>)));
  1875     QSignalSpy spyCM(m1.data(), SIGNAL(contactsChanged(QList<QContactLocalId>)));
  1714     QSignalSpy spyCR(m1.data(), SIGNAL(contactsRemoved(QList<QContactLocalId>)));
  1876     QSignalSpy spyCR(m1.data(), SIGNAL(contactsRemoved(QList<QContactLocalId>)));
  1715 
  1877 
  1716     QList<QVariant> args;
  1878     QList<QVariant> args;
       
  1879     QList<QContactLocalId> arg;
  1717     QContact c;
  1880     QContact c;
  1718     QContactLocalId temp;
       
  1719     QList<QContact> batchAdd;
  1881     QList<QContact> batchAdd;
  1720     QList<QContactLocalId> batchRemove;
  1882     QList<QContactLocalId> batchRemove;
  1721     QList<QContactLocalId> sigids;
  1883     QList<QContactLocalId> sigids;
  1722     int addSigCount = 0; // the expected signal counts.
  1884     int addSigCount = 0; // the expected signal counts.
  1723     int modSigCount = 0;
  1885     int modSigCount = 0;
  1727 
  1889 
  1728     // verify add emits signal added
  1890     // verify add emits signal added
  1729     QContactName nc;
  1891     QContactName nc;
  1730     saveContactName(&c, nameDef, &nc, "John");
  1892     saveContactName(&c, nameDef, &nc, "John");
  1731     QVERIFY(m1->saveContact(&c));
  1893     QVERIFY(m1->saveContact(&c));
       
  1894     QContactLocalId cid = c.id().localId();
  1732     addSigCount += 1;
  1895     addSigCount += 1;
  1733     QTRY_COMPARE(spyCA.count(), addSigCount);
  1896     QTRY_COMPARE(spyCA.count(), addSigCount);
  1734     args = spyCA.takeFirst();
  1897     args = spyCA.takeFirst();
  1735     addSigCount -= 1;
  1898     addSigCount -= 1;
  1736     QVERIFY(args.count() == 1);
  1899     arg = args.first().value<QList<quint32> >();
  1737     temp = QContactLocalId(args.at(0).value<quint32>());
  1900     QVERIFY(arg.count() == 1);
       
  1901     QCOMPARE(QContactLocalId(arg.at(0)), cid);
  1738 
  1902 
  1739     // verify save modified emits signal changed
  1903     // verify save modified emits signal changed
  1740     saveContactName(&c, nameDef, &nc, "Citizen");
  1904     saveContactName(&c, nameDef, &nc, "Citizen");
  1741     QVERIFY(m1->saveContact(&c));
  1905     QVERIFY(m1->saveContact(&c));
  1742     modSigCount += 1;
  1906     modSigCount += 1;
  1743     QTRY_COMPARE(spyCM.count(), modSigCount);
  1907     QTRY_COMPARE(spyCM.count(), modSigCount);
  1744     args = spyCM.takeFirst();
  1908     args = spyCM.takeFirst();
  1745     modSigCount -= 1;
  1909     modSigCount -= 1;
  1746     QVERIFY(args.count() == 1);
  1910     arg = args.first().value<QList<quint32> >();
  1747     QCOMPARE(temp, QContactLocalId(args.at(0).value<quint32>()));
  1911     QVERIFY(arg.count() == 1);
       
  1912     QCOMPARE(QContactLocalId(arg.at(0)), cid);
  1748 
  1913 
  1749     // verify remove emits signal removed
  1914     // verify remove emits signal removed
  1750     m1->removeContact(c.id().localId());
  1915     m1->removeContact(c.id().localId());
  1751     remSigCount += 1;
  1916     remSigCount += 1;
  1752     QTRY_COMPARE(spyCR.count(), remSigCount);
  1917     QTRY_COMPARE(spyCR.count(), remSigCount);
  1753     args = spyCR.takeFirst();
  1918     args = spyCR.takeFirst();
  1754     remSigCount -= 1;
  1919     remSigCount -= 1;
  1755     QVERIFY(args.count() == 1);
  1920     arg = args.first().value<QList<quint32> >();
  1756     QCOMPARE(temp, QContactLocalId(args.at(0).value<quint32>()));
  1921     QVERIFY(arg.count() == 1);
       
  1922     QCOMPARE(QContactLocalId(arg.at(0)), cid);
  1757 
  1923 
  1758     // verify multiple adds works as advertised
  1924     // verify multiple adds works as advertised
  1759     QContact c2, c3;
  1925     QContact c2, c3;
  1760     QContactName nc2, nc3;
  1926     QContactName nc2, nc3;
  1761     saveContactName(&c2, nameDef, &nc2, "Mark");
  1927     saveContactName(&c2, nameDef, &nc2, "Mark");
  1842     sigids.clear();
  2008     sigids.clear();
  1843     QTRY_WAIT( while(spyCR.size() > 0) {sigids += spyCR.takeFirst().at(0).value<QList<QContactLocalId> >(); }, sigids.contains(c.localId()) && sigids.contains(c2.localId()) && sigids.contains(c3.localId()));
  2009     QTRY_WAIT( while(spyCR.size() > 0) {sigids += spyCR.takeFirst().at(0).value<QList<QContactLocalId> >(); }, sigids.contains(c.localId()) && sigids.contains(c2.localId()) && sigids.contains(c3.localId()));
  1844 
  2010 
  1845     QTRY_COMPARE(spyCA.count(), 0);
  2011     QTRY_COMPARE(spyCA.count(), 0);
  1846     QTRY_COMPARE(spyCM.count(), 0);
  2012     QTRY_COMPARE(spyCM.count(), 0);
       
  2013 
       
  2014     QScopedPointer<QContactManager> m2(QContactManager::fromUri(uri));
       
  2015 
       
  2016     QVERIFY(m1->hasFeature(QContactManager::Anonymous) ==
       
  2017         m2->hasFeature(QContactManager::Anonymous));
  1847 
  2018 
  1848     /* Now some cross manager testing */
  2019     /* Now some cross manager testing */
  1849     if (!m1->hasFeature(QContactManager::Anonymous)) {
  2020     if (!m1->hasFeature(QContactManager::Anonymous)) {
  1850         // verify that signals are emitted for modifications made to other managers (same id).
  2021         // verify that signals are emitted for modifications made to other managers (same id).
  1851         QContactName ncs = c.detail(QContactName::DefinitionName);
  2022         QContactName ncs = c.detail(QContactName::DefinitionName);
  2124     QContactName name;
  2295     QContactName name;
  2125     saveContactName(&d, cm->detailDefinition(QContactName::DefinitionName, QContactType::TypeContact), &name, "Wesley");
  2296     saveContactName(&d, cm->detailDefinition(QContactName::DefinitionName, QContactType::TypeContact), &name, "Wesley");
  2126 
  2297 
  2127     QVERIFY(d.displayLabel().isEmpty());
  2298     QVERIFY(d.displayLabel().isEmpty());
  2128 
  2299 
  2129     QString synth = cm->synthesizedDisplayLabel(d);
  2300     QString synth = cm->synthesizedContactDisplayLabel(d);
       
  2301 
       
  2302     // Make sure this doesn't crash
       
  2303     cm->synthesizeContactDisplayLabel(0);
       
  2304 
       
  2305     // Make sure this gives the same results
       
  2306     cm->synthesizeContactDisplayLabel(&d);
       
  2307     QCOMPARE(d.displayLabel(), synth);
  2130 
  2308 
  2131     /*
  2309     /*
  2132      * The display label is not updated until you save the contact.
  2310      * The display label is not updated until you save the contact or call synthCDL
  2133      */
  2311      */
  2134     QVERIFY(cm->saveContact(&d));
  2312     QVERIFY(cm->saveContact(&d));
  2135     d = cm->contact(d.id().localId());
  2313     d = cm->contact(d.id().localId());
  2136     QVERIFY(!d.isEmpty());
  2314     QVERIFY(!d.isEmpty());
  2137     QCOMPARE(d.displayLabel(), synth);
  2315     QCOMPARE(d.displayLabel(), synth);
  2183     c.saveDetail(&p1);
  2361     c.saveDetail(&p1);
  2184     c.saveDetail(&p2);
  2362     c.saveDetail(&p2);
  2185     c.saveDetail(&p3);
  2363     c.saveDetail(&p3);
  2186     c.saveDetail(&u);
  2364     c.saveDetail(&u);
  2187 
  2365 
  2188     // set a preference for dialing a particular saved phonenumber.
       
  2189     c.setPreferredDetail("Dial", p2);
       
  2190 
       
  2191     QVERIFY(cm->saveContact(&c));          // save the contact
  2366     QVERIFY(cm->saveContact(&c));          // save the contact
  2192     QContact loaded = cm->contact(c.id().localId()); // reload the contact
  2367     QContact loaded = cm->contact(c.id().localId()); // reload the contact
  2193 
       
  2194     // test that the preference was saved correctly.
       
  2195     QContactDetail pref = loaded.preferredDetail("Dial");
       
  2196     QVERIFY(pref == p2);
       
  2197 
       
  2198     cm->removeContact(c.id().localId());
  2368     cm->removeContact(c.id().localId());
  2199 }
  2369 }
  2200 
  2370 
  2201 void tst_QContactManager::changeSet()
  2371 void tst_QContactManager::changeSet()
  2202 {
  2372 {
  2212     QVERIFY(changeSet.changedContacts().isEmpty());
  2382     QVERIFY(changeSet.changedContacts().isEmpty());
  2213     QVERIFY(changeSet.removedContacts().isEmpty());
  2383     QVERIFY(changeSet.removedContacts().isEmpty());
  2214     QVERIFY(changeSet.addedContacts().contains(id));
  2384     QVERIFY(changeSet.addedContacts().contains(id));
  2215 
  2385 
  2216     changeSet.insertChangedContact(id);
  2386     changeSet.insertChangedContact(id);
  2217     changeSet.insertChangedContact(id);
  2387     changeSet.insertChangedContacts(QList<QContactLocalId>() << id);
  2218     QVERIFY(changeSet.changedContacts().size() == 1); // set, should only be added once.
  2388     QVERIFY(changeSet.changedContacts().size() == 1); // set, should only be added once.
  2219     QVERIFY(!changeSet.addedContacts().isEmpty());
  2389     QVERIFY(!changeSet.addedContacts().isEmpty());
  2220     QVERIFY(!changeSet.changedContacts().isEmpty());
  2390     QVERIFY(!changeSet.changedContacts().isEmpty());
  2221     QVERIFY(changeSet.removedContacts().isEmpty());
  2391     QVERIFY(changeSet.removedContacts().isEmpty());
  2222     QVERIFY(changeSet.changedContacts().contains(id));
  2392     QVERIFY(changeSet.changedContacts().contains(id));
       
  2393     changeSet.clearChangedContacts();
       
  2394     QVERIFY(changeSet.changedContacts().isEmpty());
       
  2395 
       
  2396     changeSet.insertRemovedContacts(QList<QContactLocalId>() << id);
       
  2397     QVERIFY(changeSet.removedContacts().contains(id));
       
  2398     changeSet.clearRemovedContacts();
       
  2399     QVERIFY(changeSet.removedContacts().isEmpty());
  2223 
  2400 
  2224     QVERIFY(changeSet.dataChanged() == false);
  2401     QVERIFY(changeSet.dataChanged() == false);
  2225     QContactChangeSet changeSet2;
  2402     QContactChangeSet changeSet2;
  2226     changeSet2 = changeSet;
  2403     changeSet2 = changeSet;
  2227     QVERIFY(changeSet.addedContacts() == changeSet2.addedContacts());
  2404     QVERIFY(changeSet.addedContacts() == changeSet2.addedContacts());
  2228     changeSet.emitSignals(0);
  2405     changeSet.emitSignals(0);
  2229 
  2406 
       
  2407     changeSet2.clearAddedContacts();
       
  2408     QVERIFY(changeSet2.addedContacts().isEmpty());
       
  2409     changeSet2.insertAddedContacts(changeSet.addedContacts().toList());
       
  2410     QVERIFY(changeSet.addedContacts() == changeSet2.addedContacts());
       
  2411 
  2230     changeSet2.clearAll();
  2412     changeSet2.clearAll();
  2231     QVERIFY(changeSet.addedContacts() != changeSet2.addedContacts());
  2413     QVERIFY(changeSet.addedContacts() != changeSet2.addedContacts());
  2232 
  2414 
  2233     QContactChangeSet changeSet3(changeSet2);
  2415     QContactChangeSet changeSet3(changeSet2);
  2234     QVERIFY(changeSet.addedContacts() != changeSet3.addedContacts());
  2416     QVERIFY(changeSet.addedContacts() != changeSet3.addedContacts());
  2239     QVERIFY(changeSet.dataChanged() != changeSet2.dataChanged());
  2421     QVERIFY(changeSet.dataChanged() != changeSet2.dataChanged());
  2240     QVERIFY(changeSet.dataChanged() != changeSet3.dataChanged());
  2422     QVERIFY(changeSet.dataChanged() != changeSet3.dataChanged());
  2241     changeSet.emitSignals(0);
  2423     changeSet.emitSignals(0);
  2242 
  2424 
  2243     changeSet.addedRelationshipsContacts().insert(id);
  2425     changeSet.addedRelationshipsContacts().insert(id);
       
  2426     changeSet.insertAddedRelationshipsContacts(QList<QContactLocalId>() << id);
       
  2427     QVERIFY(changeSet.addedRelationshipsContacts().contains(id));
       
  2428     changeSet.clearAddedRelationshipsContacts();
       
  2429     QVERIFY(changeSet.addedRelationshipsContacts().isEmpty());
       
  2430     changeSet.insertRemovedRelationshipsContacts(QList<QContactLocalId>() << id);
       
  2431     QVERIFY(changeSet.removedRelationshipsContacts().contains(id));
       
  2432     changeSet.clearRemovedRelationshipsContacts();
       
  2433     QVERIFY(changeSet.removedRelationshipsContacts().isEmpty());
  2244     changeSet.emitSignals(0);
  2434     changeSet.emitSignals(0);
  2245     changeSet.removedRelationshipsContacts().insert(id);
  2435     changeSet.removedRelationshipsContacts().insert(id);
  2246     changeSet.emitSignals(0);
  2436     changeSet.emitSignals(0);
  2247 
  2437 
  2248     changeSet.setOldAndNewSelfContactId(QPair<QContactLocalId, QContactLocalId>(QContactLocalId(0), id));
  2438     changeSet.setOldAndNewSelfContactId(QPair<QContactLocalId, QContactLocalId>(QContactLocalId(0), id));
  2255     QVERIFY(changeSet2.oldAndNewSelfContactId() != changeSet.oldAndNewSelfContactId());
  2445     QVERIFY(changeSet2.oldAndNewSelfContactId() != changeSet.oldAndNewSelfContactId());
  2256     changeSet.setDataChanged(true);
  2446     changeSet.setDataChanged(true);
  2257     changeSet.emitSignals(0);
  2447     changeSet.emitSignals(0);
  2258 }
  2448 }
  2259 
  2449 
       
  2450 void tst_QContactManager::fetchHint()
       
  2451 {
       
  2452     QContactFetchHint hint;
       
  2453     hint.setOptimizationHints(QContactFetchHint::NoBinaryBlobs);
       
  2454     QCOMPARE(hint.optimizationHints(), QContactFetchHint::NoBinaryBlobs);
       
  2455     QStringList rels;
       
  2456     rels << QString(QLatin1String(QContactRelationship::HasMember));
       
  2457     hint.setRelationshipTypesHint(rels);
       
  2458     QCOMPARE(hint.relationshipTypesHint(), rels);
       
  2459 }
       
  2460 
  2260 void tst_QContactManager::selfContactId()
  2461 void tst_QContactManager::selfContactId()
  2261 {
  2462 {
  2262     QFETCH(QString, uri);
  2463     QFETCH(QString, uri);
  2263     QScopedPointer<QContactManager> cm(QContactManager::fromUri(uri));
  2464     QScopedPointer<QContactManager> cm(QContactManager::fromUri(uri));
  2264 
  2465 
  2265     // early out if the manager doesn't support self contact id saving
  2466     // early out if the manager doesn't support self contact id saving
  2266     QContactLocalId selfContact = cm->selfContactId();
  2467     QContactLocalId selfContact = cm->selfContactId();
  2267     if (!cm->hasFeature(QContactManager::SelfContact)) {
  2468     if (!cm->hasFeature(QContactManager::SelfContact)) {
  2268         // ensure that the error codes / return values are meaningful failures.
  2469         // ensure that the error codes / return values are meaningful failures.
       
  2470         QEXPECT_FAIL("mgr='maemo5'", "maemo5 supports getting the self contact but not setting it.", Continue);
  2269         QVERIFY(cm->error() == QContactManager::DoesNotExistError);
  2471         QVERIFY(cm->error() == QContactManager::DoesNotExistError);
  2270         QVERIFY(!cm->setSelfContactId(QContactLocalId(123)));
  2472         QVERIFY(!cm->setSelfContactId(QContactLocalId(123)));
  2271         QVERIFY(cm->error() == QContactManager::NotSupportedError);
  2473         QVERIFY(cm->error() == QContactManager::NotSupportedError);
  2272         QSKIP("Manager does not support the concept of a self-contact", SkipSingle);
  2474         QSKIP("Manager does not support the concept of a self-contact", SkipSingle);
  2273     }
  2475     }