summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorRenato Araujo Oliveira Filho <renato.filho@canonical.com>2015-01-19 17:08:23 -0300
committerRenato Araujo Oliveira Filho <renato.filho@canonical.com>2015-02-06 11:58:38 +0000
commit86aa56275c33be673f60f3c2b51d4f719de9315c (patch)
tree1a536662e27c456e2afb1b4012e5922c9b3d6043 /tests
parentc08717fb6b3975273ffc5c8036a6b8aa0b87d679 (diff)
Add QContactCollection.
The QContactCollection class represents a collection of contacts in a manager. This class was implemented based on QOrganizerCollection. Change-Id: I5377f9043a66726182b7a0ed7f40733ffe08b619 Reviewed-by: Matthew Vogt <matthew.vogt@qinetic.com.au> Reviewed-by: Christopher Adams <chris.adams@jollamobile.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/contacts/contacts.pro1
-rw-r--r--tests/auto/contacts/qcontactasync/unittest/tst_qcontactasync.cpp472
-rw-r--r--tests/auto/contacts/qcontactcollection/qcontactcollection.pro5
-rw-r--r--tests/auto/contacts/qcontactcollection/tst_qcontactcollection.cpp397
-rw-r--r--tests/auto/contacts/qcontactfilter/tst_qcontactfilter.cpp94
-rw-r--r--tests/auto/contacts/qcontactmanager/tst_qcontactmanager.cpp166
-rw-r--r--tests/auto/contacts/qmlcontacts/qmlcontacts.pro2
-rw-r--r--tests/auto/contacts/qmlcontacts/testcases/ContactsSavingTestCase.qml17
-rw-r--r--tests/auto/contacts/qmlcontacts/testcases/tst_contact_collection_filter.qml161
9 files changed, 1315 insertions, 0 deletions
diff --git a/tests/auto/contacts/contacts.pro b/tests/auto/contacts/contacts.pro
index fe4cb4865..408b57e44 100644
--- a/tests/auto/contacts/contacts.pro
+++ b/tests/auto/contacts/contacts.pro
@@ -4,6 +4,7 @@ TEMPLATE = subdirs
SUBDIRS += \
qcontact \
qcontactasync \
+ qcontactcollection \
qcontactdetail \
qcontactdetails \
qcontactfilter \
diff --git a/tests/auto/contacts/qcontactasync/unittest/tst_qcontactasync.cpp b/tests/auto/contacts/qcontactasync/unittest/tst_qcontactasync.cpp
index 59a584f83..885606b27 100644
--- a/tests/auto/contacts/qcontactasync/unittest/tst_qcontactasync.cpp
+++ b/tests/auto/contacts/qcontactasync/unittest/tst_qcontactasync.cpp
@@ -56,6 +56,13 @@ QTCONTACTS_USE_NAMESPACE
fqcfr2.start(); \
fqcfr3.start();
+/* Define an innocuous request (fetch ie doesn't mutate) to "fill up" any queues */
+#define FILL_QUEUE_WITH_FETCH_REQUESTS_WITH_MANAGER(manager) QContactFetchRequest fqifr1, fqifr2, fqifr3; \
+ fqifr1.setManager(manager); fqifr1.start(); \
+ fqifr2.setManager(manager); fqifr2.start(); \
+ fqifr3.setManager(manager); fqifr3.start();
+
+
//TESTED_COMPONENT=src/contacts
// Unfortunately the plumbing isn't in place to allow cancelling requests at arbitrary points
@@ -230,6 +237,13 @@ private slots:
void relationshipSave();
void relationshipSave_data() { addManagers(); }
+ void collectionFetch();
+ void collectionFetch_data() { addManagers(); }
+ void collectionRemove();
+ void collectionRemove_data() { addManagers(); }
+ void collectionSave();
+ void collectionSave_data() { addManagers(); }
+
void maliciousManager(); // uses it's own custom data (manager)
void testQuickDestruction();
@@ -245,6 +259,7 @@ private:
bool compareContacts(QContact ca, QContact cb);
bool containsIgnoringTimestamps(const QList<QContact>& list, const QContact& c);
bool compareIgnoringTimestamps(const QContact& ca, const QContact& cb);
+ bool containsAllCollectionIds(const QList<QContactCollectionId>& target, const QList<QContactCollectionId>& ids);
QContactManager* prepareModel(const QString& uri);
Qt::HANDLE m_mainThreadId;
@@ -376,6 +391,18 @@ bool tst_QContactAsync::compareIgnoringTimestamps(const QContact& ca, const QCon
return false;
}
+bool tst_QContactAsync::containsAllCollectionIds(const QList<QContactCollectionId> &target, const QList<QContactCollectionId> &ids)
+{
+ bool containsAllIds = true;
+ foreach (QContactCollectionId id, ids) {
+ if (!target.contains(id)) {
+ containsAllIds = false;
+ break;
+ }
+ }
+ return containsAllIds;
+}
+
void tst_QContactAsync::testDestructor()
{
QFETCH(QString, uri);
@@ -1316,6 +1343,9 @@ void tst_QContactAsync::contactSave()
//QCOMPARE(result, expected);
// XXX: really, we should use isSuperset() from tst_QContactManager, but this will do for now:
QVERIFY(result.first().detail<QContactName>() == nameDetail);
+
+ // check if the contact was saved on default collection
+ QCOMPARE(result.first().collectionId().toString(), cm->defaultCollection().id().toString());
QCOMPARE(cm->contactIds().size(), originalCount + 1);
// update a previously saved contact
@@ -2413,6 +2443,443 @@ void tst_QContactAsync::relationshipSave()
}
}
+void tst_QContactAsync::collectionFetch()
+{
+ QFETCH(QString, uri);
+ QScopedPointer<QContactManager> cm(prepareModel(uri));
+
+ QContactCollectionFetchRequest cfr;
+ QVERIFY(cfr.type() == QContactAbstractRequest::CollectionFetchRequest);
+
+ // initial state - not started, no manager.
+ QVERIFY(!cfr.isActive());
+ QVERIFY(!cfr.isFinished());
+ QVERIFY(!cfr.start());
+ QVERIFY(!cfr.cancel());
+ QVERIFY(!cfr.waitForFinished());
+
+ // retrieve all collections.
+ cfr.setManager(cm.data());
+ QCOMPARE(cfr.manager(), cm.data());
+ QVERIFY(!cfr.isActive());
+ QVERIFY(!cfr.isFinished());
+ QVERIFY(!cfr.cancel());
+ QVERIFY(!cfr.waitForFinished());
+ qRegisterMetaType<QContactCollectionFetchRequest*>("QContactCollectionFetchRequest*");
+ QThreadSignalSpy spy(&cfr, SIGNAL(stateChanged(QContactAbstractRequest::State)));
+ QVERIFY(!cfr.cancel()); // not started
+
+ QVERIFY(cfr.start());
+ //QVERIFY(cfr.isFinished() || !cfr.start()); // already started. // thread scheduling means this is untestable
+ QVERIFY((cfr.isActive() && cfr.state() == QContactAbstractRequest::ActiveState) || cfr.isFinished());
+ QVERIFY(cfr.waitForFinished());
+ QVERIFY(cfr.isFinished());
+
+ QVERIFY(spy.count() >= 1); // active + finished progress signals
+ spy.clear();
+
+ QList<QContactCollection> syncCols = cm->collections();
+ QList<QContactCollection> cols = cfr.collections();
+ QCOMPARE(cols.size(), syncCols.size());
+ for (int i = 0; i < cols.size(); i++) {
+ QContactCollection curr = cols.at(i);
+ QVERIFY(syncCols.contains(curr));
+ }
+
+ // cancelling
+ int bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT; // attempt to cancel 40 times. If it doesn't work due to threading, bail out.
+ while (true) {
+ QVERIFY(!cfr.cancel()); // not started
+ FILL_QUEUE_WITH_FETCH_REQUESTS_WITH_MANAGER(cm.data());
+ QVERIFY(cfr.start());
+ if (!cfr.cancel()) {
+ // due to thread scheduling, async cancel might be attempted
+ // after the request has already finished.. so loop and try again.
+ spy.clear();
+ cfr.waitForFinished();
+ bailoutCount -= 1;
+ if (!bailoutCount) {
+// qWarning("Unable to test cancelling due to thread scheduling!");
+ bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT;
+ break;
+ }
+ continue;
+ }
+
+ // if we get here, then we are cancelling the request.
+ QVERIFY(cfr.waitForFinished());
+ QVERIFY(cfr.isCanceled());
+
+ QVERIFY(spy.count() >= 1); // active + cancelled progress signals
+ spy.clear();
+ break;
+ }
+
+ // restart, and wait for progress after cancel.
+ while (true) {
+ QVERIFY(!cfr.cancel()); // not started
+ FILL_QUEUE_WITH_FETCH_REQUESTS_WITH_MANAGER(cm.data());
+ QVERIFY(cfr.start());
+ if (!cfr.cancel()) {
+ // due to thread scheduling, async cancel might be attempted
+ // after the request has already finished.. so loop and try again.
+ cfr.waitForFinished();
+ bailoutCount -= 1;
+ spy.clear();
+ if (!bailoutCount) {
+ //qWarning("Unable to test cancelling due to thread scheduling!");
+ bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT;
+ break;
+ }
+ continue;
+ }
+ cfr.waitForFinished();
+ QVERIFY(spy.count() >= 1); // active + cancelled progress signals
+ spy.clear();
+ QVERIFY(!cfr.isActive());
+ QVERIFY(cfr.state() == QContactAbstractRequest::CanceledState);
+ break;
+ }
+}
+
+void tst_QContactAsync::collectionRemove()
+{
+ QFETCH(QString, uri);
+ QScopedPointer<QContactManager> cm(prepareModel(uri));
+ QContactCollectionRemoveRequest crr;
+ QVERIFY(crr.type() == QContactAbstractRequest::CollectionRemoveRequest);
+
+ // initial state - not started, no manager.
+ QVERIFY(!crr.isActive());
+ QVERIFY(!crr.isFinished());
+ QVERIFY(!crr.start());
+ QVERIFY(!crr.cancel());
+ QVERIFY(!crr.waitForFinished());
+
+ // specific collection set
+ QContactCollectionId removeId = cm->collections().last().id();
+ if (cm->defaultCollection().id() == removeId)
+ removeId = cm->collections().first().id();
+ crr.setCollectionId(removeId);
+ QVERIFY(crr.collectionIds() == QList<QContactCollectionId>() << removeId);
+ int originalCount = cm->collections().size();
+ crr.setManager(cm.data());
+ QCOMPARE(crr.manager(), cm.data());
+ QVERIFY(!crr.isActive());
+ QVERIFY(!crr.isFinished());
+ QVERIFY(!crr.cancel());
+ QVERIFY(!crr.waitForFinished());
+ qRegisterMetaType<QContactCollectionRemoveRequest*>("QContactCollectionRemoveRequest*");
+ QThreadSignalSpy spy(&crr, SIGNAL(stateChanged(QContactAbstractRequest::State)));
+ QVERIFY(!crr.cancel()); // not started
+ QVERIFY(crr.start());
+ QVERIFY((crr.isActive() &&crr.state() == QContactAbstractRequest::ActiveState) || crr.isFinished());
+ //QVERIFY(crr.isFinished() || !crr.start()); // already started. // thread scheduling means this is untestable
+ QVERIFY(crr.waitForFinished());
+ QVERIFY(crr.isFinished());
+
+ QVERIFY(spy.count() >= 1); // active + finished progress signals
+ spy.clear();
+
+ QCOMPARE(cm->collections().size(), originalCount - 1); // should have removed that particular collection.
+ QVERIFY(crr.error() == QContactManager::NoError);
+ QVERIFY(crr.errorMap().isEmpty());
+
+ // remove all collections
+ QList<QContactCollectionId> allCollectionIds;
+ QList<QContactCollection> allCollections = cm->collections();
+ for (int i = 0; i < allCollections.size(); ++i)
+ allCollectionIds << allCollections.at(i).id();
+ crr.setCollectionIds(allCollectionIds);
+
+ QVERIFY(!crr.cancel()); // not started
+ QVERIFY(crr.start());
+
+ QVERIFY((crr.isActive() && crr.state() == QContactAbstractRequest::ActiveState) || crr.isFinished());
+ //QVERIFY(crr.isFinished() || !crr.start()); // already started. // thread scheduling means this is untestable
+ QVERIFY(crr.waitForFinished());
+ QVERIFY(crr.isFinished());
+
+ QVERIFY(cm->collections().size() >= 1); // at least one collection must be left, since default collection cannot be removed.
+ QVERIFY(spy.count() >= 1); // active + finished progress signals
+ spy.clear();
+
+ // remove empty list
+ QList<QContactCollectionId> collectionIdList;
+ QContactCollectionRemoveRequest crr1;
+ crr1.setManager(cm.data());
+ crr1.setCollectionIds(collectionIdList);
+ crr1.start();
+ crr1.waitForFinished();
+ QVERIFY(crr1.isFinished());
+ QVERIFY(crr1.error() == QContactManager::NoError);
+
+ // cancelling
+ QContactCollection temp;
+ temp.setMetaData(QContactCollection::KeyDescription, "Should not be removed!");
+ cm->saveCollection(&temp);
+ crr.setCollectionId(temp.id());
+
+ int collectionCount = cm->collections().size();
+ int bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT; // attempt to cancel 40 times. If it doesn't work due to threading, bail out.
+ while (true) {
+ QVERIFY(!crr.cancel()); // not started
+ FILL_QUEUE_WITH_FETCH_REQUESTS_WITH_MANAGER(cm.data());
+ QVERIFY(spy.count() == 0);
+ QVERIFY(crr.start());
+ if (!crr.cancel()) {
+ // due to thread scheduling, async cancel might be attempted
+ // after the request has already finished.. so loop and try again.
+ crr.waitForFinished();
+ temp.setId(QContactCollectionId());
+ if (!cm->saveCollection(&temp)) {
+ QSKIP("Unable to save temporary item for remove request cancellation test!");
+ }
+ crr.setCollectionId(temp.id());
+ bailoutCount -= 1;
+ if (!bailoutCount) {
+// qWarning("Unable to test cancelling due to thread scheduling!");
+ bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT;
+ break;
+ }
+ spy.clear();
+ continue;
+ }
+
+ // if we get here, then we are cancelling the request.
+ QVERIFY(crr.waitForFinished());
+ QVERIFY(crr.isCanceled());
+ QCOMPARE(cm->collections().size(), collectionCount); // temp collection should not have been removed
+ QList<QContactCollectionId> removeCollectionIds;
+ QList<QContactCollection> removeCollections = cm->collections();
+ for (int i = 0; i < removeCollections.size(); ++i)
+ removeCollectionIds << removeCollections.at(i).id();
+ QVERIFY(containsAllCollectionIds(removeCollectionIds, crr.collectionIds()));
+ QVERIFY(spy.count() >= 1); // active + cancelled progress signals
+ spy.clear();
+ break;
+ }
+
+ // restart, and wait for progress after cancel.
+ while (true) {
+ QVERIFY(!crr.cancel()); // not started
+ FILL_QUEUE_WITH_FETCH_REQUESTS_WITH_MANAGER(cm.data());
+ QVERIFY(crr.start());
+ if (!crr.cancel()) {
+ // due to thread scheduling, async cancel might be attempted
+ // after the request has already finished.. so loop and try again.
+ crr.waitForFinished();
+ temp.setId(QContactCollectionId());
+ if (!cm->saveCollection(&temp)) {
+ QSKIP("Unable to save temporary item for remove request cancellation test!");
+ }
+ crr.setCollectionId(temp.id());
+ bailoutCount -= 1;
+ if (!bailoutCount) {
+// qWarning("Unable to test cancelling due to thread scheduling!");
+ bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT;
+ break;
+ }
+ spy.clear();
+ continue;
+ }
+ crr.waitForFinished();
+ QVERIFY(crr.isCanceled());
+ QCOMPARE(cm->collections().size(), collectionCount); // temp collection should not have been removed
+ QList<QContactCollectionId> removeCollectionIds;
+ QList<QContactCollection> removeCollections = cm->collections();
+ for (int i = 0; i < removeCollections.size(); ++i)
+ removeCollectionIds << removeCollections.at(i).id();
+ QVERIFY(containsAllCollectionIds(removeCollectionIds, crr.collectionIds()));
+ QVERIFY(spy.count() >= 1); // active + cancelled progress signals
+ spy.clear();
+ break;
+ }
+
+ // now clean up our temp collection.
+ cm->removeCollection(temp.id());
+
+}
+
+void tst_QContactAsync::collectionSave()
+{
+ QFETCH(QString, uri);
+ QScopedPointer<QContactManager> cm(prepareModel(uri));
+ QContactCollectionSaveRequest csr;
+ QVERIFY(csr.type() == QContactAbstractRequest::CollectionSaveRequest);
+
+ // initial state - not started, no manager.
+ QVERIFY(!csr.isActive());
+ QVERIFY(!csr.isFinished());
+ QVERIFY(!csr.start());
+ QVERIFY(!csr.cancel());
+ QVERIFY(!csr.waitForFinished());
+
+ // save a new item
+ int originalCount = cm->collections().size();
+ QContactCollection testCollection;
+ testCollection.setMetaData(QContactCollection::KeyDescription, "test description");
+ testCollection.setMetaData(QContactCollection::KeyName, "New collection");
+ QList<QContactCollection> saveList;
+ saveList << testCollection;
+ csr.setManager(cm.data());
+ QCOMPARE(csr.manager(), cm.data());
+ QVERIFY(!csr.isActive());
+ QVERIFY(!csr.isFinished());
+ QVERIFY(!csr.cancel());
+ QVERIFY(!csr.waitForFinished());
+ qRegisterMetaType<QContactCollectionSaveRequest*>("QContactCollectionSaveRequest*");
+ QThreadSignalSpy spy(&csr, SIGNAL(stateChanged(QContactAbstractRequest::State)));
+ csr.setCollection(testCollection);
+ QCOMPARE(csr.collections(), saveList);
+ QVERIFY(!csr.cancel()); // not started
+ QVERIFY(csr.start());
+
+ QVERIFY((csr.isActive() && csr.state() == QContactAbstractRequest::ActiveState) || csr.isFinished());
+ //QVERIFY(csr.isFinished() || !csr.start()); // already started. // thread scheduling means this is untestable
+ QVERIFY(csr.waitForFinished());
+ QVERIFY(csr.isFinished());
+ QVERIFY(spy.count() >= 1); // active + finished progress signals
+ spy.clear();
+
+ QList<QContactCollection> expected = csr.collections();
+ QCOMPARE(expected.size(), 1);
+ QList<QContactCollection> result;
+ result << cm->collection(csr.collections().at(0).id());
+
+ // find the saved one, compare.
+ foreach (const QContactCollection &col, result)
+ QVERIFY(col.id() == expected.at(0).id());
+
+ // update a previously saved collection
+ QVERIFY(!result.isEmpty()); // make sure that we were able to retrieve the required collection.
+ testCollection = result.first();
+ testCollection.setMetaData(QContactCollection::KeyName, "test name");
+ saveList.clear();
+ saveList << testCollection;
+ csr.setCollections(saveList);
+ QCOMPARE(csr.collections(), saveList);
+ QVERIFY(!csr.cancel()); // not started
+ QVERIFY(csr.start());
+
+ QVERIFY((csr.isActive() && csr.state() == QContactAbstractRequest::ActiveState) || csr.isFinished());
+ //QVERIFY(csr.isFinished() || !csr.start()); // already started. // thread scheduling means this is untestable
+ QVERIFY(csr.waitForFinished());
+
+ QVERIFY(csr.isFinished());
+ QVERIFY(spy.count() >= 1); // active + finished progress signals
+ spy.clear();
+
+ expected = csr.collections();
+ result.clear();
+ result = cm->collections();
+ // find the saved one, compare.
+ foreach (const QContactCollection& col, result) {
+ if (col.id() == expected.at(0).id()) {
+ QVERIFY(col == expected.at(0)); // XXX TODO: if we change the semantic so that save merely updates the id...?
+ }
+ }
+ QCOMPARE(cm->collections().size(), originalCount + 1); // ie shouldn't have added an extra one (would be +2)
+ QVERIFY(csr.error() == QContactManager::NoError);
+ QVERIFY(csr.errorMap().isEmpty());
+
+ // save empty list
+ QList<QContactCollection> collectionList;
+ QContactCollectionSaveRequest csr1;
+ csr1.setManager(cm.data());
+ csr1.setCollections(collectionList);
+ csr1.start();
+ csr1.waitForFinished();
+ QVERIFY(csr1.isFinished());
+ QVERIFY(csr1.error() == QContactManager::NoError);
+
+ // cancelling
+ QContactCollection temp;
+ temp.setMetaData(testCollection.metaData());
+ temp.setExtendedMetaData("test", "shouldn't be saved");
+ saveList.clear();
+ saveList << temp;
+ csr.setCollections(saveList);
+
+ int bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT; // attempt to cancel 40 times. If it doesn't work due to threading, bail out.
+ while (true) {
+ QVERIFY(!csr.cancel()); // not started
+ FILL_QUEUE_WITH_FETCH_REQUESTS_WITH_MANAGER(cm.data());
+ QVERIFY(csr.start());
+ if (!csr.cancel()) {
+ // due to thread scheduling, async cancel might be attempted
+ // after the request has already finished.. so loop and try again.
+ csr.waitForFinished();
+ saveList = csr.collections();
+ if (cm->collections().size() > (originalCount + 1) && !cm->removeCollection(saveList.at(0).id())) {
+ QSKIP("Unable to remove saved collection to test cancellation of collection save request");
+ }
+ saveList.clear();
+ saveList << temp;
+ csr.setCollections(saveList);
+ bailoutCount -= 1;
+ if (!bailoutCount) {
+// qWarning("Unable to test cancelling due to thread scheduling!");
+ bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT;
+ break;
+ }
+ spy.clear();
+ continue;
+ }
+
+ // if we get here, then we are cancelling the request.
+ QVERIFY(csr.waitForFinished());
+ QVERIFY(csr.isCanceled());
+ QVERIFY(spy.count() >= 1); // active + cancelled progress signals
+ spy.clear();
+
+ // verify that the changes were not saved
+ expected.clear();
+ QList<QContactCollection> allCollections = cm->collections();
+ QVERIFY(!allCollections.contains(temp)); // should NOT contain it since it was cancelled.
+ QCOMPARE(allCollections.size(), originalCount + 1);
+ break;
+ }
+ // restart, and wait for progress after cancel.
+
+ while (true) {
+ QVERIFY(!csr.cancel()); // not started
+ FILL_QUEUE_WITH_FETCH_REQUESTS_WITH_MANAGER(cm.data());
+ QVERIFY(csr.start());
+ if (!csr.cancel()) {
+ // due to thread scheduling, async cancel might be attempted
+ // after the request has already finished.. so loop and try again.
+ csr.waitForFinished();
+ saveList = csr.collections();
+ if (cm->collections().size() > (originalCount + 1) && !cm->removeCollection(saveList.at(0).id())) {
+ QSKIP("Unable to remove saved item to test cancellation of item save request");
+ }
+ saveList.clear();
+ saveList << temp;
+ csr.setCollections(saveList);
+ bailoutCount -= 1;
+ if (!bailoutCount) {
+// qWarning("Unable to test cancelling due to thread scheduling!");
+ bailoutCount = MAX_OPTIMISTIC_SCHEDULING_LIMIT;
+ break;
+ }
+ spy.clear();
+ continue;
+ }
+ csr.waitForFinished(); // now wait until finished (if it hasn't already).
+ QVERIFY(csr.isCanceled());
+ QVERIFY(spy.count() >= 1); // active + cancelled progress signals
+ spy.clear();
+
+ // verify that the changes were not saved
+ expected.clear();
+ QList<QContactCollection> allCollections = cm->collections();
+ QVERIFY(!allCollections.contains(temp));
+ QCOMPARE(cm->collections().size(), originalCount + 1);
+ break;
+ }
+}
+
void tst_QContactAsync::maliciousManager()
{
// use the invalid manager: passes all requests through to base class
@@ -2655,6 +3122,11 @@ QContactManager* tst_QContactAsync::prepareModel(const QString& managerUri)
crb.setRelationshipType(QContactRelationship::IsSameAs());
cm->saveRelationship(&crb);
+ QContactCollection testCollection;
+ testCollection.setMetaData(QContactCollection::KeyName, "Test Collection");
+ testCollection.setMetaData(QContactCollection::KeyDescription, "test collection");
+ cm->saveCollection(&testCollection);
+
return cm;
// TODO: cleanup once test is complete
diff --git a/tests/auto/contacts/qcontactcollection/qcontactcollection.pro b/tests/auto/contacts/qcontactcollection/qcontactcollection.pro
new file mode 100644
index 000000000..bb6599776
--- /dev/null
+++ b/tests/auto/contacts/qcontactcollection/qcontactcollection.pro
@@ -0,0 +1,5 @@
+include(../../auto.pri)
+
+QT += contacts
+
+SOURCES += tst_qcontactcollection.cpp
diff --git a/tests/auto/contacts/qcontactcollection/tst_qcontactcollection.cpp b/tests/auto/contacts/qcontactcollection/tst_qcontactcollection.cpp
new file mode 100644
index 000000000..d36f36c48
--- /dev/null
+++ b/tests/auto/contacts/qcontactcollection/tst_qcontactcollection.cpp
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2015 Canonical Ltd
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <QtCore/qset.h>
+
+#include <QtContacts/qcontacts.h>
+
+
+QTCONTACTS_USE_NAMESPACE
+
+static inline QContactCollectionId makeId(const QString &managerName, uint id)
+{
+ return QContactCollectionId(QStringLiteral("qtcontacts:%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint)));
+}
+
+class tst_QContactCollection: public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QContactCollection();
+ virtual ~tst_QContactCollection();
+
+private slots:
+ void metaData();
+ void compare();
+ void idComparison();
+ void idHash();
+ void idStringFunctions();
+ void hash();
+ void datastream();
+ void traits();
+ void idTraits();
+};
+
+tst_QContactCollection::tst_QContactCollection()
+{
+}
+
+tst_QContactCollection::~tst_QContactCollection()
+{
+}
+
+void tst_QContactCollection::metaData()
+{
+ QContactCollection c;
+ QVERIFY(c.metaData().isEmpty());
+ c.setExtendedMetaData(QString(QStringLiteral("test")), 5);
+ QCOMPARE(c.extendedMetaData(QString(QStringLiteral("test"))).toInt(), 5);
+
+ QMap<QContactCollection::MetaDataKey, QVariant> mdm;
+ mdm.insert(QContactCollection::KeyName, QString(QStringLiteral("test2")));
+ c.setMetaData(mdm);
+ QCOMPARE(c.metaData(), mdm);
+ QCOMPARE(c.metaData(QContactCollection::KeyName).toString(), QString(QStringLiteral("test2")));
+}
+
+void tst_QContactCollection::compare()
+{
+ QContactCollection c, c2;
+ QVERIFY(c == c2);
+ c.setExtendedMetaData(QStringLiteral("test"), 5);
+ QVERIFY(c != c2);
+ c2.setExtendedMetaData(QStringLiteral("test"), 5);
+ QVERIFY(c == c2);
+
+ QMap<QContactCollection::MetaDataKey, QVariant> mdm;
+ mdm.insert(QContactCollection::KeyName, QStringLiteral("test2"));
+ c.setMetaData(mdm);
+ QVERIFY(c != c2);
+ c2.setMetaData(mdm);
+ QVERIFY(c == c2);
+
+ c2 = QContactCollection();
+ QVERIFY(c != c2);
+ c2 = c;
+ QVERIFY(c == c2);
+
+ c.setId(makeId(QStringLiteral("a"), 1));
+ QVERIFY(c != c2);
+ c2.setId(makeId(QStringLiteral("a"), 1));
+ QVERIFY(c == c2);
+ c.setId(makeId(QStringLiteral("b"), 1));
+ QVERIFY(c != c2);
+ c2.setId(c.id());
+ QVERIFY(c == c2);
+ c.setId(makeId(QStringLiteral("b"), 2));
+}
+
+void tst_QContactCollection::idComparison()
+{
+ QContactCollectionId id1(makeId("a", 1));
+ QContactCollectionId id2(makeId("a", 1));
+ QVERIFY(!(id1 < id2));
+ QVERIFY(!(id2 < id1));
+ QVERIFY(id1 == id2);
+
+ QContactCollectionId id3(makeId("a", 2));
+ QContactCollectionId id4(makeId("b", 1));
+ QContactCollectionId id5(makeId("b", 2));
+ QVERIFY((((id1 < id3) && !(id3 < id1)) || ((id3 < id1) && !(id1 < id3))) && (id1 != id3));
+ QVERIFY((((id1 < id4) && !(id4 < id1)) || ((id4 < id1) && !(id1 < id4))) && (id1 != id4));
+ QVERIFY((((id3 < id4) && !(id4 < id3)) || ((id4 < id3) && !(id3 < id4))) && (id3 != id4));
+ QVERIFY((((id1 < id5) && !(id5 < id1)) || ((id5 < id1) && !(id1 < id5))) && (id3 != id4));
+
+ QContactCollectionId id6;
+ QContactCollectionId id7(QString(), "1");
+ QContactCollectionId id8(QString(), "2");
+ QContactCollectionId id9(QStringLiteral("qtcontacts:basic:"), QByteArray());
+ QVERIFY(id6.isNull());
+ QVERIFY(id7.isNull());
+ QVERIFY(id8.isNull());
+ QVERIFY(id9.isNull());
+ QVERIFY(id6 == id7);
+ QVERIFY(!(id6 < id7));
+ QVERIFY(id7 == id6);
+ QVERIFY(!(id7 < id6));
+ QVERIFY(id7 == id8);
+ QVERIFY(!(id7 < id8));
+ QVERIFY(id8 == id7);
+ QVERIFY(!(id9 < id8));
+ QVERIFY(id8 == id9);
+ QVERIFY(!(id8 < id9));
+ QVERIFY(id9 == id8);
+ QVERIFY(!(id9 < id8));
+
+ QVERIFY(!(id1 == id6));
+ QVERIFY(!(id1 < id6));
+ QVERIFY(id6 < id1);
+ QVERIFY(!(id1 == id7));
+ QVERIFY(!(id1 < id7));
+ QVERIFY(id7 < id1);
+ QVERIFY(!(id1 == id8));
+ QVERIFY(!(id1 < id8));
+ QVERIFY(id8 < id1);
+ QVERIFY(!(id1 == id9));
+ QVERIFY(!(id1 < id9));
+ QVERIFY(id9 < id1);
+}
+
+void tst_QContactCollection::idHash()
+{
+ QContactCollectionId id1(makeId("a", 1));
+ QContactCollectionId id2(makeId("a", 1));
+ QContactCollectionId id3(makeId("b", 1));
+ QContactCollectionId id4(makeId("a", 2));
+ // note that the hash function ignores the managerUri
+ QCOMPARE(qHash(id1), qHash(id2));
+ QCOMPARE(qHash(id1), qHash(id3));
+ QVERIFY(qHash(id1) != qHash(id4));
+
+ QSet<QContactCollectionId> set;
+ set.insert(id1);
+ set.insert(id2);
+ set.insert(id3);
+ set.insert(id4);
+ QCOMPARE(set.size(), 3);
+}
+
+void tst_QContactCollection::idStringFunctions()
+{
+ // TODO: review test
+ QContactCollectionId id1(makeId("a", 1));
+ QContactCollectionId id2(makeId("a", 1));
+ QContactCollectionId id3(makeId("b", 1));
+ QContactCollectionId id4(makeId("a", 2));
+ QVERIFY(qHash(id1) == qHash(id2));
+ QVERIFY(qHash(id1) != qHash(id4));
+
+ // note that the toString and fromString functions are
+ // engine and id specific. This test merely checks that
+ // the API is hooked up correctly.
+
+ QVERIFY(id1.toString() == id2.toString());
+ QVERIFY(id1.toString() != id3.toString());
+ QVERIFY(id1.toString() != id4.toString());
+ QVERIFY(id3.toString() != id4.toString());
+
+ // this should "work" -- string of the correct format
+ const uint numericId2 = 2u;
+ const QByteArray localId2 = QByteArray(reinterpret_cast<const char *>(&numericId2), sizeof(uint));
+ QString prebuiltidstring = QString("qtcontacts") + QString(":") + QString("a") + QString("::") + localId2.toHex();
+ QContactCollectionId rebuiltid = QContactCollectionId::fromString(prebuiltidstring);
+ QVERIFY(rebuiltid == id4);
+ QVERIFY(rebuiltid.localId() == id4.localId());
+
+ // this string has the right format and one parameter, but requires a working backend
+ prebuiltidstring = QString("qtcontacts") + QString(":") + QString("a") + QString(":") + QString("key=value") + QString(":") + localId2.toHex();
+ rebuiltid = QContactCollectionId::fromString(prebuiltidstring);
+ QVERIFY(rebuiltid != id4);
+ QVERIFY(rebuiltid.localId() == id4.localId());
+
+ // this string has the right format and some parameters, but requires a working backend
+ prebuiltidstring = QString("qtcontacts") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=value2") + QString(":") + localId2.toHex();
+ rebuiltid = QContactCollectionId::fromString(prebuiltidstring);
+ QVERIFY(rebuiltid != id4);
+ QVERIFY(rebuiltid.localId() == id4.localId());
+
+ // this string has the right format but misses the value for a parameter
+ prebuiltidstring = QString("qtcontacts") + QString(":") + QString("a") + QString(":") + QString("key=value&key2=") + QString(":") + localId2.toHex();
+ rebuiltid = QContactCollectionId::fromString(prebuiltidstring);
+ QVERIFY(rebuiltid != id4);
+ QVERIFY(rebuiltid.localId() == id4.localId());
+
+ // this string misses a field (the parameters)
+ prebuiltidstring = QString("qtcontacts") + QString(":") + QString("a") + QString(":") + localId2.toHex();
+ rebuiltid = QContactCollectionId::fromString(prebuiltidstring);
+ QVERIFY(rebuiltid == QContactCollectionId()); // invalid so should be null.
+
+ // this string misses two fields (params plus manager uri)
+ prebuiltidstring = QString("qtcontacts") + QString(":") + QString::number(2);
+ rebuiltid = QContactCollectionId::fromString(prebuiltidstring);
+ QVERIFY(rebuiltid == QContactCollectionId()); // invalid so should be null.
+
+ // this string misses the prefix (qtorganizer)
+ prebuiltidstring = QString("notorganizer") + QString(":") + QString("a") + QString("::") + localId2.toHex();
+ rebuiltid = QContactCollectionId::fromString(prebuiltidstring);
+ QVERIFY(rebuiltid == QContactCollectionId()); // invalid so should be null.
+
+ // this string misses the manager uri
+ prebuiltidstring = QString("notorganizer") + QString(":::") + localId2.toHex();
+ rebuiltid = QContactCollectionId::fromString(prebuiltidstring);
+ QVERIFY(rebuiltid == QContactCollectionId()); // invalid so should be null.
+}
+
+void tst_QContactCollection::hash()
+{
+ // TODO: review tests
+ QContactCollectionId id(makeId("a", 1));
+ QContactCollection c1;
+ c1.setId(id);
+ c1.setExtendedMetaData("key", "value");
+ QContactCollection c2;
+ c2.setId(id);
+ c2.setExtendedMetaData("key", "value");
+ QContactCollection c3;
+ c3.setId(id);
+ c3.setExtendedMetaData("key", "another value");
+ QContactCollection c4; // no details
+ c4.setId(id);
+ QContactCollection c5;
+ c5.setId(id);
+ c5.setExtendedMetaData("key", "value");
+ QVERIFY(qHash(c1) == qHash(c2));
+ QVERIFY(qHash(c1) != qHash(c3));
+ QVERIFY(qHash(c1) != qHash(c4));
+ QVERIFY(qHash(c1) == qHash(c5));
+}
+
+void tst_QContactCollection::datastream()
+{
+ // collection datastreaming
+ QByteArray buffer;
+ QContactCollection collectionIn;
+ collectionIn.setExtendedMetaData("key", "value");
+ QContactCollection collectionOut;
+ QContactCollectionId originalId;
+
+ // first, stream an item with a complete id
+ {
+ QDataStream stream1(&buffer, QIODevice::WriteOnly);
+ QContactManager om("memory");
+ QVERIFY(om.saveCollection(&collectionIn)); // fill in its ID
+ originalId = collectionIn.id();
+ stream1 << collectionIn;
+ QVERIFY(buffer.size() > 0);
+ QDataStream stream2(buffer);
+ stream2 >> collectionOut;
+ QCOMPARE(collectionOut, collectionIn); // can use QCOMPARE for collections, since no detail keys.
+ }
+
+ // second, stream an item with an id with the mgr uri set, local id null
+ {
+ QDataStream stream1(&buffer, QIODevice::WriteOnly);
+ collectionIn.setId(QContactCollectionId());
+ stream1 << collectionIn;
+ QVERIFY(buffer.size() > 0);
+ QDataStream stream2(buffer);
+ stream2 >> collectionOut;
+ QCOMPARE(collectionOut, collectionIn); // can use QCOMPARE for collections, since no detail keys.
+ }
+
+ // third, stream an item with a null id
+ {
+ QDataStream stream1(&buffer, QIODevice::WriteOnly);
+ collectionIn.setId(QContactCollectionId());
+ stream1 << collectionIn;
+ QVERIFY(buffer.size() > 0);
+ QDataStream stream2(buffer);
+ stream2 >> collectionOut;
+ QVERIFY(collectionOut.metaData() == collectionIn.metaData());
+ QVERIFY(collectionOut.id() == collectionIn.id()); // should both be null ids.
+ }
+
+ // id datastreaming
+ buffer.clear();
+ QContactCollectionId inputId;
+ QContactCollectionId outputId;
+
+ // first, stream the whole id (mgr uri set, local id set)
+ {
+ inputId = originalId;
+ QString serializedId = inputId.toString();
+ outputId = QContactCollectionId::fromString(serializedId);
+ QCOMPARE(inputId, outputId);
+
+ inputId = originalId;
+ buffer.clear();
+ QDataStream stream1(&buffer, QIODevice::WriteOnly);
+ stream1 << inputId;
+ QVERIFY(buffer.size() > 0);
+ QDataStream stream2(buffer);
+ stream2 >> outputId;
+ QCOMPARE(inputId, outputId);
+ }
+
+ // second, stream a null id
+ {
+ inputId = QContactCollectionId();
+ QString serializedId = inputId.toString();
+ outputId = QContactCollectionId::fromString(serializedId);
+ QCOMPARE(inputId, outputId);
+
+ inputId = QContactCollectionId();
+ buffer.clear();
+ QDataStream stream1(&buffer, QIODevice::WriteOnly);
+ stream1 << inputId;
+ QVERIFY(buffer.size() > 0);
+ QDataStream stream2(buffer);
+ stream2 >> outputId;
+ QCOMPARE(inputId, outputId);
+ }
+}
+
+void tst_QContactCollection::traits()
+{
+ QCOMPARE(sizeof(QContactCollection), sizeof(void *));
+ QVERIFY(QTypeInfo<QContactCollection>::isComplex);
+ QVERIFY(!QTypeInfo<QContactCollection>::isStatic);
+ QVERIFY(!QTypeInfo<QContactCollection>::isLarge);
+ QVERIFY(!QTypeInfo<QContactCollection>::isPointer);
+ QVERIFY(!QTypeInfo<QContactCollection>::isDummy);
+}
+
+void tst_QContactCollection::idTraits()
+{
+ QCOMPARE(sizeof(QContactCollectionId), 2*sizeof(void *));
+ QVERIFY(QTypeInfo<QContactCollectionId>::isComplex);
+ QVERIFY(!QTypeInfo<QContactCollectionId>::isStatic);
+ QVERIFY(QTypeInfo<QContactCollectionId>::isLarge);
+ QVERIFY(!QTypeInfo<QContactCollectionId>::isPointer);
+ QVERIFY(!QTypeInfo<QContactCollectionId>::isDummy);
+}
+
+QTEST_MAIN(tst_QContactCollection)
+#include "tst_qcontactcollection.moc"
diff --git a/tests/auto/contacts/qcontactfilter/tst_qcontactfilter.cpp b/tests/auto/contacts/qcontactfilter/tst_qcontactfilter.cpp
index e347c3fdd..4df9a25f3 100644
--- a/tests/auto/contacts/qcontactfilter/tst_qcontactfilter.cpp
+++ b/tests/auto/contacts/qcontactfilter/tst_qcontactfilter.cpp
@@ -55,6 +55,11 @@ static inline QContactId makeId(const QString &managerName, uint id)
return QContactId(QStringLiteral("qtcontacts:basic%1:").arg(managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint)));
}
+static inline QContactCollectionId makeCollectionId(uint id)
+{
+ return QContactCollectionId(QStringLiteral("qtcontacts:basic:"), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint)));
+}
+
class tst_QContactFilter : public QObject
{
Q_OBJECT
@@ -81,9 +86,12 @@ private slots:
void canonicalizedFilter_data();
void testFilter();
void testFilter_data();
+ void collectionFilter();
void datastream();
void datastream_data();
+ void testDebugStreamOut();
+ void testDebugStreamOut_data();
void traits();
};
@@ -1210,6 +1218,40 @@ void tst_QContactFilter::testFilter_data()
}
}
+void tst_QContactFilter::collectionFilter()
+{
+ QContactCollectionFilter icf;
+
+ QVERIFY(icf.collectionIds().isEmpty());
+
+ QContactCollectionId id1 = makeCollectionId(5);
+ QContactCollectionId id2 = makeCollectionId(6);
+ QContactCollectionId id3 = makeCollectionId(7);
+ QContactCollectionId id4 = makeCollectionId(12);
+ QSet<QContactCollectionId> ids;
+ ids << id1 << id2 << id3;
+
+ icf.setCollectionIds(ids);
+ QVERIFY(icf.collectionIds() == ids);
+
+ icf.setCollectionId(id4);
+ ids.clear();
+ ids << id4;
+ QVERIFY(icf.collectionIds() == ids);
+
+ QContactCollectionFilter icf2;
+ icf2 = icf;
+ QVERIFY(icf2.collectionIds() == ids);
+
+ QContactFilter fil;
+ fil = icf;
+ QVERIFY(fil.type() == QContactFilter::CollectionFilter);
+
+ QContactCollectionFilter icf3(fil);
+ QVERIFY(fil.type() == QContactFilter::CollectionFilter);
+ QVERIFY(icf3.collectionIds() == ids);
+}
+
void tst_QContactFilter::datastream()
{
QFETCH(QContactFilter, filterIn);
@@ -1286,6 +1328,58 @@ void tst_QContactFilter::datastream_data()
}
}
+void tst_QContactFilter::testDebugStreamOut()
+{
+ QFETCH(QContactFilter, filterIn);
+ QFETCH(QString, messageExpected);
+
+ QTest::ignoreMessage(QtDebugMsg, messageExpected.toUtf8());
+ qDebug() << filterIn;
+}
+
+void tst_QContactFilter::testDebugStreamOut_data()
+{
+ QTest::addColumn<QContactFilter>("filterIn");
+ QTest::addColumn<QString>("messageExpected");
+
+ {
+ QContactCollectionFilter filter;
+ QContactCollectionId id1 = makeCollectionId(5);
+ QContactCollectionId id2 = makeCollectionId(6);
+ QContactCollectionId id3 = makeCollectionId(7);
+ QContactCollectionId id4 = makeCollectionId(12);
+ QSet<QContactCollectionId> ids;
+ ids << id1 << id2 << id3;
+ filter.setCollectionIds(ids);
+ // Testing method setCollectionIds
+ QTest::newRow("collection") << (QContactFilter)filter << "QContactFilter(QContactCollectionFilter(collectionIds=(QContactCollectionId(qtcontacts:basic::05000000), QContactCollectionId(qtcontacts:basic::06000000), QContactCollectionId(qtcontacts:basic::07000000))))";
+
+ filter.setCollectionId(id2);
+ // Testing method setCollectionId (and the related clearing of the collection)
+ QTest::newRow("collection") << (QContactFilter)filter << "QContactFilter(QContactCollectionFilter(collectionIds=(QContactCollectionId(qtcontacts:basic::06000000))))";
+ filter.setCollectionId(id4);
+ // Testing again method setCollectionId (and the related clearing of the collection)
+ QTest::newRow("collection") << (QContactFilter)filter << "QContactFilter(QContactCollectionFilter(collectionIds=(QContactCollectionId(qtcontacts:basic::0c000000))))";
+ ids.clear();
+ ids << id4;
+ // Testing again method setCollectionIds
+ QTest::newRow("collection") << (QContactFilter)filter << "QContactFilter(QContactCollectionFilter(collectionIds=(QContactCollectionId(qtcontacts:basic::0c000000))))";
+
+ QContactCollectionFilter filter2;
+ filter2 = filter;
+ // Testing again method setCollectionIds on the copied filter
+ QTest::newRow("collection") << (QContactFilter)filter2 << "QContactFilter(QContactCollectionFilter(collectionIds=(QContactCollectionId(qtcontacts:basic::0c000000))))";
+
+ QContactFilter fil;
+ fil = filter;
+ // Testing that the assignment/conversion went fine
+ QTest::newRow("collection") << (QContactFilter)fil << "QContactFilter(QContactCollectionFilter(collectionIds=(QContactCollectionId(qtcontacts:basic::0c000000))))";
+
+ QContactCollectionFilter filter3(fil);
+ QTest::newRow("collection") << (QContactFilter)filter3 << "QContactFilter(QContactCollectionFilter(collectionIds=(QContactCollectionId(qtcontacts:basic::0c000000))))";
+ }
+}
+
void tst_QContactFilter::traits()
{
QCOMPARE(sizeof(QContactFilter), sizeof(void *));
diff --git a/tests/auto/contacts/qcontactmanager/tst_qcontactmanager.cpp b/tests/auto/contacts/qcontactmanager/tst_qcontactmanager.cpp
index 7e7f8d0a0..94395c859 100644
--- a/tests/auto/contacts/qcontactmanager/tst_qcontactmanager.cpp
+++ b/tests/auto/contacts/qcontactmanager/tst_qcontactmanager.cpp
@@ -150,6 +150,10 @@ private slots:
void contactType();
void lateDeletion();
void compareVariant();
+ void createCollection();
+ void modifyCollection();
+ void removeCollection();
+ void saveContactIntoCollections();
#if defined(USE_VERSIT_PLZ)
void partialSave();
@@ -190,6 +194,10 @@ private slots:
void lateDeletion_data() {addManagers();}
void testInterSectionOfIdFilters_data() {addManagers();}
void testInterSectionOfIdAndDetailFilters_data() {addManagers();}
+ void createCollection_data() {addManagers();}
+ void modifyCollection_data() {addManagers();}
+ void removeCollection_data() {addManagers();}
+ void saveContactIntoCollections_data() {addManagers();}
};
// Helper class that connects to a signal on ctor, and disconnects on dtor
@@ -1474,15 +1482,23 @@ void tst_QContactManager::memoryManager()
nc.setLastName("Civilian");
c.saveDetail(&nc);
m1.saveContact(&c);
+
+ // reset ids
c.setId(QContactId());
+ c.setCollectionId(QContactCollectionId());
+
QContact c2;
QContactName nc2 = c2.detail(QContactName::Type);
c2 = c;
nc2.setMiddleName("Public");
c2.saveDetail(&nc2);
+
m2.saveContact(&c2); // save c2 first; c will be given a higher id
m2.saveContact(&c); // save c to m2
+
+ // reset ids
c.setId(QContactId());
+ c.setCollectionId(QContactCollectionId());
nc.setSuffix("MD");
c.saveDetail(&nc);
m3.saveContact(&c);
@@ -1871,6 +1887,7 @@ void tst_QContactManager::signalEmission()
qRegisterMetaType<QContactId>("QContactId");
qRegisterMetaType<QList<QContactId> >("QList<QContactId>");
qRegisterMetaType<QList<QContactDetail::DetailType> >("QList<QContactDetail::DetailType>");
+
QSignalSpy spyCA(m1.data(), SIGNAL(contactsAdded(QList<QContactId>)));
QSignalSpy spyCM(m1.data(), SIGNAL(contactsChanged(QList<QContactId>, QList<QContactDetail::DetailType>)));
QSignalSpy spyCR(m1.data(), SIGNAL(contactsRemoved(QList<QContactId>)));
@@ -1879,8 +1896,10 @@ void tst_QContactManager::signalEmission()
QTestSignalSink cmsink(m1.data(), SIGNAL(contactsChanged(QList<QContactId>, QList<QContactDetail::DetailType>)));
QTestSignalSink crsink(m1.data(), SIGNAL(contactsRemoved(QList<QContactId>)));
+
QList<QVariant> args;
QList<QContactId> arg;
+ QList<QContactCollectionId> collectionIdList;
QContact c;
QList<QContact> batchAdd;
QList<QContactId> batchRemove;
@@ -3209,6 +3228,153 @@ void tst_QContactManager::compareVariant()
QVERIFY((comparison + expected) == 0);
}
+void tst_QContactManager::createCollection()
+{
+ QFETCH(QString, uri);
+ QScopedPointer<QContactManager> cm(QContactManager::fromUri(uri));
+
+ qRegisterMetaType<QList<QContactCollectionId> >("QList<QContactCollectionId>");
+ QSignalSpy collectionsAddedSpy(cm.data(), SIGNAL(collectionsAdded(QList<QContactCollectionId>)));
+ QByteArray collectionName = QUuid::createUuid().toByteArray();
+
+ // create collection
+ {
+ QContactCollection col;
+ col.setMetaData(QContactCollection::KeyName, collectionName);
+ QVERIFY(cm->saveCollection(&col));
+ }
+
+ // check "collectionsAdded" signal
+ QCOMPARE(collectionsAddedSpy.count(), 1);
+ QList<QContactCollectionId> ids = collectionsAddedSpy.takeFirst().at(0).value<QList<QContactCollectionId> >();
+ QCOMPARE(ids.count(), 1);
+
+ // query for new collection
+ {
+ QContactCollection col = cm->collection(ids.at(0));
+ QVERIFY(!col.id().isNull());
+ QCOMPARE(col.id().toString(), ids.at(0).toString());
+ QCOMPARE(col.metaData(QContactCollection::KeyName).toByteArray(), collectionName);
+ }
+}
+
+void tst_QContactManager::modifyCollection()
+{
+ QFETCH(QString, uri);
+ QScopedPointer<QContactManager> cm(QContactManager::fromUri(uri));
+
+ qRegisterMetaType<QList<QContactCollectionId> >("QList<QContactCollectionId>");
+ QSignalSpy collectionsAddedSpy(cm.data(), SIGNAL(collectionsAdded(QList<QContactCollectionId>)));
+ QSignalSpy collectionsChangedSpy(cm.data(), SIGNAL(collectionsChanged(QList<QContactCollectionId>)));
+
+ QContactCollectionId colId;
+ QByteArray collectionName = QUuid::createUuid().toByteArray();
+
+ // save a new collection
+ {
+ QContactCollection col;
+ col.setMetaData(QContactCollection::KeyName, collectionName);
+ QVERIFY(cm->saveCollection(&col));
+ QTRY_COMPARE(collectionsAddedSpy.count(), 1);
+ colId = col.id();
+ QVERIFY(!colId.isNull());
+ }
+
+ // edit collection
+ {
+ QCOMPARE(collectionsChangedSpy.count(), 0);
+ QContactCollection col = cm->collection(colId);
+ QByteArray newCollectionName = QUuid::createUuid().toByteArray();
+ col.setMetaData(QContactCollection::KeyName, newCollectionName);
+ QVERIFY(cm->saveCollection(&col));
+
+ // check signal "collectionsChanged" fired contains the collection id
+ QTRY_COMPARE(collectionsChangedSpy.count(), 1);
+ QList<QContactCollectionId> ids = collectionsChangedSpy.takeFirst().at(0).value<QList<QContactCollectionId> >();
+ QCOMPARE(ids.at(0).toString(), colId.toString());
+
+ // check if the collection name was updated
+ QContactCollection col2 = cm->collection(colId);
+ QCOMPARE(col2.metaData(QContactCollection::KeyName).toByteArray(), newCollectionName);
+ }
+}
+
+void tst_QContactManager::removeCollection()
+{
+ QFETCH(QString, uri);
+ QScopedPointer<QContactManager> cm(QContactManager::fromUri(uri));
+
+ qRegisterMetaType<QList<QContactCollectionId> >("QList<QContactCollectionId>");
+ QSignalSpy collectionsAddedSpy(cm.data(), SIGNAL(collectionsAdded(QList<QContactCollectionId>)));
+ QSignalSpy collectionsRemovedSpy(cm.data(), SIGNAL(collectionsRemoved(QList<QContactCollectionId>)));
+
+ QContactCollectionId colId;
+
+ // save a new collection
+ {
+ QContactCollection col;
+ QByteArray collectionName = QUuid::createUuid().toByteArray();
+ col.setMetaData(QContactCollection::KeyName, collectionName);
+ QVERIFY(cm->saveCollection(&col));
+ QTRY_COMPARE(collectionsAddedSpy.count(), 1);
+ colId = col.id();
+ }
+ QList<QContactCollection> collections = cm->collections();
+
+ // remove collection
+ cm->removeCollection(colId);
+
+ // check "collectionsRemoved" signal
+ QTRY_COMPARE(collectionsRemovedSpy.count(), 1);
+ QList<QContactCollectionId> ids = collectionsRemovedSpy.takeFirst().at(0).value<QList<QContactCollectionId> >();
+ QCOMPARE(ids.at(0).toString(), colId.toString());
+
+
+ // check if the correct collection was removed
+ QList<QContactCollection> collectionsAfterRemoval = cm->collections();
+ QCOMPARE(collections.count() - 1, collectionsAfterRemoval.count());
+ Q_FOREACH (const QContactCollection &col, collectionsAfterRemoval) {
+ collections.removeAll(col);
+ }
+ QCOMPARE(collections.count(), 1);
+ QCOMPARE(collections.at(0).id().toString(), colId.toString());
+}
+
+void tst_QContactManager::saveContactIntoCollections()
+{
+ QFETCH(QString, uri);
+ QScopedPointer<QContactManager> cm(QContactManager::fromUri(uri));
+
+ qRegisterMetaType<QList<QContactCollectionId> >("QList<QContactCollectionId>");
+ QSignalSpy collectionsAddedSpy(cm.data(), SIGNAL(collectionsAdded(QList<QContactCollectionId>)));
+ QByteArray collectionName = QUuid::createUuid().toByteArray();
+ QContactCollectionId colId;
+ QContactId cId;
+
+ // create collection
+ {
+ QContactCollection col;
+ col.setMetaData(QContactCollection::KeyName, collectionName);
+ QVERIFY(cm->saveCollection(&col));
+ QTRY_COMPARE(collectionsAddedSpy.count(), 1);
+ colId = col.id();
+ }
+
+ // create contact
+ {
+ QContact c = createContact("Alice", "Last", "12345");
+ c.setCollectionId(colId);
+ cm->saveContact(&c);
+ cId = c.id();
+ }
+
+ // query new contact and check for collection
+ {
+ QContact c = cm->contact(cId);
+ QCOMPARE(c.collectionId().toString(), colId.toString());
+ }
+}
+
void tst_QContactManager::compareVariant_data()
{
QTest::addColumn<QVariant>("a");
diff --git a/tests/auto/contacts/qmlcontacts/qmlcontacts.pro b/tests/auto/contacts/qmlcontacts/qmlcontacts.pro
index 540543d76..0a9187726 100644
--- a/tests/auto/contacts/qmlcontacts/qmlcontacts.pro
+++ b/tests/auto/contacts/qmlcontacts/qmlcontacts.pro
@@ -12,8 +12,10 @@ OTHER_FILES += \
testcases/ContactsSavingTestCase.qml \
testcases/ContactsSignalingTestCase.qml \
testcases/ContactsTestHelper.qml \
+ testcases/tst_collection.qml \
testcases/tst_contact_add_detail.qml \
testcases/tst_contact_addresses.qml \
+ testcases/tst_contact_collection_filter.qml \
testcases/tst_contact_detail_access.qml \
testcases/tst_contactdetail.qml \
testcases/tst_contact_emails.qml \
diff --git a/tests/auto/contacts/qmlcontacts/testcases/ContactsSavingTestCase.qml b/tests/auto/contacts/qmlcontacts/testcases/ContactsSavingTestCase.qml
index bc2911178..b5e2ded90 100644
--- a/tests/auto/contacts/qmlcontacts/testcases/ContactsSavingTestCase.qml
+++ b/tests/auto/contacts/qmlcontacts/testcases/ContactsSavingTestCase.qml
@@ -48,6 +48,7 @@ TestCase {
id: contactsSavingTestCase
property SignalSpy spy
+ property SignalSpy collectionSpy
property bool debug: false
ContactsTestConfiguration {
@@ -69,6 +70,15 @@ TestCase {
contactsSavingTestCase);
spy.target = model;
spy.signalName = "contactsChanged";
+
+ collectionSpy = Qt.createQmlObject(
+ "import QtTest 1.0;" +
+ "SignalSpy {" +
+ "}",
+ contactsSavingTestCase);
+ collectionSpy.target = model
+ collectionSpy.signalName = "collectionsChanged"
+
return spy;
}
@@ -83,6 +93,13 @@ TestCase {
spy.wait();
}
+ // Verify that the collectionsChanged signal is emitted
+ function waitForCollectionsChanged() {
+ logDebug("waitForCollectionsChanged");
+ collectionSpy.wait();
+ }
+
+
// Wait until duration has elapsed, or the contactsChanged signal is emitted
function waitUntilContactsChanged(duration) {
logDebug("waitUntilContactsChanged");
diff --git a/tests/auto/contacts/qmlcontacts/testcases/tst_contact_collection_filter.qml b/tests/auto/contacts/qmlcontacts/testcases/tst_contact_collection_filter.qml
new file mode 100644
index 000000000..074adb52a
--- /dev/null
+++ b/tests/auto/contacts/qmlcontacts/testcases/tst_contact_collection_filter.qml
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2015 Canonical Ltd
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+import QtContacts 5.0
+
+ContactsSavingTestCase {
+ id: testcase
+ name: "Contacts collection filter test"
+
+ property string defaultCollectionId: ""
+
+ ContactModel {
+ id: model
+ manager: getManagerUnderTest()
+ autoUpdate: true
+ }
+
+ Collection {
+ id: testCollection
+ name: 'My collection filter test'
+ description: 'collection filter test'
+ }
+
+ Contact {
+ id: contact1;
+ Name {
+ firstName: "A"
+ }
+ PhoneNumber {
+ number: "1111111111"
+ }
+ }
+
+ Contact {
+ id: contact2;
+ Name {
+ firstName: "B"
+ }
+ PhoneNumber {
+ number: "2222222222"
+ }
+ }
+
+ Contact {
+ id: contact3;
+ Name {
+ firstName: "John Joe"
+ }
+ PhoneNumber {
+ number: "3333333333"
+ }
+ }
+
+ function createCollectionFilter(ids)
+ {
+ var filter = Qt.createQmlObject(
+ "import QtContacts 5.0;" +
+ "CollectionFilter {}",
+ testcase);
+
+ filter.ids = ids
+ return filter;
+ }
+
+ function initTestCase() {
+ initTestForModel(model);
+ waitUntilContactsChanged();
+ compare(model.collections.length, 1);
+ defaultCollectionId = model.collections[0].collectionId
+ // The wait is needed so the model is populated
+ // (e.g. with garbage left from previous test runs)
+ // before cleanup() is called.
+ emptyContacts(model);
+ model.saveCollection(testCollection)
+ waitForCollectionsChanged();
+ compare(model.collections.length, 2);
+ model.saveContact(contact1);
+ waitForContactsChanged();
+ compare(contact1.collectionId, defaultCollectionId);
+ contact2.collectionId = testCollection.collectionId
+ model.saveContact(contact2);
+ waitForContactsChanged();
+ contact3.collectionId = testCollection.collectionId
+ model.saveContact(contact3);
+ waitForContactsChanged();
+ compare(model.contacts.length, 3);
+ }
+
+ function test_collectionFilter(data) {
+ var filterDefaultCollection = createCollectionFilter([defaultCollectionId]);
+ model.filter = filterDefaultCollection;
+ waitForContactsChanged();
+ compare(model.contacts.length, 1);
+
+ var filterOnlyNewCollection = createCollectionFilter([testCollection.collectionId]);
+ model.filter = filterOnlyNewCollection;
+ waitForContactsChanged();
+ compare(model.contacts.length, 2);
+
+ var filterNewCollectionAndDefaultCollection = createCollectionFilter([defaultCollectionId, testCollection.collectionId])
+ model.filter = filterNewCollectionAndDefaultCollection;
+ waitForContactsChanged();
+ compare(model.contacts.length, 3);
+
+ var filterEmpty = createCollectionFilter([])
+ model.filter = filterEmpty;
+ waitForContactsChanged();
+ compare(model.contacts.length, 0);
+
+ var filterValidAndInvalidIds = createCollectionFilter([defaultCollectionId, "12345678", testCollection.collectionId])
+ model.filter = filterValidAndInvalidIds;
+ waitForContactsChanged();
+ compare(model.contacts.length, 3);
+
+ var filterWithInvalidId = createCollectionFilter(["12345678"])
+ model.filter = filterWithInvalidId;
+ waitForContactsChanged();
+ compare(model.contacts.length, 0);
+ }
+}