qtmobility/tests/auto/qcontactasync/unittest/tst_qcontactasync.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
--- a/qtmobility/tests/auto/qcontactasync/unittest/tst_qcontactasync.cpp	Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/tests/auto/qcontactasync/unittest/tst_qcontactasync.cpp	Mon May 03 13:18:40 2010 +0300
@@ -216,16 +216,19 @@
     void testQuickDestruction_data() { addManagers(); }
 
     void threadDelivery();
-    void progressReceived(QContactFetchRequest* request, bool appendOnly);
     void threadDelivery_data() { addManagers(); }
+protected slots:
+    void resultsAvailableReceived();
 
 private:
+    bool compareContactLists(QList<QContact> lista, QList<QContact> listb);
+    bool compareContacts(QContact ca, QContact cb);
     bool containsIgnoringTimestamps(const QList<QContact>& list, const QContact& c);
     bool compareIgnoringTimestamps(const QContact& ca, const QContact& cb);
     QContactManager* prepareModel(const QString& uri);
 
     Qt::HANDLE m_mainThreadId;
-    Qt::HANDLE m_progressSlotThreadId;
+    Qt::HANDLE m_resultsAvailableSlotThreadId;
     QContactManagerDataHolder managerDataHolder;
 };
 
@@ -253,6 +256,60 @@
 {
 }
 
+bool tst_QContactAsync::compareContactLists(QList<QContact> lista, QList<QContact> listb)
+{
+    // NOTE: This compare is contact order insensitive.  
+    
+    // Remove matching contacts
+    foreach (QContact a, lista) {
+        foreach (QContact b, listb) {
+            if (compareContacts(a, b)) {
+                lista.removeOne(a);
+                listb.removeOne(b);
+                break;
+            }
+        }
+    }    
+    return (lista.count() == 0 && listb.count() == 0);
+}
+
+bool tst_QContactAsync::compareContacts(QContact ca, QContact cb)
+{
+    // NOTE: This compare is contact detail order insensitive.
+    
+    if (ca.localId() != cb.localId())
+        return false;
+    
+    QList<QContactDetail> aDetails = ca.details();
+    QList<QContactDetail> bDetails = cb.details();
+
+    // Remove matching details
+    foreach (QContactDetail ad, aDetails) {
+        foreach (QContactDetail bd, bDetails) {
+            if (ad == bd) {
+                ca.removeDetail(&ad);
+                cb.removeDetail(&bd);
+                break;
+            }
+            
+            // Special handling for timestamp
+            if (ad.definitionName() == QContactTimestamp::DefinitionName &&
+                bd.definitionName() == QContactTimestamp::DefinitionName) {
+                QContactTimestamp at = static_cast<QContactTimestamp>(ad);
+                QContactTimestamp bt = static_cast<QContactTimestamp>(bd);
+                if (at.created().toString() == bt.created().toString() &&
+                    at.lastModified().toString() == bt.lastModified().toString()) {
+                    ca.removeDetail(&ad);
+                    cb.removeDetail(&bd);
+                    break;
+                }
+                    
+            }            
+        }
+    }
+    return (ca == cb);
+}
+
 bool tst_QContactAsync::containsIgnoringTimestamps(const QList<QContact>& list, const QContact& c)
 {
     QList<QContact> cl = list;
@@ -418,8 +475,10 @@
     sorting.clear();
     cfr.setFilter(fil);
     cfr.setSorting(sorting);
-    cfr.setDefinitionRestrictions(QStringList(QContactName::DefinitionName));
-    QCOMPARE(cfr.definitionRestrictions(), QStringList(QContactName::DefinitionName));
+    QContactFetchHint fetchHint;
+    fetchHint.setDetailDefinitionsHint(QStringList(QContactName::DefinitionName));
+    cfr.setFetchHint(fetchHint);
+    QCOMPARE(cfr.fetchHint().detailDefinitionsHint(), QStringList(QContactName::DefinitionName));
     QVERIFY(!cfr.cancel()); // not started
     QVERIFY(cfr.start());
     QVERIFY((cfr.isActive() && cfr.state() == QContactAbstractRequest::ActiveState) || cfr.isFinished());
@@ -478,7 +537,7 @@
     sorting.clear();
     cfr.setFilter(fil);
     cfr.setSorting(sorting);
-    cfr.setDefinitionRestrictions(QStringList());
+    cfr.setFetchHint(QContactFetchHint());
 
     int bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT; // attempt to cancel 40 times.  If it doesn't work due to threading, bail out.
     while (true) {
@@ -493,7 +552,8 @@
             sorting.clear();
             cfr.setFilter(fil);
             cfr.setSorting(sorting);
-            cfr.setDefinitionRestrictions(QStringList());
+            cfr.setFetchHint(QContactFetchHint());
+            cfr.setFetchHint(QContactFetchHint());
             bailoutCount -= 1;
             if (!bailoutCount) {
                 qWarning("Unable to test cancelling due to thread scheduling!");
@@ -524,7 +584,7 @@
             sorting.clear();
             cfr.setFilter(fil);
             cfr.setSorting(sorting);
-            cfr.setDefinitionRestrictions(QStringList());
+            cfr.setFetchHint(QContactFetchHint());
             bailoutCount -= 1;
             spy.clear();
             if (!bailoutCount) {
@@ -901,7 +961,7 @@
     expected.clear();
     expected << cm->contact(cm->contactIds().last());
     result = csr.contacts();
-    QCOMPARE(expected, result);
+    QVERIFY(compareContactLists(expected, result));
 
     //here we can't compare the whole contact details, testContact would be updated by async call because we just use QThreadSignalSpy to receive signals.
     //QVERIFY(containsIgnoringTimestamps(expected, testContact));
@@ -1128,7 +1188,7 @@
 
     QScopedPointer<QContactManager> cm(prepareModel(uri));
     if (!cm->hasFeature(QContactManager::MutableDefinitions)) {
-       QSKIP("This contact manager doest not support mutable definitions, can't remove a definition!", SkipSingle);
+       QSKIP("This contact manager does not support mutable definitions, can't remove a definition!", SkipSingle);
     }
     QContactDetailDefinitionRemoveRequest drr;
     QVERIFY(drr.type() == QContactAbstractRequest::DetailDefinitionRemoveRequest);
@@ -1236,7 +1296,7 @@
             drr.waitForFinished();
             drr.setDefinitionNames(QContactType::TypeContact, removeIds);
 
-            QCOMPARE(cm->detailDefinitions().keys().size(), originalCount - 2); // hasn't changed
+            QCOMPARE(cm->detailDefinitions().keys().size(), originalCount - 3); // finished
             bailoutCount -= 1;
             if (!bailoutCount) {
                 qWarning("Unable to test cancelling due to thread scheduling!");
@@ -1244,6 +1304,7 @@
                 break;
             }
             spy.clear();
+            // XXX should be readded
             continue;
         }
 
@@ -1281,7 +1342,7 @@
         QVERIFY(spy.count() >= 1); // active + cancelled progress signals
         spy.clear();
 
-        QCOMPARE(cm->detailDefinitions().keys().size(), originalCount - 2); // hasn't changed
+        QCOMPARE(cm->detailDefinitions().keys().size(), originalCount - 3); // hasn't changed
         break;
     }
 
@@ -1295,7 +1356,7 @@
 
     if (!cm->hasFeature(QContactManager::MutableDefinitions)) {
 
-       QSKIP("This contact manager doest not support mutable definitions, can't save a definition!", SkipSingle);
+       QSKIP("This contact manager does not support mutable definitions, can't save a definition!", SkipSingle);
     }
     
     QContactDetailDefinitionSaveRequest dsr;
@@ -1457,6 +1518,15 @@
 {
     QFETCH(QString, uri);
     QScopedPointer<QContactManager> cm(prepareModel(uri));
+
+    if (!cm->hasFeature(QContactManager::Relationships)) {
+       QSKIP("This contact manager does not support relationships!", SkipSingle);
+    }
+    
+    if (cm->managerName() == "symbian") {
+        QSKIP("This contact manager does not support the required relationship types for this test to pass!", SkipSingle);
+    }
+    
     QContactRelationshipFetchRequest rfr;
     QVERIFY(rfr.type() == QContactAbstractRequest::RelationshipFetchRequest);
 
@@ -1529,7 +1599,7 @@
     QVERIFY(spy.count() >= 1); // active + finished progress signals
     spy.clear();
 
-    rels = cm->relationships(aId, QContactRelationshipFilter::First);
+    rels = cm->relationships(aId, QContactRelationship::First);
     result = rfr.relationships();
     QCOMPARE(rels, result);
 
@@ -1557,7 +1627,7 @@
     spy.clear();
 
     // retrieve rels where second = id of B, and ensure that we get the same results
-    rels = cm->relationships(bId, QContactRelationshipFilter::Second);
+    rels = cm->relationships(bId, QContactRelationship::Second);
     result = rfr.relationships();
     QCOMPARE(rels, result);
 
@@ -1590,7 +1660,7 @@
     QVERIFY(rfr.start());
     QVERIFY(rfr.waitForFinished());
     result = rfr.relationships();
-    rels = cm->relationships(cId, QContactRelationshipFilter::First);
+    rels = cm->relationships(cId, QContactRelationship::First);
     QCOMPARE(rels, result);
 
     // cancelling
@@ -1655,6 +1725,15 @@
 {
     QFETCH(QString, uri);
     QScopedPointer<QContactManager> cm(prepareModel(uri));
+    
+    if (!cm->hasFeature(QContactManager::Relationships)) {
+       QSKIP("This contact manager does not support relationships!", SkipSingle);
+    }
+    
+    if (cm->managerName() == "symbian") {
+        QSKIP("This contact manager does not support the required relationship types for this test to pass!", SkipSingle);
+    }
+    
     QContactRelationshipRemoveRequest rrr;
     QVERIFY(rrr.type() == QContactAbstractRequest::RelationshipRemoveRequest);
 
@@ -1710,7 +1789,7 @@
     QVERIFY(rrr.isFinished());
     QVERIFY(spy.count() >= 1); // active + finished progress signals
     spy.clear();
-    QCOMPARE(cm->relationships(QContactRelationship::HasAssistant, cId, QContactRelationshipFilter::Second).size(), 1);
+    QCOMPARE(cm->relationships(QContactRelationship::HasAssistant, cId, QContactRelationship::Second).size(), 1);
 
     // remove (asynchronously) a nonexistent relationship - should fail.
     r.setFirst(cId);
@@ -1730,7 +1809,7 @@
     QVERIFY(spy.count() >= 1); // active + finished progress signals
     spy.clear();
 
-    QCOMPARE(cm->relationships(QContactRelationship::HasManager, cId, QContactRelationshipFilter::First).size(), 0);
+    QCOMPARE(cm->relationships(QContactRelationship::HasManager, cId, QContactRelationship::First).size(), 0);
 //    QCOMPARE(rrr.error(), QContactManager::DoesNotExistError);
 
     // cancelling
@@ -1803,6 +1882,15 @@
 {
     QFETCH(QString, uri);
     QScopedPointer<QContactManager> cm(prepareModel(uri));
+    
+    if (!cm->hasFeature(QContactManager::Relationships)) {
+       QSKIP("This contact manager does not support relationships!", SkipSingle);
+    }
+    
+    if (cm->managerName() == "symbian") {
+        QSKIP("This contact manager does not support the required relationship types for this test to pass!", SkipSingle);
+    }    
+    
     QContactRelationshipSaveRequest rsr;
     QVERIFY(rsr.type() == QContactAbstractRequest::RelationshipSaveRequest);
 
@@ -1854,7 +1942,7 @@
     QVERIFY(spy.count() >= 1); // active + finished progress signals
     spy.clear();
 
-    QList<QContactRelationship> expected = cm->relationships(QContactRelationship::HasSpouse, aId, QContactRelationshipFilter::First);
+    QList<QContactRelationship> expected = cm->relationships(QContactRelationship::HasSpouse, aId, QContactRelationship::First);
     QList<QContactRelationship> result = rsr.relationships();
     QCOMPARE(expected, result);
     QVERIFY(result.contains(testRel));
@@ -1877,7 +1965,7 @@
     spy.clear();
 
     expected.clear();
-    expected = cm->relationships(QContactRelationship::HasSpouse, aId, QContactRelationshipFilter::First);
+    expected = cm->relationships(QContactRelationship::HasSpouse, aId, QContactRelationship::First);
     result = rsr.relationships();
     QCOMPARE(result, QList<QContactRelationship>() << testRel);
     QVERIFY(expected.contains(testRel));
@@ -1918,7 +2006,7 @@
         spy.clear();
 
         // verify that the changes were not saved
-        QList<QContactRelationship> aRels = cm->relationships(aId, QContactRelationshipFilter::First);
+        QList<QContactRelationship> aRels = cm->relationships(aId, QContactRelationship::First);
         QVERIFY(!aRels.contains(testRel));
         QCOMPARE(cm->relationships(aId).size(), originalCount + 2); // should still only be two extra
 
@@ -1953,7 +2041,7 @@
         spy.clear();
 
         // verify that the changes were not saved
-        QList<QContactRelationship> aRels = cm->relationships(aId, QContactRelationshipFilter::First);
+        QList<QContactRelationship> aRels = cm->relationships(aId, QContactRelationship::First);
         QVERIFY(!aRels.contains(testRel));
         QCOMPARE(cm->relationships(aId).size(), originalCount + 2); // should still only be two extra
 
@@ -2110,18 +2198,19 @@
     QFETCH(QString, uri);
     QScopedPointer<QContactManager> cm(prepareModel(uri));
     m_mainThreadId = cm->thread()->currentThreadId();
-    m_progressSlotThreadId = m_mainThreadId;
+    m_resultsAvailableSlotThreadId = m_mainThreadId;
 
     // now perform a fetch request and check that the progress is delivered to the correct thread.
     QContactFetchRequest *req = new QContactFetchRequest;
     req->setManager(cm.data());
-    connect(req, SIGNAL(progress(QContactFetchRequest*,bool)), this, SLOT(progressReceived(QContactFetchRequest*, bool)));
+    connect(req, SIGNAL(resultsAvailable()), this, SLOT(resultsAvailableReceived()));
     req->start();
 
     int totalWaitTime = 0;
+    QTest::qWait(1); // force it to process events at least once.
     while (req->state() != QContactAbstractRequest::FinishedState) {
         // ensure that the progress signal was delivered to the main thread.
-        QCOMPARE(m_mainThreadId, m_progressSlotThreadId);
+        QCOMPARE(m_mainThreadId, m_resultsAvailableSlotThreadId);
 
         QTest::qWait(5); // spin until done
         totalWaitTime += 5;
@@ -2134,14 +2223,17 @@
     }
 
     // ensure that the progress signal was delivered to the main thread.
-    QCOMPARE(m_mainThreadId, m_progressSlotThreadId);
+    QCOMPARE(m_mainThreadId, m_resultsAvailableSlotThreadId);
     delete req;
 }
 
-void tst_QContactAsync::progressReceived(QContactFetchRequest* request, bool appendOnly)
+void tst_QContactAsync::resultsAvailableReceived()
 {
-    Q_UNUSED(appendOnly);
-    m_progressSlotThreadId = request->thread()->currentThreadId();
+    QContactFetchRequest *req = qobject_cast<QContactFetchRequest *>(QObject::sender());
+    if (req)
+        m_resultsAvailableSlotThreadId = req->thread()->currentThreadId();
+    else
+        qDebug() << "resultsAvailableReceived() : request deleted; unable to set thread id!";
 }
 
 void tst_QContactAsync::addManagers()
@@ -2155,6 +2247,7 @@
     managers.removeAll("invalid");
     managers.removeAll("maliciousplugin");
     managers.removeAll("testdummy");
+    managers.removeAll("symbiansim"); // SIM backend does not support all the required details for tests to pass.
 
     foreach(QString mgr, managers) {
         QMap<QString, QString> params;
@@ -2205,6 +2298,15 @@
     cm->saveContact(&a);
     cm->saveContact(&b);
     cm->saveContact(&c);
+    
+    if (!cm->hasFeature(QContactManager::Relationships)) {
+        return cm;
+    }
+    
+    if (cm->managerName() == "symbian") {
+        // Symbian backend does not support other relationships than HasMember (which is same as groups)
+        return cm;
+    }
 
     QContactRelationship arb;
     arb.setFirst(a.id());