--- a/qtmobility/tests/auto/qcontactmanager/tst_qcontactmanager.cpp Mon May 03 13:18:40 2010 +0300
+++ b/qtmobility/tests/auto/qcontactmanager/tst_qcontactmanager.cpp Fri May 14 16:41:33 2010 +0300
@@ -108,6 +108,8 @@
int foo;
};
Q_DECLARE_METATYPE(UnsupportedMetatype)
+Q_DECLARE_METATYPE(QContact)
+Q_DECLARE_METATYPE(QContactManager::Error)
class tst_QContactManager : public QObject
{
@@ -127,11 +129,11 @@
QContact createContact(QContactDetailDefinition nameDef, QString firstName, QString lastName, QString phoneNumber);
void saveContactName(QContact *contact, QContactDetailDefinition nameDef, QContactName *contactName, const QString &name) const;
- QContactManagerDataHolder managerDataHolder;
+ QScopedPointer<QContactManagerDataHolder> managerDataHolder;
public slots:
- void init();
- void cleanup();
+ void initTestCase();
+ void cleanupTestCase();
private slots:
void doDump();
@@ -143,6 +145,7 @@
/* Special test with special data */
void uriParsing();
void nameSynthesis();
+ void compatibleContact();
/* Tests that are run on all managers */
void metadata();
@@ -167,10 +170,13 @@
void invalidManager();
void memoryManager();
void changeSet();
-
- /* data providers (mostly all engines) */
- void uriParsing_data(); // Special data
- void nameSynthesis_data(); // Special data
+ void fetchHint();
+
+ /* Special test with special data */
+ void uriParsing_data();
+ void nameSynthesis_data();
+ void compatibleContact_data();
+ /* Tests that are run on all managers */
void metadata_data() {addManagers();}
void nullIdOperations_data() {addManagers();}
void add_data() {addManagers();}
@@ -195,8 +201,10 @@
{
}
-void tst_QContactManager::init()
+void tst_QContactManager::initTestCase()
{
+ managerDataHolder.reset(new QContactManagerDataHolder());
+
/* Make sure these other test plugins are NOT loaded by default */
// These are now removed from the list of managers in addManagers()
//QVERIFY(!QContactManager::availableManagers().contains("testdummy"));
@@ -204,8 +212,9 @@
//QVERIFY(!QContactManager::availableManagers().contains("maliciousplugin"));
}
-void tst_QContactManager::cleanup()
+void tst_QContactManager::cleanupTestCase()
{
+ managerDataHolder.reset(0);
}
void tst_QContactManager::dumpContactDifferences(const QContact& ca, const QContact& cb)
@@ -293,6 +302,33 @@
}
}
+ // Second remove any superset matches (eg, backend adds a field)
+ aDetails = a.details();
+ bDetails = b.details();
+ foreach (QContactDetail d, aDetails) {
+ foreach (QContactDetail d2, bDetails) {
+ if (d.definitionName() == d2.definitionName()) {
+ bool canRemove = true;
+ QMap<QString, QVariant> d2map = d2.variantValues();
+ foreach (QString key, d2map.keys()) {
+ if (d.value(key) != d2.value(key)) {
+ // d can have _more_ keys than d2,
+ // but not _less_; and it cannot
+ // change the value.
+ canRemove = false;
+ }
+ }
+
+ if (canRemove) {
+ // if we get to here, we can remove the details.
+ a.removeDetail(&d);
+ b.removeDetail(&d2);
+ break;
+ }
+ }
+ }
+ }
+
// check for contact type updates
if (!a.type().isEmpty())
if (!b.type().isEmpty())
@@ -311,7 +347,7 @@
void tst_QContactManager::dumpContact(const QContact& contact)
{
QContactManager m;
- qDebug() << "Contact: " << contact.id().localId() << "(" << m.synthesizedDisplayLabel(contact) << ")";
+ qDebug() << "Contact: " << contact.id().localId() << "(" << m.synthesizedContactDisplayLabel(contact) << ")";
QList<QContactDetail> details = contact.details();
foreach(QContactDetail d, details) {
qDebug() << " " << d.definitionName() << ":";
@@ -703,11 +739,11 @@
QVERIFY(cm->saveContact(&alice));
QVERIFY(cm->error() == QContactManager::NoError);
- QVERIFY(alice.id() != QContactId());
+ QVERIFY(!alice.id().managerUri().isEmpty());
+ QVERIFY(alice.id().localId() != 0);
QCOMPARE(cm->contactIds().count(), currCount+1);
QContact added = cm->contact(alice.id().localId());
- QVERIFY(added.id() != QContactId());
QVERIFY(added.id() == alice.id());
if (!isSuperset(added, alice)) {
@@ -748,6 +784,18 @@
// continue;
//}
+ if (cm->managerName() == "maemo5") {
+ // The maemo5 backend only supports reading of Guid and QCOA
+ if (def.name() == QContactGuid::DefinitionName)
+ continue;
+ if (def.name() == QContactOnlineAccount::DefinitionName)
+ continue;
+ }
+
+ // This is probably read-only
+ if (def.name() == QContactTimestamp::DefinitionName)
+ continue;
+
// otherwise, create a new detail of the given type and save it to the contact
QContactDetail det(def.name());
QMap<QString, QContactDetailFieldDefinition> fieldmap = def.fields();
@@ -756,6 +804,10 @@
// get the field, and check to see that it's not constrained.
QContactDetailFieldDefinition currentField = fieldmap.value(fieldKey);
+ // Don't test detail uris as these are manager specific
+ if (fieldKey == QContactDetail::FieldDetailUri)
+ continue;
+
// Special case: phone number.
if (def.name() == QContactPhoneNumber::DefinitionName &&
fieldKey == QContactPhoneNumber::FieldNumber) {
@@ -810,12 +862,13 @@
// if we get here, we don't know what sort of value can be saved...
}
}
- megacontact.saveDetail(&det);
+ if (!det.isEmpty())
+ megacontact.saveDetail(&det);
}
QVERIFY(cm->saveContact(&megacontact)); // must be able to save since built from definitions.
QContact retrievedMegacontact = cm->contact(megacontact.id().localId());
- if (retrievedMegacontact != megacontact) {
+ if (!isSuperset(retrievedMegacontact, megacontact)) {
dumpContactDifferences(megacontact, retrievedMegacontact);
QEXPECT_FAIL("mgr='wince'", "Address Display Label mismatch", Continue);
QCOMPARE(megacontact, retrievedMegacontact);
@@ -845,7 +898,7 @@
// verify save
QContact retrievedContactable = cm->contact(veryContactable.id().localId());
- if (retrievedContactable != veryContactable) {
+ if (!isSuperset(retrievedContactable, veryContactable)) {
dumpContactDifferences(veryContactable, retrievedContactable);
QEXPECT_FAIL("mgr='wince'", "Number of phones supported mismatch", Continue);
QCOMPARE(veryContactable, retrievedContactable);
@@ -1146,7 +1199,7 @@
nf.setLastName("Lastname");
foo.saveDetail(&nf);
- QVERIFY(manager.synthesizedDisplayLabel(foo).isEmpty());
+ QVERIFY(manager.synthesizedContactDisplayLabel(foo).isEmpty());
QVERIFY(manager.error() == QContactManager::NotSupportedError);
QVERIFY(manager.saveContact(&foo) == false);
@@ -1594,7 +1647,119 @@
c.saveDetail(&org2);
// Finally!
- QCOMPARE(cm.synthesizedDisplayLabel(c), expected);
+ QCOMPARE(cm.synthesizedContactDisplayLabel(c), expected);
+}
+
+void tst_QContactManager::compatibleContact_data()
+{
+ QTest::addColumn<QContact>("input");
+ QTest::addColumn<QContact>("expected");
+ QTest::addColumn<QContactManager::Error>("error");
+
+ QContact baseContact;
+ QContactName name;
+ name.setFirstName(QLatin1String("First"));
+ baseContact.saveDetail(&name);
+
+ {
+ QTest::newRow("already compatible") << baseContact << baseContact << QContactManager::NoError;
+ }
+
+ {
+ QContact contact(baseContact);
+ QContactDetail detail("UnknownDetail");
+ detail.setValue("Key", QLatin1String("Value"));
+ contact.saveDetail(&detail);
+ QTest::newRow("unknown detail") << contact << baseContact << QContactManager::NoError;
+ }
+
+ {
+ QContact contact(baseContact);
+ QContactType type1;
+ type1.setType(QContactType::TypeContact);
+ contact.saveDetail(&type1);
+ QContactType type2;
+ type2.setType(QContactType::TypeGroup);
+ contact.saveDetail(&type2);
+ QContact expected(baseContact);
+ expected.saveDetail(&type2);
+ QTest::newRow("duplicate unique field") << contact << expected << QContactManager::NoError;
+ }
+
+ {
+ QContact contact(baseContact);
+ QContactPhoneNumber phoneNumber;
+ phoneNumber.setValue("UnknownKey", "Value");
+ contact.saveDetail(&phoneNumber);
+ QTest::newRow("unknown field") << contact << baseContact << QContactManager::NoError;
+ }
+
+ {
+ QContact contact(baseContact);
+ QContactDisplayLabel displayLabel;
+ displayLabel.setValue(QContactDisplayLabel::FieldLabel, QStringList("Value"));
+ contact.saveDetail(&displayLabel);
+ QTest::newRow("wrong type") << contact << baseContact << QContactManager::NoError;
+ }
+
+ {
+ QContact contact(baseContact);
+ QContactPhoneNumber phoneNumber1;
+ phoneNumber1.setNumber(QLatin1String("1234"));
+ phoneNumber1.setSubTypes(QStringList()
+ << QContactPhoneNumber::SubTypeMobile
+ << QContactPhoneNumber::SubTypeVoice
+ << QLatin1String("InvalidSubtype"));
+ contact.saveDetail(&phoneNumber1);
+ QContact expected(baseContact);
+ QContactPhoneNumber phoneNumber2;
+ phoneNumber2.setNumber(QLatin1String("1234"));
+ phoneNumber2.setSubTypes(QStringList()
+ << QContactPhoneNumber::SubTypeMobile
+ << QContactPhoneNumber::SubTypeVoice);
+ expected.saveDetail(&phoneNumber2);
+ QTest::newRow("bad value (list)") << contact << expected << QContactManager::NoError;
+ }
+
+ {
+ QContact contact(baseContact);
+ QContactPhoneNumber phoneNumber1;
+ phoneNumber1.setNumber(QLatin1String("1234"));
+ phoneNumber1.setSubTypes(QStringList(QLatin1String("InvalidSubtype")));
+ contact.saveDetail(&phoneNumber1);
+ QContact expected(baseContact);
+ QContactPhoneNumber phoneNumber2;
+ phoneNumber2.setNumber(QLatin1String("1234"));
+ expected.saveDetail(&phoneNumber2);
+ QTest::newRow("all bad value (list)") << contact << expected << QContactManager::NoError;
+ }
+
+ {
+ QContact contact(baseContact);
+ QContactGender gender;
+ gender.setGender(QLatin1String("UnknownGender"));
+ contact.saveDetail(&gender);
+ QTest::newRow("bad value (string)") << contact << baseContact << QContactManager::NoError;
+ }
+
+ {
+ QContact contact;
+ QContactGender gender;
+ gender.setGender(QLatin1String("UnknownGender"));
+ contact.saveDetail(&gender);
+ QTest::newRow("bad value (string)") << contact << QContact() << QContactManager::DoesNotExistError;
+ }
+}
+
+void tst_QContactManager::compatibleContact()
+{
+ QContactManager cm("memory");
+
+ QFETCH(QContact, input);
+ QFETCH(QContact, expected);
+ QFETCH(QContactManager::Error, error);
+ QCOMPARE(cm.compatibleContact(input), expected);
+ QCOMPARE(cm.error(), error);
}
void tst_QContactManager::contactValidation()
@@ -1700,12 +1865,9 @@
void tst_QContactManager::signalEmission()
{
+ QTest::qWait(500); // clear the signal queue
QFETCH(QString, uri);
QScopedPointer<QContactManager> m1(QContactManager::fromUri(uri));
- QScopedPointer<QContactManager> m2(QContactManager::fromUri(uri));
-
- QVERIFY(m1->hasFeature(QContactManager::Anonymous) ==
- m2->hasFeature(QContactManager::Anonymous));
qRegisterMetaType<QContactLocalId>("QContactLocalId");
qRegisterMetaType<QList<QContactLocalId> >("QList<QContactLocalId>");
@@ -1714,8 +1876,8 @@
QSignalSpy spyCR(m1.data(), SIGNAL(contactsRemoved(QList<QContactLocalId>)));
QList<QVariant> args;
+ QList<QContactLocalId> arg;
QContact c;
- QContactLocalId temp;
QList<QContact> batchAdd;
QList<QContactLocalId> batchRemove;
QList<QContactLocalId> sigids;
@@ -1729,12 +1891,14 @@
QContactName nc;
saveContactName(&c, nameDef, &nc, "John");
QVERIFY(m1->saveContact(&c));
+ QContactLocalId cid = c.id().localId();
addSigCount += 1;
QTRY_COMPARE(spyCA.count(), addSigCount);
args = spyCA.takeFirst();
addSigCount -= 1;
- QVERIFY(args.count() == 1);
- temp = QContactLocalId(args.at(0).value<quint32>());
+ arg = args.first().value<QList<quint32> >();
+ QVERIFY(arg.count() == 1);
+ QCOMPARE(QContactLocalId(arg.at(0)), cid);
// verify save modified emits signal changed
saveContactName(&c, nameDef, &nc, "Citizen");
@@ -1743,8 +1907,9 @@
QTRY_COMPARE(spyCM.count(), modSigCount);
args = spyCM.takeFirst();
modSigCount -= 1;
- QVERIFY(args.count() == 1);
- QCOMPARE(temp, QContactLocalId(args.at(0).value<quint32>()));
+ arg = args.first().value<QList<quint32> >();
+ QVERIFY(arg.count() == 1);
+ QCOMPARE(QContactLocalId(arg.at(0)), cid);
// verify remove emits signal removed
m1->removeContact(c.id().localId());
@@ -1752,8 +1917,9 @@
QTRY_COMPARE(spyCR.count(), remSigCount);
args = spyCR.takeFirst();
remSigCount -= 1;
- QVERIFY(args.count() == 1);
- QCOMPARE(temp, QContactLocalId(args.at(0).value<quint32>()));
+ arg = args.first().value<QList<quint32> >();
+ QVERIFY(arg.count() == 1);
+ QCOMPARE(QContactLocalId(arg.at(0)), cid);
// verify multiple adds works as advertised
QContact c2, c3;
@@ -1845,6 +2011,11 @@
QTRY_COMPARE(spyCA.count(), 0);
QTRY_COMPARE(spyCM.count(), 0);
+ QScopedPointer<QContactManager> m2(QContactManager::fromUri(uri));
+
+ QVERIFY(m1->hasFeature(QContactManager::Anonymous) ==
+ m2->hasFeature(QContactManager::Anonymous));
+
/* Now some cross manager testing */
if (!m1->hasFeature(QContactManager::Anonymous)) {
// verify that signals are emitted for modifications made to other managers (same id).
@@ -2126,10 +2297,17 @@
QVERIFY(d.displayLabel().isEmpty());
- QString synth = cm->synthesizedDisplayLabel(d);
+ QString synth = cm->synthesizedContactDisplayLabel(d);
+
+ // Make sure this doesn't crash
+ cm->synthesizeContactDisplayLabel(0);
+
+ // Make sure this gives the same results
+ cm->synthesizeContactDisplayLabel(&d);
+ QCOMPARE(d.displayLabel(), synth);
/*
- * The display label is not updated until you save the contact.
+ * The display label is not updated until you save the contact or call synthCDL
*/
QVERIFY(cm->saveContact(&d));
d = cm->contact(d.id().localId());
@@ -2185,16 +2363,8 @@
c.saveDetail(&p3);
c.saveDetail(&u);
- // set a preference for dialing a particular saved phonenumber.
- c.setPreferredDetail("Dial", p2);
-
QVERIFY(cm->saveContact(&c)); // save the contact
QContact loaded = cm->contact(c.id().localId()); // reload the contact
-
- // test that the preference was saved correctly.
- QContactDetail pref = loaded.preferredDetail("Dial");
- QVERIFY(pref == p2);
-
cm->removeContact(c.id().localId());
}
@@ -2214,12 +2384,19 @@
QVERIFY(changeSet.addedContacts().contains(id));
changeSet.insertChangedContact(id);
- changeSet.insertChangedContact(id);
+ changeSet.insertChangedContacts(QList<QContactLocalId>() << id);
QVERIFY(changeSet.changedContacts().size() == 1); // set, should only be added once.
QVERIFY(!changeSet.addedContacts().isEmpty());
QVERIFY(!changeSet.changedContacts().isEmpty());
QVERIFY(changeSet.removedContacts().isEmpty());
QVERIFY(changeSet.changedContacts().contains(id));
+ changeSet.clearChangedContacts();
+ QVERIFY(changeSet.changedContacts().isEmpty());
+
+ changeSet.insertRemovedContacts(QList<QContactLocalId>() << id);
+ QVERIFY(changeSet.removedContacts().contains(id));
+ changeSet.clearRemovedContacts();
+ QVERIFY(changeSet.removedContacts().isEmpty());
QVERIFY(changeSet.dataChanged() == false);
QContactChangeSet changeSet2;
@@ -2227,6 +2404,11 @@
QVERIFY(changeSet.addedContacts() == changeSet2.addedContacts());
changeSet.emitSignals(0);
+ changeSet2.clearAddedContacts();
+ QVERIFY(changeSet2.addedContacts().isEmpty());
+ changeSet2.insertAddedContacts(changeSet.addedContacts().toList());
+ QVERIFY(changeSet.addedContacts() == changeSet2.addedContacts());
+
changeSet2.clearAll();
QVERIFY(changeSet.addedContacts() != changeSet2.addedContacts());
@@ -2241,6 +2423,14 @@
changeSet.emitSignals(0);
changeSet.addedRelationshipsContacts().insert(id);
+ changeSet.insertAddedRelationshipsContacts(QList<QContactLocalId>() << id);
+ QVERIFY(changeSet.addedRelationshipsContacts().contains(id));
+ changeSet.clearAddedRelationshipsContacts();
+ QVERIFY(changeSet.addedRelationshipsContacts().isEmpty());
+ changeSet.insertRemovedRelationshipsContacts(QList<QContactLocalId>() << id);
+ QVERIFY(changeSet.removedRelationshipsContacts().contains(id));
+ changeSet.clearRemovedRelationshipsContacts();
+ QVERIFY(changeSet.removedRelationshipsContacts().isEmpty());
changeSet.emitSignals(0);
changeSet.removedRelationshipsContacts().insert(id);
changeSet.emitSignals(0);
@@ -2257,6 +2447,17 @@
changeSet.emitSignals(0);
}
+void tst_QContactManager::fetchHint()
+{
+ QContactFetchHint hint;
+ hint.setOptimizationHints(QContactFetchHint::NoBinaryBlobs);
+ QCOMPARE(hint.optimizationHints(), QContactFetchHint::NoBinaryBlobs);
+ QStringList rels;
+ rels << QString(QLatin1String(QContactRelationship::HasMember));
+ hint.setRelationshipTypesHint(rels);
+ QCOMPARE(hint.relationshipTypesHint(), rels);
+}
+
void tst_QContactManager::selfContactId()
{
QFETCH(QString, uri);
@@ -2266,6 +2467,7 @@
QContactLocalId selfContact = cm->selfContactId();
if (!cm->hasFeature(QContactManager::SelfContact)) {
// ensure that the error codes / return values are meaningful failures.
+ QEXPECT_FAIL("mgr='maemo5'", "maemo5 supports getting the self contact but not setting it.", Continue);
QVERIFY(cm->error() == QContactManager::DoesNotExistError);
QVERIFY(!cm->setSelfContactId(QContactLocalId(123)));
QVERIFY(cm->error() == QContactManager::NotSupportedError);