qtmobility/tests/auto/qversit/tst_qversit.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
    41 
    41 
    42 #include "qversitdefs_p.h"
    42 #include "qversitdefs_p.h"
    43 #include "tst_qversit.h"
    43 #include "tst_qversit.h"
    44 #include "qversitreader.h"
    44 #include "qversitreader.h"
    45 #include "qversitreader_p.h"
    45 #include "qversitreader_p.h"
       
    46 #include "qversitcontactexporter.h"
    46 #include "qversitcontactimporter.h"
    47 #include "qversitcontactimporter.h"
    47 #include "qcontact.h"
    48 #include "qcontact.h"
    48 #include "qcontactmanager.h"
    49 #include "qcontactmanager.h"
    49 #include "qcontactmanagerengine.h"
    50 #include "qcontactmanagerengine.h"
    50 
    51 
    79     }
    80     }
    80 
    81 
    81     int mIndex;
    82     int mIndex;
    82     QMap<QString, QByteArray> mObjects;
    83     QMap<QString, QByteArray> mObjects;
    83 };
    84 };
       
    85 
       
    86 
       
    87 class MyDetailHandler : public QVersitContactExporterDetailHandler {
       
    88 public:
       
    89     MyDetailHandler() : detailNumber(0) {}
       
    90     bool preProcessDetail(const QContact& contact, const QContactDetail& detail,
       
    91                           QVersitDocument* document) {
       
    92         Q_UNUSED(contact) Q_UNUSED(detail) Q_UNUSED(document)
       
    93         return false;
       
    94     }
       
    95     /* eg. a detail with definition name "Detail" and fields "Field1"="Value1" and
       
    96      * "Field2"="Value2" will be exported to the vCard properties:
       
    97      * G0.DETAIL-FIELD1:Value1
       
    98      * G0.DETAIL-FIELD2:Value2
       
    99      * And the next detail (say, "Detail" with a field "Field1"="Value3" will generate:
       
   100      * G1.DETAIL-FIELD1:Value3
       
   101      * ie. Different details will have different vCard groups.
       
   102      */
       
   103     bool postProcessDetail(const QContact& contact, const QContactDetail& detail,
       
   104                            bool alreadyProcessed, QVersitDocument* document) {
       
   105         Q_UNUSED(contact)
       
   106         // beware: if the base implementation exports some but not all fields, alreadyProcessed
       
   107         // will be true and the unprocessed fields won't be exported
       
   108         if (alreadyProcessed)
       
   109             return false;
       
   110         if (detail.definitionName() == QContactType::DefinitionName)
       
   111             return false; // special case of an unhandled detail that we don't export
       
   112         QVersitProperty property;
       
   113         QVariantMap fields = detail.variantValues();
       
   114         // fields from the same detail have the same group so the importer can collate them
       
   115         QString detailGroup = QLatin1String("G") + QString::number(detailNumber++);
       
   116         for (QVariantMap::const_iterator it = fields.constBegin();
       
   117                 it != fields.constEnd();
       
   118                 it++) {
       
   119             property.setGroups(QStringList(detailGroup));
       
   120             // beware: detail.definitionName and the field name will be made uppercase on export
       
   121             property.setName(QLatin1String("X-QCONTACTDETAIL-")
       
   122                              + detail.definitionName()
       
   123                              + QLatin1String("-")
       
   124                              + it.key());
       
   125             // beware: this might not handle nonstring values properly:
       
   126             property.setValue(it.value());
       
   127             document->addProperty(property);
       
   128         }
       
   129         return true;
       
   130     }
       
   131 private:
       
   132     int detailNumber;
       
   133 };
       
   134 
       
   135 class MyPropertyHandler : public QVersitContactImporterPropertyHandler {
       
   136 public:
       
   137     bool preProcessProperty(const QVersitDocument& document, const QVersitProperty& property,
       
   138                             int contactIndex, QContact* contact) {
       
   139         Q_UNUSED(document) Q_UNUSED(property) Q_UNUSED(contactIndex) Q_UNUSED(contact)
       
   140         return false;
       
   141     }
       
   142     /* eg. if the document has the properties:
       
   143      * G0.DETAIL-FIELD1:Value1
       
   144      * G0.DETAIL-FIELD2:Value2
       
   145      * G1.DETAIL-FIELD1:Value3
       
   146      * This will generate two details - the first with fields "FIELD1"="Value1" and
       
   147      * "FIELD2"="Value2" and the second with "FIELD1"="Value3"
       
   148      * ie. the vCard groups determine which properties form a single detail.
       
   149      */
       
   150     bool postProcessProperty(const QVersitDocument& document, const QVersitProperty& property,
       
   151                              bool alreadyProcessed, int contactIndex, QContact* contact) {
       
   152         Q_UNUSED(document) Q_UNUSED(contactIndex)
       
   153         const QString prefix = QLatin1String("X-QCONTACTDETAIL-");
       
   154         if (alreadyProcessed)
       
   155             return false;
       
   156         if (!property.name().startsWith(prefix))
       
   157             return false;
       
   158         QString detailAndField = property.name().mid(prefix.size());
       
   159         QStringList detailAndFieldParts = detailAndField.split(QLatin1Char('-'),
       
   160                                                                QString::SkipEmptyParts);
       
   161         if (detailAndFieldParts.size() != 2)
       
   162             return false;
       
   163         QString definitionName = detailAndFieldParts.at(0);
       
   164         QString fieldName = detailAndFieldParts.at(1);
       
   165         if (property.groups().size() != 1)
       
   166             return false;
       
   167         QString group = property.groups().first();
       
   168         // find a detail generated from the a property with the same group
       
   169         QContactDetail detail = handledDetails.value(group);
       
   170         // make sure the the existing detail has the same definition name
       
   171         if (detail.definitionName() != definitionName)
       
   172             detail = QContactDetail(definitionName);
       
   173         detail.setValue(fieldName, property.value());
       
   174         contact->saveDetail(&detail);
       
   175         handledDetails.insert(group, detail);
       
   176         return false;
       
   177     }
       
   178     QMap<QString, QContactDetail> handledDetails; // map from group name to detail
       
   179 };
       
   180 
    84 QTM_END_NAMESPACE
   181 QTM_END_NAMESPACE
    85 
   182 
    86 QTM_USE_NAMESPACE
   183 QTM_USE_NAMESPACE
    87 
   184 
    88 #ifndef TESTDATA_DIR
   185 #ifndef TESTDATA_DIR
    89 #define TESTDATA_DIR "./"
   186 #define TESTDATA_DIR "./"
    90 #endif
   187 #endif
    91 
   188 
    92 Q_DECLARE_METATYPE(QList<QContact>)
   189 Q_DECLARE_METATYPE(QList<QContact>)
       
   190 Q_DECLARE_METATYPE(QContact)
    93 
   191 
    94 void tst_QVersit::testImportFiles()
   192 void tst_QVersit::testImportFiles()
    95 {
   193 {
    96     QFETCH(QString, filename);
   194     QFETCH(QString, filename);
    97     QFETCH(QByteArray, charset);
   195     QFETCH(QByteArray, charset);
   109     QList<QVersitDocument> documents = reader.results();
   207     QList<QVersitDocument> documents = reader.results();
   110     QCOMPARE(reader.error(), QVersitReader::NoError);
   208     QCOMPARE(reader.error(), QVersitReader::NoError);
   111     QVersitContactImporter importer;
   209     QVersitContactImporter importer;
   112     MyQVersitResourceHandler resourceHandler;
   210     MyQVersitResourceHandler resourceHandler;
   113     importer.setResourceHandler(&resourceHandler);
   211     importer.setResourceHandler(&resourceHandler);
       
   212     MyPropertyHandler propertyHandler;
       
   213     importer.setPropertyHandler(&propertyHandler);
   114     QVERIFY(importer.importDocuments(documents));
   214     QVERIFY(importer.importDocuments(documents));
   115     QList<QContact> contacts = importer.contacts();
   215     QList<QContact> contacts = importer.contacts();
   116 
   216 
   117     if (expectedContacts.size() > 0) {
   217     if (expectedContacts.size() > 0) {
   118         QCOMPARE(contacts.size(), expectedContacts.size());
   218         QCOMPARE(contacts.size(), expectedContacts.size());
   159         QContact contact;
   259         QContact contact;
   160         QContactName name;
   260         QContactName name;
   161         name.setCustomLabel(QLatin1String("Firstname Lastname"));
   261         name.setCustomLabel(QLatin1String("Firstname Lastname"));
   162         name.setFirstName(QLatin1String("Firstname"));
   262         name.setFirstName(QLatin1String("Firstname"));
   163         name.setLastName(QLatin1String("Lastname"));
   263         name.setLastName(QLatin1String("Lastname"));
   164         name.setMiddleName(QString());
       
   165         name.setPrefix(QLatin1String("Title"));
   264         name.setPrefix(QLatin1String("Title"));
   166         name.setSuffix(QLatin1String("Suffix"));
   265         name.setSuffix(QLatin1String("Suffix"));
   167         contact.saveDetail(&name);
   266         contact.saveDetail(&name);
   168         QContactOrganization org;
   267         QContactOrganization org;
   169         org.setName(QLatin1String("Company Name"));
   268         org.setName(QLatin1String("Company Name"));
   195         QContact contact;
   294         QContact contact;
   196         QContactName name;
   295         QContactName name;
   197         name.setCustomLabel(QLatin1String("first last"));
   296         name.setCustomLabel(QLatin1String("first last"));
   198         name.setFirstName(QLatin1String("first"));
   297         name.setFirstName(QLatin1String("first"));
   199         name.setLastName(QLatin1String("last"));
   298         name.setLastName(QLatin1String("last"));
   200         name.setMiddleName(QString());
       
   201         name.setPrefix(QString());
       
   202         name.setSuffix(QString());
       
   203         contact.saveDetail(&name);
   299         contact.saveDetail(&name);
   204         QContactOrganization org;
   300         QContactOrganization org;
   205         org.setName(QLatin1String("Nokia"));
   301         org.setName(QLatin1String("Nokia"));
   206         org.setDepartment(QStringList(QLatin1String("Qt DF")));
   302         org.setDepartment(QStringList(QLatin1String("Qt DF")));
   207         contact.saveDetail(&org);
   303         contact.saveDetail(&org);
   216 
   312 
   217     {
   313     {
   218         QContact contact;
   314         QContact contact;
   219         QContactName name;
   315         QContactName name;
   220         name.setFirstName(QLatin1String("name"));
   316         name.setFirstName(QLatin1String("name"));
   221         name.setLastName(QString());
       
   222         name.setMiddleName(QString());
       
   223         name.setPrefix(QString());
       
   224         name.setSuffix(QString());
       
   225         contact.saveDetail(&name);
   317         contact.saveDetail(&name);
   226         QContactFamily family;
   318         QContactFamily family;
   227         family.setChildren(QStringList(QLatin1String("Child1")));
   319         family.setChildren(QStringList(QLatin1String("Child1")));
   228         contact.saveDetail(&family);
   320         contact.saveDetail(&family);
   229         family.setChildren(QStringList(QLatin1String("Child2")) << QLatin1String("Child3"));
   321         family.setChildren(QStringList(QLatin1String("Child2")) << QLatin1String("Child3"));
   248         QContactManagerEngine::setContactDisplayLabel(&contact, QLatin1String("name"));
   340         QContactManagerEngine::setContactDisplayLabel(&contact, QLatin1String("name"));
   249         QTEST_NEW_ROW("test1.vcf", "UTF-8", QList<QContact>() << contact);
   341         QTEST_NEW_ROW("test1.vcf", "UTF-8", QList<QContact>() << contact);
   250     }
   342     }
   251 }
   343 }
   252 
   344 
       
   345 void tst_QVersit::testExportImport()
       
   346 {
       
   347     // Test that a contact, when exported, then imported again, is unaltered
       
   348     QFETCH(QContact, contact);
       
   349 
       
   350     QVersitContactExporter exporter;
       
   351     MyDetailHandler detailHandler;
       
   352     exporter.setDetailHandler(&detailHandler);
       
   353     QVERIFY(exporter.exportContacts(QList<QContact>() << contact, QVersitDocument::VCard30Type));
       
   354     QList<QVersitDocument> documents = exporter.documents();
       
   355     QCOMPARE(documents.size(), 1);
       
   356 
       
   357     QVersitContactImporter importer;
       
   358     MyPropertyHandler propertyHandler;
       
   359     importer.setPropertyHandler(&propertyHandler);
       
   360     QVERIFY(importer.importDocuments(documents));
       
   361     QList<QContact> contacts = importer.contacts();
       
   362     QCOMPARE(contacts.size(), 1);
       
   363     // We can't do a deep compare because detail ids are different
       
   364     QCOMPARE(contacts.first().details().count(), contact.details().count());
       
   365 }
       
   366 
       
   367 void tst_QVersit::testExportImport_data()
       
   368 {
       
   369     QTest::addColumn<QContact>("contact");
       
   370 
       
   371     QContact contact;
       
   372     QContactName name;
       
   373     name.setFirstName(QLatin1String("first"));
       
   374     name.setLastName(QLatin1String("last"));
       
   375     name.setCustomLabel(QLatin1String("custom"));
       
   376     contact.saveDetail(&name);
       
   377     // detail definition/field names are encoded as vCard property names, which must be uppercase,
       
   378     // so only uppercase definition/field names work.
       
   379     QContactDetail customDetail1("CUSTOMDETAIL");
       
   380     customDetail1.setValue(QLatin1String("CUSTOMFIELD11"), QLatin1String("Value11"));
       
   381     customDetail1.setValue(QLatin1String("CUSTOMFIELD12"), QLatin1String("Value12"));
       
   382     contact.saveDetail(&customDetail1);
       
   383     QContactDetail customDetail2("CUSTOMDETAIL");
       
   384     customDetail2.setValue(QLatin1String("CUSTOMFIELD21"), QLatin1String("Value21"));
       
   385     customDetail2.setValue(QLatin1String("CUSTOMFIELD22"), QLatin1String("Value22"));
       
   386     contact.saveDetail(&customDetail2);
       
   387     contact.setType(QContactType::TypeContact);
       
   388 
       
   389     QTest::newRow("custom detail") << contact;
       
   390 }
       
   391 
   253 QTEST_MAIN(tst_QVersit)
   392 QTEST_MAIN(tst_QVersit)