| 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_qversitorganizerexporter.h" | 
| 37 | #include <QtTest/QtTest> | 
| 38 |  | 
| 39 | QTORGANIZER_USE_NAMESPACE | 
| 40 | QTVERSITORGANIZER_USE_NAMESPACE | 
| 41 |  | 
| 42 | Q_DECLARE_METATYPE(QList<QOrganizerItem>) | 
| 43 | Q_DECLARE_METATYPE(QList<QOrganizerItemDetail>) | 
| 44 | Q_DECLARE_METATYPE(QList<QVersitProperty>) | 
| 45 |  | 
| 46 | void tst_QVersitOrganizerExporter::testExport() | 
| 47 | { | 
| 48 |     QFETCH(QList<QOrganizerItem>, items); | 
| 49 |     QFETCH(QVersitDocument, expectedDocument); | 
| 50 |  | 
| 51 |     QVersitOrganizerExporter exporter; | 
| 52 |     QVERIFY(exporter.exportItems(items)); | 
| 53 |     QVERIFY(exporter.errorMap().isEmpty()); | 
| 54 |     QVersitDocument document = exporter.document(); | 
| 55 |     if (document != expectedDocument) { | 
| 56 |         qDebug() << "Actual:"  << document; | 
| 57 |         qDebug() << "Expected:"  << expectedDocument; | 
| 58 |         QCOMPARE(document, expectedDocument); | 
| 59 |     } | 
| 60 | } | 
| 61 |  | 
| 62 | void tst_QVersitOrganizerExporter::testExport_data() | 
| 63 | { | 
| 64 |     QTest::addColumn<QList<QOrganizerItem> >(name: "items" ); | 
| 65 |     QTest::addColumn<QVersitDocument>(name: "expectedDocument" ); | 
| 66 |  | 
| 67 |     { | 
| 68 |         QVersitDocument document(QVersitDocument::ICalendar20Type); | 
| 69 |         document.setComponentType(QStringLiteral("VCALENDAR" )); | 
| 70 |         QVersitDocument nested(QVersitDocument::ICalendar20Type); | 
| 71 |         nested.setComponentType(QStringLiteral("VEVENT" )); | 
| 72 |         QVersitProperty property; | 
| 73 |         property.setName(QStringLiteral("SUMMARY" )); | 
| 74 |         property.setValue(QStringLiteral("Bastille Day Party" )); | 
| 75 |         nested.addProperty(property); | 
| 76 |         property.setName(QStringLiteral("DTSTART" )); | 
| 77 |         property.setValue(QStringLiteral("19970714T170000Z" )); | 
| 78 |         nested.addProperty(property); | 
| 79 |         property.setName(QStringLiteral("DTEND" )); | 
| 80 |         property.setValue(QStringLiteral("19970715T035959Z" )); | 
| 81 |         nested.addProperty(property); | 
| 82 |         document.addSubDocument(subdocument: nested); | 
| 83 |  | 
| 84 |         nested.clear(); | 
| 85 |         nested.setType(QVersitDocument::ICalendar20Type); | 
| 86 |         nested.setComponentType(QStringLiteral("VTODO" )); | 
| 87 |         property.setName(QStringLiteral("SUMMARY" )); | 
| 88 |         property.setValue(QStringLiteral("Take out the garbage" )); | 
| 89 |         nested.addProperty(property); | 
| 90 |         property.setName(QStringLiteral("DTSTART" )); | 
| 91 |         property.setValue(QStringLiteral("20100609T080000" )); | 
| 92 |         nested.addProperty(property); | 
| 93 |         property.setName(QStringLiteral("DUE" )); | 
| 94 |         property.setValue(QStringLiteral("20100610T080000" )); | 
| 95 |         nested.addProperty(property); | 
| 96 |         document.addSubDocument(subdocument: nested); | 
| 97 |  | 
| 98 |         nested.clear(); | 
| 99 |         nested.setType(QVersitDocument::ICalendar20Type); | 
| 100 |         nested.setComponentType(QStringLiteral("VJOURNAL" )); | 
| 101 |         property.setName(QStringLiteral("SUMMARY" )); | 
| 102 |         property.setValue(QStringLiteral("Trip to Thailand" )); | 
| 103 |         nested.addProperty(property); | 
| 104 |         property.setName(QStringLiteral("DTSTART" )); | 
| 105 |         property.setValue(QStringLiteral("20100615T112300" )); | 
| 106 |         nested.addProperty(property); | 
| 107 |         document.addSubDocument(subdocument: nested); | 
| 108 |  | 
| 109 |         QOrganizerEvent event; | 
| 110 |         event.setDisplayLabel(QStringLiteral("Bastille Day Party" )); | 
| 111 |         event.setStartDateTime(QDateTime(QDate(1997, 7, 14), QTime(17, 0, 0), Qt::UTC)); | 
| 112 |         event.setEndDateTime(QDateTime(QDate(1997, 7, 15), QTime(3, 59, 59), Qt::UTC)); | 
| 113 |  | 
| 114 |         QOrganizerTodo todo; | 
| 115 |         todo.setDisplayLabel(QStringLiteral("Take out the garbage" )); | 
| 116 |         todo.setStartDateTime(QDateTime(QDate(2010, 6, 9), QTime(8, 0, 0))); | 
| 117 |         todo.setDueDateTime(QDateTime(QDate(2010, 6, 10), QTime(8, 0, 0))); | 
| 118 |  | 
| 119 |         QOrganizerJournal journal; | 
| 120 |         journal.setDisplayLabel(QStringLiteral("Trip to Thailand" )); | 
| 121 |         journal.setDateTime(QDateTime(QDate(2010, 6, 15), QTime(11, 23, 0))); | 
| 122 |  | 
| 123 |         QList<QOrganizerItem> items; | 
| 124 |         items << static_cast<QOrganizerItem>(event); | 
| 125 |         items << static_cast<QOrganizerItem>(todo); | 
| 126 |         items << static_cast<QOrganizerItem>(journal); | 
| 127 |  | 
| 128 |         QTest::newRow(dataTag: "sample event, todo and journal" ) << items << document; | 
| 129 |     } | 
| 130 |  | 
| 131 |     { | 
| 132 |         QVersitDocument document(QVersitDocument::ICalendar20Type); | 
| 133 |         document.setComponentType(QStringLiteral("VCALENDAR" )); | 
| 134 |         QVersitDocument nested(QVersitDocument::ICalendar20Type); | 
| 135 |         nested.setComponentType(QStringLiteral("VEVENT" )); | 
| 136 |         QVersitProperty property; | 
| 137 |         property.setName(QStringLiteral("UID" )); | 
| 138 |         property.setValue(QStringLiteral("1234" )); | 
| 139 |         nested.addProperty(property); | 
| 140 |         property.setName(QStringLiteral("RECURRENCE-ID" )); | 
| 141 |         property.setValue(QStringLiteral("20100608" )); | 
| 142 |         nested.addProperty(property); | 
| 143 |         document.addSubDocument(subdocument: nested); | 
| 144 |  | 
| 145 |         // An event occurrence with OriginalDate and Guid set | 
| 146 |         QOrganizerEventOccurrence event; | 
| 147 |         event.setGuid(QStringLiteral("1234" )); | 
| 148 |         event.setOriginalDate(QDate(2010, 6, 8)); | 
| 149 |  | 
| 150 |         QList<QOrganizerItem> items; | 
| 151 |         items << static_cast<QOrganizerItem>(event); | 
| 152 |  | 
| 153 |         QTest::newRow(dataTag: "event occurrence exception" ) << items << document; | 
| 154 |     } | 
| 155 | } | 
| 156 |  | 
| 157 | /*! Test that bad input causes the exporter to fail with the correct error */ | 
| 158 | void tst_QVersitOrganizerExporter::testExportError() | 
| 159 | { | 
| 160 |     QFETCH(QList<QOrganizerItem>, items); | 
| 161 |     QFETCH(QVersitDocument, expectedDocument); | 
| 162 |     QFETCH(int, expectedError); | 
| 163 |  | 
| 164 |     QVersitOrganizerExporter exporter; | 
| 165 |     QVERIFY(!exporter.exportItems(items)); | 
| 166 |     QVERIFY(!exporter.errorMap().isEmpty()); | 
| 167 |     QVERIFY(exporter.errorMap()[0] == expectedError); | 
| 168 |     QVersitDocument document = exporter.document(); | 
| 169 |     if (document != expectedDocument) { | 
| 170 |         qDebug() << "Actual:"  << document; | 
| 171 |         qDebug() << "Expected:"  << expectedDocument; | 
| 172 |         QCOMPARE(document, expectedDocument); | 
| 173 |     } | 
| 174 | } | 
| 175 |  | 
| 176 | void tst_QVersitOrganizerExporter::testExportError_data() | 
| 177 | { | 
| 178 |     QTest::addColumn<QList<QOrganizerItem> >(name: "items" ); | 
| 179 |     QTest::addColumn<QVersitDocument>(name: "expectedDocument" ); | 
| 180 |     QTest::addColumn<int>(name: "expectedError" ); | 
| 181 |  | 
| 182 |     QVersitDocument document(QVersitDocument::ICalendar20Type); | 
| 183 |     document.setComponentType(QStringLiteral("VCALENDAR" )); | 
| 184 |  | 
| 185 |     // An event occurrence with OriginalDate set but no Guid | 
| 186 |     QOrganizerEventOccurrence event; | 
| 187 |     event.setOriginalDate(QDate(2010, 6, 8)); | 
| 188 |  | 
| 189 |     QList<QOrganizerItem> items; | 
| 190 |     items << static_cast<QOrganizerItem>(event); | 
| 191 |  | 
| 192 |     QTest::newRow(dataTag: "event occurrence exception with no guid" ) << items << document | 
| 193 |         << (int)QVersitOrganizerExporter::UnderspecifiedOccurrenceError; | 
| 194 | } | 
| 195 |  | 
| 196 | void tst_QVersitOrganizerExporter::testExportEventDetails() | 
| 197 | { | 
| 198 |     QFETCH(QList<QOrganizerItemDetail>, details); | 
| 199 |     QFETCH(QList<QVersitProperty>, expectedProperties); | 
| 200 |  | 
| 201 |     QVersitOrganizerExporter exporter; | 
| 202 |     QOrganizerEvent item; | 
| 203 |     foreach (QOrganizerItemDetail detail, details) { | 
| 204 |         item.saveDetail(detail: &detail); | 
| 205 |     } | 
| 206 |     QVERIFY(exporter.exportItems(QList<QOrganizerItem>() << item)); | 
| 207 |     QVERIFY(exporter.errorMap().isEmpty()); | 
| 208 |     QVersitDocument document = exporter.document(); | 
| 209 |     QList<QVersitDocument> subDocuments = document.subDocuments(); | 
| 210 |     QCOMPARE(subDocuments.size(), 1); | 
| 211 |     int currentVAlarmSubDocumentIndex = 0; | 
| 212 |     foreach(const QVersitProperty& expectedProperty, expectedProperties) { | 
| 213 |         QList<QVersitProperty> actualProperties = | 
| 214 |             findPropertiesByName(document: subDocuments.first(), propertyName: expectedProperty.name()); | 
| 215 |         if (expectedProperty.valueType() == QVersitProperty::VersitDocumentType) { | 
| 216 |             QCOMPARE(subDocuments.first().subDocuments().size(), expectedProperties.size()); | 
| 217 |             QVersitDocument actualVAlarmDocument = | 
| 218 |                     subDocuments.first().subDocuments().at(i: currentVAlarmSubDocumentIndex); | 
| 219 |             QVersitDocument expectedVAlarmDocument = | 
| 220 |                     expectedProperty.variantValue().value<QVersitDocument>(); | 
| 221 |             foreach (const QVersitProperty &valarmProp, expectedVAlarmDocument.properties()) { | 
| 222 |                 if (!actualVAlarmDocument.properties().contains(t: valarmProp)) { | 
| 223 |                             qDebug() << "Actual:"  << actualVAlarmDocument.properties(); | 
| 224 |                             qDebug() << "Expected to find:"  << valarmProp; | 
| 225 |                             QVERIFY(false); | 
| 226 |                 } | 
| 227 |             } | 
| 228 |             currentVAlarmSubDocumentIndex ++; //move to next expected valarm document | 
| 229 |         } else if (!actualProperties.contains(t: expectedProperty)) { | 
| 230 |             qDebug() << "Actual:"  << actualProperties; | 
| 231 |             qDebug() << "Expected to find:"  << expectedProperty; | 
| 232 |             QVERIFY(false); | 
| 233 |         } | 
| 234 |     } | 
| 235 | } | 
| 236 |  | 
| 237 | void tst_QVersitOrganizerExporter::testExportEventDetails_data() | 
| 238 | { | 
| 239 |     QTest::addColumn<QList<QOrganizerItemDetail> >(name: "details" ); | 
| 240 |     QTest::addColumn<QList<QVersitProperty> >(name: "expectedProperties" ); | 
| 241 |  | 
| 242 |     { | 
| 243 |         QVersitProperty property; | 
| 244 |         property.setName(QStringLiteral("SUMMARY" )); | 
| 245 |         property.setValue(QStringLiteral("jabberwocky" )); | 
| 246 |         QOrganizerItemDisplayLabel displayLabel; | 
| 247 |         displayLabel.setLabel(QStringLiteral("jabberwocky" )); | 
| 248 |         QTest::newRow(dataTag: "one summary" ) << (QList<QOrganizerItemDetail>() << displayLabel) | 
| 249 |             << (QList<QVersitProperty>() << property); | 
| 250 |     } | 
| 251 |  | 
| 252 |     { | 
| 253 |         QVersitProperty property; | 
| 254 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 255 |         QList<QVersitProperty> valarmProperties; | 
| 256 |         QMultiHash<QString, QString> parameters; | 
| 257 |         property.setName(QStringLiteral("ACTION" )); | 
| 258 |         property.setValue(QStringLiteral("AUDIO" )); | 
| 259 |         valarmProperties << property; | 
| 260 |         property.setName(QStringLiteral("ATTACH" )); | 
| 261 |         property.setValue(QUrl(QStringLiteral("http://qt.nokia.com" ))); | 
| 262 |         valarmProperties << property; | 
| 263 |         property.setName(QStringLiteral("DURATION" )); | 
| 264 |         property.setValue(QStringLiteral("PT5S" )); | 
| 265 |         valarmProperties << property; | 
| 266 |         property.setName(QStringLiteral("REPEAT" )); | 
| 267 |         property.setValue(3); | 
| 268 |         valarmProperties << property; | 
| 269 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 270 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("START" )); | 
| 271 |         property.setParameters(parameters); | 
| 272 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 273 |         valarmProperties << property; | 
| 274 |         property.clear(); | 
| 275 |         valarmDocument.setComponentType("VALARM" ); | 
| 276 |         valarmDocument.setProperties(valarmProperties); | 
| 277 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 278 |         property.setName(QStringLiteral("VALARM" )); | 
| 279 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 280 |         QOrganizerItemAudibleReminder audibleReminder; | 
| 281 |         audibleReminder.setDataUrl(QUrl("http://qt.nokia.com" )); | 
| 282 |         audibleReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 283 |         audibleReminder.setSecondsBeforeStart(90); | 
| 284 |         QTest::newRow(dataTag: "audible reminder" ) << (QList<QOrganizerItemDetail>() << audibleReminder) | 
| 285 |             << (QList<QVersitProperty>() << property); | 
| 286 |     } | 
| 287 |  | 
| 288 |     { | 
| 289 |         QVersitProperty property; | 
| 290 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 291 |         QList<QVersitProperty> valarmProperties; | 
| 292 |         QMultiHash<QString, QString> parameters; | 
| 293 |  | 
| 294 |         property.setName(QStringLiteral("ACTION" )); | 
| 295 |         property.setValue(QStringLiteral("DISPLAY" )); | 
| 296 |         valarmProperties << property; | 
| 297 |         property.setName(QStringLiteral("x-QTPROJECT-ATTACH" )); | 
| 298 |         property.setValue(QUrl(QStringLiteral("http://qt.nokia.com" ))); | 
| 299 |         valarmProperties << property; | 
| 300 |         property.setName(QStringLiteral("DURATION" )); | 
| 301 |         property.setValue(QStringLiteral("PT5S" )); | 
| 302 |         valarmProperties << property; | 
| 303 |         property.setName(QStringLiteral("REPEAT" )); | 
| 304 |         property.setValue(3); | 
| 305 |         valarmProperties << property; | 
| 306 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 307 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("START" )); | 
| 308 |         property.setParameters(parameters); | 
| 309 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 310 |         valarmProperties << property; | 
| 311 |         property.clear(); | 
| 312 |         property.setName(QStringLiteral("DESCRIPTION" )); | 
| 313 |         property.setValue(QStringLiteral("Test visual reminder" )); | 
| 314 |         valarmProperties << property; | 
| 315 |  | 
| 316 |         valarmDocument.setComponentType("VALARM" ); | 
| 317 |         valarmDocument.setProperties(valarmProperties); | 
| 318 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 319 |         property.setName(QStringLiteral("VALARM" )); | 
| 320 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 321 |         QOrganizerItemVisualReminder visualReminder; | 
| 322 |         visualReminder.setDataUrl(QUrl("http://qt.nokia.com" )); | 
| 323 |         visualReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 324 |         visualReminder.setSecondsBeforeStart(90); | 
| 325 |         visualReminder.setMessage(QStringLiteral("Test visual reminder" )); | 
| 326 |         QTest::newRow(dataTag: "visual reminder" ) << (QList<QOrganizerItemDetail>() << visualReminder) | 
| 327 |             << (QList<QVersitProperty>() << property); | 
| 328 |     } | 
| 329 |  | 
| 330 |     { | 
| 331 |         QVersitProperty property; | 
| 332 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 333 |         QList<QVersitProperty> valarmProperties; | 
| 334 |         QMultiHash<QString, QString> parameters; | 
| 335 |  | 
| 336 |         property.setName(QStringLiteral("ACTION" )); | 
| 337 |         property.setValue(QStringLiteral("DISPLAY" )); | 
| 338 |         valarmProperties << property; | 
| 339 |         property.setName(QStringLiteral("x-QTPROJECT-ATTACH" )); | 
| 340 |         property.setValue(QUrl(QStringLiteral("http://qt.nokia.com" ))); | 
| 341 |         valarmProperties << property; | 
| 342 |         property.setName(QStringLiteral("DURATION" )); | 
| 343 |         property.setValue(QStringLiteral("PT5S" )); | 
| 344 |         valarmProperties << property; | 
| 345 |         property.setName(QStringLiteral("REPEAT" )); | 
| 346 |         property.setValue(3); | 
| 347 |         valarmProperties << property; | 
| 348 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 349 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("START" )); | 
| 350 |         property.setParameters(parameters); | 
| 351 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 352 |         valarmProperties << property; | 
| 353 |         property.clear(); | 
| 354 |         property.setName(QStringLiteral("DESCRIPTION" )); | 
| 355 |         property.setValue(QStringLiteral("" )); | 
| 356 |         valarmProperties << property; | 
| 357 |  | 
| 358 |         valarmDocument.setComponentType("VALARM" ); | 
| 359 |         valarmDocument.setProperties(valarmProperties); | 
| 360 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 361 |         property.setName(QStringLiteral("VALARM" )); | 
| 362 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 363 |         QOrganizerItemVisualReminder visualReminder; | 
| 364 |         visualReminder.setDataUrl(QUrl("http://qt.nokia.com" )); | 
| 365 |         visualReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 366 |         visualReminder.setSecondsBeforeStart(90); | 
| 367 |         QTest::newRow(dataTag: "visual reminder: no message" ) << (QList<QOrganizerItemDetail>() << visualReminder) | 
| 368 |             << (QList<QVersitProperty>() << property); | 
| 369 |     } | 
| 370 |  | 
| 371 |     { | 
| 372 |         QVersitProperty property; | 
| 373 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 374 |         QList<QVersitProperty> valarmProperties; | 
| 375 |         QMultiHash<QString, QString> parameters; | 
| 376 |  | 
| 377 |         property.setName(QStringLiteral("ACTION" )); | 
| 378 |         property.setValue(QStringLiteral("EMAIL" )); | 
| 379 |         valarmProperties << property; | 
| 380 |         property.setName(QStringLiteral("DURATION" )); | 
| 381 |         property.setValue(QStringLiteral("PT5S" )); | 
| 382 |         valarmProperties << property; | 
| 383 |         property.setName(QStringLiteral("REPEAT" )); | 
| 384 |         property.setValue(3); | 
| 385 |         valarmProperties << property; | 
| 386 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 387 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("START" )); | 
| 388 |         property.setParameters(parameters); | 
| 389 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 390 |         valarmProperties << property; | 
| 391 |         property.clear(); | 
| 392 |         property.setName(QStringLiteral("DESCRIPTION" )); | 
| 393 |         property.setValue(QStringLiteral("Test email body" )); | 
| 394 |         valarmProperties << property; | 
| 395 |         property.setName(QStringLiteral("SUMMARY" )); | 
| 396 |         property.setValue(QStringLiteral("Test email subject" )); | 
| 397 |         valarmProperties << property; | 
| 398 |         property.setName(QStringLiteral("ATTENDEE" )); | 
| 399 |         property.setValue(QStringLiteral("First email recipient" )); | 
| 400 |         valarmProperties << property; | 
| 401 |         property.setValue(QStringLiteral("Second email recipient" )); | 
| 402 |         valarmProperties << property; | 
| 403 |  | 
| 404 |         valarmDocument.setComponentType("VALARM" ); | 
| 405 |         valarmDocument.setProperties(valarmProperties); | 
| 406 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 407 |         property.setName(QStringLiteral("VALARM" )); | 
| 408 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 409 |         QOrganizerItemEmailReminder emailReminder; | 
| 410 |         QVariantList attachments; | 
| 411 |         emailReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 412 |         emailReminder.setSecondsBeforeStart(90); | 
| 413 |         emailReminder.setRecipients((QStringList() << QStringLiteral("First email recipient" ) | 
| 414 |                                     << QStringLiteral("Second email recipient" ))); | 
| 415 |         emailReminder.setContents(QStringLiteral("Test email subject" ), | 
| 416 |                                   QStringLiteral("Test email body" ), | 
| 417 |                                   attachments); | 
| 418 |         QTest::newRow(dataTag: "email reminder" ) << (QList<QOrganizerItemDetail>() << emailReminder) | 
| 419 |             << (QList<QVersitProperty>() << property); | 
| 420 |     } | 
| 421 |  | 
| 422 |     { | 
| 423 |         QVersitProperty property; | 
| 424 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 425 |         QList<QVersitProperty> valarmProperties; | 
| 426 |         QMultiHash<QString, QString> parameters; | 
| 427 |  | 
| 428 |         property.setName(QStringLiteral("ACTION" )); | 
| 429 |         property.setValue(QStringLiteral("EMAIL" )); | 
| 430 |         valarmProperties << property; | 
| 431 |         property.setName(QStringLiteral("DURATION" )); | 
| 432 |         property.setValue(QStringLiteral("PT5S" )); | 
| 433 |         valarmProperties << property; | 
| 434 |         property.setName(QStringLiteral("REPEAT" )); | 
| 435 |         property.setValue(3); | 
| 436 |         valarmProperties << property; | 
| 437 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 438 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("START" )); | 
| 439 |         property.setParameters(parameters); | 
| 440 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 441 |         valarmProperties << property; | 
| 442 |         property.clear(); | 
| 443 |         property.setName(QStringLiteral("DESCRIPTION" )); | 
| 444 |         property.setValue(QStringLiteral("" )); | 
| 445 |         valarmProperties << property; | 
| 446 |         property.setName(QStringLiteral("SUMMARY" )); | 
| 447 |         property.setValue(QStringLiteral("" )); | 
| 448 |         valarmProperties << property; | 
| 449 |         property.setName(QStringLiteral("ATTENDEE" )); | 
| 450 |         property.setValue(QStringLiteral("First email recipient" )); | 
| 451 |         valarmProperties << property; | 
| 452 |         property.setValue(QStringLiteral("Second email recipient" )); | 
| 453 |         valarmProperties << property; | 
| 454 |  | 
| 455 |         valarmDocument.setComponentType("VALARM" ); | 
| 456 |         valarmDocument.setProperties(valarmProperties); | 
| 457 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 458 |         property.setName(QStringLiteral("VALARM" )); | 
| 459 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 460 |         QOrganizerItemEmailReminder emailReminder; | 
| 461 |         QVariantList attachments; | 
| 462 |         emailReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 463 |         emailReminder.setSecondsBeforeStart(90); | 
| 464 |         emailReminder.setRecipients((QStringList() << QStringLiteral("First email recipient" ) | 
| 465 |                                     << QStringLiteral("Second email recipient" ))); | 
| 466 |         emailReminder.setValue(field: QOrganizerItemEmailReminder::FieldAttachments, value: attachments); | 
| 467 |         QTest::newRow(dataTag: "email reminder: no subject, no body" ) << (QList<QOrganizerItemDetail>() << emailReminder) | 
| 468 |             << (QList<QVersitProperty>() << property); | 
| 469 |     } | 
| 470 |  | 
| 471 |     { | 
| 472 |         QList<QOrganizerItemDetail> detailsToExport; | 
| 473 |         QList<QVersitProperty> expectedProperties; | 
| 474 |         { | 
| 475 |             QVersitProperty property; | 
| 476 |             QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 477 |             QList<QVersitProperty> valarmProperties; | 
| 478 |             QMultiHash<QString, QString> parameters; | 
| 479 |             property.setName(QStringLiteral("ACTION" )); | 
| 480 |             property.setValue(QStringLiteral("AUDIO" )); | 
| 481 |             valarmProperties << property; | 
| 482 |             property.setName(QStringLiteral("ATTACH" )); | 
| 483 |             property.setValue(QUrl(QStringLiteral("http://qt.nokia.com" ))); | 
| 484 |             valarmProperties << property; | 
| 485 |             property.setName(QStringLiteral("DURATION" )); | 
| 486 |             property.setValue(QStringLiteral("PT5S" )); | 
| 487 |             valarmProperties << property; | 
| 488 |             property.setName(QStringLiteral("REPEAT" )); | 
| 489 |             property.setValue(3); | 
| 490 |             valarmProperties << property; | 
| 491 |             property.setName(QStringLiteral("TRIGGER" )); | 
| 492 |             parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("START" )); | 
| 493 |             property.setParameters(parameters); | 
| 494 |             property.setValue(QStringLiteral("-PT90S" )); | 
| 495 |             valarmProperties << property; | 
| 496 |             property.clear(); | 
| 497 |             valarmDocument.setComponentType("VALARM" ); | 
| 498 |             valarmDocument.setProperties(valarmProperties); | 
| 499 |             property.setValueType(QVersitProperty::VersitDocumentType); | 
| 500 |             property.setName(QStringLiteral("VALARM" )); | 
| 501 |             property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 502 |             QOrganizerItemAudibleReminder audibleReminder; | 
| 503 |             audibleReminder.setDataUrl(QUrl("http://qt.nokia.com" )); | 
| 504 |             audibleReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 505 |             audibleReminder.setSecondsBeforeStart(90); | 
| 506 |             detailsToExport << audibleReminder; | 
| 507 |             expectedProperties << property; | 
| 508 |         } | 
| 509 |  | 
| 510 |         { | 
| 511 |             QVersitProperty property; | 
| 512 |             QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 513 |             QList<QVersitProperty> valarmProperties; | 
| 514 |             QMultiHash<QString, QString> parameters; | 
| 515 |  | 
| 516 |             property.setName(QStringLiteral("ACTION" )); | 
| 517 |             property.setValue(QStringLiteral("DISPLAY" )); | 
| 518 |             valarmProperties << property; | 
| 519 |             property.setName(QStringLiteral("x-QTPROJECT-ATTACH" )); | 
| 520 |             property.setValue(QUrl(QStringLiteral("http://qt.nokia.com" ))); | 
| 521 |             valarmProperties << property; | 
| 522 |             property.setName(QStringLiteral("DURATION" )); | 
| 523 |             property.setValue(QStringLiteral("PT5S" )); | 
| 524 |             valarmProperties << property; | 
| 525 |             property.setName(QStringLiteral("REPEAT" )); | 
| 526 |             property.setValue(3); | 
| 527 |             valarmProperties << property; | 
| 528 |             property.setName(QStringLiteral("TRIGGER" )); | 
| 529 |             parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("START" )); | 
| 530 |             property.setParameters(parameters); | 
| 531 |             property.setValue(QStringLiteral("-PT90S" )); | 
| 532 |             valarmProperties << property; | 
| 533 |             property.clear(); | 
| 534 |             property.setName(QStringLiteral("DESCRIPTION" )); | 
| 535 |             property.setValue(QStringLiteral("" )); | 
| 536 |             valarmProperties << property; | 
| 537 |  | 
| 538 |             valarmDocument.setComponentType("VALARM" ); | 
| 539 |             valarmDocument.setProperties(valarmProperties); | 
| 540 |             property.setValueType(QVersitProperty::VersitDocumentType); | 
| 541 |             property.setName(QStringLiteral("VALARM" )); | 
| 542 |             property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 543 |             QOrganizerItemVisualReminder visualReminder; | 
| 544 |             visualReminder.setDataUrl(QUrl("http://qt.nokia.com" )); | 
| 545 |             visualReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 546 |             visualReminder.setSecondsBeforeStart(90); | 
| 547 |             detailsToExport << visualReminder; | 
| 548 |             expectedProperties << property; | 
| 549 |         } | 
| 550 |         { | 
| 551 |             QVersitProperty property; | 
| 552 |             QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 553 |             QList<QVersitProperty> valarmProperties; | 
| 554 |             QMultiHash<QString, QString> parameters; | 
| 555 |  | 
| 556 |             property.setName(QStringLiteral("ACTION" )); | 
| 557 |             property.setValue(QStringLiteral("EMAIL" )); | 
| 558 |             valarmProperties << property; | 
| 559 |             property.setName(QStringLiteral("DURATION" )); | 
| 560 |             property.setValue(QStringLiteral("PT5S" )); | 
| 561 |             valarmProperties << property; | 
| 562 |             property.setName(QStringLiteral("REPEAT" )); | 
| 563 |             property.setValue(3); | 
| 564 |             valarmProperties << property; | 
| 565 |             property.setName(QStringLiteral("TRIGGER" )); | 
| 566 |             parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("START" )); | 
| 567 |             property.setParameters(parameters); | 
| 568 |             property.setValue(QStringLiteral("-PT90S" )); | 
| 569 |             valarmProperties << property; | 
| 570 |             property.clear(); | 
| 571 |             property.setName(QStringLiteral("DESCRIPTION" )); | 
| 572 |             property.setValue(QStringLiteral("" )); | 
| 573 |             valarmProperties << property; | 
| 574 |             property.setName(QStringLiteral("SUMMARY" )); | 
| 575 |             property.setValue(QStringLiteral("" )); | 
| 576 |             valarmProperties << property; | 
| 577 |             property.setName(QStringLiteral("ATTENDEE" )); | 
| 578 |             property.setValue(QStringLiteral("First email recipient" )); | 
| 579 |             valarmProperties << property; | 
| 580 |             property.setValue(QStringLiteral("Second email recipient" )); | 
| 581 |             valarmProperties << property; | 
| 582 |  | 
| 583 |             valarmDocument.setComponentType("VALARM" ); | 
| 584 |             valarmDocument.setProperties(valarmProperties); | 
| 585 |             property.setValueType(QVersitProperty::VersitDocumentType); | 
| 586 |             property.setName(QStringLiteral("VALARM" )); | 
| 587 |             property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 588 |             QOrganizerItemEmailReminder emailReminder; | 
| 589 |             QVariantList attachments; | 
| 590 |             emailReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 591 |             emailReminder.setSecondsBeforeStart(90); | 
| 592 |             emailReminder.setRecipients((QStringList() << QStringLiteral("First email recipient" ) | 
| 593 |                                         << QStringLiteral("Second email recipient" ))); | 
| 594 |             emailReminder.setValue(field: QOrganizerItemEmailReminder::FieldAttachments, value: attachments); | 
| 595 |             detailsToExport << emailReminder; | 
| 596 |             expectedProperties << property; | 
| 597 |         } | 
| 598 |         QTest::newRow(dataTag: "multiple reminders" ) << detailsToExport << expectedProperties; | 
| 599 |     } | 
| 600 |     { | 
| 601 |         QVersitProperty property; | 
| 602 |         property.setName(QStringLiteral("DESCRIPTION" )); | 
| 603 |         property.setValue(QStringLiteral("Twinkle, twinkle, little bat! How I wonder what you're at." )); | 
| 604 |         QOrganizerItemDescription description; | 
| 605 |         description.setDescription(QStringLiteral("Twinkle, twinkle, little bat! How I wonder what you're at." )); | 
| 606 |         QTest::newRow(dataTag: "one description" ) << (QList<QOrganizerItemDetail>() << description) | 
| 607 |             << (QList<QVersitProperty>() << property); | 
| 608 |     } | 
| 609 |  | 
| 610 |     { | 
| 611 |         QVersitProperty property = createExtendedDetailPropertyForStringData(name: "name" , data: "data" ); | 
| 612 |         QOrganizerItemExtendedDetail extendedDetail = createExtendedDetail(name: "name" , QStringLiteral("data" )); | 
| 613 |         QTest::newRow(dataTag: "extended detail" ) << (QList<QOrganizerItemDetail>() << extendedDetail) | 
| 614 |                                          << (QList<QVersitProperty>() << property); | 
| 615 |     } | 
| 616 |  | 
| 617 |     { | 
| 618 |         QVersitProperty property; // Proper version. | 
| 619 |         property.setName(QStringLiteral("X-QTPROJECT-VERSION" )); | 
| 620 |         property.setValueType(QVersitProperty::CompoundType); | 
| 621 |         property.setValue(QStringList() << QStringLiteral("4711" ) << QStringLiteral("134f23dbb2" )); | 
| 622 |         QOrganizerItemVersion version; | 
| 623 |         version.setVersion(4711); | 
| 624 |         version.setExtendedVersion(QByteArray("134f23dbb2" )); | 
| 625 |         QTest::newRow(dataTag: "version" ) << (QList<QOrganizerItemDetail>() << version) | 
| 626 |             << (QList<QVersitProperty>() << property); | 
| 627 |     } | 
| 628 |  | 
| 629 |     { | 
| 630 |         QVersitProperty property; // Extended version empty. | 
| 631 |         property.setName(QStringLiteral("X-QTPROJECT-VERSION" )); | 
| 632 |         property.setValueType(QVersitProperty::CompoundType); | 
| 633 |         property.setValue(QStringList() << QStringLiteral("4711" ) << QStringLiteral("" )); | 
| 634 |         QOrganizerItemVersion version; | 
| 635 |         version.setVersion(4711); | 
| 636 |         version.setExtendedVersion(QByteArray("" )); | 
| 637 |         QTest::newRow(dataTag: "version" ) << (QList<QOrganizerItemDetail>() << version) | 
| 638 |                                  << (QList<QVersitProperty>() << property); | 
| 639 |     } | 
| 640 |  | 
| 641 |     { | 
| 642 |         QVersitProperty property; // No extended version. | 
| 643 |         property.setName(QStringLiteral("X-QTPROJECT-VERSION" )); | 
| 644 |         property.setValueType(QVersitProperty::CompoundType); | 
| 645 |         property.setValue(QStringList() << QStringLiteral("4711" ) << QStringLiteral("" )); | 
| 646 |         QOrganizerItemVersion version; | 
| 647 |         version.setVersion(4711); | 
| 648 |         QTest::newRow(dataTag: "version" ) << (QList<QOrganizerItemDetail>() << version) | 
| 649 |                                  << (QList<QVersitProperty>() << property); | 
| 650 |     } | 
| 651 |  | 
| 652 |     { | 
| 653 |         QVersitProperty property; // Empty version detail. | 
| 654 |         QOrganizerItemVersion version; | 
| 655 |         property.setName(QStringLiteral("X-QTPROJECT-VERSION" )); | 
| 656 |         property.setValueType(QVersitProperty::CompoundType); | 
| 657 |         property.setValue(QStringList() << QStringLiteral("0" ) << QStringLiteral("" )); | 
| 658 |         QTest::newRow(dataTag: "version" ) << (QList<QOrganizerItemDetail>() << version) | 
| 659 |                                  << (QList<QVersitProperty>()); | 
| 660 |     } | 
| 661 |  | 
| 662 |     { | 
| 663 |         QVersitProperty property1; | 
| 664 |         property1.setName(QStringLiteral("COMMENT" )); | 
| 665 |         property1.setValue(QStringLiteral("Comment 1" )); | 
| 666 |         QVersitProperty property2; | 
| 667 |         property2.setName(QStringLiteral("COMMENT" )); | 
| 668 |         property2.setValue(QStringLiteral("Comment 2" )); | 
| 669 |         QOrganizerItemComment ; | 
| 670 |         comment1.setComment(QStringLiteral("Comment 1" )); | 
| 671 |         QOrganizerItemComment ; | 
| 672 |         comment2.setComment(QStringLiteral("Comment 2" )); | 
| 673 |         QTest::newRow(dataTag: "two comments" ) | 
| 674 |             << (QList<QOrganizerItemDetail>() << comment1 << comment2) | 
| 675 |             << (QList<QVersitProperty>() << property1 << property2); | 
| 676 |     } | 
| 677 |  | 
| 678 |     { | 
| 679 |         QVersitProperty property; | 
| 680 |         property.setName(QStringLiteral("UID" )); | 
| 681 |         property.setValue(QStringLiteral("1234567" )); | 
| 682 |         QOrganizerItemGuid guid; | 
| 683 |         guid.setGuid(QStringLiteral("1234567" )); | 
| 684 |         QTest::newRow(dataTag: "guid" ) << (QList<QOrganizerItemDetail>() << guid) | 
| 685 |             << (QList<QVersitProperty>() << property); | 
| 686 |     } | 
| 687 |  | 
| 688 |     { | 
| 689 |         QList<QVersitProperty> properties; | 
| 690 |         QVersitProperty dtstart; | 
| 691 |         dtstart.setName(QStringLiteral("DTSTART" )); | 
| 692 |         dtstart.setValue(QStringLiteral("20100102T030405" )); | 
| 693 |         properties << dtstart; | 
| 694 |         QVersitProperty dtend; | 
| 695 |         dtend.setName(QStringLiteral("DTEND" )); | 
| 696 |         dtend.setValue(QStringLiteral("20100102T030406" )); | 
| 697 |         properties << dtend; | 
| 698 |         QOrganizerEventTime etr; | 
| 699 |         etr.setStartDateTime(QDateTime(QDate(2010, 1, 2), QTime(3, 4, 5))); | 
| 700 |         etr.setEndDateTime(QDateTime(QDate(2010, 1, 2), QTime(3, 4, 6))); | 
| 701 |         QTest::newRow(dataTag: "dtstart and dtend" ) << (QList<QOrganizerItemDetail>() << etr) | 
| 702 |             << properties; | 
| 703 |     } | 
| 704 |  | 
| 705 |     { | 
| 706 |         QList<QVersitProperty> properties; | 
| 707 |         QVersitProperty dtstart; | 
| 708 |         dtstart.setName(QStringLiteral("DTSTART" )); | 
| 709 |         dtstart.setValue(QStringLiteral("20100102" )); | 
| 710 |         dtstart.insertParameter(QStringLiteral("VALUE" ), QStringLiteral("DATE" )); | 
| 711 |         properties << dtstart; | 
| 712 |         QVersitProperty dtend; | 
| 713 |         dtend.setName(QStringLiteral("DTEND" )); | 
| 714 |         // Note: in iCalendar, the end date is exclusive while in Qt Organizer, it is inclusive. | 
| 715 |         // Hence, this is an event that occurs all day on 2 January (not including 3 January) | 
| 716 |         dtend.setValue(QStringLiteral("20100103" )); | 
| 717 |         dtend.insertParameter(QStringLiteral("VALUE" ), QStringLiteral("DATE" )); | 
| 718 |         properties << dtend; | 
| 719 |         QOrganizerEventTime etr; | 
| 720 |         etr.setStartDateTime(QDateTime(QDate(2010, 1, 2), QTime(3, 4, 5))); | 
| 721 |         etr.setEndDateTime(QDateTime(QDate(2010, 1, 2), QTime(3, 4, 6))); | 
| 722 |         etr.setAllDay(true); | 
| 723 |         QTest::newRow(dataTag: "all day event" ) << (QList<QOrganizerItemDetail>() << etr) | 
| 724 |             << properties; | 
| 725 |     } | 
| 726 |  | 
| 727 |     { | 
| 728 |         QList<QVersitProperty> properties; | 
| 729 |         QVersitProperty created; | 
| 730 |         created.setName(QStringLiteral("CREATED" )); | 
| 731 |         created.setValue(QDateTime(QDate(2010, 1, 2), QTime(3, 4, 5)).toUTC().toString( | 
| 732 |                     QStringLiteral("yyyyMMddTHHmmssZ" ))); | 
| 733 |         properties << created; | 
| 734 |         QVersitProperty modified; | 
| 735 |         modified.setName(QStringLiteral("LAST-MODIFIED" )); | 
| 736 |         modified.setValue(QDateTime(QDate(2010, 1, 2), QTime(3, 4, 6)).toUTC().toString( | 
| 737 |                     QStringLiteral("yyyyMMddTHHmmssZ" ))); | 
| 738 |         properties << modified; | 
| 739 |         QOrganizerItemTimestamp timestamp; | 
| 740 |         timestamp.setCreated(QDateTime(QDate(2010, 1, 2), QTime(3, 4, 5))); | 
| 741 |         timestamp.setLastModified(QDateTime(QDate(2010, 1, 2), QTime(3, 4, 6))); | 
| 742 |         QTest::newRow(dataTag: "created and last modified" ) | 
| 743 |             << (QList<QOrganizerItemDetail>() << timestamp) | 
| 744 |             << properties; | 
| 745 |     } | 
| 746 |  | 
| 747 |     { | 
| 748 |         QVersitProperty rrule; | 
| 749 |         rrule.setValueType(QVersitProperty::PreformattedType); | 
| 750 |         rrule.setName(QStringLiteral("RRULE" )); | 
| 751 |         rrule.setValue(QStringLiteral("FREQ=DAILY" )); | 
| 752 |         QOrganizerItemRecurrence recurrence; | 
| 753 |         QOrganizerRecurrenceRule recurrenceRule; | 
| 754 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 755 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 756 |         QTest::newRow(dataTag: "rrule daily" ) | 
| 757 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 758 |             << (QList<QVersitProperty>() << rrule); | 
| 759 |  | 
| 760 |         rrule.setValue(QStringLiteral("FREQ=WEEKLY" )); | 
| 761 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 762 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 763 |         QTest::newRow(dataTag: "rrule weekly" ) | 
| 764 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 765 |             << (QList<QVersitProperty>() << rrule); | 
| 766 |  | 
| 767 |         rrule.setValue(QStringLiteral("FREQ=MONTHLY" )); | 
| 768 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Monthly); | 
| 769 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 770 |         QTest::newRow(dataTag: "rrule monthly" ) | 
| 771 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 772 |             << (QList<QVersitProperty>() << rrule); | 
| 773 |  | 
| 774 |         rrule.setValue(QStringLiteral("FREQ=YEARLY" )); | 
| 775 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 776 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 777 |         QTest::newRow(dataTag: "rrule yearly" ) | 
| 778 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 779 |             << (QList<QVersitProperty>() << rrule); | 
| 780 |  | 
| 781 |         rrule.setValue(QStringLiteral("FREQ=MONTHLY;INTERVAL=2;BYDAY=TU" )); | 
| 782 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Monthly); | 
| 783 |         recurrenceRule.setInterval(2); | 
| 784 |         recurrenceRule.setDaysOfWeek(QSet<Qt::DayOfWeek>() << Qt::Tuesday); | 
| 785 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 786 |         QTest::newRow(dataTag: "rrule monthly" ) | 
| 787 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 788 |             << (QList<QVersitProperty>() << rrule); | 
| 789 |     } | 
| 790 |  | 
| 791 |     { | 
| 792 |         QVersitProperty rrule; | 
| 793 |         rrule.setValueType(QVersitProperty::PreformattedType); | 
| 794 |         rrule.setName(QStringLiteral("RRULE" )); | 
| 795 |         rrule.setValue(QStringLiteral("FREQ=MONTHLY;BYMONTHDAY=-3,1" )); | 
| 796 |         QOrganizerItemRecurrence recurrence; | 
| 797 |         QOrganizerRecurrenceRule recurrenceRule; | 
| 798 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Monthly); | 
| 799 |         recurrenceRule.setDaysOfMonth(QSet<int>() << 1 << -3); | 
| 800 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 801 |         QTest::newRow(dataTag: "rrule bymonthday" ) | 
| 802 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 803 |             << (QList<QVersitProperty>() << rrule); | 
| 804 |     } | 
| 805 |  | 
| 806 |     { | 
| 807 |         QVersitProperty rrule; | 
| 808 |         rrule.setValueType(QVersitProperty::PreformattedType); | 
| 809 |         rrule.setName(QStringLiteral("RRULE" )); | 
| 810 |         rrule.setValue(QStringLiteral("FREQ=YEARLY;BYWEEKNO=-3,1" )); | 
| 811 |         QOrganizerItemRecurrence recurrence; | 
| 812 |         QOrganizerRecurrenceRule recurrenceRule; | 
| 813 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 814 |         recurrenceRule.setWeeksOfYear(QSet<int>() << 1 << -3); | 
| 815 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 816 |         QTest::newRow(dataTag: "rrule byweekno" ) | 
| 817 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 818 |             << (QList<QVersitProperty>() << rrule); | 
| 819 |     } | 
| 820 |  | 
| 821 |     { | 
| 822 |         QVersitProperty rrule; | 
| 823 |         rrule.setValueType(QVersitProperty::PreformattedType); | 
| 824 |         rrule.setName(QStringLiteral("RRULE" )); | 
| 825 |         rrule.setValue(QStringLiteral("FREQ=YEARLY;BYMONTH=1,10" )); | 
| 826 |         QOrganizerItemRecurrence recurrence; | 
| 827 |         QOrganizerRecurrenceRule recurrenceRule; | 
| 828 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 829 |         recurrenceRule.setMonthsOfYear(QSet<QOrganizerRecurrenceRule::Month>() | 
| 830 |                 << QOrganizerRecurrenceRule::January | 
| 831 |                 << QOrganizerRecurrenceRule::October); | 
| 832 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 833 |         QTest::newRow(dataTag: "rrule bymonth" ) | 
| 834 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 835 |             << (QList<QVersitProperty>() << rrule); | 
| 836 |     } | 
| 837 |  | 
| 838 |     { | 
| 839 |         QVersitProperty rrule; | 
| 840 |         rrule.setValueType(QVersitProperty::PreformattedType); | 
| 841 |         rrule.setName(QStringLiteral("RRULE" )); | 
| 842 |         rrule.setValue(QStringLiteral("FREQ=YEARLY;BYYEARDAY=-1,1,366" )); | 
| 843 |         QOrganizerItemRecurrence recurrence; | 
| 844 |         QOrganizerRecurrenceRule recurrenceRule; | 
| 845 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 846 |         recurrenceRule.setDaysOfYear(QSet<int>() << 1 << 366 << -1); | 
| 847 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 848 |         QTest::newRow(dataTag: "rrule byyearday" ) | 
| 849 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 850 |             << (QList<QVersitProperty>() << rrule); | 
| 851 |     } | 
| 852 |  | 
| 853 |     { | 
| 854 |         QVersitProperty rrule; | 
| 855 |         rrule.setValueType(QVersitProperty::PreformattedType); | 
| 856 |         rrule.setName(QStringLiteral("RRULE" )); | 
| 857 |         rrule.setValue(QStringLiteral("FREQ=WEEKLY;COUNT=4;INTERVAL=2;BYDAY=TU,SU;WKST=SU" )); | 
| 858 |         QOrganizerItemRecurrence recurrence; | 
| 859 |         QOrganizerRecurrenceRule recurrenceRule; | 
| 860 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 861 |         recurrenceRule.setInterval(2); | 
| 862 |         recurrenceRule.setLimit(4); | 
| 863 |         recurrenceRule.setDaysOfWeek(QSet<Qt::DayOfWeek>() << Qt::Tuesday << Qt::Sunday); | 
| 864 |         recurrenceRule.setFirstDayOfWeek(Qt::Sunday); | 
| 865 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 866 |         QTest::newRow(dataTag: "rrule wkst" ) | 
| 867 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 868 |             << (QList<QVersitProperty>() << rrule); | 
| 869 |     } | 
| 870 |  | 
| 871 |     { | 
| 872 |         QVersitProperty rrule; | 
| 873 |         rrule.setValueType(QVersitProperty::PreformattedType); | 
| 874 |         rrule.setName(QStringLiteral("RRULE" )); | 
| 875 |         rrule.setValue(QStringLiteral("FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1" )); | 
| 876 |         QOrganizerItemRecurrence recurrence; | 
| 877 |         QOrganizerRecurrenceRule recurrenceRule; | 
| 878 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Monthly); | 
| 879 |         recurrenceRule.setDaysOfWeek(QSet<Qt::DayOfWeek>() | 
| 880 |                 << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday); | 
| 881 |         recurrenceRule.setPositions(QSet<int>() << -1); | 
| 882 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 883 |         QTest::newRow(dataTag: "rrule bysetpos" ) | 
| 884 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 885 |             << (QList<QVersitProperty>() << rrule); | 
| 886 |     } | 
| 887 |  | 
| 888 |     { | 
| 889 |         QVersitProperty rrule; | 
| 890 |         rrule.setValueType(QVersitProperty::PreformattedType); | 
| 891 |         rrule.setName(QStringLiteral("RRULE" )); | 
| 892 |         rrule.setValue(QStringLiteral("FREQ=DAILY;UNTIL=20000131;BYMONTH=1" )); | 
| 893 |         QOrganizerItemRecurrence recurrence; | 
| 894 |         QOrganizerRecurrenceRule recurrenceRule; | 
| 895 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 896 |         recurrenceRule.setLimit(QDate(2000, 1, 31)); | 
| 897 |         recurrenceRule.setMonthsOfYear(QSet<QOrganizerRecurrenceRule::Month>() | 
| 898 |                 << QOrganizerRecurrenceRule::January); | 
| 899 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 900 |         QTest::newRow(dataTag: "rrule until" ) | 
| 901 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 902 |             << (QList<QVersitProperty>() << rrule); | 
| 903 |     } | 
| 904 |  | 
| 905 |     { | 
| 906 |         QVersitProperty rrule; | 
| 907 |         rrule.setValueType(QVersitProperty::PreformattedType); | 
| 908 |         rrule.setName(QStringLiteral("RRULE" )); | 
| 909 |         rrule.setValue(QStringLiteral("FREQ=DAILY;COUNT=5;BYMONTH=1" )); | 
| 910 |         QOrganizerItemRecurrence recurrence; | 
| 911 |         QOrganizerRecurrenceRule recurrenceRule; | 
| 912 |         recurrenceRule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 913 |         recurrenceRule.setLimit(5); | 
| 914 |         recurrenceRule.setMonthsOfYear(QSet<QOrganizerRecurrenceRule::Month>() | 
| 915 |                 << QOrganizerRecurrenceRule::January); | 
| 916 |         recurrence.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>() << recurrenceRule); | 
| 917 |         QTest::newRow(dataTag: "rrule count" ) | 
| 918 |             << (QList<QOrganizerItemDetail>() << recurrence) | 
| 919 |             << (QList<QVersitProperty>() << rrule); | 
| 920 |     } | 
| 921 |  | 
| 922 |     { | 
| 923 |         QVersitProperty rdate; | 
| 924 |         rdate.insertParameter(QStringLiteral("VALUE" ), QStringLiteral("DATE" )); | 
| 925 |         rdate.setName(QStringLiteral("RDATE" )); | 
| 926 |         rdate.setValue(QStringLiteral("19970304" )); | 
| 927 |         QOrganizerEventTime etr; | 
| 928 |         etr.setStartDateTime(QDateTime(QDate(1997, 3, 4), QTime(11, 0, 0))); | 
| 929 |         etr.setEndDateTime(QDateTime(QDate(1997, 3, 4), QTime(11, 0, 0))); | 
| 930 |         QOrganizerItemRecurrence recurrence; | 
| 931 |         QSet<QDate> recurrenceDates; | 
| 932 |         recurrenceDates << QDate(1997, 3, 4); | 
| 933 |         recurrence.setRecurrenceDates(recurrenceDates); | 
| 934 |         QTest::newRow(dataTag: "rdate" ) | 
| 935 |             << (QList<QOrganizerItemDetail>() << etr << recurrence) | 
| 936 |             << (QList<QVersitProperty>() << rdate); | 
| 937 |  | 
| 938 |         rdate.setValue(QStringLiteral("19970304,19970504,19970704" )); | 
| 939 |         recurrenceDates.clear(); | 
| 940 |         recurrenceDates << QDate(1997, 3, 4) | 
| 941 |                         << QDate(1997, 5, 4) | 
| 942 |                         << QDate(1997, 7, 4); | 
| 943 |         recurrence.setRecurrenceDates(recurrenceDates); | 
| 944 |         QTest::newRow(dataTag: "multiple rdate" ) | 
| 945 |             << (QList<QOrganizerItemDetail>() << etr << recurrence) | 
| 946 |             << (QList<QVersitProperty>() << rdate); | 
| 947 |     } | 
| 948 |  | 
| 949 |     { | 
| 950 |         QVersitProperty rdate; | 
| 951 |         rdate.insertParameter(QStringLiteral("VALUE" ), QStringLiteral("DATE" )); | 
| 952 |         rdate.setName(QStringLiteral("EXDATE" )); | 
| 953 |         rdate.setValue(QStringLiteral("19970304" )); | 
| 954 |         QOrganizerEventTime etr; | 
| 955 |         etr.setStartDateTime(QDateTime(QDate(1997, 3, 4), QTime(11, 0, 0))); | 
| 956 |         etr.setEndDateTime(QDateTime(QDate(1997, 3, 4), QTime(11, 0, 0))); | 
| 957 |         QOrganizerItemRecurrence recurrence; | 
| 958 |         QSet<QDate> exceptionDates; | 
| 959 |         exceptionDates << QDate(1997, 3, 4); | 
| 960 |         recurrence.setExceptionDates(exceptionDates); | 
| 961 |         QTest::newRow(dataTag: "exdate" ) | 
| 962 |             << (QList<QOrganizerItemDetail>() << etr << recurrence) | 
| 963 |             << (QList<QVersitProperty>() << rdate); | 
| 964 |     } | 
| 965 |  | 
| 966 |     { | 
| 967 |         QVersitProperty property; | 
| 968 |         property.setName(QStringLiteral("CATEGORIES" )); | 
| 969 |         property.setValue(QStringLiteral("Important Event" )); | 
| 970 |         QOrganizerItemTag tag; | 
| 971 |         tag.setTag(QStringLiteral("Important Event" )); | 
| 972 |         QTest::newRow(dataTag: "tag 1" ) | 
| 973 |                 << (QList<QOrganizerItemDetail>() << tag) | 
| 974 |                 << (QList<QVersitProperty>() << property); | 
| 975 |  | 
| 976 |         // Set another one for multiple handling test | 
| 977 |         property.setValue(QStringLiteral("Important Event 2" )); | 
| 978 |         tag.setTag(QStringLiteral("Important Event 2" )); | 
| 979 |         QTest::newRow(dataTag: "tag 2" ) | 
| 980 |                 << (QList<QOrganizerItemDetail>() << tag) | 
| 981 |                 << (QList<QVersitProperty>() << property); | 
| 982 |  | 
| 983 |         // Empty tag | 
| 984 |         property.clear(); | 
| 985 |         property.setName("CATEGORIES" ); | 
| 986 |         tag.removeValue(field: QOrganizerItemTag::FieldTag); | 
| 987 |         QTest::newRow(dataTag: "empty tag" ) | 
| 988 |                 << (QList<QOrganizerItemDetail>() << tag) | 
| 989 |                 << (QList<QVersitProperty>() << property); | 
| 990 |     } | 
| 991 |  | 
| 992 |     { | 
| 993 |         QVersitProperty property; | 
| 994 |         property.setName(QStringLiteral("PRIORITY" )); | 
| 995 |         property.setValue(QStringLiteral("0" )); | 
| 996 |  | 
| 997 |         QOrganizerItemPriority detail; | 
| 998 |         detail.setPriority(QOrganizerItemPriority::UnknownPriority); | 
| 999 |         QTest::newRow(dataTag: "priority 0" ) | 
| 1000 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1001 |             << (QList<QVersitProperty>() << property); | 
| 1002 |  | 
| 1003 |         property.setValue(QStringLiteral("1" )); | 
| 1004 |         detail.setPriority(QOrganizerItemPriority::HighestPriority); | 
| 1005 |         QTest::newRow(dataTag: "priority 1" ) | 
| 1006 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1007 |             << (QList<QVersitProperty>() << property); | 
| 1008 |  | 
| 1009 |         property.setValue(QStringLiteral("2" )); | 
| 1010 |         detail.setPriority(QOrganizerItemPriority::ExtremelyHighPriority); | 
| 1011 |         QTest::newRow(dataTag: "priority 2" ) | 
| 1012 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1013 |             << (QList<QVersitProperty>() << property); | 
| 1014 |  | 
| 1015 |         property.setValue(QStringLiteral("3" )); | 
| 1016 |         detail.setPriority(QOrganizerItemPriority::VeryHighPriority); | 
| 1017 |         QTest::newRow(dataTag: "priority 3" ) | 
| 1018 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1019 |             << (QList<QVersitProperty>() << property); | 
| 1020 |  | 
| 1021 |         property.setValue(QStringLiteral("4" )); | 
| 1022 |         detail.setPriority(QOrganizerItemPriority::HighPriority); | 
| 1023 |         QTest::newRow(dataTag: "priority 4" ) | 
| 1024 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1025 |             << (QList<QVersitProperty>() << property); | 
| 1026 |  | 
| 1027 |         property.setValue(QStringLiteral("5" )); | 
| 1028 |         detail.setPriority(QOrganizerItemPriority::MediumPriority); | 
| 1029 |         QTest::newRow(dataTag: "priority 5" ) | 
| 1030 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1031 |             << (QList<QVersitProperty>() << property); | 
| 1032 |  | 
| 1033 |         property.setValue(QStringLiteral("6" )); | 
| 1034 |         detail.setPriority(QOrganizerItemPriority::LowPriority); | 
| 1035 |         QTest::newRow(dataTag: "priority 6" ) | 
| 1036 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1037 |             << (QList<QVersitProperty>() << property); | 
| 1038 |  | 
| 1039 |         property.setValue(QStringLiteral("7" )); | 
| 1040 |         detail.setPriority(QOrganizerItemPriority::VeryLowPriority); | 
| 1041 |         QTest::newRow(dataTag: "priority 7" ) | 
| 1042 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1043 |             << (QList<QVersitProperty>() << property); | 
| 1044 |  | 
| 1045 |         property.setValue(QStringLiteral("8" )); | 
| 1046 |         detail.setPriority(QOrganizerItemPriority::ExtremelyLowPriority); | 
| 1047 |         QTest::newRow(dataTag: "priority 8" ) | 
| 1048 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1049 |             << (QList<QVersitProperty>() << property); | 
| 1050 |  | 
| 1051 |         property.setValue(QStringLiteral("9" )); | 
| 1052 |         detail.setPriority(QOrganizerItemPriority::LowestPriority); | 
| 1053 |         QTest::newRow(dataTag: "priority 9" ) | 
| 1054 |             << (QList<QOrganizerItemDetail>() << detail) | 
| 1055 |             << (QList<QVersitProperty>() << property); | 
| 1056 |     } | 
| 1057 | } | 
| 1058 |  | 
| 1059 | void tst_QVersitOrganizerExporter::testExportTodoDetails() | 
| 1060 | { | 
| 1061 |     QFETCH(QList<QOrganizerItemDetail>, details); | 
| 1062 |     QFETCH(QList<QVersitProperty>, expectedProperties); | 
| 1063 |  | 
| 1064 |     QVersitOrganizerExporter exporter; | 
| 1065 |     QOrganizerTodo item; | 
| 1066 |     foreach (QOrganizerItemDetail detail, details) { | 
| 1067 |         item.saveDetail(detail: &detail); | 
| 1068 |     } | 
| 1069 |     QVERIFY(exporter.exportItems(QList<QOrganizerItem>() << item)); | 
| 1070 |     QVERIFY(exporter.errorMap().isEmpty()); | 
| 1071 |     QVersitDocument document = exporter.document(); | 
| 1072 |     QList<QVersitDocument> subDocuments = document.subDocuments(); | 
| 1073 |     QCOMPARE(subDocuments.size(), 1); | 
| 1074 |     foreach(const QVersitProperty& expectedProperty, expectedProperties) { | 
| 1075 |         QList<QVersitProperty> actualProperties = | 
| 1076 |             findPropertiesByName(document: subDocuments.first(), propertyName: expectedProperty.name()); | 
| 1077 |         if (expectedProperty.valueType() == QVersitProperty::VersitDocumentType) { | 
| 1078 |             QCOMPARE(subDocuments.first().subDocuments().size(), 1); | 
| 1079 |             QVersitDocument actualVAlarmDocument = | 
| 1080 |                     subDocuments.first().subDocuments().first(); | 
| 1081 |             QVersitDocument expectedVAlarmDocument = | 
| 1082 |                     expectedProperty.variantValue().value<QVersitDocument>(); | 
| 1083 |             foreach (const QVersitProperty &valarmProp, expectedVAlarmDocument.properties()) { | 
| 1084 |                 if (!actualVAlarmDocument.properties().contains(t: valarmProp)) { | 
| 1085 |                             qDebug() << "Actual:"  << actualVAlarmDocument.properties(); | 
| 1086 |                             qDebug() << "Expected to find:"  << valarmProp; | 
| 1087 |                             QVERIFY(false); | 
| 1088 |                 } | 
| 1089 |             } | 
| 1090 |         } else if (!actualProperties.contains(t: expectedProperty)) { | 
| 1091 |             qDebug() << "Actual:"  << actualProperties; | 
| 1092 |             qDebug() << "Expected to find:"  << expectedProperty; | 
| 1093 |             QVERIFY(false); | 
| 1094 |         } | 
| 1095 |     } | 
| 1096 | } | 
| 1097 |  | 
| 1098 | void tst_QVersitOrganizerExporter::testExportTodoDetails_data() | 
| 1099 | { | 
| 1100 |     QTest::addColumn<QList<QOrganizerItemDetail> >(name: "details" ); | 
| 1101 |     QTest::addColumn<QList<QVersitProperty> >(name: "expectedProperties" ); | 
| 1102 |  | 
| 1103 |     { | 
| 1104 |         QList<QVersitProperty> properties; | 
| 1105 |         QVersitProperty dtstart; | 
| 1106 |         dtstart.setName(QStringLiteral("DTSTART" )); | 
| 1107 |         dtstart.setValue(QStringLiteral("20100102" )); | 
| 1108 |         dtstart.insertParameter(QStringLiteral("VALUE" ), QStringLiteral("DATE" )); | 
| 1109 |         properties << dtstart; | 
| 1110 |         QVersitProperty due; | 
| 1111 |         due.setName(QStringLiteral("DUE" )); | 
| 1112 |         due.setValue(QStringLiteral("20100103" )); | 
| 1113 |         due.insertParameter(QStringLiteral("VALUE" ), QStringLiteral("DATE" )); | 
| 1114 |         properties << due; | 
| 1115 |         QOrganizerTodoTime todoTime; | 
| 1116 |         todoTime.setStartDateTime(QDateTime(QDate(2010, 1, 2), QTime(3, 4, 5))); | 
| 1117 |         todoTime.setDueDateTime(QDateTime(QDate(2010, 1, 3), QTime(3, 4, 6))); | 
| 1118 |         todoTime.setAllDay(true); | 
| 1119 |         QTest::newRow(dataTag: "all day todo" ) << (QList<QOrganizerItemDetail>() << todoTime) | 
| 1120 |             << properties; | 
| 1121 |     } | 
| 1122 |  | 
| 1123 |     { | 
| 1124 |         QVersitProperty property; | 
| 1125 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 1126 |         QList<QVersitProperty> valarmProperties; | 
| 1127 |         QMultiHash<QString, QString> parameters; | 
| 1128 |         property.setName(QStringLiteral("ACTION" )); | 
| 1129 |         property.setValue(QStringLiteral("AUDIO" )); | 
| 1130 |         valarmProperties << property; | 
| 1131 |         property.setName(QStringLiteral("ATTACH" )); | 
| 1132 |         property.setValue(QUrl(QStringLiteral("http://qt.nokia.com" ))); | 
| 1133 |         valarmProperties << property; | 
| 1134 |         property.setName(QStringLiteral("DURATION" )); | 
| 1135 |         property.setValue(QStringLiteral("PT5S" )); | 
| 1136 |         valarmProperties << property; | 
| 1137 |         property.setName(QStringLiteral("REPEAT" )); | 
| 1138 |         property.setValue(3); | 
| 1139 |         valarmProperties << property; | 
| 1140 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 1141 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("END" )); | 
| 1142 |         property.setParameters(parameters); | 
| 1143 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 1144 |         valarmProperties << property; | 
| 1145 |         property.clear(); | 
| 1146 |         valarmDocument.setComponentType("VALARM" ); | 
| 1147 |         valarmDocument.setProperties(valarmProperties); | 
| 1148 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 1149 |         property.setName(QStringLiteral("VALARM" )); | 
| 1150 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 1151 |         QOrganizerItemAudibleReminder audibleReminder; | 
| 1152 |         audibleReminder.setDataUrl(QUrl("http://qt.nokia.com" )); | 
| 1153 |         audibleReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 1154 |         audibleReminder.setSecondsBeforeStart(90); | 
| 1155 |         QTest::newRow(dataTag: "audible reminder" ) << (QList<QOrganizerItemDetail>() << audibleReminder) | 
| 1156 |             << (QList<QVersitProperty>() << property); | 
| 1157 |     } | 
| 1158 |  | 
| 1159 |     { | 
| 1160 |         QVersitProperty property; | 
| 1161 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 1162 |         QList<QVersitProperty> valarmProperties; | 
| 1163 |         QMultiHash<QString, QString> parameters; | 
| 1164 |  | 
| 1165 |         property.setName(QStringLiteral("ACTION" )); | 
| 1166 |         property.setValue(QStringLiteral("DISPLAY" )); | 
| 1167 |         valarmProperties << property; | 
| 1168 |         property.setName(QStringLiteral("x-QTPROJECT-ATTACH" )); | 
| 1169 |         property.setValue(QUrl(QStringLiteral("http://qt.nokia.com" ))); | 
| 1170 |         valarmProperties << property; | 
| 1171 |         property.setName(QStringLiteral("DURATION" )); | 
| 1172 |         property.setValue(QStringLiteral("PT5S" )); | 
| 1173 |         valarmProperties << property; | 
| 1174 |         property.setName(QStringLiteral("REPEAT" )); | 
| 1175 |         property.setValue(3); | 
| 1176 |         valarmProperties << property; | 
| 1177 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 1178 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("END" )); | 
| 1179 |         property.setParameters(parameters); | 
| 1180 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 1181 |         valarmProperties << property; | 
| 1182 |         property.clear(); | 
| 1183 |         property.setName(QStringLiteral("DESCRIPTION" )); | 
| 1184 |         property.setValue(QStringLiteral("Test visual reminder" )); | 
| 1185 |         valarmProperties << property; | 
| 1186 |  | 
| 1187 |         valarmDocument.setComponentType("VALARM" ); | 
| 1188 |         valarmDocument.setProperties(valarmProperties); | 
| 1189 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 1190 |         property.setName(QStringLiteral("VALARM" )); | 
| 1191 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 1192 |         QOrganizerItemVisualReminder visualReminder; | 
| 1193 |         visualReminder.setDataUrl(QUrl("http://qt.nokia.com" )); | 
| 1194 |         visualReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 1195 |         visualReminder.setSecondsBeforeStart(90); | 
| 1196 |         visualReminder.setMessage(QStringLiteral("Test visual reminder" )); | 
| 1197 |         QTest::newRow(dataTag: "visual reminder" ) << (QList<QOrganizerItemDetail>() << visualReminder) | 
| 1198 |             << (QList<QVersitProperty>() << property); | 
| 1199 |     } | 
| 1200 |  | 
| 1201 |     { | 
| 1202 |         QVersitProperty property; | 
| 1203 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 1204 |         QList<QVersitProperty> valarmProperties; | 
| 1205 |         QMultiHash<QString, QString> parameters; | 
| 1206 |  | 
| 1207 |         property.setName(QStringLiteral("ACTION" )); | 
| 1208 |         property.setValue(QStringLiteral("DISPLAY" )); | 
| 1209 |         valarmProperties << property; | 
| 1210 |         property.setName(QStringLiteral("x-QTPROJECT-ATTACH" )); | 
| 1211 |         property.setValue(QUrl(QStringLiteral("http://qt.nokia.com" ))); | 
| 1212 |         valarmProperties << property; | 
| 1213 |         property.setName(QStringLiteral("DURATION" )); | 
| 1214 |         property.setValue(QStringLiteral("PT5S" )); | 
| 1215 |         valarmProperties << property; | 
| 1216 |         property.setName(QStringLiteral("REPEAT" )); | 
| 1217 |         property.setValue(3); | 
| 1218 |         valarmProperties << property; | 
| 1219 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 1220 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("END" )); | 
| 1221 |         property.setParameters(parameters); | 
| 1222 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 1223 |         valarmProperties << property; | 
| 1224 |         property.clear(); | 
| 1225 |         property.setName(QStringLiteral("DESCRIPTION" )); | 
| 1226 |         property.setValue(QStringLiteral("" )); | 
| 1227 |         valarmProperties << property; | 
| 1228 |  | 
| 1229 |         valarmDocument.setComponentType("VALARM" ); | 
| 1230 |         valarmDocument.setProperties(valarmProperties); | 
| 1231 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 1232 |         property.setName(QStringLiteral("VALARM" )); | 
| 1233 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 1234 |         QOrganizerItemVisualReminder visualReminder; | 
| 1235 |         visualReminder.setDataUrl(QUrl("http://qt.nokia.com" )); | 
| 1236 |         visualReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 1237 |         visualReminder.setSecondsBeforeStart(90); | 
| 1238 |         QTest::newRow(dataTag: "visual reminder: no message" ) << (QList<QOrganizerItemDetail>() << visualReminder) | 
| 1239 |             << (QList<QVersitProperty>() << property); | 
| 1240 |     } | 
| 1241 |  | 
| 1242 |     { | 
| 1243 |         QVersitProperty property; | 
| 1244 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 1245 |         QList<QVersitProperty> valarmProperties; | 
| 1246 |         QMultiHash<QString, QString> parameters; | 
| 1247 |  | 
| 1248 |         property.setName(QStringLiteral("ACTION" )); | 
| 1249 |         property.setValue(QStringLiteral("EMAIL" )); | 
| 1250 |         valarmProperties << property; | 
| 1251 |         property.setName(QStringLiteral("DURATION" )); | 
| 1252 |         property.setValue(QStringLiteral("PT5S" )); | 
| 1253 |         valarmProperties << property; | 
| 1254 |         property.setName(QStringLiteral("REPEAT" )); | 
| 1255 |         property.setValue(3); | 
| 1256 |         valarmProperties << property; | 
| 1257 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 1258 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("END" )); | 
| 1259 |         property.setParameters(parameters); | 
| 1260 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 1261 |         valarmProperties << property; | 
| 1262 |         property.clear(); | 
| 1263 |         property.setName(QStringLiteral("DESCRIPTION" )); | 
| 1264 |         property.setValue(QStringLiteral("Test email body" )); | 
| 1265 |         valarmProperties << property; | 
| 1266 |         property.setName(QStringLiteral("SUMMARY" )); | 
| 1267 |         property.setValue(QStringLiteral("Test email subject" )); | 
| 1268 |         valarmProperties << property; | 
| 1269 |         property.setName(QStringLiteral("ATTENDEE" )); | 
| 1270 |         property.setValue(QStringLiteral("First email recipient" )); | 
| 1271 |         valarmProperties << property; | 
| 1272 |         property.setValue(QStringLiteral("Second email recipient" )); | 
| 1273 |         valarmProperties << property; | 
| 1274 |  | 
| 1275 |         valarmDocument.setComponentType("VALARM" ); | 
| 1276 |         valarmDocument.setProperties(valarmProperties); | 
| 1277 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 1278 |         property.setName(QStringLiteral("VALARM" )); | 
| 1279 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 1280 |         QOrganizerItemEmailReminder emailReminder; | 
| 1281 |         QVariantList attachments; | 
| 1282 |         emailReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 1283 |         emailReminder.setSecondsBeforeStart(90); | 
| 1284 |         emailReminder.setRecipients((QStringList() << QStringLiteral("First email recipient" ) | 
| 1285 |                                     << QStringLiteral("Second email recipient" ))); | 
| 1286 |         emailReminder.setContents(QStringLiteral("Test email subject" ), | 
| 1287 |                                   QStringLiteral("Test email body" ), | 
| 1288 |                                   attachments); | 
| 1289 |         QTest::newRow(dataTag: "email reminder" ) << (QList<QOrganizerItemDetail>() << emailReminder) | 
| 1290 |             << (QList<QVersitProperty>() << property); | 
| 1291 |     } | 
| 1292 |  | 
| 1293 |     { | 
| 1294 |         QVersitProperty property; | 
| 1295 |         QVersitDocument valarmDocument(QVersitDocument::ICalendar20Type); | 
| 1296 |         QList<QVersitProperty> valarmProperties; | 
| 1297 |         QMultiHash<QString, QString> parameters; | 
| 1298 |  | 
| 1299 |         property.setName(QStringLiteral("ACTION" )); | 
| 1300 |         property.setValue(QStringLiteral("EMAIL" )); | 
| 1301 |         valarmProperties << property; | 
| 1302 |         property.setName(QStringLiteral("DURATION" )); | 
| 1303 |         property.setValue(QStringLiteral("PT5S" )); | 
| 1304 |         valarmProperties << property; | 
| 1305 |         property.setName(QStringLiteral("REPEAT" )); | 
| 1306 |         property.setValue(3); | 
| 1307 |         valarmProperties << property; | 
| 1308 |         property.setName(QStringLiteral("TRIGGER" )); | 
| 1309 |         parameters.insert(QStringLiteral("RELATED" ), QStringLiteral("END" )); | 
| 1310 |         property.setParameters(parameters); | 
| 1311 |         property.setValue(QStringLiteral("-PT90S" )); | 
| 1312 |         valarmProperties << property; | 
| 1313 |         property.clear(); | 
| 1314 |         property.setName(QStringLiteral("DESCRIPTION" )); | 
| 1315 |         property.setValue(QStringLiteral("" )); | 
| 1316 |         valarmProperties << property; | 
| 1317 |         property.setName(QStringLiteral("SUMMARY" )); | 
| 1318 |         property.setValue(QStringLiteral("" )); | 
| 1319 |         valarmProperties << property; | 
| 1320 |         property.setName(QStringLiteral("ATTENDEE" )); | 
| 1321 |         property.setValue(QStringLiteral("First email recipient" )); | 
| 1322 |         valarmProperties << property; | 
| 1323 |         property.setValue(QStringLiteral("Second email recipient" )); | 
| 1324 |         valarmProperties << property; | 
| 1325 |  | 
| 1326 |         valarmDocument.setComponentType("VALARM" ); | 
| 1327 |         valarmDocument.setProperties(valarmProperties); | 
| 1328 |         property.setValueType(QVersitProperty::VersitDocumentType); | 
| 1329 |         property.setName(QStringLiteral("VALARM" )); | 
| 1330 |         property.setValue(QVariant::fromValue(value: valarmDocument)); | 
| 1331 |         QOrganizerItemEmailReminder emailReminder; | 
| 1332 |         QVariantList attachments; | 
| 1333 |         emailReminder.setRepetition(count: 3, delaySeconds: 5); | 
| 1334 |         emailReminder.setSecondsBeforeStart(90); | 
| 1335 |         emailReminder.setRecipients((QStringList() << QStringLiteral("First email recipient" ) | 
| 1336 |                                     << QStringLiteral("Second email recipient" ))); | 
| 1337 |         emailReminder.setValue(field: QOrganizerItemEmailReminder::FieldAttachments, value: attachments); | 
| 1338 |         QTest::newRow(dataTag: "email reminder: no subject, no body" ) << (QList<QOrganizerItemDetail>() << emailReminder) | 
| 1339 |             << (QList<QVersitProperty>() << property); | 
| 1340 |     } | 
| 1341 |  | 
| 1342 |  | 
| 1343 |     { | 
| 1344 |         QVersitProperty property; | 
| 1345 |         property.setName(QStringLiteral("STATUS" )); | 
| 1346 |         property.setValue(QStringLiteral("COMPLETED" )); | 
| 1347 |         QOrganizerTodoProgress progress; | 
| 1348 |         progress.setStatus(QOrganizerTodoProgress::StatusComplete); | 
| 1349 |         QTest::newRow(dataTag: "status completed" ) | 
| 1350 |             << (QList<QOrganizerItemDetail>() << progress) | 
| 1351 |             << (QList<QVersitProperty>() << property); | 
| 1352 |  | 
| 1353 |         property.setValue(QStringLiteral("NEEDS-ACTION" )); | 
| 1354 |         progress.setStatus(QOrganizerTodoProgress::StatusNotStarted); | 
| 1355 |         QTest::newRow(dataTag: "status needs-action" ) | 
| 1356 |             << (QList<QOrganizerItemDetail>() << progress) | 
| 1357 |             << (QList<QVersitProperty>() << property); | 
| 1358 |  | 
| 1359 |         property.setValue(QStringLiteral("IN-PROCESS" )); | 
| 1360 |         progress.setStatus(QOrganizerTodoProgress::StatusInProgress); | 
| 1361 |         QTest::newRow(dataTag: "status in-process" ) | 
| 1362 |             << (QList<QOrganizerItemDetail>() << progress) | 
| 1363 |             << (QList<QVersitProperty>() << property); | 
| 1364 |     } | 
| 1365 |  | 
| 1366 |     { | 
| 1367 |         QVersitProperty property; | 
| 1368 |         property.setName(QStringLiteral("PERCENT-COMPLETE" )); | 
| 1369 |         property.setValue(QStringLiteral("42" )); | 
| 1370 |         QOrganizerTodoProgress progress; | 
| 1371 |         progress.setPercentageComplete(42); | 
| 1372 |         QTest::newRow(dataTag: "percent-complete" ) | 
| 1373 |             << (QList<QOrganizerItemDetail>() << progress) | 
| 1374 |             << (QList<QVersitProperty>() << property); | 
| 1375 |     } | 
| 1376 |  | 
| 1377 |     { | 
| 1378 |         QVersitProperty property; | 
| 1379 |         property.setName(QStringLiteral("COMPLETED" )); | 
| 1380 |         property.setValue(QStringLiteral("20100609T161500" )); | 
| 1381 |         QOrganizerTodoProgress progress; | 
| 1382 |         progress.setFinishedDateTime(QDateTime(QDate(2010, 6, 9), QTime(16, 15, 0))); | 
| 1383 |         QTest::newRow(dataTag: "completed" ) | 
| 1384 |             << (QList<QOrganizerItemDetail>() << progress) | 
| 1385 |             << (QList<QVersitProperty>() << property); | 
| 1386 |     } | 
| 1387 |  | 
| 1388 |     { | 
| 1389 |         QVersitProperty property; | 
| 1390 |         property.setName(QStringLiteral("CATEGORIES" )); | 
| 1391 |         property.setValue(QStringLiteral("Important Event" )); | 
| 1392 |         QOrganizerItemTag tag; | 
| 1393 |         tag.setTag(QStringLiteral("Important Event" )); | 
| 1394 |         QTest::newRow(dataTag: "tag 1" ) | 
| 1395 |                 << (QList<QOrganizerItemDetail>() << tag) | 
| 1396 |                 << (QList<QVersitProperty>() << property); | 
| 1397 |  | 
| 1398 |         // Set another one for multiple handling test | 
| 1399 |         property.setValue(QStringLiteral("Important Event 2" )); | 
| 1400 |         tag.setTag(QStringLiteral("Important Event 2" )); | 
| 1401 |         QTest::newRow(dataTag: "tag 2" ) | 
| 1402 |                 << (QList<QOrganizerItemDetail>() << tag) | 
| 1403 |                 << (QList<QVersitProperty>() << property); | 
| 1404 |  | 
| 1405 |         // Empty tag | 
| 1406 |         property.clear(); | 
| 1407 |         property.setName("CATEGORIES" ); | 
| 1408 |         tag.removeValue(field: QOrganizerItemTag::FieldTag); | 
| 1409 |         QTest::newRow(dataTag: "empty tag" ) | 
| 1410 |                 << (QList<QOrganizerItemDetail>() << tag) | 
| 1411 |                 << (QList<QVersitProperty>() << property); | 
| 1412 |     } | 
| 1413 |  | 
| 1414 |     { | 
| 1415 |         QVersitProperty property = createExtendedDetailPropertyForStringData(name: "name" , data: "data" ); | 
| 1416 |         QOrganizerItemExtendedDetail extendedDetail = createExtendedDetail(name: "name" , QStringLiteral("data" )); | 
| 1417 |         QTest::newRow(dataTag: "extended detail" ) << (QList<QOrganizerItemDetail>() << extendedDetail) | 
| 1418 |             << (QList<QVersitProperty>() << property); | 
| 1419 |     } | 
| 1420 | } | 
| 1421 |  | 
| 1422 | void tst_QVersitOrganizerExporter::testExtendedDetail() | 
| 1423 | { | 
| 1424 |     QFETCH(QString, extendedDetailName); | 
| 1425 |     QFETCH(QVariant, extendedDetailData); | 
| 1426 |     QFETCH(QString, extendedDetailDataInProperty); | 
| 1427 |     QFETCH(bool, extendedDetailPropertyCreated); | 
| 1428 |  | 
| 1429 |     QOrganizerEvent item; | 
| 1430 |     QOrganizerItemExtendedDetail extendedDetail = createExtendedDetail(name: extendedDetailName, data: extendedDetailData); | 
| 1431 |     item.saveDetail(detail: &extendedDetail); | 
| 1432 |  | 
| 1433 |     QVersitProperty expectedProperty = | 
| 1434 |             createExtendedDetailProperty(name: extendedDetailName, data: extendedDetailDataInProperty); | 
| 1435 |  | 
| 1436 |     QVersitOrganizerExporter exporter; | 
| 1437 |     QVERIFY(exporter.exportItems(QList<QOrganizerItem>() << item)); | 
| 1438 |  | 
| 1439 |     QVersitDocument document = exporter.document().subDocuments().first(); | 
| 1440 |     QList<QVersitProperty> actualProperties = | 
| 1441 |             findPropertiesByName(document, propertyName: expectedProperty.name()); | 
| 1442 |     if (!extendedDetailPropertyCreated) { | 
| 1443 |         QCOMPARE(actualProperties.size(), 0); | 
| 1444 |     } else { | 
| 1445 |         QCOMPARE(actualProperties.size(), 1); | 
| 1446 |         if (static_cast<QMetaType::Type>(extendedDetailData.type()) == QMetaType::Double | 
| 1447 |                 || static_cast<QMetaType::Type>(extendedDetailData.type()) == QMetaType::Float) { | 
| 1448 |             QCOMPARE(actualProperties.first().name(), expectedProperty.name()); | 
| 1449 |             QStringList actualStringList = actualProperties.first().variantValue().toStringList(); | 
| 1450 |             QCOMPARE(actualStringList.size(), 2); | 
| 1451 |             QString actualString = actualStringList.at(i: 1); | 
| 1452 |             actualString.replace(c: '[',after: "" ).replace(c: ']',after: "" ).replace(c: '\n', after: "" ); | 
| 1453 |             QStringList expectedStringList = expectedProperty.variantValue().toStringList(); | 
| 1454 |             QCOMPARE(expectedStringList.size(), 2); | 
| 1455 |             QString expectedString = expectedStringList.at(i: 1); | 
| 1456 |             expectedString.replace(c: '[',after: "" ).replace(c: ']',after: "" ).replace(c: '\n', after: "" ); | 
| 1457 |             if (static_cast<QMetaType::Type>(extendedDetailData.type()) == QMetaType::Float) { | 
| 1458 |                 float actualF = actualString.toFloat(); | 
| 1459 |                 float expectedF = expectedString.toFloat(); | 
| 1460 |                 QCOMPARE(actualStringList.first(), expectedStringList.first()); // "name" | 
| 1461 |                 QCOMPARE(actualF, expectedF); // "value" | 
| 1462 |             } else { | 
| 1463 |                 double actualD = actualString.toDouble(); | 
| 1464 |                 double expectedD = expectedString.toDouble(); | 
| 1465 |                 QCOMPARE(actualStringList.first(), expectedStringList.first()); // "name" | 
| 1466 |                 QCOMPARE(actualD, expectedD); // "value" | 
| 1467 |             } | 
| 1468 |         } else if (!actualProperties.contains(t: expectedProperty)) { | 
| 1469 |             qDebug() << "Actual:"  << actualProperties; | 
| 1470 |             qDebug() << "Expected to find:"  << expectedProperty; | 
| 1471 |             QVERIFY(false); | 
| 1472 |         } | 
| 1473 |     } | 
| 1474 | } | 
| 1475 |  | 
| 1476 | void tst_QVersitOrganizerExporter::testExtendedDetail_data() | 
| 1477 | { | 
| 1478 |     QTest::addColumn<QString>(name: "extendedDetailName" ); | 
| 1479 |     QTest::addColumn<QVariant>(name: "extendedDetailData" ); | 
| 1480 |     QTest::addColumn<QString>(name: "extendedDetailDataInProperty" ); | 
| 1481 |     QTest::addColumn<bool>(name: "extendedDetailPropertyCreated" ); | 
| 1482 |  | 
| 1483 |     QString jsonArrayWith("[\n    %1\n]\n" ); | 
| 1484 |     QString jsonArrayWithString = jsonArrayWith.arg(a: "\"%1\"" ); | 
| 1485 |     { | 
| 1486 |         QTest::newRow(dataTag: "string data" ) | 
| 1487 |                 << QString("name" ) | 
| 1488 |                 << QVariant(QString("data" )) | 
| 1489 |                 << jsonArrayWithString.arg(a: "data" ) | 
| 1490 |                 << true; | 
| 1491 |         QTest::newRow(dataTag: "string data, empty" ) | 
| 1492 |                 << QString("name" ) | 
| 1493 |                 << QVariant(QString("" )) | 
| 1494 |                 << jsonArrayWithString.arg(a: "" ) | 
| 1495 |                 << true; | 
| 1496 |         QTest::newRow(dataTag: "string data, containing reserved characters" ) | 
| 1497 |                 << QString("name" ) | 
| 1498 |                 << QVariant(QString(",;:\\" )) | 
| 1499 |                 << jsonArrayWithString.arg(a: ",;:\\\\" ) | 
| 1500 |                 << true; | 
| 1501 |     } | 
| 1502 |  | 
| 1503 |     { | 
| 1504 |         QTest::newRow(dataTag: "double data" ) | 
| 1505 |                 << QString("name" ) | 
| 1506 |                 << QVariant((double)2.0) | 
| 1507 |                 << jsonArrayWith.arg(a: "2" ) | 
| 1508 |                 << true; | 
| 1509 |         QTest::newRow(dataTag: "double data, negative" ) | 
| 1510 |                 << QString("name" ) | 
| 1511 |                 << QVariant((double)-1.0) | 
| 1512 |                 << jsonArrayWith.arg(a: "-1" ) | 
| 1513 |                 << true; | 
| 1514 |         QTest::newRow(dataTag: "double data, multiple digits" ) | 
| 1515 |                 << QString("name" ) | 
| 1516 |                 << QVariant::fromValue<double>(value: 10.199999999999999) | 
| 1517 |                 << jsonArrayWith.arg(a: "10.199999999999999" ) | 
| 1518 |                 << true; | 
| 1519 |     } | 
| 1520 |  | 
| 1521 |     { | 
| 1522 |         QTest::newRow(dataTag: "boolean data" ) | 
| 1523 |                 << QString("name" ) | 
| 1524 |                 << QVariant(true) | 
| 1525 |                 << jsonArrayWith.arg(a: "true" ) | 
| 1526 |                 << true; | 
| 1527 |     } | 
| 1528 |  | 
| 1529 |     { | 
| 1530 |         QTest::newRow(dataTag: "integer data, serialized as number/double" ) | 
| 1531 |                 << QString("name" ) | 
| 1532 |                 << QVariant((int)2) | 
| 1533 |                 << jsonArrayWith.arg(a: "2" ) | 
| 1534 |                 << true; | 
| 1535 |         QTest::newRow(dataTag: "integer data, serialized as number/double" ) | 
| 1536 |                 << QString("name" ) | 
| 1537 |                 << QVariant((int)-10) | 
| 1538 |                 << jsonArrayWith.arg(a: "-10" ) | 
| 1539 |                 << true; | 
| 1540 |     } | 
| 1541 |     { | 
| 1542 |         QTest::newRow(dataTag: "datetime data (using local time)" ) | 
| 1543 |                 << QString("name" ) | 
| 1544 |                 << QVariant(QDateTime::fromString(s: "1997-07-16T19:20:30.123+01:00" , f: Qt::ISODate)) | 
| 1545 |                 << jsonArrayWithString.arg(a: "1997-07-16T19:20:30+01:00" ) | 
| 1546 |                 << true; | 
| 1547 |         QTest::newRow(dataTag: "datetime data (using UTC)" ) | 
| 1548 |                 << QString("name" ) | 
| 1549 |                 << QVariant(QDateTime::fromString(s: "1997-07-16T19:20:30.123+01:00" , f: Qt::ISODate).toUTC()) | 
| 1550 |                 << jsonArrayWithString.arg(a: "1997-07-16T18:20:30Z" ) | 
| 1551 |                 << true; | 
| 1552 |         QTest::newRow(dataTag: "datetime data (using local time with unspecified timezone)" ) | 
| 1553 |                 << QString("name" ) | 
| 1554 |                 << QVariant(QDateTime::fromString(s: "1997-07-16T19:20:30" , f: Qt::ISODate)) | 
| 1555 |                 << jsonArrayWithString.arg(a: "1997-07-16T19:20:30" ) | 
| 1556 |                 << true; | 
| 1557 |     } | 
| 1558 |  | 
| 1559 |     { | 
| 1560 |         QTest::newRow(dataTag: "list data" ) | 
| 1561 |                 << QString("name" ) | 
| 1562 |                 << QVariant(QVariantList() << QString("string 1" ) << QString("string 2" )) | 
| 1563 |                 << QString("[\n    [\n        \"string 1\",\n        \"string 2\"\n    ]\n]\n" ) | 
| 1564 |                 << true; | 
| 1565 |     } | 
| 1566 |  | 
| 1567 |     { | 
| 1568 |         QVariantMap map; | 
| 1569 |         map["key 1" ] = QString("string 1" ); | 
| 1570 |         map["key 2" ] = QString("string 2" ); | 
| 1571 |         QTest::newRow(dataTag: "map data" ) | 
| 1572 |                 << QString("name" ) | 
| 1573 |                 << QVariant(map) | 
| 1574 |                 << QString("[\n    {\n        \"key 1\": \"string 1\",\n        \"key 2\": \"string 2\"\n    }\n]\n" ) | 
| 1575 |                 << true; | 
| 1576 |     } | 
| 1577 |  | 
| 1578 |     { | 
| 1579 |         QVariantMap map; | 
| 1580 |         map["key" ] = QVariantList() << (double)1 << (double)2; | 
| 1581 |         QTest::newRow(dataTag: "map data, containing a nested list" ) | 
| 1582 |                 << QString("name" ) | 
| 1583 |                 << QVariant(map) | 
| 1584 |                 << QString("[\n    {\n        \"key\": [\n            1,\n            2\n        ]\n    }\n]\n" ) | 
| 1585 |                 << true; | 
| 1586 |     } | 
| 1587 |  | 
| 1588 |     { | 
| 1589 |         QTest::newRow(dataTag: "empty string as name" ) | 
| 1590 |                 << QString("" ) | 
| 1591 |                 << QVariant(QString("data" )) | 
| 1592 |                 << jsonArrayWithString.arg(a: "data" ) | 
| 1593 |                 << true; | 
| 1594 |         QTest::newRow(dataTag: "name containing reserved characters" ) | 
| 1595 |                 << QString(",;:\\" ) | 
| 1596 |                 << QVariant(QString("data" )) | 
| 1597 |                 << jsonArrayWithString.arg(a: "data" ) | 
| 1598 |                 << true; | 
| 1599 |     } | 
| 1600 |  | 
| 1601 |     { | 
| 1602 |         QTest::newRow(dataTag: "empty variant as data" ) | 
| 1603 |                 << QString("name" ) | 
| 1604 |                 << QVariant() | 
| 1605 |                 << jsonArrayWith.arg(a: "null" ) | 
| 1606 |                 << true; | 
| 1607 |     } | 
| 1608 |  | 
| 1609 |     { | 
| 1610 |         QVariantHash hash; | 
| 1611 |         hash["key 1" ] = QString("string 1" ); | 
| 1612 |         hash["key 2" ] = QString("string 2" ); | 
| 1613 |         QTest::newRow(dataTag: "hash data" ) | 
| 1614 |                 << QString("name" ) | 
| 1615 |                 << QVariant(hash) | 
| 1616 |                 << QString("[\n    {\n        \"key 1\": \"string 1\",\n        \"key 2\": \"string 2\"\n    }\n]\n" ) | 
| 1617 |                 << true; | 
| 1618 |     } | 
| 1619 |     { | 
| 1620 |         QTest::newRow(dataTag: "data type not supported" ) | 
| 1621 |                 << QString("name" ) | 
| 1622 |                 << QVariant(QSize(1, 1)) | 
| 1623 |                 << QString() | 
| 1624 |                 << false; | 
| 1625 |     } | 
| 1626 | } | 
| 1627 |  | 
| 1628 | void tst_QVersitOrganizerExporter::testMultipleExtendedDetails() | 
| 1629 | { | 
| 1630 |     QOrganizerEvent item; | 
| 1631 |     QOrganizerItemExtendedDetail extendedDetail1 = createExtendedDetail(name: "detailName1" , data: "detailData1" ); | 
| 1632 |     item.saveDetail(detail: &extendedDetail1); | 
| 1633 |     QOrganizerItemExtendedDetail extendedDetail2 = createExtendedDetail(name: "detailName2" , data: "detailData2" ); | 
| 1634 |     item.saveDetail(detail: &extendedDetail2); | 
| 1635 |  | 
| 1636 |     QList<QVersitProperty> expectedProperties; | 
| 1637 |     expectedProperties << createExtendedDetailPropertyForStringData(name: extendedDetail1.name(), data: "detailData1" ); | 
| 1638 |     expectedProperties << createExtendedDetailPropertyForStringData(name: extendedDetail2.name(), data: "detailData2" ); | 
| 1639 |  | 
| 1640 |     QVersitOrganizerExporter exporter; | 
| 1641 |     QVERIFY(exporter.exportItems(QList<QOrganizerItem>() << item)); | 
| 1642 |  | 
| 1643 |     QVersitDocument document = exporter.document().subDocuments().first(); | 
| 1644 |     QCOMPARE(findPropertiesByName(document, expectedProperties.first().name()).size(), 2); | 
| 1645 |     foreach (const QVersitProperty& expectedProperty, expectedProperties) { | 
| 1646 |         QList<QVersitProperty> actualProperties = | 
| 1647 |             findPropertiesByName(document, propertyName: expectedProperty.name()); | 
| 1648 |         if (!actualProperties.contains(t: expectedProperty)) { | 
| 1649 |             qDebug() << "Actual:"  << actualProperties; | 
| 1650 |             qDebug() << "Expected to find:"  << expectedProperty; | 
| 1651 |             QVERIFY(false); | 
| 1652 |         } | 
| 1653 |     } | 
| 1654 | } | 
| 1655 |  | 
| 1656 | QOrganizerItemExtendedDetail tst_QVersitOrganizerExporter::createExtendedDetail( | 
| 1657 |         const QString &name, | 
| 1658 |         const QVariant &data) | 
| 1659 | { | 
| 1660 |     QOrganizerItemExtendedDetail extendedDetail; | 
| 1661 |     extendedDetail.setName(name); | 
| 1662 |     extendedDetail.setData(data); | 
| 1663 |     return extendedDetail; | 
| 1664 | } | 
| 1665 |  | 
| 1666 | QVersitProperty tst_QVersitOrganizerExporter::createExtendedDetailProperty( | 
| 1667 |         const QString &name, | 
| 1668 |         const QVariant &data) | 
| 1669 | { | 
| 1670 |     QVersitProperty property; | 
| 1671 |     property.setName(QStringLiteral("X-QTPROJECT-EXTENDED-DETAIL" )); | 
| 1672 |     property.setValueType(QVersitProperty::CompoundType); | 
| 1673 |     property.setValue(QStringList() << name << data.toString()); | 
| 1674 |     return property; | 
| 1675 | } | 
| 1676 |  | 
| 1677 | QVersitProperty tst_QVersitOrganizerExporter::createExtendedDetailPropertyForStringData( | 
| 1678 |         const QString &name, | 
| 1679 |         const QString &data) | 
| 1680 | { | 
| 1681 |     QString jsonArrayWith("[\n    %1\n]\n" ); | 
| 1682 |     QString jsonArrayWithString = jsonArrayWith.arg(a: "\"%1\"" ); | 
| 1683 |     return createExtendedDetailProperty(name, data: jsonArrayWithString.arg(a: data)); | 
| 1684 | } | 
| 1685 |  | 
| 1686 | QList<QVersitProperty> tst_QVersitOrganizerExporter::findPropertiesByName( | 
| 1687 |         const QVersitDocument &document, const QString &propertyName) | 
| 1688 | { | 
| 1689 |     QList<QVersitProperty> retval; | 
| 1690 |     foreach (const QVersitProperty& property, document.properties()) { | 
| 1691 |         if (property.name() == propertyName) | 
| 1692 |             retval << property; | 
| 1693 |     } | 
| 1694 |     return retval; | 
| 1695 | } | 
| 1696 |  | 
| 1697 | void tst_QVersitOrganizerExporter::testEmptyItemShouldNotBeExported() | 
| 1698 | { | 
| 1699 |     QVersitOrganizerExporter exporter; | 
| 1700 |     QList<QOrganizerItem> items; | 
| 1701 |  | 
| 1702 |     QOrganizerEvent ev; | 
| 1703 |     QVERIFY(ev.isEmpty()); | 
| 1704 |     QOrganizerItem item1; | 
| 1705 |     QVERIFY(item1.isEmpty()); | 
| 1706 |     items << static_cast<QOrganizerItem>(ev)<<item1; | 
| 1707 |  | 
| 1708 |     QVERIFY(!exporter.exportItems(items)); | 
| 1709 |     QVERIFY(!exporter.errorMap().isEmpty()); | 
| 1710 |  | 
| 1711 |     QVersitOrganizerExporter::Error errorCode = exporter.errorMap().value(akey: 0); | 
| 1712 |     QVERIFY2(errorCode == QVersitOrganizerExporter::EmptyOrganizerError, | 
| 1713 |              QString("exporter.errorMap().value(0) == "  | 
| 1714 |                      + QString::number(errorCode)).toStdString().c_str()); | 
| 1715 |     errorCode = exporter.errorMap().value(akey: 1); | 
| 1716 |     QVERIFY2(errorCode == QVersitOrganizerExporter::EmptyOrganizerError | 
| 1717 |              || errorCode == QVersitOrganizerExporter::UnknownComponentTypeError, | 
| 1718 |              QString("exporter.errorMap().value(1) == "  | 
| 1719 |                      + QString::number(errorCode)).toStdString().c_str() ); | 
| 1720 |     items.clear(); | 
| 1721 |     exporter.errorMap().clear(); | 
| 1722 | } | 
| 1723 |  | 
| 1724 | QTEST_MAIN(tst_QVersitOrganizerExporter) | 
| 1725 |  |