1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL21$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 or version 3 as published by the Free
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22** following information to ensure the GNU Lesser General Public License
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25**
26** As a special exception, The Qt Company gives you certain additional
27** rights. These rights are described in The Qt Company LGPL Exception
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29**
30** $QT_END_LICENSE$
31**
32****************************************************************************/
33
34//TESTED_COMPONENT=src/versit
35
36#include "tst_qversitcontactimporter.h"
37#include <QtVersit/qversitcontactimporter.h>
38#include <QtVersit/private/qversitcontactimporter_p.h>
39#include <QtVersit/qversitproperty.h>
40#include <QtVersit/qversitdocument.h>
41#include <QtContacts/qcontacts.h>
42#include <QtTest/QtTest>
43#include <QDir>
44
45QTCONTACTS_USE_NAMESPACE
46QTVERSIT_USE_NAMESPACE
47
48class MyQVersitContactImporterPropertyHandler : public QVersitContactImporterPropertyHandler
49{
50public:
51 MyQVersitContactImporterPropertyHandler()
52 : mPreProcess(false)
53 {
54 }
55
56 bool preProcessProperty(const QVersitDocument& document,
57 const QVersitProperty& property,
58 int contactIndex,
59 QContact* contact)
60 {
61 Q_UNUSED(document)
62 Q_UNUSED(contact)
63 Q_UNUSED(contactIndex);
64 mPreProcessedProperties.append(t: property);
65 return mPreProcess;
66 }
67
68 bool postProcessProperty(const QVersitDocument& document,
69 const QVersitProperty& property,
70 bool alreadyProcessed,
71 int contactIndex,
72 QContact* contact)
73 {
74 Q_UNUSED(document)
75 Q_UNUSED(contact)
76 Q_UNUSED(contactIndex)
77 if (!alreadyProcessed)
78 mUnknownProperties.append(t: property);
79 else
80 mPostProcessedProperties.append(t: property);
81 return false;
82 }
83
84 void clear()
85 {
86 mPreProcess = false;
87 mPropertyNamesToProcess.clear();
88 mUnknownProperties.clear();
89 mPreProcessedProperties.clear();
90 mPostProcessedProperties.clear();
91 }
92
93 // a hook to control what preProcess returns:
94 bool mPreProcess;
95 QStringList mPropertyNamesToProcess;
96 QList<QVersitProperty> mUnknownProperties;
97 QList<QVersitProperty> mPreProcessedProperties;
98 QList<QVersitProperty> mPostProcessedProperties;
99};
100
101class MyQVersitResourceHandler : public QVersitResourceHandler
102{
103public:
104 MyQVersitResourceHandler() : mIndex(0)
105 {
106 }
107
108 bool saveResource(const QByteArray& contents, const QVersitProperty& property,
109 QString* location)
110 {
111 Q_UNUSED(property);
112 *location = QString::number(mIndex++);
113 mObjects.insert(akey: *location, avalue: contents);
114 return true;
115 }
116
117 bool loadResource(const QString &location, QByteArray *contents, QString *mimeType)
118 {
119 Q_UNUSED(location)
120 Q_UNUSED(contents)
121 Q_UNUSED(mimeType)
122 return false;
123 }
124
125 void clear()
126 {
127 mIndex = 0;
128 mObjects.clear();
129 }
130
131 int mIndex;
132 QMap<QUrl, QByteArray> mObjects;
133};
134
135const static QByteArray SAMPLE_GIF(QByteArray::fromBase64(
136 base64: "R0lGODlhEgASAIAAAAAAAP///yH5BAEAAAEALAAAAAASABIAAAIdjI+py+0G"
137 "wEtxUmlPzRDnzYGfN3KBaKGT6rDmGxQAOw=="));
138
139const static QByteArray NOKIA_GIF(QByteArray::fromBase64(
140 base64: "R0lGODdhOAAKAIQRAAAvwQAwwwAwxAAxxwAyygAzywAzzBBHwC9nz0+A0HCf35+/4LDQ78/f79/o"
141 "8O/v8PD3/////////////////////////////////////////////////////////////ywAAAAA"
142 "OAAKAAAFsCAiik9kRqPJHIfhGixjisuJpqk9Inb0vjaBC0UwFH+uhM+gNBUCw6Wh92vYDAXkCZhF"
143 "apMmA3Qajppav6tr8TqUp0DqEIwtqsmRR/Kl2A4RfFKCcnBMbYR+Uw5xg2lAjIlLCS88dyYNLn1S"
144 "TYwvk3NmkXSQLgVvXmQuBCcQXlI7Io9MpyWCbKgublgCNgxfP0eOs6dvUgsPyMgvEAUAeCafUWhe"
145 "bpI2LQMFenuhZy8hADs="));
146
147void tst_QVersitContactImporter::init()
148{
149 mImporter = new QVersitContactImporter();
150 mResourceHandler = new MyQVersitResourceHandler();
151 mImporter->setResourceHandler(mResourceHandler);
152 mPropertyHandler = new MyQVersitContactImporterPropertyHandler();
153 mImporter->setPropertyHandler(mPropertyHandler);
154}
155
156void tst_QVersitContactImporter::cleanup()
157{
158 QVERIFY(mImporter->propertyHandler() == mPropertyHandler);
159 MyQVersitContactImporterPropertyHandler* nullPtr = NULL;
160 mImporter->setPropertyHandler(nullPtr);
161 delete mPropertyHandler;
162 QVERIFY(mImporter->resourceHandler() == mResourceHandler);
163 mImporter->setResourceHandler(0);
164 delete mResourceHandler;
165 delete mImporter;
166}
167
168void tst_QVersitContactImporter::testName()
169{
170 QVersitDocument document(QVersitDocument::VCard30Type);
171 QVersitProperty nameProperty;
172 QStringList value;
173 value.append(QStringLiteral("John"));//FirstName
174 value.append(QStringLiteral("Citizen"));//LastName
175 value.append(QStringLiteral("Anonymous"));//GivenName
176 value.append(QStringLiteral("Dr"));//PreFix
177 value.append(QStringLiteral("MSc"));//Suffix
178 nameProperty.setName(QStringLiteral("N"));
179 nameProperty.setValue(value);
180 nameProperty.setValueType(QVersitProperty::CompoundType);
181 document.addProperty(property: nameProperty);
182 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
183 QContact contact = mImporter->contacts().first();
184 QContactName name = (QContactName)contact.detail(type: QContactName::Type);
185 QCOMPARE(name.lastName(),value[0]);
186 QCOMPARE(name.firstName(),value[1]);
187 QCOMPARE(name.middleName(),value[2]);
188 QCOMPARE(name.prefix(),value[3]);
189 QCOMPARE(name.suffix(),value[4]);
190
191 // Multiple names, first one will be picked and rest will be discarded
192 nameProperty = QVersitProperty();
193 QStringList anotherValue;
194 anotherValue.append(QStringLiteral("FakeJohn"));//FirstName
195 anotherValue.append(QStringLiteral("FakeCitizen"));//LastName
196 anotherValue.append(QStringLiteral("FakeAnonymous"));//GivenName
197 anotherValue.append(QStringLiteral("FakeDr"));//PreFix
198 anotherValue.append(QStringLiteral("FakeMSc"));//Suffix
199 nameProperty.setName(QStringLiteral("N"));
200 nameProperty.setValue(anotherValue);
201 nameProperty.setValueType(QVersitProperty::CompoundType);
202 document.addProperty(property: nameProperty);
203 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
204 contact = mImporter->contacts().first();
205 QList<QContactDetail> names = contact.details(type: QContactName::Type);
206 QCOMPARE(names.count(),1);
207 // anotherValue should be discarded, so check for value
208 name = (QContactName)names[0];
209 QCOMPARE(name.lastName(),value[0]);
210 QCOMPARE(name.firstName(),value[1]);
211 QCOMPARE(name.middleName(),value[2]);
212 QCOMPARE(name.prefix(),value[3]);
213 QCOMPARE(name.suffix(),value[4]);
214}
215
216// check that it doesn't crash if the FN property comes before the N property.
217void tst_QVersitContactImporter::testNameWithFormatted()
218{
219 QVersitDocument document(QVersitDocument::VCard30Type);
220 QVersitProperty fnProperty;
221 fnProperty.setName(QStringLiteral("FN"));
222 fnProperty.setValue(QStringLiteral("First Last"));
223 document.addProperty(property: fnProperty);
224 QVersitProperty nProperty;
225 nProperty.setName(QStringLiteral("N"));
226 nProperty.setValue(QStringList() << QStringLiteral("Last") << QStringLiteral("First") << QStringLiteral("Middle") << QStringLiteral("Prefix") << QStringLiteral("Suffix"));
227 nProperty.setValueType(QVersitProperty::CompoundType);
228 document.addProperty(property: nProperty);
229 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
230 QContact contact = mImporter->contacts().first();
231 QContactName name = contact.detail<QContactName>();
232 QCOMPARE(name.firstName(), QStringLiteral("First"));
233 QCOMPARE(name.lastName(), QStringLiteral("Last"));
234 QCOMPARE(name.middleName(), QStringLiteral("Middle"));
235 QCOMPARE(name.prefix(), QStringLiteral("Prefix"));
236 QCOMPARE(name.suffix(), QStringLiteral("Suffix"));
237 }
238
239void tst_QVersitContactImporter::testAddress()
240{
241 QVersitDocument document(QVersitDocument::VCard30Type);
242 QVersitProperty property;
243 property.setName(QStringLiteral("ADR"));
244 property.setValue(QStringList(QString()));
245 property.setValueType(QVersitProperty::CompoundType);
246
247 // Empty value for the address
248 document = createDocumentWithProperty(property);
249 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
250 QContact contact = mImporter->contacts().first();
251 QContactAddress address = contact.detail<QContactAddress>();
252 QCOMPARE(address.postOfficeBox(),QString());
253 QCOMPARE(address.street(),QString());
254 QCOMPARE(address.locality(),QString());
255 QCOMPARE(address.region(),QString());
256 QCOMPARE(address.postcode(),QString());
257 QCOMPARE(address.country(),QString());
258
259 // Address with all the fields filled
260 property.setValue(QStringList()
261 << QStringLiteral("PO Box")
262 << QStringLiteral("E")
263 << QStringLiteral("My Street")
264 << QStringLiteral("My Town")
265 << QStringLiteral("My State")
266 << QStringLiteral("12345")
267 << QStringLiteral("My Country")
268 );
269 property.setValueType(QVersitProperty::CompoundType);
270 document = createDocumentWithProperty(property);
271 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
272 contact = mImporter->contacts().first();
273 address = contact.detail<QContactAddress>();
274 QCOMPARE(address.postOfficeBox(),QStringLiteral("PO Box"));
275 QCOMPARE(address.street(),QStringLiteral("My Street"));
276 QCOMPARE(address.locality(),QStringLiteral("My Town"));
277 QCOMPARE(address.region(),QStringLiteral("My State"));
278 QCOMPARE(address.postcode(),QStringLiteral("12345"));
279 QCOMPARE(address.country(),QStringLiteral("My Country"));
280
281 // Address with TYPE parameters converted to contexts and subtypes
282 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("HOME"));
283 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("WORK"));
284 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("DOM"));
285 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("INTL"));
286 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("POSTAL"));
287 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("PARCEL"));
288 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("X-EXTENSION"));
289 document = createDocumentWithProperty(property);
290 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
291 contact = mImporter->contacts().first();
292 address = contact.detail<QContactAddress>();
293 QList<int> contexts = address.contexts();
294 QCOMPARE(contexts.size(), 2);
295 QVERIFY(contexts.contains(QContactDetail::ContextHome));
296 QVERIFY(contexts.contains(QContactDetail::ContextWork));
297 QList<int> subTypes = address.subTypes();
298 QCOMPARE(subTypes.size(), 4);
299 QVERIFY(subTypes.contains(QContactAddress::SubTypeDomestic));
300 QVERIFY(subTypes.contains(QContactAddress::SubTypeInternational));
301 QVERIFY(subTypes.contains(QContactAddress::SubTypePostal));
302 QVERIFY(subTypes.contains(QContactAddress::SubTypeParcel));
303}
304
305void tst_QVersitContactImporter::testAddressWithoutSubTypes()
306{
307 QVersitDocument document(QVersitDocument::VCard30Type);
308 QVersitProperty property;
309 property.setName(QStringLiteral("ADR"));
310 property.setValue(QStringList()
311 << QStringLiteral("PO Box")
312 << QStringLiteral("E")
313 << QStringLiteral("My Street")
314 << QStringLiteral("My Town")
315 << QStringLiteral("My State")
316 << QStringLiteral("12345")
317 << QStringLiteral("My Country")
318 );
319 property.setValueType(QVersitProperty::CompoundType);
320 document = createDocumentWithProperty(property);
321 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
322 QContact contact = mImporter->contacts().first();
323 QContactAddress address = contact.detail<QContactAddress>();
324
325 QContactAddress otherAddress;
326 otherAddress.setPostOfficeBox(QStringLiteral("PO Box"));
327 otherAddress.setStreet(QStringLiteral("My Street"));
328 otherAddress.setLocality(QStringLiteral("My Town"));
329 otherAddress.setRegion(QStringLiteral("My State"));
330 otherAddress.setPostcode(QStringLiteral("12345"));
331 otherAddress.setCountry(QStringLiteral("My Country"));
332
333 QCOMPARE(address, otherAddress);
334}
335
336void tst_QVersitContactImporter::testOrganizationName()
337{
338 QVersitDocument document(QVersitDocument::VCard30Type);
339 QVersitProperty property;
340
341 // Empty value for the organization
342 property.setName(QStringLiteral("ORG"));
343 document = createDocumentWithProperty(property);
344 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
345 QContact contact = mImporter->contacts().first();
346 QContactOrganization organization = contact.detail<QContactOrganization>();
347 QCOMPARE(organization.name(),QString());
348 QCOMPARE(organization.department().count(),0);
349
350 // Organization with single value
351 property.setValueType(QVersitProperty::CompoundType);
352 property.setValue(QStringList(QStringLiteral("Nokia")));
353 document = createDocumentWithProperty(property);
354 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
355 contact = mImporter->contacts().first();
356 organization = contact.detail<QContactOrganization>();
357 QCOMPARE(organization.name(),QStringLiteral("Nokia"));
358 QCOMPARE(organization.department().count(),0);
359
360 // Organization with one Organizational Unit
361 property.setValue(QStringList() << QStringLiteral("Nokia") << QStringLiteral("R&D"));
362 document = createDocumentWithProperty(property);
363 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
364 contact = mImporter->contacts().first();
365 organization = contact.detail<QContactOrganization>();
366 QCOMPARE(organization.name(),QStringLiteral("Nokia"));
367 QCOMPARE(organization.department().count(),1);
368 QCOMPARE(organization.department().at(0),QStringLiteral("R&D"));
369
370 // Organization with more Organizational Units
371 property.setValue(QStringList()
372 << QStringLiteral("Nokia")
373 << QStringLiteral("R&D")
374 << QStringLiteral("Devices")
375 << QStringLiteral("Qt"));
376 property.setValueType(QVersitProperty::CompoundType);
377 document = createDocumentWithProperty(property);
378 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
379 contact = mImporter->contacts().first();
380 organization = contact.detail<QContactOrganization>();
381 QCOMPARE(organization.name(),QStringLiteral("Nokia"));
382 QCOMPARE(organization.department().count(),3);
383 QCOMPARE(organization.department().at(0),QStringLiteral("R&D"));
384 QCOMPARE(organization.department().at(1),QStringLiteral("Devices"));
385 QCOMPARE(organization.department().at(2),QStringLiteral("Qt"));
386}
387
388void tst_QVersitContactImporter::testOrganizationTitle()
389{
390 QVersitDocument document(QVersitDocument::VCard30Type);
391 QVersitProperty property;
392
393 // One title
394 property.setName(QStringLiteral("TITLE"));
395 QString titleValue(QStringLiteral("Developer"));
396 property.setValue(titleValue);
397 document = createDocumentWithProperty(property);
398 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
399 QContact contact = mImporter->contacts().first();
400 QList<QContactDetail> organizationDetails =
401 contact.details(type: QContactOrganization::Type);
402 QCOMPARE(organizationDetails.count(), 1);
403 QContactOrganization organization = static_cast<QContactOrganization>(organizationDetails[0]);
404 QCOMPARE(organization.title(),titleValue);
405
406 // Two titles -> two QContactOrganizations created
407 property.setName(QStringLiteral("TITLE"));
408 QString secondTitleValue(QStringLiteral("Hacker"));
409 property.setValue(secondTitleValue);
410 document.addProperty(property);
411 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
412 contact = mImporter->contacts().first();
413 organizationDetails = contact.details(type: QContactOrganization::Type);
414 QCOMPARE(organizationDetails.count(), 2);
415 QContactOrganization firstOrganization =
416 static_cast<QContactOrganization>(organizationDetails[0]);
417 QCOMPARE(firstOrganization.title(),titleValue);
418 QContactOrganization secondOrganization =
419 static_cast<QContactOrganization>(organizationDetails[1]);
420 QCOMPARE(secondOrganization.title(),secondTitleValue);
421
422 // Two titles and one organization name -> two QContactOrganizations created
423 property.setName(QStringLiteral("ORG"));
424 property.setValueType(QVersitProperty::CompoundType);
425 property.setValue(QStringList(QStringLiteral("Nokia")));
426 document.addProperty(property);
427 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
428 contact = mImporter->contacts().first();
429 organizationDetails = contact.details(type: QContactOrganization::Type);
430 QCOMPARE(organizationDetails.count(), 2);
431 firstOrganization = static_cast<QContactOrganization>(organizationDetails[0]);
432 QCOMPARE(firstOrganization.title(),titleValue);
433 QCOMPARE(firstOrganization.name(),QStringLiteral("Nokia"));
434 secondOrganization = static_cast<QContactOrganization>(organizationDetails[1]);
435 QCOMPARE(secondOrganization.title(),secondTitleValue);
436 QCOMPARE(secondOrganization.name(),QString());
437}
438
439void tst_QVersitContactImporter::testOrganizationAssistant()
440{
441 QContact contact;
442 QVersitDocument document(QVersitDocument::VCard30Type);
443 QVersitProperty property;
444 property.setName(QStringLiteral("X-ASSISTANT"));
445 QString assistantValue(QStringLiteral("Jenny"));
446 property.setValue(assistantValue);
447 document = createDocumentWithProperty(property);
448 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
449 contact = mImporter->contacts().first();
450 QContactOrganization organization = contact.detail<QContactOrganization>();
451 QCOMPARE(organization.assistantName(), assistantValue);
452}
453
454void tst_QVersitContactImporter::testOrganizationLogo()
455{
456 QContact contact;
457 QVersitDocument document(QVersitDocument::VCard30Type);
458 QVersitProperty property;
459
460 // Embedded LOGO
461 property.setName(QStringLiteral("LOGO"));
462 QByteArray (QByteArray::fromBase64(
463 base64: "R0lGODlhEgASAIAAAAAAAP///yH5BAEAAAEALAAAAAASABIAAAIdjI+py+0G"));
464 property.setValue(logo);
465 property.insertParameter(QStringLiteral("TYPE"),
466 QStringLiteral("GIF"));
467 document = createDocumentWithProperty(property);
468 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
469 contact = mImporter->contacts().first();
470 QContactOrganization organization = contact.detail<QContactOrganization>();
471 QByteArray content = mResourceHandler->mObjects.value(akey: organization.logoUrl().toString());
472 QCOMPARE(content, logo);
473
474 // LOGO as a URL
475 property.setName(QStringLiteral("LOGO"));
476 QString logoUrl(QStringLiteral("http://www.organization.org/logo.gif"));
477 property.setValue(logoUrl);
478 property.insertParameter(QStringLiteral("VALUE"),QStringLiteral("URL"));
479 document = createDocumentWithProperty(property);
480 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
481 contact = mImporter->contacts().first();
482 organization = contact.detail<QContactOrganization>();
483 QCOMPARE(organization.logoUrl().toString(),logoUrl);
484}
485
486void tst_QVersitContactImporter::testOrganizationRole()
487{
488 QContact contact;
489 QVersitDocument document(QVersitDocument::VCard30Type);
490 QVersitProperty property;
491
492 // Setting the role is not yet supported by QContactOrganization
493 property.setName(QStringLiteral("ROLE"));
494 QString roleValue(QStringLiteral("Very important manager and proud of it"));
495 property.setValue(roleValue);
496 document = createDocumentWithProperty(property);
497 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
498 contact = mImporter->contacts().first();
499 QContactOrganization organization = contact.detail<QContactOrganization>();
500 QCOMPARE(organization.role(), roleValue);
501}
502
503void tst_QVersitContactImporter::testTel()
504{
505 QVersitDocument document(QVersitDocument::VCard30Type);
506 QVersitProperty property;
507 property.setName(QStringLiteral("TEL"));
508 QString value(QStringLiteral("+35850987654321"));
509 property.setValue(value);
510
511 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("VOICE"));
512 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("CELL"));
513 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("MODEM"));
514 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("CAR"));
515 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("VIDEO"));
516 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("FAX"));
517 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("BBS"));
518 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("PAGER"));
519 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("HOME"));
520 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("WORK"));
521 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("ISDN"));
522
523 document.addProperty(property);
524 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
525 QContact contact = mImporter->contacts().first();
526 const QContactPhoneNumber& phone = contact.detail<QContactPhoneNumber>();
527 QCOMPARE(phone.number(),QString(value));
528
529 const QList<int> subTypes = phone.subTypes();
530 QCOMPARE(subTypes.count(), 9);
531 QVERIFY(subTypes.contains(QContactPhoneNumber::SubTypeVoice));
532 QVERIFY(subTypes.contains(QContactPhoneNumber::SubTypeMobile));
533 QVERIFY(subTypes.contains(QContactPhoneNumber::SubTypeModem));
534 QVERIFY(subTypes.contains(QContactPhoneNumber::SubTypeCar));
535 QVERIFY(subTypes.contains(QContactPhoneNumber::SubTypeVideo));
536 QVERIFY(subTypes.contains(QContactPhoneNumber::SubTypeFax));
537 QVERIFY(subTypes.contains(QContactPhoneNumber::SubTypeBulletinBoardSystem));
538 QVERIFY(subTypes.contains(QContactPhoneNumber::SubTypePager));
539 QVERIFY(subTypes.contains(QContactPhoneNumber::SubTypeIsdn));
540
541 const QList<int> contexts = phone.contexts();
542 QCOMPARE(contexts.count(),2);
543 QVERIFY(contexts.contains(QContactDetail::ContextWork));
544 QVERIFY(contexts.contains(QContactDetail::ContextHome));
545}
546
547void tst_QVersitContactImporter::testTelWithoutSubTypes()
548{
549 QVersitDocument document(QVersitDocument::VCard30Type);
550 QVersitProperty property;
551 property.setName(QStringLiteral("TEL"));
552 QString value(QStringLiteral("+35850987654321"));
553 property.setValue(value);
554
555 document.addProperty(property);
556 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
557 QContact contact = mImporter->contacts().first();
558 const QContactPhoneNumber& phone = contact.detail<QContactPhoneNumber>();
559
560 QContactPhoneNumber otherPhone;
561 otherPhone.setNumber(QStringLiteral("+35850987654321"));
562
563 QCOMPARE(otherPhone, phone);
564}
565
566void tst_QVersitContactImporter::testEmail()
567{
568 QVersitProperty property;
569 property.setName(QStringLiteral("EMAIL"));
570 QString value(QStringLiteral("john.citizen@example.com"));
571 property.setValue(value);
572 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("WORK"));
573 QVersitDocument document = createDocumentWithProperty(property);
574 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
575 QContact contact = mImporter->contacts().first();
576 QContactEmailAddress email = contact.detail<QContactEmailAddress>();
577 QCOMPARE(email.emailAddress(),value);
578 const QList<int> contexts = email.contexts();
579 QCOMPARE(contexts.count(),1);
580 QVERIFY(contexts.contains(QContactDetail::ContextWork));
581
582 QCOMPARE(mPropertyHandler->mUnknownProperties.size(), 0);
583}
584
585void tst_QVersitContactImporter::testUrl()
586{
587 QVersitProperty property;
588 property.setName(QStringLiteral("URL"));
589 QString value(QStringLiteral("http://example.com"));
590 property.setValue(value);
591 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("WORK"));
592 QVersitDocument document = createDocumentWithProperty(property);
593 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
594 QContact contact = mImporter->contacts().first();
595 QContactUrl url = contact.detail<QContactUrl>();
596 QCOMPARE(url.url(),value);
597 const QList<int> contexts = url.contexts();
598 QCOMPARE(contexts.count(),1);
599 QVERIFY(contexts.contains(QContactDetail::ContextWork));
600}
601
602void tst_QVersitContactImporter::testUid()
603{
604 QVersitProperty property;
605 property.setName(QStringLiteral("UID"));
606 QString value(QStringLiteral("unique identifier"));
607 property.setValue(value);
608 QVersitDocument document = createDocumentWithProperty(property);
609 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
610 QContact contact = mImporter->contacts().first();
611 QContactGuid uid = contact.detail<QContactGuid>();
612 QCOMPARE(uid.guid(),value);
613}
614
615void tst_QVersitContactImporter::testTimeStamp()
616{
617 // Simple date : ISO 8601 extended format
618 QVersitProperty property;
619 property.setName(QStringLiteral("REV"));
620 QString dateValue(QStringLiteral("1981-05-20"));
621 property.setValue(dateValue);
622 QVersitDocument document = createDocumentWithProperty(property);
623 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
624 QContact contact = mImporter->contacts().first();
625 QContactTimestamp timeStamp = contact.detail<QContactTimestamp>();
626 QCOMPARE(timeStamp.lastModified().date().toString(Qt::ISODate),dateValue);
627
628 // Date and Time : ISO 8601 extended format without utc offset
629 QString dateAndTimeValue(QStringLiteral("1981-05-20T23:55:55"));
630 property.setValue(dateAndTimeValue);
631 document = createDocumentWithProperty(property);
632 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
633 contact = mImporter->contacts().first();
634 timeStamp = contact.detail<QContactTimestamp>();
635 QCOMPARE(timeStamp.lastModified().toString(Qt::ISODate),dateAndTimeValue);
636
637 // Date and Time : ISO 8601 extented format with utc offset
638 QString utcOffset(QStringLiteral("Z"));
639 QString dateAndTimeWithUtcValue = dateAndTimeValue+utcOffset;
640 property.setValue(dateAndTimeWithUtcValue);
641 document = createDocumentWithProperty(property);
642 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
643 contact = mImporter->contacts().first();
644 timeStamp = contact.detail<QContactTimestamp>();
645 QCOMPARE(timeStamp.lastModified().toString(Qt::ISODate), dateAndTimeWithUtcValue);
646 QCOMPARE(timeStamp.lastModified().timeSpec(), Qt::UTC);
647
648 // Date and Time : ISO 8601 in basic format without utc offset
649 dateAndTimeValue = QStringLiteral("19810520T235555");
650 property.setValue(dateAndTimeValue);
651 document = createDocumentWithProperty(property);
652 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
653 contact = mImporter->contacts().first();
654 timeStamp = contact.detail<QContactTimestamp>();
655
656 QCOMPARE(timeStamp.lastModified().toString(QStringLiteral("yyyyMMddThhmmss")),
657 dateAndTimeValue);
658
659 // Date and Time : ISO 8601 in basic format with utc offset
660 dateAndTimeValue = QStringLiteral("19810520T235555");
661 dateAndTimeWithUtcValue = dateAndTimeValue+utcOffset;
662 property.setValue(dateAndTimeWithUtcValue);
663 document = createDocumentWithProperty(property);
664 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
665 contact = mImporter->contacts().first();
666 timeStamp = contact.detail<QContactTimestamp>();
667 QCOMPARE(timeStamp.lastModified().toString(QStringLiteral("yyyyMMddThhmmss")),
668 dateAndTimeValue);
669 QCOMPARE(timeStamp.lastModified().timeSpec(),Qt::UTC);
670}
671
672void tst_QVersitContactImporter::testVersion()
673{
674 QFETCH(QString, sequenceNumber);
675 QFETCH(QString, extendedVersion);
676 QFETCH(bool, versionCreated);
677
678 QVersitDocument document(QVersitDocument::VCard30Type);
679 addVersionPropertyToDocument(sequenceNumber,extendedVersion,document);
680 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
681 QContact contact = mImporter->contacts().first();
682 if (!versionCreated) {
683 QCOMPARE(contact.details(QContactVersion::Type).size(), 0);
684 return;
685 }
686 QContactVersion version = (QContactVersion)contact.detail(type: QContactVersion::Type);
687 QCOMPARE(version.sequenceNumber(), sequenceNumber.toInt());
688 QCOMPARE(QString(version.extendedVersion()), extendedVersion);
689}
690
691void tst_QVersitContactImporter::testVersion_data()
692{
693 QTest::addColumn<QString>(name: "sequenceNumber");
694 QTest::addColumn<QString>(name: "extendedVersion");
695 QTest::addColumn<bool>(name: "versionCreated");
696
697 {
698 QTest::newRow(dataTag: "proper version") << QString("4711") << QString("134f23dbb2") << true;
699 QTest::newRow(dataTag: "all empty") << QString("") << QString("") << false;
700 QTest::newRow(dataTag: "sequenceNumber empty") << QString("") << QString("134f23dbb3") << false;
701 QTest::newRow(dataTag: "sequenceNumber negative") << QString("-2") << QString("134f23dbb4") << true;
702 QTest::newRow(dataTag: "sequenceNumber invalid mix") << QString("2withletters") << QString("134f23dbb5") << false;
703 QTest::newRow(dataTag: "extendedVersion empty") << QString("4712") << QString("") << true;
704 QTest::newRow(dataTag: "extendedVersion negative") << QString("4713") << QString("-1234567") << true;
705 }
706}
707
708void tst_QVersitContactImporter::testMultipleVersions()
709{
710 QVersitDocument document(QVersitDocument::VCard30Type);
711 addVersionPropertyToDocument(QStringLiteral("1"), QStringLiteral("134f23dbb2"), document);
712 addVersionPropertyToDocument(QStringLiteral("2"), QStringLiteral("134f23dbb3"), document);
713 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
714 QContact contact = mImporter->contacts().first();
715 QCOMPARE(contact.details(QContactVersion::Type).size(), 1);
716 QContactVersion version = (QContactVersion)contact.detail(type: QContactVersion::Type);
717 QCOMPARE(version.sequenceNumber(), 1);
718 QCOMPARE(version.extendedVersion(), QByteArray("134f23dbb2"));
719}
720
721void tst_QVersitContactImporter::addVersionPropertyToDocument(QString sequenceNumber, QString extendedVersion, QVersitDocument &document)
722{
723 QVersitProperty property;
724 property.setName(QStringLiteral("X-QTPROJECT-VERSION"));
725 QStringList value;
726 value.append(t: sequenceNumber);
727 value.append(t: extendedVersion);
728 property.setValue(value);
729 property.setValueType(QVersitProperty::CompoundType);
730 document.addProperty(property);
731}
732
733void tst_QVersitContactImporter::testAnniversary()
734{
735 // Date : ISO 8601 extended format
736 QVersitProperty property;
737 property.setName(QStringLiteral("X-ANNIVERSARY"));
738 property.setValue(QStringLiteral("1981-05-20"));
739 QVersitDocument document = createDocumentWithProperty(property);
740 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
741 QContact contact = mImporter->contacts().first();
742 QContactAnniversary anniversary = contact.detail<QContactAnniversary>();
743 QCOMPARE(anniversary.originalDate(), QDate(1981, 5, 20));
744 QCOMPARE(anniversary.value(QContactAnniversary::FieldOriginalDate).type(), QVariant::Date);
745
746 // Evolution format
747 property.setName(QStringLiteral("X-EVOLUTION-ANNIVERSARY"));
748 property.setValue(QStringLiteral("1981-05-20"));
749 document = createDocumentWithProperty(property);
750 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
751 contact = mImporter->contacts().first();
752 anniversary = contact.detail<QContactAnniversary>();
753 QCOMPARE(anniversary.originalDate(), QDate(1981, 5, 20));
754 QCOMPARE(anniversary.value(QContactAnniversary::FieldOriginalDate).type(), QVariant::Date);
755
756 // Date : ISO 8601 in basic format
757 property.setName(QStringLiteral("X-ANNIVERSARY"));
758 property.setValue(QStringLiteral("19810520"));
759 document = createDocumentWithProperty(property);
760 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
761 contact = mImporter->contacts().first();
762 anniversary = contact.detail<QContactAnniversary>();
763 QCOMPARE(anniversary.originalDate(), QDate(1981, 5, 20));
764 QCOMPARE(anniversary.value(QContactAnniversary::FieldOriginalDate).type(), QVariant::Date);
765
766 // Date time tests
767 property.setName(QStringLiteral("X-ANNIVERSARY"));
768 property.setValue(QStringLiteral("19810520T000102")); // localtime
769 document = createDocumentWithProperty(property);
770 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
771 contact = mImporter->contacts().first();
772 anniversary = contact.detail<QContactAnniversary>();
773 QCOMPARE(anniversary.originalDate(), QDate(1981, 5, 20));
774 QCOMPARE(anniversary.originalDateTime(), QDateTime(QDate(1981, 5, 20), QTime(0,1,2), Qt::LocalTime));
775 QCOMPARE(anniversary.value(QContactAnniversary::FieldOriginalDate).type(), QVariant::DateTime);
776
777 property.setValue(QStringLiteral("19810520T010203Z")); // utc
778 document = createDocumentWithProperty(property);
779 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
780 contact = mImporter->contacts().first();
781 anniversary = contact.detail<QContactAnniversary>();
782 QCOMPARE(anniversary.originalDate(), QDate(1981, 5, 20));
783 QCOMPARE(anniversary.originalDateTime(), QDateTime(QDate(1981, 5, 20), QTime(1,2,3), Qt::UTC));
784 QCOMPARE(anniversary.value(QContactAnniversary::FieldOriginalDate).type(), QVariant::DateTime);
785}
786
787void tst_QVersitContactImporter::testBirthday()
788{
789 // Date : ISO 8601 extended format
790 QVersitProperty property;
791 property.setName(QStringLiteral("BDAY"));
792 QString dateValue(QStringLiteral("1981-05-20"));
793 property.setValue(dateValue);
794 QVersitDocument document = createDocumentWithProperty(property);
795 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
796 QContact contact = mImporter->contacts().first();
797 QContactBirthday bday = contact.detail<QContactBirthday>();
798 QCOMPARE(bday.date().toString(Qt::ISODate), dateValue);
799 QCOMPARE(bday.value(QContactBirthday::FieldBirthday).type(), QVariant::Date);
800
801 // Date : ISO 8601 in basic format
802 dateValue = QStringLiteral("19810520");
803 property.setValue(dateValue);
804 document = createDocumentWithProperty(property);
805 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
806 contact = mImporter->contacts().first();
807 bday = contact.detail<QContactBirthday>();
808 QCOMPARE(bday.date(), QDate(1981, 5, 20));
809 QCOMPARE(bday.value(QContactBirthday::FieldBirthday).type(), QVariant::Date);
810
811 dateValue = QStringLiteral("1981-05-20");
812 property.setValue(dateValue);
813 document = createDocumentWithProperty(property);
814 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
815 contact = mImporter->contacts().first();
816 bday = contact.detail<QContactBirthday>();
817 QCOMPARE(bday.date(), QDate(1981, 5, 20));
818 QCOMPARE(bday.value(QContactBirthday::FieldBirthday).type(), QVariant::Date);
819
820 dateValue = QStringLiteral("19810520T100000");
821 property.setValue(dateValue);
822 document = createDocumentWithProperty(property);
823 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
824 contact = mImporter->contacts().first();
825 bday = contact.detail<QContactBirthday>();
826 QCOMPARE(bday.dateTime(), QDateTime(QDate(1981, 5, 20), QTime(10, 0, 0), Qt::LocalTime));
827 QCOMPARE(bday.value(QContactBirthday::FieldBirthday).type(), QVariant::DateTime);
828
829 dateValue = QStringLiteral("1981-05-20T10:00:00");
830 property.setValue(dateValue);
831 document = createDocumentWithProperty(property);
832 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
833 contact = mImporter->contacts().first();
834 bday = contact.detail<QContactBirthday>();
835 QCOMPARE(bday.dateTime(), QDateTime(QDate(1981, 5, 20), QTime(10, 0, 0), Qt::LocalTime));
836 QCOMPARE(bday.value(QContactBirthday::FieldBirthday).type(), QVariant::DateTime);
837
838 dateValue = QStringLiteral("19810520T100000Z");
839 property.setValue(dateValue);
840 document = createDocumentWithProperty(property);
841 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
842 contact = mImporter->contacts().first();
843 bday = contact.detail<QContactBirthday>();
844 QCOMPARE(bday.dateTime(), QDateTime(QDate(1981, 5, 20), QTime(10, 0, 0), Qt::UTC));
845 QCOMPARE(bday.value(QContactBirthday::FieldBirthday).type(), QVariant::DateTime);
846
847 dateValue = QStringLiteral("1981-05-20T10:00:00Z");
848 property.setValue(dateValue);
849 document = createDocumentWithProperty(property);
850 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
851 contact = mImporter->contacts().first();
852 bday = contact.detail<QContactBirthday>();
853 QCOMPARE(bday.dateTime(), QDateTime(QDate(1981, 5, 20), QTime(10, 0, 0), Qt::UTC));
854 QCOMPARE(bday.value(QContactBirthday::FieldBirthday).type(), QVariant::DateTime);
855}
856
857void tst_QVersitContactImporter::testGender()
858{
859 // Check empty property.
860 QVersitProperty property1;
861 property1.setName(QStringLiteral("X-GENDER"));
862 QString val1(QStringLiteral(""));
863 property1.setValue(val1);
864 QVersitDocument document1 = createDocumentWithProperty(property: property1);
865 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document1));
866 QContact contact1 = mImporter->contacts().first();
867 QCOMPARE (contact1, QContact());
868
869 // Check valid values.
870 QVersitProperty property2;
871 property2.setName(QStringLiteral("X-GENDER"));
872 QString val2(QStringLiteral("male"));
873 property2.setValue(val2);
874 QVersitDocument document2 = createDocumentWithProperty(property: property2);
875 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document2));
876 QContact contact2 = mImporter->contacts().first();
877 QContactGender gender2 = contact2.detail<QContactGender >();
878 QCOMPARE(gender2.gender(),QContactGender::GenderMale);
879
880 QVersitProperty property3;
881 property3.setName(QStringLiteral("x-gender"));
882 QString val3(QStringLiteral("FEMALE"));
883 property3.setValue(val3);
884 QVersitDocument document3 = createDocumentWithProperty(property: property3);
885 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document3));
886 QContact contact3 = mImporter->contacts().first();
887 QContactGender gender3 = contact3.detail<QContactGender >();
888 QCOMPARE(gender3.gender(),QContactGender::GenderFemale);
889
890 QVersitProperty property4;
891 property4.setName(QStringLiteral("x-Gender"));
892 QString val4(QStringLiteral("Unspecified"));
893 property4.setValue(val4);
894 QVersitDocument document4 = createDocumentWithProperty(property: property4);
895 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document4));
896 QContact contact4 = mImporter->contacts().first();
897 QContactGender gender4 = contact4.detail<QContactGender >();
898 QCOMPARE(gender4.gender(),QContactGender::GenderUnspecified);
899
900 // Check property having an invalid value.
901 QVersitProperty property5;
902 property5.setName(QStringLiteral("X-GENDER"));
903 QString val5(QStringLiteral("Garbage"));
904 property5.setValue(val5);
905 QVersitDocument document5 = createDocumentWithProperty(property: property5);
906 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document5));
907 QContact contact5 = mImporter->contacts().first();
908 QCOMPARE(contact5, QContact());
909}
910
911void tst_QVersitContactImporter::testNickname()
912{
913 // one value
914 QVersitDocument document(QVersitDocument::VCard30Type);
915 QVersitProperty nameProperty;
916 nameProperty.setName(QStringLiteral("NICKNAME"));
917 nameProperty.setValue(QStringList(QStringLiteral("Homie")));
918 nameProperty.setValueType(QVersitProperty::ListType);
919 document.addProperty(property: nameProperty);
920 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
921 QContact contact = mImporter->contacts().first();
922 QContactNickname nickName = (QContactNickname)contact.detail(type: QContactNickname::Type);
923 QCOMPARE(nickName.nickname(), QStringLiteral("Homie"));
924
925 // comma separated values should generate multiple nickname fields
926 contact.clearDetails();
927 document.clear();
928 document.setType(QVersitDocument::VCard30Type);
929 QStringList multiVal;
930 multiVal.append(QStringLiteral("Homie"));
931 multiVal.append(QStringLiteral("SuperHero"));
932 multiVal.append(QStringLiteral("NukeSpecialist"));
933 nameProperty.setName(QStringLiteral("NICKNAME"));
934 nameProperty.setValue(multiVal);
935 nameProperty.setValueType(QVersitProperty::ListType);
936 document.addProperty(property: nameProperty);
937 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
938 contact = mImporter->contacts().first();
939 QList<QContactNickname> nickNames = contact.details<QContactNickname>();
940 QCOMPARE(nickNames.count(),3);
941 nickName = nickNames[0];
942 QCOMPARE(nickName.nickname(),QStringLiteral("Homie"));
943 nickName = nickNames[1];
944 QCOMPARE(nickName.nickname(),QStringLiteral("SuperHero"));
945 nickName = nickNames[2];
946 QCOMPARE(nickName.nickname(),QStringLiteral("NukeSpecialist"));
947
948 // X-NICKNAME
949 document.clear();
950 document.setType(QVersitDocument::VCard30Type);
951 nameProperty = QVersitProperty();
952 nameProperty.setName(QStringLiteral("X-NICKNAME"));
953 nameProperty.setValue(QStringList(QStringLiteral("Homie")));
954 nameProperty.setValueType(QVersitProperty::ListType);
955 document.addProperty(property: nameProperty);
956 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
957 contact = mImporter->contacts().first();
958 nickName = contact.detail<QContactNickname>();
959 QCOMPARE(nickName.nickname(),QStringLiteral("Homie"));
960
961 // both X-NICKNAME and NICKNAME
962 nameProperty.setName(QStringLiteral("NICKNAME"));
963 document.addProperty(property: nameProperty);
964 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
965 contact = mImporter->contacts().first();
966 nickNames = contact.details<QContactNickname>();
967 QCOMPARE(nickNames.size(), 1);
968 QCOMPARE(nickNames.first().nickname(), QStringLiteral("Homie"));
969}
970
971void tst_QVersitContactImporter::testAvatarUrl()
972{
973 QVersitProperty property;
974 property.setName(QStringLiteral("PHOTO"));
975 QString value(QStringLiteral("http://example.com/example.jpg"));
976 property.setValue(value);
977 property.insertParameter(QStringLiteral("VALUE"), QStringLiteral("URL"));
978
979 QVersitDocument document(QVersitDocument::VCard30Type);
980 document.addProperty(property);
981 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
982 QContact contact = mImporter->contacts().first();
983 QContactAvatar avatar = contact.detail<QContactAvatar>();
984 QCOMPARE(avatar.imageUrl(), QUrl(QStringLiteral("http://example.com/example.jpg")));
985
986
987 // A URL disguised inside a QByteArray.
988 document.clear();
989 document.setType(QVersitDocument::VCard30Type);
990 property.clear();
991 property.setName(QStringLiteral("PHOTO"));
992 property.setValue(QByteArray("http://example.com/example.jpg"));
993 property.insertParameter(QStringLiteral("VALUE"), QStringLiteral("URL"));
994 property.insertParameter(QStringLiteral("CHARSET"), QStringLiteral("UTF-8"));
995 document.addProperty(property);
996 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
997 contact = mImporter->contacts().first();
998 avatar = contact.detail<QContactAvatar>();
999 QCOMPARE(avatar.imageUrl(), QUrl(QStringLiteral("http://example.com/example.jpg")));
1000}
1001
1002void tst_QVersitContactImporter::testAvatarInvalid()
1003{
1004 // An avatar that's a QVersitDocument? It shouldn't work.
1005 QVersitDocument document(QVersitDocument::VCard30Type);
1006 QVersitProperty property;
1007 property.setName(QStringLiteral("PHOTO"));
1008 QVersitDocument nestedDocument;
1009 property.setValue(QVariant::fromValue(value: nestedDocument));
1010 property.insertParameter(QStringLiteral("VALUE"), QStringLiteral("URL"));
1011 document.addProperty(property);
1012 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1013 QContact contact = mImporter->contacts().first();
1014 QCOMPARE(contact.details(QContactAvatar::Type).size(), 0);
1015
1016 document.clear();
1017 document.setType(QVersitDocument::VCard30Type);
1018 property.clear();
1019 property.setName(QStringLiteral("PHOTO"));
1020 property.setValue(QVariant::fromValue(value: nestedDocument));
1021 document.addProperty(property);
1022 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1023 contact = mImporter->contacts().first();
1024 QCOMPARE(contact.details(QContactAvatar::Type).size(), 0);
1025}
1026
1027void tst_QVersitContactImporter::testGeo()
1028{
1029 // some positive values
1030 QVersitDocument document(QVersitDocument::VCard30Type);
1031 QVersitProperty nameProperty;
1032 QStringList val;
1033 val.append(QStringLiteral("45.32")); // Latitude
1034 val.append(QStringLiteral("18.53"));// Longtitude
1035 nameProperty.setName(QStringLiteral("GEO"));
1036 nameProperty.setValue(val);
1037 nameProperty.setValueType(QVersitProperty::CompoundType);
1038 document.addProperty(property: nameProperty);
1039 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1040 QContact contact = mImporter->contacts().first();
1041 QContactGeoLocation geo = (QContactGeoLocation)contact.detail(type: QContactGeoLocation::Type);
1042 QString str;
1043 str.setNum(geo.latitude(),f: '.',prec: 2);
1044 QCOMPARE(str,val[0]);
1045 str.setNum(geo.longitude(),f: '.',prec: 2);
1046 QCOMPARE(str,val[1]);
1047
1048 // some negative values
1049 document.clear();
1050 document.setType(QVersitDocument::VCard30Type);
1051 nameProperty = QVersitProperty();
1052 val.append(QStringLiteral("-45.32")); // Latitude
1053 val.append(QStringLiteral("18.53"));// Longtitude
1054 nameProperty.setName(QStringLiteral("GEO"));
1055 nameProperty.setValue(val);
1056 nameProperty.setValueType(QVersitProperty::CompoundType);
1057 document.addProperty(property: nameProperty);
1058 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1059 contact = mImporter->contacts().first();
1060 geo = (QContactGeoLocation)contact.detail(type: QContactGeoLocation::Type);
1061 str.setNum(geo.latitude(),f: '.',prec: 2);
1062 QCOMPARE(str,val[0]);
1063 str.setNum(geo.longitude(),f: '.',prec: 2);
1064 QCOMPARE(str,val[1]);
1065}
1066
1067void tst_QVersitContactImporter::testNote()
1068{
1069 // single line value
1070 QVersitDocument document(QVersitDocument::VCard30Type);
1071 QVersitProperty nameProperty;
1072 QString val(QStringLiteral("I will not sleep at my work -John"));
1073 nameProperty.setName(QStringLiteral("NOTE"));
1074 nameProperty.setValue(val);
1075 document.addProperty(property: nameProperty);
1076 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1077 QContact contact = mImporter->contacts().first();
1078 QContactNote note = (QContactNote)contact.detail(type: QContactNote::Type);
1079 QCOMPARE(note.note(),val);
1080
1081 // Multiline value and quoted printable encoding
1082 document.clear();
1083 document.setType(QVersitDocument::VCard30Type);
1084 nameProperty = QVersitProperty();
1085 val = QStringLiteral("My Dad acts like he belongs,=0D=0AHe belongs in the zoo.=0D=0A");
1086 nameProperty.setName(QStringLiteral("NOTE"));
1087 nameProperty.setValue(val);
1088 QMultiHash<QString,QString> params;
1089 params.insert(QStringLiteral("QUOTED-PRINTABLE"),avalue: val);
1090 nameProperty.setParameters(params);
1091 document.addProperty(property: nameProperty);
1092 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1093 contact = mImporter->contacts().first();
1094 note = (QContactNote)contact.detail(type: QContactNote::Type);
1095 QCOMPARE(note.note(),val);
1096}
1097
1098void tst_QVersitContactImporter::testDisplayLabel()
1099{
1100 QVersitDocument document(QVersitDocument::VCard30Type);
1101 QVersitProperty fnProperty;
1102 fnProperty.setName(QStringLiteral("FN"));
1103 fnProperty.setValue(QStringLiteral("fn"));
1104 document.addProperty(property: fnProperty);
1105 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1106 QContact contact = mImporter->contacts().first();
1107 contact = mImporter->contacts().first();
1108 QContactDisplayLabel displayLabel = contact.detail<QContactDisplayLabel>();
1109 QCOMPARE(displayLabel.label(), QStringLiteral("fn"));
1110}
1111
1112void tst_QVersitContactImporter::testOnlineAccount()
1113{
1114 QString accountUri(QStringLiteral("sip:john.citizen@example.com"));
1115 QVersitDocument document;
1116
1117 // Plain X-SIP, no TYPE ->
1118 QVersitProperty property;
1119 property.setName(QStringLiteral("X-SIP"));
1120 property.setValue(accountUri);
1121 document = createDocumentWithProperty(property);
1122 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1123 QContact contact = mImporter->contacts().first();
1124 QContactOnlineAccount onlineAccount = contact.detail<QContactOnlineAccount>();
1125 QCOMPARE(onlineAccount.accountUri(),accountUri);
1126 QList<int> subTypes = onlineAccount.subTypes();
1127 QCOMPARE(subTypes.count(),1);
1128 QVERIFY(subTypes.first() == QContactOnlineAccount::SubTypeSip);
1129
1130 // X-SIP;SWIS
1131 property = QVersitProperty();
1132 property.setName(QStringLiteral("X-SIP"));
1133 property.setValue(accountUri);
1134 QMultiHash<QString,QString> params;
1135 params.insert(QStringLiteral("TYPE"),QStringLiteral("SWIS"));
1136 property.setParameters(params);
1137 document = createDocumentWithProperty(property);
1138 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1139 contact = mImporter->contacts().first();
1140 onlineAccount = contact.detail<QContactOnlineAccount>();
1141 QCOMPARE(onlineAccount.accountUri(),accountUri);
1142 subTypes = onlineAccount.subTypes();
1143 QCOMPARE(subTypes.count(),1);
1144 QVERIFY(subTypes.first() == QContactOnlineAccount::SubTypeVideoShare);
1145
1146 // X-SIP;VOIP
1147 property = QVersitProperty();
1148 property.setName(QStringLiteral("X-SIP"));
1149 property.setValue(accountUri);
1150 params.clear();
1151 params.insert(QStringLiteral("TYPE"),QStringLiteral("VOIP"));
1152 property.setParameters(params);
1153 document = createDocumentWithProperty(property);
1154 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1155 contact = mImporter->contacts().first();
1156 onlineAccount = contact.detail<QContactOnlineAccount>();
1157 QCOMPARE(onlineAccount.accountUri(),accountUri);
1158 subTypes = onlineAccount.subTypes();
1159 QCOMPARE(subTypes.count(),1);
1160 QVERIFY(subTypes.first() == QContactOnlineAccount::SubTypeSipVoip);
1161
1162 // X-IMPP
1163 property = QVersitProperty();
1164 property.setName(QStringLiteral("X-IMPP"));
1165 property.setValue(accountUri);
1166 document = createDocumentWithProperty(property);
1167 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1168 contact = mImporter->contacts().first();
1169 onlineAccount = contact.detail<QContactOnlineAccount>();
1170 QCOMPARE(onlineAccount.accountUri(),accountUri);
1171 subTypes = onlineAccount.subTypes();
1172 QCOMPARE(subTypes.count(),1);
1173 QVERIFY(subTypes.first() == QContactOnlineAccount::SubTypeImpp);
1174
1175 // IMPP
1176 property = QVersitProperty();
1177 property.setName(QStringLiteral("IMPP"));
1178 property.setValue(accountUri);
1179 document = createDocumentWithProperty(property);
1180 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1181 contact = mImporter->contacts().first();
1182 onlineAccount = contact.detail<QContactOnlineAccount>();
1183 QCOMPARE(onlineAccount.accountUri(),accountUri);
1184 subTypes = onlineAccount.subTypes();
1185 QCOMPARE(subTypes.count(),1);
1186 QVERIFY(subTypes.first() == QContactOnlineAccount::SubTypeImpp);
1187
1188 // X-JABBER
1189 property = QVersitProperty();
1190 property.setName(QStringLiteral("X-JABBER"));
1191 property.setValue(accountUri);
1192 document = createDocumentWithProperty(property);
1193 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1194 contact = mImporter->contacts().first();
1195 onlineAccount = contact.detail<QContactOnlineAccount>();
1196 QCOMPARE(onlineAccount.accountUri(),accountUri);
1197 subTypes = onlineAccount.subTypes();
1198 QCOMPARE(subTypes.count(),1);
1199 QVERIFY(subTypes.first() == QContactOnlineAccount::SubTypeImpp);
1200 QVERIFY(onlineAccount.protocol() == QContactOnlineAccount::ProtocolJabber);
1201
1202 document = QVersitDocument(QVersitDocument::VCard30Type);
1203 property.setName("X-AIM");
1204 property.setValue("a");
1205 document.addProperty(property);
1206 property.setName("X-ICQ");
1207 property.setValue("b");
1208 document.addProperty(property);
1209 property.setName("X-MSN");
1210 property.setValue("c");
1211 document.addProperty(property);
1212 property.setName("X-QQ");
1213 property.setValue("d");
1214 document.addProperty(property);
1215 property.setName("X-YAHOO");
1216 property.setValue("e");
1217 document.addProperty(property);
1218 property.setName("X-SKYPE");
1219 property.setValue("f");
1220 document.addProperty(property);
1221 property.setName("X-SKYPE-USERNAME");
1222 property.setValue("g");
1223 document.addProperty(property);
1224 property.setName("X-MS-IMADDRESS");
1225 property.setValue("h");
1226 document.addProperty(property);
1227 property.setName("X-KADDRESSBOOK-X-IMADDRESS");
1228 property.setValue("i");
1229 document.addProperty(property);
1230 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1231 contact = mImporter->contacts().first();
1232 QList<QContactOnlineAccount> onlineAccounts = contact.details<QContactOnlineAccount>();
1233 QCOMPARE(onlineAccounts.size(), 9);
1234 QVERIFY(onlineAccounts[0].protocol() == QContactOnlineAccount::ProtocolAim);
1235 QVERIFY(onlineAccounts[0].accountUri() == "a");
1236 QVERIFY(onlineAccounts[1].protocol() == QContactOnlineAccount::ProtocolIcq);
1237 QVERIFY(onlineAccounts[1].accountUri() == "b");
1238 QVERIFY(onlineAccounts[2].protocol() == QContactOnlineAccount::ProtocolMsn);
1239 QVERIFY(onlineAccounts[2].accountUri() == "c");
1240 QVERIFY(onlineAccounts[3].protocol() == QContactOnlineAccount::ProtocolQq);
1241 QVERIFY(onlineAccounts[3].accountUri() == "d");
1242 QVERIFY(onlineAccounts[4].protocol() == QContactOnlineAccount::ProtocolYahoo);
1243 QVERIFY(onlineAccounts[4].accountUri() == "e");
1244 QVERIFY(onlineAccounts[5].protocol() == QContactOnlineAccount::ProtocolSkype);
1245 QVERIFY(onlineAccounts[5].accountUri() == "f");
1246 QVERIFY(onlineAccounts[6].protocol() == QContactOnlineAccount::ProtocolSkype);
1247 QVERIFY(onlineAccounts[6].accountUri() == "g");
1248 QVERIFY(onlineAccounts[7].protocol() == QContactOnlineAccount::ProtocolUnknown);
1249 QVERIFY(onlineAccounts[7].accountUri() == "h");
1250 QVERIFY(onlineAccounts[8].protocol() == QContactOnlineAccount::ProtocolUnknown);
1251 QVERIFY(onlineAccounts[8].accountUri() == "i");
1252}
1253
1254void tst_QVersitContactImporter::testFamily()
1255{
1256 // Interesting : kid but no wife :)
1257 QVersitDocument document(QVersitDocument::VCard30Type);
1258 QVersitProperty nameProperty;
1259 QString val(QStringLiteral("Jane")); // one is enough
1260 nameProperty.setName(QStringLiteral("X-CHILDREN"));
1261 nameProperty.setValue(QStringList(val));
1262 nameProperty.setValueType(QVersitProperty::ListType);
1263 document.addProperty(property: nameProperty);
1264 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1265 QContact contact = mImporter->contacts().first();
1266 QContactFamily family = (QContactFamily)contact.detail(type: QContactFamily::Type);
1267 QStringList children = family.children();
1268 QCOMPARE(children.count(),1); // ensure no other kids in list
1269 QCOMPARE(family.spouse(),QString()); // make sure no wife
1270 QCOMPARE(children[0],val); // ensure it is your kid
1271
1272 // Critical : wife but no kids , happy hours
1273 document.clear();
1274 document.setType(QVersitDocument::VCard30Type);
1275 nameProperty = QVersitProperty();
1276 nameProperty.setName(QStringLiteral("X-SPOUSE"));
1277 val = QStringLiteral("Jenny");
1278 nameProperty.setValue(val);
1279 document.addProperty(property: nameProperty);
1280 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1281 contact = mImporter->contacts().first();
1282 family = (QContactFamily)contact.detail(type: QContactFamily::Type);
1283 children = family.children();
1284 QCOMPARE(children.count(),0); // list should be empty as you know
1285 QCOMPARE(family.spouse(),val); // make sure thats your wife:(
1286
1287 // Hopeless : couple of kids and wife
1288 document.clear();
1289 document.setType(QVersitDocument::VCard30Type);
1290 // Add kids first
1291 nameProperty = QVersitProperty();
1292 nameProperty.setName(QStringLiteral("X-CHILDREN"));
1293 QStringList kidsVal;
1294 kidsVal.append(QStringLiteral("James"));
1295 kidsVal.append(QStringLiteral("Jake"));
1296 kidsVal.append(QStringLiteral("Jane"));
1297 nameProperty.setValue(kidsVal);
1298 nameProperty.setValueType(QVersitProperty::ListType);
1299 document.addProperty(property: nameProperty);
1300 // Add wife next
1301 val = QStringLiteral("Jenny");
1302 nameProperty = QVersitProperty();
1303 nameProperty.setName(QStringLiteral("X-SPOUSE"));
1304 nameProperty.setValue(val);
1305 document.addProperty(property: nameProperty);
1306 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1307 contact = mImporter->contacts().first();
1308 family = (QContactFamily)contact.detail(type: QContactFamily::Type);
1309 children = family.children();
1310 QCOMPARE(children.count(),3); // too late , count them now.
1311 // painfull but ensure they are your kids
1312 QCOMPARE(children, kidsVal);
1313 QCOMPARE(family.spouse(),val); // make sure thats your wife:(
1314}
1315
1316void tst_QVersitContactImporter::testFavorite()
1317{
1318 QFETCH(QString, favoriteValue);
1319 QFETCH(QString, indexValue);
1320 QFETCH(bool, favoriteCreated);
1321 QVersitDocument document(QVersitDocument::VCard30Type);
1322 addFavoritePropertyToDocument(favorite: favoriteValue, index: indexValue, document);
1323
1324 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1325
1326 QContact contact = mImporter->contacts().first();
1327 if (!favoriteCreated) {
1328 QCOMPARE(contact.details(QContactFavorite::Type).size(), 0);
1329 return;
1330 }
1331 QContactFavorite favorite = (QContactFavorite)contact.detail(type: QContactFavorite::Type);
1332 QString actualFavoriteValue = favorite.isFavorite() ? QStringLiteral("true") : QStringLiteral("false");
1333 QCOMPARE(actualFavoriteValue, favoriteValue);
1334 QCOMPARE(QString::number(favorite.index()), indexValue);
1335}
1336
1337void tst_QVersitContactImporter::testFavorite_data()
1338{
1339 QTest::addColumn<QString>(name: "favoriteValue");
1340 QTest::addColumn<QString>(name: "indexValue");
1341 QTest::addColumn<bool>(name: "favoriteCreated");
1342
1343 {
1344 QTest::newRow(dataTag: "favorite true") << QString("true") << QString("1") << true;
1345 QTest::newRow(dataTag: "favorite false") << QString("false") << QString("1") << true;
1346 QTest::newRow(dataTag: "favorite invalid") << QString("invalid") << QString("1") << false;
1347 QTest::newRow(dataTag: "favorite empty") << QString("") << QString("1") << false;
1348 QTest::newRow(dataTag: "index negative") << QString("true") << QString("-1") << true;
1349 QTest::newRow(dataTag: "index multiple digits") << QString("true") << QString("10") << true;
1350 QTest::newRow(dataTag: "index invalid") << QString("true") << QString("invalid") << false;
1351 QTest::newRow(dataTag: "index invalid mix") << QString("true") << QString("2letters") << false;
1352 QTest::newRow(dataTag: "index empty") << QString("true") << QString("") << false;
1353 }
1354}
1355
1356void tst_QVersitContactImporter::testMultipleFavorites()
1357{
1358 QVersitDocument document(QVersitDocument::VCard30Type);
1359 addFavoritePropertyToDocument(QStringLiteral("true"), QStringLiteral("1"), document);
1360 addFavoritePropertyToDocument(QStringLiteral("false"), QStringLiteral("2"), document);
1361
1362 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1363
1364 QContact contact = mImporter->contacts().first();
1365 QCOMPARE(contact.details(QContactFavorite::Type).size(), 1);
1366 QContactFavorite favorite = (QContactFavorite)contact.detail(type: QContactFavorite::Type);
1367 QCOMPARE(favorite.isFavorite(), true);
1368 QCOMPARE(favorite.index(), 1);
1369}
1370
1371void tst_QVersitContactImporter::addFavoritePropertyToDocument(QString favorite, QString index, QVersitDocument &document)
1372{
1373 QVersitProperty property;
1374 property.setName(QStringLiteral("X-QTPROJECT-FAVORITE"));
1375 QStringList value;
1376 value.append(t: favorite);
1377 value.append(t: index);
1378 property.setValue(value);
1379 property.setValueType(QVersitProperty::CompoundType);
1380 document.addProperty(property);
1381}
1382
1383void tst_QVersitContactImporter::testSound()
1384{
1385 // Test embedded sound file
1386 QVersitDocument document(QVersitDocument::VCard30Type);
1387 QVersitProperty soundProperty;
1388 QMultiHash<QString,QString> param;
1389 param.insert(QStringLiteral("TYPE"),QStringLiteral("WAVE"));
1390 soundProperty.setName(QStringLiteral("SOUND"));
1391 QByteArray val("111110000011111");
1392 soundProperty.setValue(val);
1393 soundProperty.setParameters(param);
1394 document.addProperty(property: soundProperty);
1395 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1396 QContact contact = mImporter->contacts().first();
1397 QContactRingtone ringtone = contact.detail<QContactRingtone>();
1398 QByteArray content = mResourceHandler->mObjects.value(akey: ringtone.audioRingtoneUrl());
1399 QCOMPARE(content, val);
1400
1401 // Test sound file as URL
1402 document.clear();
1403 soundProperty.clear();
1404 soundProperty.setName(QStringLiteral("SOUND"));
1405 QString soundUrl(QStringLiteral("http://qt.nokia.com/audioringtoneurl"));
1406 soundProperty.setValue(soundUrl);
1407 soundProperty.insertParameter(QStringLiteral("VALUE"),QStringLiteral("URL"));
1408 document = createDocumentWithProperty(property: soundProperty);
1409 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1410 contact = mImporter->contacts().first();
1411 ringtone = contact.detail<QContactRingtone>();
1412 QCOMPARE(ringtone.audioRingtoneUrl().toString(), soundUrl);
1413}
1414
1415void tst_QVersitContactImporter::testTag()
1416{
1417 // one value
1418 QVersitDocument document(QVersitDocument::VCard30Type);
1419 QVersitProperty tagProperty;
1420 tagProperty.setName(QStringLiteral("CATEGORIES"));
1421 tagProperty.setValue(QStringList(QStringLiteral("red")));
1422 tagProperty.setValueType(QVersitProperty::ListType);
1423 document.addProperty(property: tagProperty);
1424 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1425 QContact contact = mImporter->contacts().first();
1426 QContactTag tagDetail = contact.detail<QContactTag>();
1427 QCOMPARE(tagDetail.tag(), QStringLiteral("red"));
1428
1429 // multiple values
1430 tagProperty.setName(QStringLiteral("CATEGORIES"));
1431 tagProperty.setValue(QStringList()
1432 << QStringLiteral("red") // duplicate from previous property should be pruned
1433 << QStringLiteral("green")
1434 << QStringLiteral("blue")
1435 << QStringLiteral("blue")); // duplicates should be pruned
1436 tagProperty.setValueType(QVersitProperty::ListType);
1437 document.addProperty(property: tagProperty);
1438 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1439 contact = mImporter->contacts().first();
1440 QList<QContactTag> tagDetails = contact.details<QContactTag>();
1441 QCOMPARE(tagDetails.count(), 3);
1442 QCOMPARE(tagDetails.at(0).tag(), QStringLiteral("red"));
1443 QCOMPARE(tagDetails.at(1).tag(), QStringLiteral("green"));
1444 QCOMPARE(tagDetails.at(2).tag(), QStringLiteral("blue"));
1445}
1446
1447void tst_QVersitContactImporter::testExtendedDetail()
1448{
1449 QFETCH(QString, extendedDetailName);
1450 QFETCH(QVariant, extendedDetailData);
1451 QFETCH(QString, extendedDetailDataInProperty);
1452 QFETCH(bool, extendedDetailCreated);
1453 QVersitDocument document(QVersitDocument::VCard30Type);
1454 addExtendedDetailPropertyToDocument(name: extendedDetailName, data: extendedDetailDataInProperty, document);
1455
1456 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1457
1458 QContact contact = mImporter->contacts().first();
1459 if (!extendedDetailCreated) {
1460 QCOMPARE(contact.details(QContactExtendedDetail::Type).size(), 0);
1461 return;
1462 }
1463 QContactExtendedDetail extendedDetail = (QContactExtendedDetail)contact.detail(type: QContactExtendedDetail::Type);
1464 QCOMPARE(extendedDetail.name(), extendedDetailName);
1465 QCOMPARE(extendedDetail.data(), extendedDetailData);
1466 QCOMPARE(extendedDetail.data().type(), extendedDetailData.type());
1467}
1468
1469void tst_QVersitContactImporter::testExtendedDetail_data()
1470{
1471 QTest::addColumn<QString>(name: "extendedDetailName");
1472 QTest::addColumn<QVariant>(name: "extendedDetailData");
1473 QTest::addColumn<QString>(name: "extendedDetailDataInProperty");
1474 QTest::addColumn<bool>(name: "extendedDetailCreated");
1475
1476 QString jsonArrayWith("[\n %1\n]\n");
1477 QString jsonArrayWithString = jsonArrayWith.arg(a: "\"%1\"");
1478 {
1479 QTest::newRow(dataTag: "string data")
1480 << QString("name")
1481 << QVariant(QString("data"))
1482 << jsonArrayWithString.arg(a: "data")
1483 << true;
1484 QTest::newRow(dataTag: "string data, empty")
1485 << QString("name")
1486 << QVariant(QString(""))
1487 << jsonArrayWithString.arg(a: "")
1488 << true;
1489 QTest::newRow(dataTag: "string data, containing reserved characters")
1490 << QString("name")
1491 << QVariant(QString(",;:\\"))
1492 << jsonArrayWithString.arg(a: ",;:\\\\")
1493 << true;
1494 }
1495
1496 {
1497 QTest::newRow(dataTag: "double data")
1498 << QString("name")
1499 << QVariant((double)2.0)
1500 << jsonArrayWith.arg(a: "2")
1501 << true;
1502 QTest::newRow(dataTag: "double data, negative")
1503 << QString("name")
1504 << QVariant((double)-1.0)
1505 << jsonArrayWith.arg(a: "-1")
1506 << true;
1507 QTest::newRow(dataTag: "double data, multiple digits")
1508 << QString("name")
1509 << QVariant((double)10.2)
1510 << jsonArrayWith.arg(a: "10.2")
1511 << true;
1512 }
1513
1514 {
1515 QTest::newRow(dataTag: "boolean data")
1516 << QString("name")
1517 << QVariant(true)
1518 << jsonArrayWith.arg(a: "true")
1519 << true;
1520 }
1521
1522 {
1523 QTest::newRow(dataTag: "datetime data, imported as a string")
1524 << QString("name")
1525 << QVariant(QString("1997-07-16T19:20:30+01:00"))
1526 << jsonArrayWithString.arg(a: "1997-07-16T19:20:30+01:00")
1527 << true;
1528 }
1529
1530 {
1531 QTest::newRow(dataTag: "list data")
1532 << QString("name")
1533 << QVariant(QVariantList() << QString("string 1") << QString("string 2"))
1534 << QString("[\n [\n \"string 1\",\n \"string 2\"\n ]\n]\n")
1535 << true;
1536 }
1537
1538 {
1539 QVariantMap map;
1540 map["key 1"] = QString("string 1");
1541 map["key 2"] = QString("string 2");
1542 QTest::newRow(dataTag: "map data")
1543 << QString("name")
1544 << QVariant(map)
1545 << QString("[\n {\n \"key 1\": \"string 1\",\n \"key 2\": \"string 2\"\n }\n]\n")
1546 << true;
1547 }
1548
1549 {
1550 QVariantMap map;
1551 map["key"] = QVariantList() << (double)1 << (double)2;
1552 QTest::newRow(dataTag: "map data, containing a nested list")
1553 << QString("name")
1554 << QVariant(map)
1555 << QString("[\n {\n \"key\": [\n 1,\n 2\n ]\n }\n]\n")
1556 << true;
1557 }
1558
1559 {
1560 QTest::newRow(dataTag: "empty string as name")
1561 << QString("")
1562 << QVariant(QString("data"))
1563 << jsonArrayWithString.arg(a: "data")
1564 << true;
1565 QTest::newRow(dataTag: "name containing reserved characters")
1566 << QString(",;:\\")
1567 << QVariant(QString("data"))
1568 << jsonArrayWithString.arg(a: "data")
1569 << true;
1570 }
1571
1572 {
1573 QTest::newRow(dataTag: "null denoting an empty variant")
1574 << QString("name")
1575 << QVariant()
1576 << jsonArrayWith.arg(a: "null")
1577 << true;
1578 QTest::newRow(dataTag: "compact json with extra whitespace removed")
1579 << QString("name")
1580 << QVariant(QString("data"))
1581 << QString("[\"data\"]")
1582 << true;
1583 }
1584
1585 {
1586 QTest::newRow(dataTag: "invalid property value: empty json array as property value")
1587 << QString("name")
1588 << QVariant()
1589 << jsonArrayWith.arg(a: "")
1590 << false;
1591 QTest::newRow(dataTag: "invalid property value: invalid json value")
1592 << QString("name")
1593 << QVariant()
1594 << jsonArrayWith.arg(a: "invalid")
1595 << false;
1596 }
1597}
1598
1599void tst_QVersitContactImporter::addExtendedDetailPropertyToDocument(QString name, QString data, QVersitDocument &document)
1600{
1601 QVersitProperty property;
1602 property.setName(QStringLiteral("X-QTPROJECT-EXTENDED-DETAIL"));
1603 property.setValue(QStringList()
1604 << name
1605 << data);
1606 property.setValueType(QVersitProperty::CompoundType);
1607 document.addProperty(property);
1608}
1609
1610void tst_QVersitContactImporter::testMultipleExtendedDetails()
1611{
1612 QVersitDocument document(QVersitDocument::VCard30Type);
1613 QString jsonArrayWith("[\n %1\n]\n");
1614 QString jsonArrayWithString = jsonArrayWith.arg(a: "\"%1\"");
1615 addExtendedDetailPropertyToDocument(name: "detailName1", data: jsonArrayWithString.arg(a: "detailData1"), document);
1616 addExtendedDetailPropertyToDocument(name: "detailName2", data: jsonArrayWithString.arg(a: "detailData2"), document);
1617
1618 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1619
1620 QContact contact = mImporter->contacts().first();
1621 QCOMPARE(contact.details(QContactDetail::TypeExtendedDetail).size(), 2);
1622 QList<QContactDetail> actualDetails = contact.details(type: QContactDetail::TypeExtendedDetail);
1623 QContactExtendedDetail extendedDetail1 = (QContactExtendedDetail)actualDetails.at(i: 0);
1624 QContactExtendedDetail extendedDetail2 = (QContactExtendedDetail)actualDetails.at(i: 1);
1625 QCOMPARE(extendedDetail1.name(), QString("detailName1"));
1626 QCOMPARE(extendedDetail1.data().toString(), QString("detailData1"));
1627 QCOMPARE(extendedDetail2.name(), QString("detailName2"));
1628 QCOMPARE(extendedDetail2.data().toString(), QString("detailData2"));
1629}
1630
1631void tst_QVersitContactImporter::testPref()
1632{
1633 QVersitDocument document(QVersitDocument::VCard30Type);
1634 QVersitProperty property1;
1635 property1.setName(QStringLiteral("TEL"));
1636 property1.setValue(QStringLiteral("1"));
1637 document.addProperty(property: property1);
1638 QVersitProperty property2;
1639 property2.setName(QStringLiteral("TEL"));
1640 property2.setValue(QStringLiteral("2"));
1641 property2.insertParameter(QStringLiteral("TYPE"), QStringLiteral("PREF"));
1642 document.addProperty(property: property2);
1643 QVersitProperty property3;
1644 property3.setName(QStringLiteral("TEL"));
1645 property3.setValue(QStringLiteral("3"));
1646 property3.insertParameter(QStringLiteral("TYPE"), QStringLiteral("PREF"));
1647 document.addProperty(property: property3);
1648 QVersitProperty property4;
1649 property4.setName(QStringLiteral("TEL"));
1650 property4.setValue(QStringLiteral("4"));
1651 document.addProperty(property: property4);
1652
1653 // Test that pref details comes first.
1654 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1655 QContact contact = mImporter->contacts().first();
1656 QContactPhoneNumber firstNumber = contact.detail<QContactPhoneNumber>();
1657 QCOMPARE(firstNumber.number(), QStringLiteral("2"));
1658 QList<QContactPhoneNumber> numbers = contact.details<QContactPhoneNumber>();
1659 QCOMPARE(numbers.at(0).number(), QStringLiteral("2"));
1660 QCOMPARE(numbers.at(1).number(), QStringLiteral("3"));
1661 QCOMPARE(numbers.at(2).number(), QStringLiteral("1"));
1662 QCOMPARE(numbers.at(3).number(), QStringLiteral("4"));
1663}
1664
1665void tst_QVersitContactImporter::testPropertyHandler()
1666{
1667 QVersitDocument document(QVersitDocument::VCard30Type);
1668 QVersitProperty property;
1669
1670 // No unconverted properties, no converted properties either. Fails with EmptyDocumentError
1671 QVERIFY(!mImporter->importDocuments(QList<QVersitDocument>() << document));
1672 QCOMPARE(mPropertyHandler->mUnknownProperties.size(), 0);
1673 QCOMPARE(mPropertyHandler->mPreProcessedProperties.size(), 0);
1674 QCOMPARE(mPropertyHandler->mPostProcessedProperties.size(), 0);
1675
1676 // No unconverted properties, one converted property
1677 mPropertyHandler->clear();
1678 property.setName(QStringLiteral("FN"));
1679 property.setValue(QStringLiteral("John Citizen"));
1680 document.addProperty(property);
1681 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1682 QContact contact = mImporter->contacts().first();
1683 QCOMPARE(mPropertyHandler->mUnknownProperties.size(), 0);
1684 QCOMPARE(mPropertyHandler->mPreProcessedProperties.size(), 1);
1685 QCOMPARE(mPropertyHandler->mPostProcessedProperties.size(), 1);
1686
1687 // Set the handler to override handling of the property
1688 mPropertyHandler->clear();
1689 mPropertyHandler->mPreProcess = true;
1690 document.clear();
1691 document.setType(QVersitDocument::VCard30Type);
1692 property.setName(QStringLiteral("FN"));
1693 property.setValue(QStringLiteral("John Citizen"));
1694 document.addProperty(property);
1695 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1696 contact = mImporter->contacts().first();
1697 QCOMPARE(mPropertyHandler->mUnknownProperties.size(), 0);
1698 QCOMPARE(mPropertyHandler->mPreProcessedProperties.size(), 1);
1699 QCOMPARE(mPropertyHandler->mPostProcessedProperties.size(), 0);
1700 QContactDetail nameDetail = contact.detail(type: QContactName::Type);
1701 QVERIFY(nameDetail.isEmpty());
1702
1703 // One unknown property
1704 mPropertyHandler->clear();
1705 property.setName(QStringLiteral("X-EXTENSION-1"));
1706 property.setValue(QStringLiteral("extension value 1"));
1707 document.addProperty(property);
1708 mImporter->importDocuments(documents: QList<QVersitDocument>() << document);
1709 QList<QVersitProperty> unknownProperties = mPropertyHandler->mUnknownProperties;
1710 QCOMPARE(unknownProperties.count(), 1);
1711 QCOMPARE(unknownProperties[0].name(), QStringLiteral("X-EXTENSION-1"));
1712 QCOMPARE(unknownProperties[0].value(), QStringLiteral("extension value 1"));
1713
1714 // Two unknown properties
1715 mPropertyHandler->clear();
1716 property.setName(QStringLiteral("X-EXTENSION-2"));
1717 property.setValue(QStringLiteral("extension value 2"));
1718 document.addProperty(property);
1719 mImporter->importDocuments(documents: QList<QVersitDocument>() << document);
1720 unknownProperties = mPropertyHandler->mUnknownProperties;
1721 QCOMPARE(unknownProperties.count(), 2);
1722 QCOMPARE(unknownProperties[0].name(), QStringLiteral("X-EXTENSION-1"));
1723 QCOMPARE(unknownProperties[0].value(), QStringLiteral("extension value 1"));
1724 QCOMPARE(unknownProperties[1].name(), QStringLiteral("X-EXTENSION-2"));
1725 QCOMPARE(unknownProperties[1].value(), QStringLiteral("extension value 2"));
1726}
1727
1728void tst_QVersitContactImporter::testInvalidDocument()
1729{
1730 // invalid document (invalid type)
1731 QList<QVersitDocument> documents;
1732 QVersitDocument document(QVersitDocument::InvalidType);
1733 QVersitProperty nameProperty;
1734 nameProperty.setName(QStringLiteral("FN"));
1735 nameProperty.setValue(QStringLiteral("John Citizen"));
1736 document.addProperty(property: nameProperty);
1737 documents.append(t: document);
1738
1739 // valid document in the same list
1740 QVersitProperty telProperty;
1741 telProperty.setName(QStringLiteral("TEL"));
1742 telProperty.setValue(QStringLiteral("1234"));
1743 document.addProperty(property: telProperty);
1744 document.setType(QVersitDocument::VCard21Type);
1745 documents.append(t: document);
1746 QVERIFY(!mImporter->importDocuments(documents));
1747 QMap<int, QVersitContactImporter::Error> errorMap = mImporter->errorMap();
1748 QCOMPARE(errorMap.size(), 1);
1749 QVERIFY(errorMap.contains(0));
1750 QVERIFY(errorMap.value(0) == QVersitContactImporter::InvalidDocumentError);
1751 QList<QContact> contacts = mImporter->contacts();
1752 QCOMPARE(contacts.size(), 1);
1753 QContactPhoneNumber phoneDetail = contacts.first().detail<QContactPhoneNumber>();
1754 QCOMPARE(phoneDetail.number(), QStringLiteral("1234"));
1755
1756 // empty document
1757 document.clear();
1758 document.setType(QVersitDocument::VCard21Type);
1759 QVERIFY(!mImporter->importDocuments(QList<QVersitDocument>() << document));
1760 errorMap = mImporter->errorMap();
1761 QCOMPARE(errorMap.size(), 1);
1762 QCOMPARE(errorMap.value(0), QVersitContactImporter::EmptyDocumentError);
1763 QCOMPARE(mImporter->errors(), errorMap);
1764
1765}
1766
1767void tst_QVersitContactImporter::testEmailWithContextOther()
1768{
1769 QVersitProperty property;
1770 property.setName(QStringLiteral("EMAIL"));
1771 QString value(QStringLiteral("john.citizen@example.com"));
1772 property.setValue(value);
1773 property.insertParameter(QStringLiteral("TYPE"),QStringLiteral("OTHER"));
1774 QVersitDocument document = createDocumentWithProperty(property);
1775 QVERIFY(mImporter->importDocuments(QList<QVersitDocument>() << document));
1776 QContact contact = mImporter->contacts().first();
1777 QContactEmailAddress email = contact.detail<QContactEmailAddress>();
1778 QCOMPARE(email.emailAddress(),value);
1779 const QList<int> contexts = email.contexts();
1780 QCOMPARE(contexts.count(),1);
1781 QVERIFY(contexts.contains(QContactDetail::ContextOther));
1782}
1783
1784QVersitDocument tst_QVersitContactImporter::createDocumentWithProperty(
1785 const QVersitProperty& property)
1786{
1787 QVersitDocument document(QVersitDocument::VCard30Type);
1788 document.addProperty(property);
1789 return document;
1790}
1791
1792QVersitDocument tst_QVersitContactImporter::createDocumentWithNameAndPhoto(
1793 const QString& name,
1794 QByteArray image,
1795 const QString& imageType)
1796{
1797 QVersitDocument document(QVersitDocument::VCard30Type);
1798
1799 QVersitProperty nameProperty;
1800 nameProperty.setName(QStringLiteral("FN"));
1801 nameProperty.setValue(name);
1802 document.addProperty(property: nameProperty);
1803
1804 QVersitProperty property;
1805 property.setName(QStringLiteral("PHOTO"));
1806 property.setValue(image);
1807 if (imageType != QString()) {
1808 property.insertParameter(QStringLiteral("TYPE"), value: imageType);
1809 }
1810 document.addProperty(property);
1811
1812 return document;
1813}
1814
1815QTEST_MAIN(tst_QVersitContactImporter)
1816
1817

source code of qtpim/tests/auto/versit/qversitcontactimporter/tst_qversitcontactimporter.cpp