| 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/organizer | 
| 35 |  | 
| 36 | #include <QtTest/QtTest> | 
| 37 | #include <QtCore/QUuid> | 
| 38 |  | 
| 39 | #include <QtOrganizer/qorganizer.h> | 
| 40 | #include <QtOrganizer/qorganizeritemchangeset.h> | 
| 41 | #include "../qorganizermanagerdataholder.h" | 
| 42 |  | 
| 43 | #include <QtOrganizer/qorganizernote.h> | 
| 44 | #include <QtOrganizer/qorganizerevent.h> | 
| 45 |  | 
| 46 | QTORGANIZER_USE_NAMESPACE | 
| 47 |  | 
| 48 | // to get QFETCH to work with the template expression... | 
| 49 | typedef QMap<QString,QString> tst_QOrganizerManager_QStringMap; | 
| 50 | Q_DECLARE_METATYPE(tst_QOrganizerManager_QStringMap) | 
| 51 | Q_DECLARE_METATYPE(QList<QOrganizerItemId>) | 
| 52 |  | 
| 53 | /* A class that no backend can support */ | 
| 54 | class UnsupportedMetatype { | 
| 55 |     int foo; | 
| 56 | }; | 
| 57 | Q_DECLARE_METATYPE(UnsupportedMetatype) | 
| 58 | Q_DECLARE_METATYPE(QOrganizerItem) | 
| 59 | Q_DECLARE_METATYPE(QOrganizerManager::Error) | 
| 60 | Q_DECLARE_METATYPE(QList<QDate>) | 
| 61 | Q_DECLARE_METATYPE(QList<QOrganizerItemDetail::DetailType>); | 
| 62 |  | 
| 63 | static inline QOrganizerItemId makeItemId(uint id) | 
| 64 | { | 
| 65 |     return QOrganizerItemId(QStringLiteral("qtorganizer:basic:" ), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); | 
| 66 | } | 
| 67 |  | 
| 68 | static inline QOrganizerCollectionId makeCollectionId(uint id) | 
| 69 | { | 
| 70 |     return QOrganizerCollectionId(QStringLiteral("qtorganizer:basic:" ), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); | 
| 71 | } | 
| 72 |  | 
| 73 |  | 
| 74 | class tst_QOrganizerManager : public QObject | 
| 75 | { | 
| 76 | Q_OBJECT | 
| 77 |  | 
| 78 | public: | 
| 79 |     tst_QOrganizerManager(); | 
| 80 |     virtual ~tst_QOrganizerManager(); | 
| 81 |  | 
| 82 | private: | 
| 83 |     void dumpOrganizerItemDifferences(const QOrganizerItem& a, const QOrganizerItem& b); | 
| 84 |     void dumpOrganizerItem(const QOrganizerItem &c); | 
| 85 |     void dumpOrganizerItems(QOrganizerManager *cm); | 
| 86 |     bool isSuperset(const QOrganizerItem& ca, const QOrganizerItem& cb); | 
| 87 |     QList<QOrganizerItemDetail> removeAllDefaultDetails(const QList<QOrganizerItemDetail>& details); | 
| 88 |     void addManagers(); // add standard managers to the data | 
| 89 |  | 
| 90 |     QScopedPointer<QOrganizerManagerDataHolder> managerDataHolder; | 
| 91 |  | 
| 92 | public slots: | 
| 93 |     void initTestCase(); | 
| 94 |     void cleanupTestCase(); | 
| 95 | private slots: | 
| 96 |  | 
| 97 |     void doDump(); | 
| 98 |     void doDump_data() {addManagers();} | 
| 99 |  | 
| 100 |     /* Special test with special data */ | 
| 101 |     void uriParsing(); | 
| 102 |     void recurrenceWithGenerator(); | 
| 103 |     void todoRecurrenceWithGenerator(); | 
| 104 |     void dateRange(); | 
| 105 |  | 
| 106 |     /* Tests that are run on all managers */ | 
| 107 |     void metadata(); | 
| 108 |     void nullIdOperations(); | 
| 109 |     void add(); | 
| 110 |     void saveRecurrence(); | 
| 111 |     void persistence(); | 
| 112 |     void addExceptions(); | 
| 113 |     void modifyRecurrence(); | 
| 114 |     void addExceptionsWithGuid(); | 
| 115 |     void update(); | 
| 116 |     void remove(); | 
| 117 |     void batch(); | 
| 118 |     void observerDeletion(); | 
| 119 |     void signalEmission(); | 
| 120 |     void detailOrders(); | 
| 121 |     void itemType(); | 
| 122 |     void collections(); | 
| 123 |     void dataSerialization(); | 
| 124 |     void itemFetch(); | 
| 125 |     void todoItemFetch(); | 
| 126 |     void itemFetchV2(); | 
| 127 |     void itemFilterFetch(); | 
| 128 |     void spanOverDays(); | 
| 129 |     void incompleteTodoTime(); | 
| 130 |     void recurrence(); | 
| 131 |     void idComparison(); | 
| 132 |     void emptyItemManipulation(); | 
| 133 |     void partialSave(); | 
| 134 |  | 
| 135 |     /* Tests that take no data */ | 
| 136 |     void errorStayingPut(); | 
| 137 |     void ctors(); | 
| 138 |     void invalidManager(); | 
| 139 |     void memoryManager(); | 
| 140 |     void changeSet(); | 
| 141 |     void fetchHint(); | 
| 142 |     void testFilterFunction(); | 
| 143 |     void testReminder(); | 
| 144 |     void testIntersectionFilter(); | 
| 145 |     void testNestCompoundFilter(); | 
| 146 |     void testUnionFilter(); | 
| 147 |     void testItemOccurrences(); | 
| 148 |  | 
| 149 |     /* Special test with special data */ | 
| 150 |     void uriParsing_data(); | 
| 151 |     void recurrenceWithGenerator_data(); | 
| 152 |     void todoRecurrenceWithGenerator_data(); | 
| 153 |     void dateRange_data(); | 
| 154 |     /* Tests that are run on all managers */ | 
| 155 |     void metadata_data() {addManagers();} | 
| 156 |     void nullIdOperations_data() {addManagers();} | 
| 157 |     void add_data() {addManagers();} | 
| 158 |     void saveRecurrence_data() {addManagers();} | 
| 159 |     void persistence_data() {addManagers();} | 
| 160 |     void addExceptions_data() {addManagers();} | 
| 161 |     void addExceptionsWithGuid_data() {addManagers();} | 
| 162 |     void modifyRecurrence_data() {addManagers();} | 
| 163 |     void update_data() {addManagers();} | 
| 164 |     void remove_data() {addManagers();} | 
| 165 |     void batch_data() {addManagers();} | 
| 166 |     void signalEmission_data() {addManagers();} | 
| 167 |     void detailOrders_data() {addManagers();} | 
| 168 |     void itemType_data() {addManagers();} | 
| 169 |     void collections_data() {addManagers();} | 
| 170 |     void dataSerialization_data() {addManagers();} | 
| 171 |     void itemFetch_data() {addManagers();} | 
| 172 |     void todoItemFetch_data() {addManagers();} | 
| 173 |     void itemFetchV2_data() {addManagers();} | 
| 174 |     void itemFilterFetch_data() {addManagers();} | 
| 175 |     void spanOverDays_data() {addManagers();} | 
| 176 |     void incompleteTodoTime_data() {addManagers();} | 
| 177 |     void recurrence_data() {addManagers();} | 
| 178 |     void idComparison_data() {addManagers();} | 
| 179 |     void testReminder_data() {addManagers();} | 
| 180 |     void testIntersectionFilter_data() {addManagers();} | 
| 181 |     void testNestCompoundFilter_data() {addManagers();} | 
| 182 |     void testUnionFilter_data() {addManagers();} | 
| 183 |     void emptyItemManipulation_data() {addManagers();} | 
| 184 |     void partialSave_data() {addManagers();} | 
| 185 |     void testItemOccurrences_data(){addManagers();} | 
| 186 |  | 
| 187 |     void testTags_data() { addManagers(); } | 
| 188 |     void testTags(); | 
| 189 |  | 
| 190 |     void testExtendedDetail_data() { addManagers(); } | 
| 191 |     void testExtendedDetail(); | 
| 192 |  | 
| 193 |     void testAttendee_data() { addManagers(); } | 
| 194 |     void testAttendee(); | 
| 195 |  | 
| 196 |     void testRsvp_data() { addManagers(); } | 
| 197 |     void testRsvp(); | 
| 198 |  | 
| 199 |     void testClassification_data() { addManagers(); } | 
| 200 |     void testClassification(); | 
| 201 |  | 
| 202 |     void testVersion_data() { addManagers(); } | 
| 203 |     void testVersion(); | 
| 204 | }; | 
| 205 |  | 
| 206 | tst_QOrganizerManager::tst_QOrganizerManager() | 
| 207 | { | 
| 208 | } | 
| 209 |  | 
| 210 | tst_QOrganizerManager::~tst_QOrganizerManager() | 
| 211 | { | 
| 212 | } | 
| 213 |  | 
| 214 | void tst_QOrganizerManager::initTestCase() | 
| 215 | { | 
| 216 |     managerDataHolder.reset(other: new QOrganizerManagerDataHolder()); | 
| 217 |  | 
| 218 |     /* Make sure these other test plugins are NOT loaded by default */ | 
| 219 |     // These are now removed from the list of managers in addManagers() | 
| 220 |     QVERIFY(!QOrganizerManager::availableManagers().contains("testdummy" )); | 
| 221 |     QVERIFY(!QOrganizerManager::availableManagers().contains("teststaticdummy" )); | 
| 222 | } | 
| 223 |  | 
| 224 | void tst_QOrganizerManager::cleanupTestCase() | 
| 225 | { | 
| 226 |     managerDataHolder.reset(other: 0); | 
| 227 | } | 
| 228 |  | 
| 229 | void tst_QOrganizerManager::dumpOrganizerItemDifferences(const QOrganizerItem& ca, const QOrganizerItem& cb) | 
| 230 | { | 
| 231 |     // Try to narrow down the differences | 
| 232 |     QOrganizerItem a(ca); | 
| 233 |     QOrganizerItem b(cb); | 
| 234 |  | 
| 235 |     // Check the display label | 
| 236 |     QCOMPARE(a.displayLabel(), b.displayLabel()); | 
| 237 |  | 
| 238 |     // Now look at the rest | 
| 239 |     QList<QOrganizerItemDetail> aDetails = a.details(); | 
| 240 |     QList<QOrganizerItemDetail> bDetails = b.details(); | 
| 241 |  | 
| 242 |     // They can be in any order, so loop | 
| 243 |     // First remove any matches | 
| 244 |     foreach(QOrganizerItemDetail d, aDetails) { | 
| 245 |         foreach(QOrganizerItemDetail d2, bDetails) { | 
| 246 |             if(d == d2) { | 
| 247 |                 a.removeDetail(detail: &d); | 
| 248 |                 b.removeDetail(detail: &d2); | 
| 249 |                 break; | 
| 250 |             } | 
| 251 |         } | 
| 252 |     } | 
| 253 |  | 
| 254 |     // Now dump the extra details that were unmatched in A (note that DisplayLabel and Type are always present). | 
| 255 |     aDetails = a.details(); | 
| 256 |     bDetails = b.details(); | 
| 257 |     foreach(QOrganizerItemDetail d, aDetails) { | 
| 258 |         if (d.type() != QOrganizerItemDetail::TypeDisplayLabel && d.type() != QOrganizerItemDetail::TypeItemType) | 
| 259 |             qDebug() << "A item had extra detail:"  << d.type() << d.values(); | 
| 260 |     } | 
| 261 |     // and same for B | 
| 262 |     foreach(QOrganizerItemDetail d, bDetails) { | 
| 263 |         if (d.type() != QOrganizerItemDetail::TypeDisplayLabel && d.type() != QOrganizerItemDetail::TypeItemType) | 
| 264 |             qDebug() << "B item had extra detail:"  << d.type() << d.values(); | 
| 265 |     } | 
| 266 |  | 
| 267 |     // now test specifically the display label and the type | 
| 268 |     if (a.displayLabel() != b.displayLabel()) { | 
| 269 |         qDebug() << "A item display label ="  << a.displayLabel(); | 
| 270 |         qDebug() << "B item display label ="  << b.displayLabel(); | 
| 271 |     } | 
| 272 |     if (a.type() != b.type()) { | 
| 273 |         qDebug() << "A item type ="  << a.type(); | 
| 274 |         qDebug() << "B item type ="  << b.type(); | 
| 275 |     } | 
| 276 | } | 
| 277 |  | 
| 278 | bool tst_QOrganizerManager::isSuperset(const QOrganizerItem& ca, const QOrganizerItem& cb) | 
| 279 | { | 
| 280 |     // returns true if item ca is a superset of item cb | 
| 281 |     // we use this test instead of equality because dynamic information | 
| 282 |     // such as presence/location, and synthesised information such as | 
| 283 |     // display label and (possibly) type, may differ between a item | 
| 284 |     // in memory and the item in the managed store. | 
| 285 |  | 
| 286 |     QOrganizerItem a(ca); | 
| 287 |     QOrganizerItem b(cb); | 
| 288 |     QList<QOrganizerItemDetail> aDetails = a.details(); | 
| 289 |     QList<QOrganizerItemDetail> bDetails = b.details(); | 
| 290 |  | 
| 291 |     // They can be in any order, so loop | 
| 292 |     // First remove any matches | 
| 293 |     foreach(QOrganizerItemDetail d, aDetails) { | 
| 294 |         foreach(QOrganizerItemDetail d2, bDetails) { | 
| 295 |             if(d == d2) { | 
| 296 |                 a.removeDetail(detail: &d); | 
| 297 |                 b.removeDetail(detail: &d2); | 
| 298 |                 break; | 
| 299 |             } | 
| 300 |         } | 
| 301 |     } | 
| 302 |  | 
| 303 |     // Second remove any superset matches (eg, backend adds a field) | 
| 304 |     aDetails = a.details(); | 
| 305 |     bDetails = b.details(); | 
| 306 |     foreach (QOrganizerItemDetail d, aDetails) { | 
| 307 |         foreach (QOrganizerItemDetail d2, bDetails) { | 
| 308 |             if (d.type() == d2.type()) { | 
| 309 |                 bool canRemove = true; | 
| 310 |                 QMap<int, QVariant> d2map = d2.values(); | 
| 311 |                 foreach (int key, d2map.keys()) { | 
| 312 |                     if (d.value(field: key) != d2.value(field: key)) { | 
| 313 |                         // d can have _more_ keys than d2, | 
| 314 |                         // but not _less_; and it cannot | 
| 315 |                         // change the value. | 
| 316 |                         canRemove = false; | 
| 317 |                     } | 
| 318 |                 } | 
| 319 |  | 
| 320 |                 if (canRemove) { | 
| 321 |                     // if we get to here, we can remove the details. | 
| 322 |                     a.removeDetail(detail: &d); | 
| 323 |                     b.removeDetail(detail: &d2); | 
| 324 |                     break; | 
| 325 |                 } | 
| 326 |             } | 
| 327 |         } | 
| 328 |     } | 
| 329 |  | 
| 330 |     // check for item type updates | 
| 331 |     if (a.type() != QOrganizerItemType::TypeUndefined) | 
| 332 |         if (b.type() != QOrganizerItemType::TypeUndefined) | 
| 333 |             if (a.type() != b.type()) | 
| 334 |                 return false; // nonempty type is different. | 
| 335 |  | 
| 336 |     // Now check to see if b has any details remaining; if so, a is not a superset. | 
| 337 |     // Note that the DisplayLabel and Type can never be removed. | 
| 338 |     if (b.details().size() > 2 | 
| 339 |             || (b.details().size() == 2 && (b.details().value(i: 0).type() != QOrganizerItemDetail::TypeDisplayLabel | 
| 340 |                                             || b.details().value(i: 1).type() != QOrganizerItemDetail::TypeItemType))) | 
| 341 |         return false; | 
| 342 |     return true; | 
| 343 | } | 
| 344 |  | 
| 345 | void tst_QOrganizerManager::dumpOrganizerItem(const QOrganizerItem& item) | 
| 346 | { | 
| 347 |     QOrganizerManager m; | 
| 348 |     qDebug() << "OrganizerItem: "  << item.id() << "("  << item.displayLabel() << ")" ; | 
| 349 |     QList<QOrganizerItemDetail> details = item.details(); | 
| 350 |     foreach(QOrganizerItemDetail d, details) { | 
| 351 |         qDebug() << "  "  << d.type() << ":" ; | 
| 352 |         qDebug() << "    Vals:"  << d.values(); | 
| 353 |     } | 
| 354 | } | 
| 355 |  | 
| 356 | void tst_QOrganizerManager::dumpOrganizerItems(QOrganizerManager *cm) | 
| 357 | { | 
| 358 |     QList<QOrganizerItemId> ids = cm->itemIds(); | 
| 359 |  | 
| 360 |     qDebug() << "There are"  << ids.count() << "items in"  << cm->managerUri(); | 
| 361 |  | 
| 362 |     foreach(QOrganizerItemId id, ids) { | 
| 363 |         QOrganizerItem c = cm->item(itemId: id); | 
| 364 |         dumpOrganizerItem(item: c); | 
| 365 |     } | 
| 366 | } | 
| 367 |  | 
| 368 | void tst_QOrganizerManager::uriParsing_data() | 
| 369 | { | 
| 370 |     QTest::addColumn<QString>(name: "uri" ); | 
| 371 |     QTest::addColumn<bool>(name: "good" ); // is this a good uri or not | 
| 372 |     QTest::addColumn<QString>(name: "manager" ); | 
| 373 |     QTest::addColumn<QMap<QString, QString> >(name: "parameters" ); | 
| 374 |  | 
| 375 |     QMap<QString, QString> inparameters; | 
| 376 |     inparameters.insert(akey: "foo" , avalue: "bar" ); | 
| 377 |     inparameters.insert(akey: "bazflag" , avalue: QString()); | 
| 378 |     inparameters.insert(akey: "bar" , avalue: "glob" ); | 
| 379 |  | 
| 380 |     QMap<QString, QString> inparameters2; | 
| 381 |     inparameters2.insert(akey: "this has spaces" , avalue: QString()); | 
| 382 |     inparameters2.insert(akey: "and& an" , avalue: " &" ); | 
| 383 |     inparameters2.insert(akey: "and an " , avalue: "=quals" ); | 
| 384 |  | 
| 385 |     QTest::newRow(dataTag: "built" ) << QOrganizerManager::buildUri(managerName: "manager" , params: inparameters) << true << "manager"  << inparameters; | 
| 386 |     QTest::newRow(dataTag: "built with escaped parameters" ) << QOrganizerManager::buildUri(managerName: "manager" , params: inparameters2) << true << "manager"  << inparameters2; | 
| 387 |     QTest::newRow(dataTag: "no scheme" ) << "this should not split"  << false << QString() << tst_QOrganizerManager_QStringMap(); | 
| 388 |     QTest::newRow(dataTag: "wrong scheme" ) << "invalidscheme:foo bar"  << false << QString() << tst_QOrganizerManager_QStringMap(); | 
| 389 |     QTest::newRow(dataTag: "right scheme, no colon" ) << "qtorganizer"  << false << QString() << tst_QOrganizerManager_QStringMap(); | 
| 390 |     QTest::newRow(dataTag: "no manager, colon, no params" ) << "qtorganizer::"  << false  << "manager"  << tst_QOrganizerManager_QStringMap(); | 
| 391 |     QTest::newRow(dataTag: "yes manager, no colon, no params" ) << "qtorganizer:manager"  << true << "manager"  << tst_QOrganizerManager_QStringMap(); | 
| 392 |     QTest::newRow(dataTag: "yes manager, yes colon, no params" ) << "qtorganizer:manager:"  << true << "manager" << tst_QOrganizerManager_QStringMap(); | 
| 393 |     QTest::newRow(dataTag: "yes params" ) << "qtorganizer:manager:foo=bar&bazflag=&bar=glob"  << true << "manager"  << inparameters; | 
| 394 |     QTest::newRow(dataTag: "yes params but misformed" ) << "qtorganizer:manager:foo=bar&=gloo&bar=glob"  << false << "manager"  << inparameters; | 
| 395 |     QTest::newRow(dataTag: "yes params but misformed 2" ) << "qtorganizer:manager:=&=gloo&bar=glob"  << false << "manager"  << inparameters; | 
| 396 |     QTest::newRow(dataTag: "yes params but misformed 3" ) << "qtorganizer:manager:=="  << false << "manager"  << inparameters; | 
| 397 |     QTest::newRow(dataTag: "yes params but misformed 4" ) << "qtorganizer:manager:&&"  << false << "manager"  << inparameters; | 
| 398 |     QTest::newRow(dataTag: "yes params but misformed 5" ) << "qtorganizer:manager:&goo=bar"  << false << "manager"  << inparameters; | 
| 399 |     QTest::newRow(dataTag: "yes params but misformed 6" ) << "qtorganizer:manager:goo&bar"  << false << "manager"  << inparameters; | 
| 400 |     QTest::newRow(dataTag: "yes params but misformed 7" ) << "qtorganizer:manager:goo&bar&gob"  << false << "manager"  << inparameters; | 
| 401 |     QTest::newRow(dataTag: "yes params but misformed 8" ) << "qtorganizer:manager:==&&==&goo=bar"  << false << "manager"  << inparameters; | 
| 402 |     QTest::newRow(dataTag: "yes params but misformed 9" ) << "qtorganizer:manager:foo=bar=baz"  << false << "manager"  << inparameters; | 
| 403 |     QTest::newRow(dataTag: "yes params but misformed 10" ) << "qtorganizer:manager:foo=bar=baz=glob"  << false << "manager"  << inparameters; | 
| 404 |     QTest::newRow(dataTag: "no manager but yes params" ) << "qtorganizer::foo=bar&bazflag=&bar=glob"  << false << QString() << inparameters; | 
| 405 |     QTest::newRow(dataTag: "no manager or params" ) << "qtorganizer::"  << false << QString() << inparameters; | 
| 406 |     QTest::newRow(dataTag: "no manager or params or colon" ) << "qtorganizer:"  << false << QString() << inparameters; | 
| 407 | } | 
| 408 |  | 
| 409 | void tst_QOrganizerManager::addManagers() | 
| 410 | { | 
| 411 |     QTest::addColumn<QString>(name: "uri" ); | 
| 412 |  | 
| 413 |     QStringList managers = QOrganizerManager::availableManagers(); | 
| 414 |  | 
| 415 |     /* Known one that will not pass */ | 
| 416 |     managers.removeAll(t: "invalid" ); | 
| 417 |     managers.removeAll(t: "skeleton" ); | 
| 418 |     managers.removeAll(t: "testdummy" ); | 
| 419 |     managers.removeAll(t: "teststaticdummy" ); | 
| 420 |     managers.removeAll(t: "maliciousplugin" ); | 
| 421 |  | 
| 422 |     foreach(QString mgr, managers) { | 
| 423 |         QMap<QString, QString> params; | 
| 424 |         QTest::newRow(dataTag: QString("mgr='%1'" ).arg(a: mgr).toLatin1().constData()) << QOrganizerManager::buildUri(managerName: mgr, params); | 
| 425 |         if (mgr == "memory" ) { | 
| 426 |             params.insert(akey: "id" , avalue: "tst_QOrganizerManager" ); | 
| 427 |             QTest::newRow(dataTag: QString("mgr='%1', params" ).arg(a: mgr).toLatin1().constData()) << QOrganizerManager::buildUri(managerName: mgr, params); | 
| 428 |         } | 
| 429 |     } | 
| 430 | } | 
| 431 |  | 
| 432 | void tst_QOrganizerManager::metadata() | 
| 433 | { | 
| 434 |     // ensure that the backend is publishing its metadata (name / parameters / uri) correctly | 
| 435 |     QFETCH(QString, uri); | 
| 436 |     QScopedPointer<QOrganizerManager> cm(new QOrganizerManager("memory" )); | 
| 437 |     QVERIFY(QOrganizerManager::buildUri(cm->managerName(), cm->managerParameters()) == cm->managerUri()); | 
| 438 | } | 
| 439 |  | 
| 440 |  | 
| 441 | void tst_QOrganizerManager::nullIdOperations() | 
| 442 | { | 
| 443 |     QFETCH(QString, uri); | 
| 444 |     QScopedPointer<QOrganizerManager> cm(new QOrganizerManager("memory" )); | 
| 445 |     QVERIFY(!cm->removeItem(QOrganizerItemId())); | 
| 446 |     QVERIFY(cm->error() == QOrganizerManager::DoesNotExistError); | 
| 447 |  | 
| 448 |  | 
| 449 |     QOrganizerItem c = cm->item(itemId: QOrganizerItemId()); | 
| 450 |     QVERIFY(c.id() == QOrganizerItemId()); | 
| 451 |     QVERIFY(c.isEmpty()); | 
| 452 |     QVERIFY(cm->error() == QOrganizerManager::DoesNotExistError); | 
| 453 |  | 
| 454 |  | 
| 455 |     /* TODO: rewrite tests using toString() / fromString() | 
| 456 |     // test that streaming null ids doesn't crash. | 
| 457 |     { | 
| 458 |         QOrganizerItemId nullId; | 
| 459 |         QByteArray buffer; | 
| 460 |         QDataStream outBufferStream(&buffer, QIODevice::WriteOnly); | 
| 461 |         outBufferStream << nullId; | 
| 462 |         QVERIFY(buffer.length() > 0); | 
| 463 |  | 
| 464 |         QDataStream inBufferStream(buffer); | 
| 465 |         QOrganizerItemId id; | 
| 466 |         inBufferStream >> id; | 
| 467 |         QVERIFY(id == nullId); | 
| 468 |     } | 
| 469 |  | 
| 470 |     { | 
| 471 |         QOrganizerItemId nullid; | 
| 472 |         QByteArray buffer; | 
| 473 |         QDataStream outBufferStream(&buffer, QIODevice::WriteOnly); | 
| 474 |         outBufferStream << nullid; | 
| 475 |         QVERIFY(buffer.length() > 0); | 
| 476 |  | 
| 477 |         // cannot stream in local ids; must stream in entire ids. | 
| 478 |         //QDataStream inBufferStream(buffer); | 
| 479 |         //QOrganizerItemId id; | 
| 480 |         //inBufferStream >> id; | 
| 481 |         //QVERIFY(id == nullid); | 
| 482 |     } | 
| 483 |  | 
| 484 |     { | 
| 485 |         QOrganizerCollectionId nullId; | 
| 486 |         QByteArray buffer; | 
| 487 |         QDataStream outBufferStream(&buffer, QIODevice::WriteOnly); | 
| 488 |         outBufferStream << nullId; | 
| 489 |         QVERIFY(buffer.length() > 0); | 
| 490 |  | 
| 491 |         QDataStream inBufferStream(buffer); | 
| 492 |         QOrganizerCollectionId id; | 
| 493 |         inBufferStream >> id; | 
| 494 |         QVERIFY(id == nullId); | 
| 495 |     } | 
| 496 |  | 
| 497 |     { | 
| 498 |         QOrganizerCollectionId nullLocalId; | 
| 499 |         QByteArray buffer; | 
| 500 |         QDataStream outBufferStream(&buffer, QIODevice::WriteOnly); | 
| 501 |         outBufferStream << nullLocalId; | 
| 502 |         QVERIFY(buffer.length() > 0); | 
| 503 |  | 
| 504 |         // cannot stream in local ids; must stream in entire ids. | 
| 505 |         //QDataStream inBufferStream(buffer); | 
| 506 |         //QOrganizerCollectionLocalId id; | 
| 507 |         //inBufferStream >> id; | 
| 508 |         //QVERIFY(id == nullLocalId); | 
| 509 |     } | 
| 510 |     */ | 
| 511 | } | 
| 512 |  | 
| 513 | void tst_QOrganizerManager::uriParsing() | 
| 514 | { | 
| 515 |     QFETCH(QString, uri); | 
| 516 |     QFETCH(bool, good); | 
| 517 |     QFETCH(QString, manager); | 
| 518 |     QFETCH(tst_QOrganizerManager_QStringMap, parameters); | 
| 519 |  | 
| 520 |     QString outmanager; | 
| 521 |     QMap<QString, QString> outparameters; | 
| 522 |  | 
| 523 |     if (good) { | 
| 524 |         /* Good split */ | 
| 525 |         /* Test splitting */ | 
| 526 |         QVERIFY(QOrganizerManager::parseUri(uri, 0, 0)); // no out parms | 
| 527 |  | 
| 528 |         // 1 out param | 
| 529 |         QVERIFY(QOrganizerManager::parseUri(uri, &outmanager, 0)); | 
| 530 |         QCOMPARE(manager, outmanager); | 
| 531 |         QVERIFY(QOrganizerManager::parseUri(uri, 0, &outparameters)); | 
| 532 |  | 
| 533 |         QCOMPARE(parameters, outparameters); | 
| 534 |  | 
| 535 |         outmanager.clear(); | 
| 536 |         outparameters.clear(); | 
| 537 |         QVERIFY(QOrganizerManager::parseUri(uri, &outmanager, &outparameters)); | 
| 538 |  | 
| 539 |         QCOMPARE(manager, outmanager); | 
| 540 |         QCOMPARE(parameters, outparameters); | 
| 541 |     } else { | 
| 542 |         /* bad splitting */ | 
| 543 |         outmanager.clear(); | 
| 544 |         outparameters.clear(); | 
| 545 |         QVERIFY(QOrganizerManager::parseUri(uri, 0, 0) == false); | 
| 546 |         QVERIFY(QOrganizerManager::parseUri(uri, &outmanager, 0) == false); | 
| 547 |         QVERIFY(outmanager.isEmpty()); | 
| 548 |         QVERIFY(QOrganizerManager::parseUri(uri, 0, &outparameters) == false); | 
| 549 |         QVERIFY(outparameters.isEmpty()); | 
| 550 |  | 
| 551 |         /* make sure the in parameters don't change with a bad split */ | 
| 552 |         outmanager = manager; | 
| 553 |         outparameters = parameters; | 
| 554 |         QVERIFY(QOrganizerManager::parseUri(uri, &outmanager, 0) == false); | 
| 555 |         QCOMPARE(manager, outmanager); | 
| 556 |         QVERIFY(QOrganizerManager::parseUri(uri, 0, &outparameters) == false); | 
| 557 |         QCOMPARE(parameters, outparameters); | 
| 558 |     } | 
| 559 | } | 
| 560 |  | 
| 561 | void tst_QOrganizerManager::ctors() | 
| 562 | { | 
| 563 |     /* test the different ctors to make sure we end up with the same uri */ | 
| 564 |     QVERIFY(QOrganizerManager::availableManagers().count() >= 1); // invalid, and probably something else | 
| 565 |     QVERIFY(QOrganizerManager::availableManagers().contains("invalid" )); | 
| 566 |     QString defaultStore = QOrganizerManager::availableManagers().value(i: 0); | 
| 567 |  | 
| 568 |     qDebug() << "Available managers:"  << QOrganizerManager::availableManagers(); | 
| 569 |  | 
| 570 |     QMap<QString, QString> randomParameters; | 
| 571 |     randomParameters.insert(akey: "something" , avalue: "old" ); | 
| 572 |     randomParameters.insert(akey: "something..." , avalue: "new" ); | 
| 573 |     randomParameters.insert(akey: "something " , avalue: "borrowed" ); | 
| 574 |     randomParameters.insert(akey: " something" , avalue: "blue" ); | 
| 575 |  | 
| 576 |     QObject parent; | 
| 577 |  | 
| 578 |     QOrganizerManager cm; // default | 
| 579 |     QOrganizerManager cm2(defaultStore); | 
| 580 |     QOrganizerManager cm3(defaultStore, QMap<QString, QString>()); | 
| 581 |     //QOrganizerManager cm4(cm.managerUri()); // should fail | 
| 582 |  | 
| 583 |     QScopedPointer<QOrganizerManager> cm5(QOrganizerManager::fromUri(uri: QOrganizerManager::buildUri(managerName: defaultStore, params: QMap<QString, QString>()))); | 
| 584 |     QScopedPointer<QOrganizerManager> cm6(QOrganizerManager::fromUri(uri: cm.managerUri())); // uri is not a name; should fail. | 
| 585 |     QScopedPointer<QOrganizerManager> cm9(QOrganizerManager::fromUri(uri: QString(), parent: &parent)); | 
| 586 |  | 
| 587 |     QVERIFY(cm9->parent() == &parent); | 
| 588 |  | 
| 589 |     /* OLD TEST WAS THIS: */ | 
| 590 |     //QCOMPARE(cm.managerUri(), cm2.managerUri()); | 
| 591 |     //QCOMPARE(cm.managerUri(), cm3.managerUri()); | 
| 592 |     //QCOMPARE(cm.managerUri(), cm5->managerUri()); | 
| 593 |     //QCOMPARE(cm.managerUri(), cm6->managerUri()); | 
| 594 |     //QCOMPARE(cm.managerUri(), cm9->managerUri()); | 
| 595 |     /* NEW TEST IS THIS: Test that the names of the managers are the same */ | 
| 596 |     QCOMPARE(cm.managerName(), cm2.managerName()); | 
| 597 |     QCOMPARE(cm.managerName(), cm3.managerName()); | 
| 598 |     QCOMPARE(cm.managerName(), cm5->managerName()); | 
| 599 |     QCOMPARE(cm.managerName(), cm6->managerName()); | 
| 600 |     QCOMPARE(cm.managerName(), cm9->managerName()); | 
| 601 |  | 
| 602 |     //QVERIFY(cm.managerUri() != cm4.managerUri()); | 
| 603 |  | 
| 604 |     /* Test that we get invalid stores when we do silly things */ | 
| 605 |     QOrganizerManager em("non existent" ); | 
| 606 |     QOrganizerManager em2("non existent" , QMap<QString, QString>()); | 
| 607 |     QOrganizerManager em3("memory" , randomParameters); | 
| 608 |  | 
| 609 |     /* Also invalid, since we don't have one of these anyway */ | 
| 610 |     QScopedPointer<QOrganizerManager> em4(QOrganizerManager::fromUri(uri: "invalid uri" )); | 
| 611 |     QScopedPointer<QOrganizerManager> em5(QOrganizerManager::fromUri(uri: QOrganizerManager::buildUri(managerName: "nonexistent" , params: QMap<QString, QString>()))); | 
| 612 |     QScopedPointer<QOrganizerManager> em6(QOrganizerManager::fromUri(uri: em3.managerUri())); | 
| 613 |  | 
| 614 |  | 
| 615 |     /* | 
| 616 |      * Sets of stores that should be equivalent: | 
| 617 |      * - 1, 2, 4, 5 | 
| 618 |      * - 3, 6 | 
| 619 |      */ | 
| 620 |  | 
| 621 |     /* First some URI testing for equivalent stores */ | 
| 622 |     QVERIFY(em.managerUri() == em2.managerUri()); | 
| 623 |     QVERIFY(em.managerUri() == em5->managerUri()); | 
| 624 |     QVERIFY(em.managerUri() == em4->managerUri()); | 
| 625 |     QVERIFY(em2.managerUri() == em4->managerUri()); | 
| 626 |     QVERIFY(em2.managerUri() == em5->managerUri()); | 
| 627 |     QVERIFY(em4->managerUri() == em5->managerUri()); | 
| 628 |  | 
| 629 |     QVERIFY(em3.managerUri() == em6->managerUri()); | 
| 630 |  | 
| 631 |     /* Test the stores that should not be the same */ | 
| 632 |     QVERIFY(em.managerUri() != em3.managerUri()); | 
| 633 |     QVERIFY(em.managerUri() != em6->managerUri()); | 
| 634 |  | 
| 635 |     /* now the components */ | 
| 636 |     QCOMPARE(em.managerName(), QString("invalid" )); | 
| 637 |     QCOMPARE(em2.managerName(), QString("invalid" )); | 
| 638 |     QCOMPARE(em3.managerName(), QString("memory" )); | 
| 639 |     QCOMPARE(em4->managerName(), QString("invalid" )); | 
| 640 |     QCOMPARE(em5->managerName(), QString("invalid" )); | 
| 641 |     QCOMPARE(em6->managerName(), QString("memory" )); | 
| 642 |     QCOMPARE(em.managerParameters(), tst_QOrganizerManager_QStringMap()); | 
| 643 |     QCOMPARE(em2.managerParameters(), tst_QOrganizerManager_QStringMap()); | 
| 644 |     QCOMPARE(em4->managerParameters(), tst_QOrganizerManager_QStringMap()); | 
| 645 |     QCOMPARE(em5->managerParameters(), tst_QOrganizerManager_QStringMap()); | 
| 646 |     QCOMPARE(em3.managerParameters(), em6->managerParameters()); // memory engine discards the given params, replaces with id. | 
| 647 |  | 
| 648 |  | 
| 649 |     // Finally test the platform specific engines are actually the defaults | 
| 650 |     QCOMPARE(defaultStore, QString("invalid" )); | 
| 651 | } | 
| 652 |  | 
| 653 | void tst_QOrganizerManager::doDump() | 
| 654 | { | 
| 655 |     // Only do this if it has been explicitly selected | 
| 656 |     if (QCoreApplication::arguments().contains(str: "doDump" )) { | 
| 657 |         QFETCH(QString, uri); | 
| 658 |         QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 659 |  | 
| 660 |         dumpOrganizerItems(cm: cm.data()); | 
| 661 |     } | 
| 662 | } | 
| 663 |  | 
| 664 | Q_DECLARE_METATYPE(QVariant) | 
| 665 |  | 
| 666 | void tst_QOrganizerManager::add() | 
| 667 | { | 
| 668 |     QFETCH(QString, uri); | 
| 669 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 670 |  | 
| 671 |     // Use note & todo item depending on backend support | 
| 672 |     QOrganizerItemType::ItemType type; | 
| 673 |     if (cm->supportedItemTypes().contains(t: QOrganizerItemType::TypeNote)) | 
| 674 |         type = QOrganizerItemType::TypeNote; | 
| 675 |     else if (cm->supportedItemTypes().contains(t: QOrganizerItemType::TypeTodo)) | 
| 676 |         type = QOrganizerItemType::TypeTodo; | 
| 677 |     else | 
| 678 |         QSKIP("This manager does not support note or todo item" ); | 
| 679 |  | 
| 680 |     QOrganizerItem item; | 
| 681 |     item.setType(type); | 
| 682 |     item.setDisplayLabel("This is a note" ); | 
| 683 |     item.setDescription("This note is a particularly notey note" ); | 
| 684 |     int currCount = cm->itemIds().count(); | 
| 685 |     QVERIFY(cm->saveItem(&item)); | 
| 686 |     QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 687 |  | 
| 688 |     QVERIFY(!item.id().managerUri().isEmpty()); | 
| 689 |     QVERIFY(!item.id().isNull()); | 
| 690 |     QCOMPARE(cm->itemIds().count(), currCount+1); | 
| 691 |  | 
| 692 |     QOrganizerItem added = cm->item(itemId: item.id()); | 
| 693 |     QVERIFY(added.id() == item.id()); | 
| 694 |  | 
| 695 |     if (!isSuperset(ca: added, cb: item)) { | 
| 696 |         // XXX TODO: fix the isSuperset so that it ignores timestamps. | 
| 697 |         //dumpOrganizerItems(cm.data()); | 
| 698 |         //dumpOrganizerItemDifferences(added, note); | 
| 699 |         QCOMPARE(added, item); | 
| 700 |     } | 
| 701 |  | 
| 702 |     // now try adding an item that does not exist in the database with non-zero id | 
| 703 |     QOrganizerItem nonexistentItem; | 
| 704 |     nonexistentItem.setType(type); | 
| 705 |     nonexistentItem.setDisplayLabel("Another note." ); | 
| 706 |     nonexistentItem.setDescription("This is `another note`'s description" ); | 
| 707 |     QVERIFY(cm->saveItem(&nonexistentItem));       // should work | 
| 708 |     QVERIFY(cm->removeItem(nonexistentItem.id())); // now nonexistentItem has an id which does not exist | 
| 709 |  | 
| 710 |     QVERIFY(!cm->saveItem(&nonexistentItem));      // hence, should fail | 
| 711 |     QCOMPARE(cm->error(), QOrganizerManager::DoesNotExistError); | 
| 712 |     nonexistentItem.setId(QOrganizerItemId()); | 
| 713 |     QVERIFY(cm->saveItem(&nonexistentItem));       // after setting id to zero, should save | 
| 714 |     QVERIFY(cm->removeItem(nonexistentItem.id())); | 
| 715 |  | 
| 716 |     // now try adding a "megaevent" | 
| 717 |     // - get list of all definitions supported by the manager | 
| 718 |     // - add one detail of each definition to a item | 
| 719 |     // - save the item | 
| 720 |     // - read it back | 
| 721 |     // - ensure that it's the same. | 
| 722 | #if 0 // This test is currently excluded; can it be reinstated? | 
| 723 |     QOrganizerEvent megaevent; | 
| 724 |     QMap<QString, QOrganizerItemDetailDefinition> defmap = cm->detailDefinitions(QOrganizerItemType::TypeEvent); | 
| 725 |     QList<QOrganizerItemDetailDefinition> defs = defmap.values(); | 
| 726 |     foreach (const QOrganizerItemDetailDefinition def, defs) { | 
| 727 |  | 
| 728 |         // This is probably read-only | 
| 729 |         if (def.name() == QOrganizerItemTimestamp::DefinitionName) | 
| 730 |             continue; | 
| 731 |  | 
| 732 |         // otherwise, create a new detail of the given type and save it to the item | 
| 733 |         QOrganizerItemDetail det(def.name()); | 
| 734 |         QMap<QString, QOrganizerItemDetailFieldDefinition> fieldmap = def.fields(); | 
| 735 |         QStringList fieldKeys = fieldmap.keys(); | 
| 736 |         foreach (const QString& fieldKey, fieldKeys) { | 
| 737 |             // get the field, and check to see that it's not constrained. | 
| 738 |             QOrganizerItemDetailFieldDefinition currentField = fieldmap.value(fieldKey); | 
| 739 |  | 
| 740 |             // Attempt to create a worthy value | 
| 741 |             if (!currentField.allowableValues().isEmpty()) { | 
| 742 |                 // we want to save a value that will be accepted. | 
| 743 |                 if (currentField.dataType() == QVariant::StringList) | 
| 744 |                     det.setValue(fieldKey, QStringList() << currentField.allowableValues().first().toString()); | 
| 745 |                 else if (currentField.dataType() == QVariant::List) | 
| 746 |                     det.setValue(fieldKey, QVariantList() << currentField.allowableValues().first()); | 
| 747 |                 else | 
| 748 |                     det.setValue(fieldKey, currentField.allowableValues().first()); | 
| 749 |             } else { | 
| 750 |                 // any value of the correct type will be accepted | 
| 751 |                 bool savedSuccessfully = false; | 
| 752 |                 QVariant dummyValue = QVariant(fieldKey); // try to get some unique string data | 
| 753 |                 if (currentField.dataType() < static_cast<int>(QVariant::UserType)) { | 
| 754 |                     QVariant::Type type = static_cast<QVariant::Type>(currentField.dataType()); | 
| 755 |                     // It is not a user-defined type | 
| 756 |                     if (dummyValue.canConvert(type)) { | 
| 757 |                         savedSuccessfully = dummyValue.convert(type); | 
| 758 |                         if (savedSuccessfully) { | 
| 759 |                             // we have successfully created a (supposedly) valid field for this detail. | 
| 760 |                             det.setValue(fieldKey, dummyValue); | 
| 761 |                             continue; | 
| 762 |                         } | 
| 763 |                     } | 
| 764 |  | 
| 765 |                     // nope, couldn't save the string value (test); try a date. | 
| 766 |                     dummyValue = QVariant(QDate::currentDate()); | 
| 767 |                     if (dummyValue.canConvert(type)) { | 
| 768 |                         savedSuccessfully = dummyValue.convert(type); | 
| 769 |                         if (savedSuccessfully) { | 
| 770 |                             // we have successfully created a (supposedly) valid field for this detail. | 
| 771 |                             det.setValue(fieldKey, dummyValue); | 
| 772 |                             continue; | 
| 773 |                         } | 
| 774 |                     } | 
| 775 |  | 
| 776 |                     // nope, couldn't convert a string or a date - try the integer value (42) | 
| 777 |                     dummyValue = QVariant(42); | 
| 778 |                     if (dummyValue.canConvert(type)) { | 
| 779 |                         savedSuccessfully = dummyValue.convert(type); | 
| 780 |                         if (savedSuccessfully) { | 
| 781 |                             // we have successfully created a (supposedly) valid field for this detail. | 
| 782 |                             det.setValue(fieldKey, dummyValue); | 
| 783 |                             continue; | 
| 784 |                         } | 
| 785 |                     } | 
| 786 |                 } | 
| 787 |  | 
| 788 |                 // if we get here, we don't know what sort of value can be saved... | 
| 789 |             } | 
| 790 |         } | 
| 791 |         if (!det.isEmpty()) | 
| 792 |             megaevent.saveDetail(&det); | 
| 793 |     } | 
| 794 |  | 
| 795 |     QVERIFY(cm->saveItem(&megaevent)); // must be able to save since built from definitions. | 
| 796 |     QOrganizerItem retrievedMegaitem = cm->item(megaevent.id()); | 
| 797 |     if (!isSuperset(retrievedMegaitem, megaevent)) { | 
| 798 |         dumpOrganizerItemDifferences(megaevent, retrievedMegaitem); | 
| 799 |     } | 
| 800 |  | 
| 801 |     // now a item with many details of a particular definition | 
| 802 |     // if the detail is not unique it should then support minumum of two of the same kind | 
| 803 |     // const int nrOfdetails = 2; | 
| 804 |     // XXX TODO. | 
| 805 | #endif | 
| 806 | } | 
| 807 |  | 
| 808 | void tst_QOrganizerManager::saveRecurrence() | 
| 809 | { | 
| 810 |     QFETCH(QString, uri); | 
| 811 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 812 |  | 
| 813 |     QOrganizerEvent event; | 
| 814 |     event.setDisplayLabel(QStringLiteral("meeting" )); | 
| 815 |     event.setStartDateTime(QDateTime(QDate(2010, 1, 1), QTime(11, 0, 0))); | 
| 816 |     event.setEndDateTime(QDateTime(QDate(2010, 1, 1), QTime(12, 0, 0))); | 
| 817 |     QOrganizerRecurrenceRule rrule; | 
| 818 |     rrule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 819 |     rrule.setLimit(QDate(2011, 1, 1)); | 
| 820 |     rrule.setInterval(2); | 
| 821 |     rrule.setDaysOfWeek(QSet<Qt::DayOfWeek>() << Qt::Monday << Qt::Tuesday); | 
| 822 |     rrule.setDaysOfMonth(QSet<int>() << 1 << 2); | 
| 823 |     rrule.setDaysOfYear(QSet<int>() << 1 << 2); | 
| 824 |     rrule.setMonthsOfYear(QSet<QOrganizerRecurrenceRule::Month>() | 
| 825 |             << QOrganizerRecurrenceRule::January | 
| 826 |             << QOrganizerRecurrenceRule::February); | 
| 827 |     rrule.setWeeksOfYear(QSet<int>() << 1 << 2); | 
| 828 |     rrule.setFirstDayOfWeek(Qt::Tuesday); | 
| 829 |  | 
| 830 |     //this is disabled because certain backend doesn't support it. | 
| 831 |     //rrule.setPositions(QSet<int>() << 1 << 2); | 
| 832 |  | 
| 833 |     event.setRecurrenceRule(rrule); | 
| 834 |     event.setExceptionRule(rrule); | 
| 835 |     QSet<QDate> rdates; | 
| 836 |     rdates << QDate(2010, 1, 4) << QDate(2010, 4, 1); | 
| 837 |     event.setRecurrenceDates(rdates); | 
| 838 |     event.setExceptionDates(rdates); | 
| 839 |  | 
| 840 |     QVERIFY(cm->saveItem(&event)); | 
| 841 |     QOrganizerEvent savedEvent(cm->item(itemId: event.id())); | 
| 842 |     QCOMPARE(event.recurrenceRule(), savedEvent.recurrenceRule()); | 
| 843 |     QCOMPARE(event.exceptionRule(), savedEvent.exceptionRule()); | 
| 844 |     QCOMPARE(event.recurrenceDates(), savedEvent.recurrenceDates()); | 
| 845 |     QCOMPARE(event.exceptionDates(), savedEvent.exceptionDates()); | 
| 846 | } | 
| 847 |  | 
| 848 | void tst_QOrganizerManager::persistence() | 
| 849 | { | 
| 850 |     // Test that changes in one manager are visible from another | 
| 851 |     QFETCH(QString, uri); | 
| 852 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 853 |     if (cm->managerName() == "memory" ) | 
| 854 |         return; // memory engine is not persistent | 
| 855 |  | 
| 856 |     cm->removeItems(itemIds: cm->itemIds()); | 
| 857 |     QScopedPointer<QOrganizerManager> cm2(QOrganizerManager::fromUri(uri)); | 
| 858 |     QCOMPARE(cm->items().size(), 0); | 
| 859 |  | 
| 860 |     // Add an event | 
| 861 |     QOrganizerEvent event; | 
| 862 |     event.setDisplayLabel(QStringLiteral("meeting" )); | 
| 863 |     event.setStartDateTime(QDateTime(QDate(2010, 1, 1), QTime(11, 0, 0))); | 
| 864 |     event.setEndDateTime(QDateTime(QDate(2010, 1, 1), QTime(12, 0, 0))); | 
| 865 |     QVERIFY(cm->saveItem(&event)); | 
| 866 |     QTest::qWait(ms: 500); | 
| 867 |     QCOMPARE(cm->items().size(), 1); | 
| 868 |     QCOMPARE(cm2->items().size(), 1); | 
| 869 |  | 
| 870 |     // Remove the event | 
| 871 |     cm->removeItems(itemIds: cm->itemIds()); | 
| 872 |     QTest::qWait(ms: 500); | 
| 873 |     QCOMPARE(cm->items().size(), 0); | 
| 874 |     QCOMPARE(cm2->items().size(), 0); | 
| 875 |  | 
| 876 | //#if 0 | 
| 877 |     // This is disabled because it'll fail on managers that don't support collections | 
| 878 |  | 
| 879 |     // Remove all non-default collections | 
| 880 |     QList<QOrganizerCollection> collections(cm->collections()); | 
| 881 |     QOrganizerCollectionId defaultCollectionId(cm->defaultCollectionId()); | 
| 882 |     foreach (const QOrganizerCollection &col, collections) { | 
| 883 |         QOrganizerCollectionId id(col.id()); | 
| 884 |         if (id != defaultCollectionId) | 
| 885 |             cm->removeCollection(collectionId: id); | 
| 886 |     } | 
| 887 |     QTest::qWait(ms: 500); | 
| 888 |     QCOMPARE(cm2->collections().size(), cm->collections().size()); | 
| 889 |  | 
| 890 |     QOrganizerCollection collection; | 
| 891 |     collection.setMetaData(key: QOrganizerCollection::KeyName, QStringLiteral("test collection" )); | 
| 892 |     QVERIFY(cm->saveCollection(&collection)); | 
| 893 |     QTest::qWait(ms: 500); | 
| 894 |     QCOMPARE(cm2->collections().size(), cm->collections().size()); | 
| 895 | //#endif | 
| 896 | } | 
| 897 |  | 
| 898 | void tst_QOrganizerManager::addExceptions() | 
| 899 | { | 
| 900 |     QFETCH(QString, uri); | 
| 901 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 902 |  | 
| 903 |     QOrganizerEvent event; | 
| 904 |     event.setDisplayLabel(QStringLiteral("meeting" )); | 
| 905 |     event.setStartDateTime(QDateTime(QDate(2010, 1, 1), QTime(11, 0, 0))); | 
| 906 |     event.setEndDateTime(QDateTime(QDate(2010, 1, 1), QTime(12, 0, 0))); | 
| 907 |     QOrganizerRecurrenceRule rrule; | 
| 908 |     rrule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 909 |     rrule.setLimit(3); | 
| 910 |     event.setRecurrenceRule(rrule); | 
| 911 |     QVERIFY(cm->saveItem(&event)); | 
| 912 |     QVERIFY(!event.id().isNull()); | 
| 913 |     event = cm->item(itemId: event.id()); | 
| 914 |     // the guid must be set so when it is exported to iCalendar, the relationship can be represented | 
| 915 |     QVERIFY(!event.guid().isEmpty()); | 
| 916 |  | 
| 917 |     QList<QOrganizerItem> items = | 
| 918 |         cm->itemOccurrences(parentItem: event, startDateTime: QDateTime(QDate(2010, 1, 1), QTime(0, 0, 0)), | 
| 919 |                                  endDateTime: QDateTime(QDate(2010, 2, 1), QTime(0, 0, 0))); | 
| 920 |     QCOMPARE(items.size(), 3); | 
| 921 |     QOrganizerItem secondItem = items.at(i: 1); | 
| 922 |     QCOMPARE(secondItem.type(), QOrganizerItemType::TypeEventOccurrence); | 
| 923 |     QOrganizerEventOccurrence secondEvent = static_cast<QOrganizerEventOccurrence>(secondItem); // not sure this is the best way... | 
| 924 |     QCOMPARE(secondEvent.startDateTime(), QDateTime(QDate(2010, 1, 8), QTime(11, 0, 0))); | 
| 925 |     QCOMPARE(secondEvent.id(), QOrganizerItemId()); | 
| 926 |     QCOMPARE(secondEvent.parentId(), event.id()); | 
| 927 |  | 
| 928 |     // save a change to an occurrence's detail (ie. create an exception) | 
| 929 |     secondEvent.setDisplayLabel(QStringLiteral("seminar" )); | 
| 930 |     QVERIFY(cm->saveItem(&secondEvent)); | 
| 931 |     event = cm->item(itemId: event.id()); // reload the event to pick up any changed exception dates. | 
| 932 |     items = cm->itemOccurrences(parentItem: event, startDateTime: QDateTime(QDate(2010, 1, 1), QTime(0, 0, 0)), | 
| 933 |                                      endDateTime: QDateTime(QDate(2010, 2, 1), QTime(0, 0, 0))); | 
| 934 |     QCOMPARE(items.size(), 3); // shouldn't change the count. | 
| 935 |  | 
| 936 |     // save a change to an occurrence's time | 
| 937 |     QOrganizerEventOccurrence thirdEvent = static_cast<QOrganizerEventOccurrence>(items.at(i: 2)); | 
| 938 |     QCOMPARE(thirdEvent.id(), QOrganizerItemId()); | 
| 939 |     QCOMPARE(thirdEvent.parentId(), event.id()); | 
| 940 |     thirdEvent.setStartDateTime(QDateTime(QDate(2010, 1, 15), QTime(13, 0, 0))); | 
| 941 |     thirdEvent.setEndDateTime(QDateTime(QDate(2010, 1, 15), QTime(14, 0, 0))); | 
| 942 |     QVERIFY(cm->saveItem(&thirdEvent)); | 
| 943 |     event = cm->item(itemId: event.id()); // reload the event to pick up any changed exception dates. | 
| 944 |     items = cm->itemOccurrences(parentItem: event, startDateTime: QDateTime(QDate(2010, 1, 1), QTime(0, 0, 0)), | 
| 945 |                                      endDateTime: QDateTime(QDate(2010, 2, 1), QTime(0, 0, 0))); | 
| 946 |     QCOMPARE(items.size(), 3); // shouldn't change the count. | 
| 947 |  | 
| 948 |     QOrganizerItem firstItem; | 
| 949 |     bool foundFirst = false; | 
| 950 |     bool foundSecond = false; | 
| 951 |     bool foundThird = false; | 
| 952 |     foreach (const QOrganizerItem& item, items) { | 
| 953 |         if (item.id().isNull()) { | 
| 954 |             foundFirst = true; | 
| 955 |             firstItem = item; | 
| 956 |         } | 
| 957 |  | 
| 958 |         if (item.id() == secondEvent.id()) { | 
| 959 |             foundSecond = true; | 
| 960 |             secondEvent = item; | 
| 961 |         } | 
| 962 |  | 
| 963 |         if (item.id() == thirdEvent.id()) { | 
| 964 |             foundThird = true; | 
| 965 |             thirdEvent = item; | 
| 966 |         } | 
| 967 |     } | 
| 968 |  | 
| 969 |     // check that saving an exception doesn't change other items | 
| 970 |     QVERIFY(foundFirst); // there should still be one "generated" occurrence | 
| 971 |     QCOMPARE(firstItem.displayLabel(), QStringLiteral("meeting" )); // and it should have the original label. | 
| 972 |     // item occurrences which are not exceptions should have zero id | 
| 973 |     QVERIFY(firstItem.id().isNull()); | 
| 974 |  | 
| 975 |     // the exception's changes have been persisted | 
| 976 |     QVERIFY(foundSecond); | 
| 977 |     QCOMPARE(secondEvent.displayLabel(), QStringLiteral("seminar" )); | 
| 978 |     // item occurrences which are persisted exceptions should have non-zero id | 
| 979 |     QVERIFY(!secondEvent.id().isNull()); | 
| 980 |  | 
| 981 |     QVERIFY(foundThird); | 
| 982 |     QCOMPARE(thirdEvent.startDateTime(), QDateTime(QDate(2010, 1, 15), QTime(13, 0, 0))); | 
| 983 |     QCOMPARE(thirdEvent.endDateTime(), QDateTime(QDate(2010, 1, 15), QTime(14, 0, 0))); | 
| 984 |     QVERIFY(!thirdEvent.id().isNull()); | 
| 985 |  | 
| 986 |     // remove persisted exception, it should not modify parent item's exception dates | 
| 987 |     cm->removeItem(itemId: secondEvent.id()); | 
| 988 |     event = cm->item(itemId: event.id()); // reload the event to pick up any changed exception dates. | 
| 989 |     items = cm->itemOccurrences(parentItem: event, startDateTime: QDateTime(QDate(2010, 1, 1), QTime(0, 0, 0)), | 
| 990 |                                      endDateTime: QDateTime(QDate(2010, 2, 1), QTime(0, 0, 0))); | 
| 991 |     QCOMPARE(items.size(), 2); // shouldn't change the count. | 
| 992 |  | 
| 993 |     // remove the parent item, persisted exceptions should be removed also | 
| 994 |  | 
| 995 |     cm->removeItem(itemId: event.id()); | 
| 996 |     QVERIFY(cm->item(thirdEvent.id()).isEmpty()); | 
| 997 |  | 
| 998 | } | 
| 999 |  | 
| 1000 | void tst_QOrganizerManager::modifyRecurrence() | 
| 1001 | { | 
| 1002 |     QFETCH(QString, uri); | 
| 1003 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 1004 |  | 
| 1005 |     QOrganizerEvent event; | 
| 1006 |     event.setDisplayLabel(QStringLiteral("recurring meeting" )); | 
| 1007 |     event.setStartDateTime(QDateTime(QDate(2010, 1, 1), QTime(11, 0, 0))); | 
| 1008 |     event.setEndDateTime(QDateTime(QDate(2010, 1, 1), QTime(12, 0, 0))); | 
| 1009 |     QOrganizerRecurrenceRule rrule; | 
| 1010 |     rrule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 1011 |     rrule.setLimit(QDate(2014, 1, 1)); | 
| 1012 |     event.setRecurrenceRule(rrule); | 
| 1013 |     QVERIFY(cm->saveItem(&event)); | 
| 1014 |     QVERIFY(!event.id().isNull()); | 
| 1015 |     event = cm->item(itemId: event.id()); | 
| 1016 |     // the guid must be set so when it is exported to iCalendar, the relationship can be represented | 
| 1017 |     QVERIFY(!event.guid().isEmpty()); | 
| 1018 |     QList<QOrganizerItem> items = cm->itemOccurrences(parentItem: event); | 
| 1019 |     QCOMPARE(items.size(), 5); | 
| 1020 |     QOrganizerItem secondItem = items.at(i: 1); | 
| 1021 |     QCOMPARE(secondItem.type(), QOrganizerItemType::TypeEventOccurrence); | 
| 1022 |     QOrganizerEventOccurrence secondEvent = static_cast<QOrganizerEventOccurrence>(secondItem); // not sure this is the best way... | 
| 1023 |     QCOMPARE(secondEvent.startDateTime(), QDateTime(QDate(2011, 1, 1), QTime(11, 0, 0))); | 
| 1024 |     QCOMPARE(secondEvent.id(), QOrganizerItemId()); | 
| 1025 |     QCOMPARE(secondEvent.parentId(), event.id()); | 
| 1026 |  | 
| 1027 |     // save a change to an occurrence's detail (ie. create an exception) | 
| 1028 |     secondEvent.setDisplayLabel(QStringLiteral("exceptional display label" )); | 
| 1029 |     QVERIFY(cm->saveItem(&secondEvent)); | 
| 1030 |     event = cm->item(itemId: event.id()); // reload the event to pick up any changed exception dates. | 
| 1031 |     items = cm->itemOccurrences(parentItem: event); | 
| 1032 |     QCOMPARE(items.size(), 5); // shouldn't change the count. | 
| 1033 |  | 
| 1034 |     // save a change to an occurrence's time | 
| 1035 |     QOrganizerEventOccurrence thirdEvent = static_cast<QOrganizerEventOccurrence>(items.at(i: 2)); | 
| 1036 |     QCOMPARE(thirdEvent.id(), QOrganizerItemId()); | 
| 1037 |     QCOMPARE(thirdEvent.parentId(), event.id()); | 
| 1038 |     thirdEvent.setStartDateTime(QDateTime(QDate(2012, 1, 2), QTime(15, 0, 0))); | 
| 1039 |     thirdEvent.setEndDateTime(QDateTime(QDate(2012, 1, 2), QTime(16, 0, 0))); | 
| 1040 |     QVERIFY(cm->saveItem(&thirdEvent)); | 
| 1041 |     event = cm->item(itemId: event.id()); // reload the event to pick up any changed exception dates. | 
| 1042 |     items = cm->itemOccurrences(parentItem: event); | 
| 1043 |     QCOMPARE(items.size(), 5); // shouldn't change the count. | 
| 1044 |  | 
| 1045 |     QCOMPARE(items[0].id(), QOrganizerItemId()); | 
| 1046 |     QCOMPARE(items[1].id(), secondEvent.id()); | 
| 1047 |     QCOMPARE(items[2].id(), thirdEvent.id()); | 
| 1048 |     QCOMPARE(items[3].id(), QOrganizerItemId()); | 
| 1049 |     QCOMPARE(items[4].id(), QOrganizerItemId()); | 
| 1050 |  | 
| 1051 |     // modify recurrence rule | 
| 1052 |     rrule.setLimit(QDate(2011, 1, 1)); | 
| 1053 |     event.setRecurrenceRule(rrule); | 
| 1054 |     QVERIFY(cm->saveItem(&event)); | 
| 1055 |     items = cm->itemOccurrences(parentItem: event); | 
| 1056 |     QCOMPARE(items.size(), 2); // only one generated and one exception should be left | 
| 1057 |  | 
| 1058 |     // use different function to fetch events | 
| 1059 |     items = cm->items(); | 
| 1060 |     QCOMPARE(items.size(), 2); // only one generated and one exception should be left | 
| 1061 | } | 
| 1062 |  | 
| 1063 |  | 
| 1064 | /*test ItemOccurrences function maxCount parameters*/ | 
| 1065 | void tst_QOrganizerManager::testItemOccurrences() | 
| 1066 | { | 
| 1067 |     //Get the uri value | 
| 1068 |     QFETCH (QString, uri); | 
| 1069 |     //Create the QOrganizerManager | 
| 1070 |     QScopedPointer<QOrganizerManager> cm (QOrganizerManager::fromUri (uri)); | 
| 1071 |  | 
| 1072 |     //Create the weekly recurrence event data that is used by the test | 
| 1073 |     QOrganizerEvent event; | 
| 1074 |     event.setDisplayLabel (QStringLiteral ("meeting" )); | 
| 1075 |     event.setStartDateTime (QDateTime (QDate (2010, 1, 1), QTime (11, 0, 0))); | 
| 1076 |     event.setEndDateTime (QDateTime (QDate (2010, 1, 1), QTime (12, 0, 0))); | 
| 1077 |  | 
| 1078 |     //Create weekly recurrence rule and count limit is 3 | 
| 1079 |     QOrganizerRecurrenceRule rrule; | 
| 1080 |     rrule.setFrequency (QOrganizerRecurrenceRule::Weekly); | 
| 1081 |     rrule.setLimit (3); | 
| 1082 |     event.setRecurrenceRule (rrule); | 
| 1083 |  | 
| 1084 |     //Save the event | 
| 1085 |     QVERIFY (cm->saveItem (&event)); | 
| 1086 |  | 
| 1087 |     //Varify the event data guid | 
| 1088 |     QVERIFY (!event.id().isNull ()); | 
| 1089 |     event = cm->item (itemId: event.id ()); | 
| 1090 |     //The guid(Globally unique identifier) must be set so when it is exported to iCalendar, the relationship can be represented | 
| 1091 |     QVERIFY (!event.guid().isEmpty ()); | 
| 1092 |  | 
| 1093 |     //Use default parameter value to fetch | 
| 1094 |     QList<QOrganizerItem> items = cm->itemOccurrences( | 
| 1095 |                                             parentItem: event,     //parantItem | 
| 1096 |                                             startDateTime: QDateTime (QDate (2010, 1, 1), QTime (0, 0, 0)), //start date | 
| 1097 |                                             endDateTime: QDateTime (QDate (2010, 2, 1), QTime (0, 0, 0))  //end date | 
| 1098 |                                             ); | 
| 1099 |     //The result should be same as rrule's limitation 3 | 
| 1100 |     QCOMPARE(items.size(), 3); | 
| 1101 |  | 
| 1102 |     //Assign maxCount negative value to get same result as default value | 
| 1103 |     QList<QOrganizerItem> items2 = cm->itemOccurrences( | 
| 1104 |                                             parentItem: event,     //parantItem | 
| 1105 |                                             startDateTime: QDateTime (QDate (2010, 1, 1), QTime (0, 0, 0)), //start date | 
| 1106 |                                             endDateTime: QDateTime (QDate (2010, 2, 1), QTime (0, 0, 0)), //end date | 
| 1107 |                                             maxCount: -5   //maxCount | 
| 1108 |                                             ); | 
| 1109 |     //The result should be same as rrule's limitation | 
| 1110 |     QCOMPARE(items2.size(), 3); | 
| 1111 |  | 
| 1112 |     //Assign maxCount bigger value to get same result as default value | 
| 1113 |     QList<QOrganizerItem> items3 = cm->itemOccurrences( | 
| 1114 |                                             parentItem: event, | 
| 1115 |                                             startDateTime: QDateTime (QDate (2010, 1, 1), QTime (0, 0, 0)), | 
| 1116 |                                             endDateTime: QDateTime (QDate (2010, 2, 1), QTime (0, 0, 0)), | 
| 1117 |                                             maxCount: 4 | 
| 1118 |                                             ); | 
| 1119 |     //The result should be same as rrule's limitation since the maxCount is bigger than the actually data | 
| 1120 |     QCOMPARE(items3.size(), 3); | 
| 1121 |  | 
| 1122 | /*------------------------------------------------------------------------ | 
| 1123 |     Create 2nd Daily event data, now We have Weekly and Daily 2 different events and make the situation more complex. | 
| 1124 |     maxCount is also smaller than the actual item data. | 
| 1125 | */ | 
| 1126 |     //Create 2nd Daily event data and limitation is 20 | 
| 1127 |     QOrganizerEvent event2; | 
| 1128 |     event2.setDisplayLabel (QStringLiteral ("meeting2" )); | 
| 1129 |     event2.setStartDateTime (QDateTime (QDate (2010, 1, 1), QTime (11, 0, 0))); | 
| 1130 |     event2.setEndDateTime (QDateTime (QDate (2010, 1, 1), QTime (12, 0, 0))); | 
| 1131 |     rrule.setFrequency (QOrganizerRecurrenceRule::Daily); | 
| 1132 |     rrule.setLimit (20); | 
| 1133 |     event2.setRecurrenceRule (rrule); | 
| 1134 |     QVERIFY (cm->saveItem (&event2)); | 
| 1135 |     event2 = cm->item (itemId: event2.id ()); | 
| 1136 |     // The guid must be set so when it is exported to iCalendar, the relationship can be represented | 
| 1137 |     QVERIFY (!event2.guid().isEmpty ()); | 
| 1138 |  | 
| 1139 |     //Use default maxCount parameter value to fetch | 
| 1140 |     QList<QOrganizerItem> items4 = cm->itemOccurrences( | 
| 1141 |                                             parentItem: event2, | 
| 1142 |                                             startDateTime: QDateTime (QDate (2010, 1, 1), QTime (0, 0, 0)), | 
| 1143 |                                             endDateTime: QDateTime (QDate (2010, 2, 1), QTime (0, 0, 0)) | 
| 1144 |                                             ); | 
| 1145 |  | 
| 1146 |     //The result should be same as rrule's limitation 20 | 
| 1147 |     QCOMPARE (items4.size (), 20); | 
| 1148 |  | 
| 1149 |     //Normal daily event items fetch with 5 max count limitation | 
| 1150 |     QList<QOrganizerItem> items5 = cm->itemOccurrences( | 
| 1151 |                                             parentItem: event2, | 
| 1152 |                                             startDateTime: QDateTime (QDate (2010, 1, 1), QTime (0, 0, 0)), | 
| 1153 |                                             endDateTime: QDateTime (QDate (2010, 2, 1), QTime (0, 0, 0)), | 
| 1154 |                                             maxCount: 5 | 
| 1155 |                                             ); | 
| 1156 |     //The result should be same as maxCount 5 which is smaller than event rrule's limitation 20 | 
| 1157 |     QCOMPARE (items5.size (), 5); | 
| 1158 |  | 
| 1159 |     //Normal daily event items fetch with 0 max count limitation | 
| 1160 |     QList<QOrganizerItem> items6 = cm->itemOccurrences( | 
| 1161 |                                             parentItem: event2, | 
| 1162 |                                             startDateTime: QDateTime (QDate (2010, 1, 1), QTime (0, 0, 0)), | 
| 1163 |                                             endDateTime: QDateTime (QDate (2010, 2, 1), QTime (0, 0, 0)), | 
| 1164 |                                             maxCount: 0 | 
| 1165 |                                             ); | 
| 1166 |     //The result should be 0 | 
| 1167 |     QCOMPARE (items6.size (), 0); | 
| 1168 | } | 
| 1169 |  | 
| 1170 | void tst_QOrganizerManager::addExceptionsWithGuid() | 
| 1171 | { | 
| 1172 |     // It should be possible to save an exception that has at least an originalDate and either a | 
| 1173 |     // guid or a parentId.  If guid and parentId are both specified, the client should | 
| 1174 |     // ensure they are consistent and the manager should fail if they are not.  If only one of the | 
| 1175 |     // guid or parentId are specified, the manager should generate the other one. | 
| 1176 |     // This test case tests all of this. | 
| 1177 |     QFETCH(QString, uri); | 
| 1178 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 1179 |  | 
| 1180 |     // Set up some recurring items | 
| 1181 |     QOrganizerEvent christmas; | 
| 1182 |     christmas.setGuid("christmas" ); | 
| 1183 |     christmas.setStartDateTime(QDateTime(QDate(2009, 12, 25), QTime(0, 0, 0))); | 
| 1184 |     christmas.setEndDateTime(QDateTime(QDate(2009, 12, 26), QTime(0, 0, 0))); | 
| 1185 |     christmas.setDisplayLabel(QStringLiteral("Christmas" )); | 
| 1186 |     QOrganizerRecurrenceRule rrule; | 
| 1187 |     rrule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 1188 |     christmas.setRecurrenceRule(rrule); | 
| 1189 |     QVERIFY(cm->saveItem(&christmas)); | 
| 1190 |     QVERIFY(!christmas.id().managerUri().isEmpty()); | 
| 1191 |     QVERIFY(!christmas.id().isNull()); | 
| 1192 |  | 
| 1193 |     QOrganizerEvent newYearsDay; | 
| 1194 |     newYearsDay.setGuid("newyear" ); | 
| 1195 |     newYearsDay.setStartDateTime(QDateTime(QDate(2010, 1, 1), QTime(0, 0, 0))); | 
| 1196 |     newYearsDay.setEndDateTime(QDateTime(QDate(2010, 1, 2), QTime(0, 0, 0))); | 
| 1197 |     newYearsDay.setDisplayLabel(QStringLiteral("New Years Day" )); | 
| 1198 |     newYearsDay.setRecurrenceRule(rrule); | 
| 1199 |     QVERIFY(cm->saveItem(&newYearsDay)); | 
| 1200 |  | 
| 1201 |     QOrganizerTodo report; | 
| 1202 |     report.setGuid("report" ); | 
| 1203 |     report.setDueDateTime(QDateTime(QDate(2010, 1, 11), QTime(0, 0, 0))); | 
| 1204 |     report.setDisplayLabel(QStringLiteral("Report" )); | 
| 1205 |     QVERIFY(cm->saveItem(&report)); | 
| 1206 |  | 
| 1207 |     // The tests: | 
| 1208 |     // exception with no guid or parentId fails | 
| 1209 |     QOrganizerEventOccurrence exception; | 
| 1210 |     exception.setOriginalDate(QDate(2010, 12, 25)); | 
| 1211 |     exception.setStartDateTime(QDateTime(QDate(2010, 12, 25), QTime(0, 0, 0))); | 
| 1212 |     exception.setEndDateTime(QDateTime(QDate(2010, 12, 26), QTime(0, 0, 0))); | 
| 1213 |     exception.setDisplayLabel(QStringLiteral("Xmas" )); | 
| 1214 | //    if (cm->detailDefinitions(QOrganizerItemType::TypeEventOccurrence).contains(QOrganizerItemComment::DefinitionName)) | 
| 1215 | //        exception.addComment(QLatin1String("With the in-laws")); | 
| 1216 |     QVERIFY(!cm->saveItem(&exception)); | 
| 1217 |     QCOMPARE(cm->error(), QOrganizerManager::InvalidOccurrenceError); | 
| 1218 |  | 
| 1219 |     // exception with invalid guid fails | 
| 1220 |     exception.setId(QOrganizerItemId()); | 
| 1221 |     exception.setGuid(QStringLiteral("halloween" )); | 
| 1222 |     QVERIFY(!cm->saveItem(&exception)); | 
| 1223 |     QCOMPARE(cm->error(), QOrganizerManager::InvalidOccurrenceError); | 
| 1224 |  | 
| 1225 |     // with the guid set, it should work | 
| 1226 |     exception.setId(QOrganizerItemId()); | 
| 1227 |     exception.setGuid(QStringLiteral("christmas" )); | 
| 1228 |     QVERIFY(cm->saveItem(&exception)); | 
| 1229 |     QVERIFY(!exception.id().isNull()); | 
| 1230 |     QOrganizerEventOccurrence savedException = cm->item(itemId: exception.id()); | 
| 1231 |     QCOMPARE(savedException.parentId(), christmas.id()); // parentId should be set by manager | 
| 1232 |  | 
| 1233 |     // with the id, guid and the parentId all set and consistent, it should work | 
| 1234 |     exception = savedException; | 
| 1235 |     QVERIFY(cm->saveItem(&exception)); | 
| 1236 |     savedException = cm->item(itemId: exception.id()); | 
| 1237 |     QCOMPARE(savedException.parentId(), christmas.id()); | 
| 1238 |  | 
| 1239 |     // Make a fresh exception object on a fresh date to avoid clashing with the previously saved one | 
| 1240 |     // can't set parentId to a non-event | 
| 1241 |     QOrganizerEventOccurrence exception2; | 
| 1242 |     exception2.setOriginalDate(QDate(2011, 12, 25)); | 
| 1243 |     exception2.setStartDateTime(QDateTime(QDate(2011, 12, 25), QTime(0, 0, 0))); | 
| 1244 |     exception2.setEndDateTime(QDateTime(QDate(2011, 12, 26), QTime(0, 0, 0))); | 
| 1245 |     exception2.setDisplayLabel(QStringLiteral("XMas" )); | 
| 1246 | //    if (cm->detailDefinitions(QOrganizerItemType::TypeEventOccurrence).contains(QOrganizerItemComment::DefinitionName)) | 
| 1247 | //        exception2.addComment(QLatin1String("With the in-laws")); | 
| 1248 |     exception2.setParentId(report.id()); // report is not an event | 
| 1249 |     QVERIFY(!cm->saveItem(&exception2)); | 
| 1250 |     QCOMPARE(cm->error(), QOrganizerManager::InvalidOccurrenceError); | 
| 1251 |  | 
| 1252 |     // can't set guid to a non-event | 
| 1253 |     exception2.setGuid(QStringLiteral("report" )); | 
| 1254 |     exception2.setParentId(QOrganizerItemId()); | 
| 1255 |     QVERIFY(!cm->saveItem(&exception2)); | 
| 1256 |     QCOMPARE(cm->error(), QOrganizerManager::InvalidOccurrenceError); | 
| 1257 |  | 
| 1258 |     // can't make the guid inconsistent with the parentId | 
| 1259 |     exception2.setParentId(christmas.id()); | 
| 1260 |     exception2.setGuid(QStringLiteral("newyear" )); | 
| 1261 |     QVERIFY(!cm->saveItem(&exception2)); | 
| 1262 |     QCOMPARE(cm->error(), QOrganizerManager::InvalidOccurrenceError); | 
| 1263 |  | 
| 1264 |     // with just the parentId set to a valid parent, it should work | 
| 1265 |     exception2.setGuid(QStringLiteral("" )); | 
| 1266 |     QVERIFY(cm->saveItem(&exception2)); | 
| 1267 |     savedException = cm->item(itemId: exception2.id()); | 
| 1268 |     QCOMPARE(savedException.parentId(), christmas.id()); | 
| 1269 |     QCOMPARE(savedException.guid(), QStringLiteral("christmas" )); // guid should be set by manager | 
| 1270 |  | 
| 1271 |     // Make a fresh exception object on a fresh date to avoid clashing with the previously saved one | 
| 1272 |     // exception without originalDate fails | 
| 1273 |     QOrganizerEventOccurrence exception3; | 
| 1274 |     exception3.setStartDateTime(QDateTime(QDate(2012, 12, 25), QTime(0, 0, 0))); | 
| 1275 |     exception3.setEndDateTime(QDateTime(QDate(2012, 12, 26), QTime(0, 0, 0))); | 
| 1276 |     exception3.setDisplayLabel(QStringLiteral("XMas" )); | 
| 1277 | //    if (cm->detailDefinitions(QOrganizerItemType::TypeEventOccurrence).contains(QOrganizerItemComment::DefinitionName)) | 
| 1278 | //        exception3.addComment(QLatin1String("With the in-laws")); | 
| 1279 |     exception3.setParentId(christmas.id()); | 
| 1280 |     exception3.setGuid(QStringLiteral("christmas" )); | 
| 1281 |     QVERIFY(!cm->saveItem(&exception3)); | 
| 1282 |     QCOMPARE(cm->error(), QOrganizerManager::InvalidOccurrenceError); | 
| 1283 |  | 
| 1284 |     // with original date, guid and parentId set and consistent, and id=0, it should work | 
| 1285 |     exception3.setOriginalDate(QDate(2012, 12, 25)); | 
| 1286 |     QVERIFY(cm->saveItem(&exception3)); | 
| 1287 |     QVERIFY(!exception3.id().isNull()); | 
| 1288 |     savedException = cm->item(itemId: exception3.id()); | 
| 1289 |     QCOMPARE(savedException.parentId(), christmas.id()); | 
| 1290 | } | 
| 1291 |  | 
| 1292 | void tst_QOrganizerManager::update() | 
| 1293 | { | 
| 1294 |     QFETCH(QString, uri); | 
| 1295 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 1296 |  | 
| 1297 |     // Use note & todo item depending on backend support | 
| 1298 |     QOrganizerItemType::ItemType type; | 
| 1299 |     if (cm->supportedItemTypes().contains(t: QOrganizerItemType::TypeNote)) | 
| 1300 |         type = QOrganizerItemType::TypeNote; | 
| 1301 |     else if (cm->supportedItemTypes().contains(t: QOrganizerItemType::TypeTodo)) | 
| 1302 |         type = QOrganizerItemType::TypeTodo; | 
| 1303 |     else | 
| 1304 |         QSKIP("This manager does not support note or todo item" ); | 
| 1305 |  | 
| 1306 |     // Save a new item first | 
| 1307 |     QOrganizerItem item; | 
| 1308 |     item.setType(type); | 
| 1309 |     item.setDisplayLabel("Yet another note" ); | 
| 1310 |     item.setDescription("Surprisingly, this note is not a particularly notey note" ); | 
| 1311 |     QVERIFY(cm->saveItem(&item)); | 
| 1312 |     QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 1313 |  | 
| 1314 |     // Update name | 
| 1315 |     QOrganizerItemDescription descr = item.detail(detailType: QOrganizerItemDetail::TypeDescription); | 
| 1316 |     descr.setDescription("This note is now slightly noteworthy" ); | 
| 1317 |     item.saveDetail(detail: &descr); | 
| 1318 |     QVERIFY(cm->saveItem(&item)); | 
| 1319 |     QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 1320 |     descr.setDescription("This is a very noteworthy note" ); | 
| 1321 |     item.saveDetail(detail: &descr); | 
| 1322 |     QVERIFY(cm->saveItem(&item)); | 
| 1323 |     QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 1324 |     QOrganizerItem updated = cm->item(itemId: item.id()); | 
| 1325 |     QOrganizerItemDescription updatedDescr = updated.detail(detailType: QOrganizerItemDetail::TypeDescription); | 
| 1326 |     QCOMPARE(updatedDescr, descr); | 
| 1327 |  | 
| 1328 |     /* Create a recurring event, update an occurrence and save (should persist as an exceptional occurrence) */ | 
| 1329 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 1330 |     QOrganizerEvent recEvent; | 
| 1331 |     recEvent.setDescription("a recurring event" ); | 
| 1332 |     recEvent.setStartDateTime(QDateTime(QDate(2010, 10, 20), QTime(8, 0, 0))); | 
| 1333 |     recEvent.setEndDateTime(QDateTime(QDate(2010, 10, 20), QTime(10, 0, 0))); | 
| 1334 |     QOrganizerRecurrenceRule rrule; | 
| 1335 |     rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 1336 |     rrule.setLimit(3); | 
| 1337 |     recEvent.setRecurrenceRule(rrule); | 
| 1338 |     QVERIFY(cm->saveItem(&recEvent)); | 
| 1339 |     int persistentCount = cm->itemsForExport().size(); | 
| 1340 |     QCOMPARE(persistentCount, 1); // just the parent | 
| 1341 |     QList<QOrganizerItem> items = cm->items(); | 
| 1342 |     QCOMPARE(items.size(), 3); | 
| 1343 |     bool foundException = false; | 
| 1344 |     QOrganizerEventOccurrence exception; | 
| 1345 |     foreach (const QOrganizerEventOccurrence& curr, items) { | 
| 1346 |         if (curr.startDateTime() == QDateTime(QDate(2010, 10, 21), QTime(8, 0, 0))) { | 
| 1347 |             exception = curr; | 
| 1348 |             foundException = true; | 
| 1349 |             break; | 
| 1350 |         } | 
| 1351 |     } | 
| 1352 |     QVERIFY(foundException); | 
| 1353 |     exception.setDescription("different description" ); | 
| 1354 |     QVERIFY(cm->saveItem(&exception)); | 
| 1355 |     persistentCount = cm->itemsForExport().size(); | 
| 1356 |     QCOMPARE(persistentCount, 2); // parent plus one exception | 
| 1357 |     items = cm->items(); | 
| 1358 |     QCOMPARE(items.size(), 3); | 
| 1359 |     foreach (const QOrganizerEventOccurrence& curr, items) { | 
| 1360 |         if (curr.startDateTime() == QDateTime(QDate(2010, 10, 21), QTime(8, 0, 0))) { | 
| 1361 |             QVERIFY(!curr.id().isNull()); | 
| 1362 |             QCOMPARE(curr.description(), QStringLiteral("different description" )); | 
| 1363 |         } else { | 
| 1364 |             QVERIFY(curr.id().isNull()); | 
| 1365 |         } | 
| 1366 |     } | 
| 1367 |  | 
| 1368 |     /* Save a non-updated occurrence - should still persist as an exceptional occurrence */ | 
| 1369 |     QOrganizerEventOccurrence secondException; | 
| 1370 |     foreach (const QOrganizerEventOccurrence& curr, items) { | 
| 1371 |         if (curr.startDateTime() == QDateTime(QDate(2010, 10, 22), QTime(8, 0, 0))) { | 
| 1372 |             secondException = curr; | 
| 1373 |             foundException = true; | 
| 1374 |             break; | 
| 1375 |         } | 
| 1376 |     } | 
| 1377 |     QVERIFY(foundException); | 
| 1378 |     QVERIFY(cm->saveItem(&secondException)); // no changes, but should save as an exception anyway. | 
| 1379 |     persistentCount = cm->itemsForExport().size(); | 
| 1380 |     QCOMPARE(persistentCount, 3); // parent plus two exceptions | 
| 1381 |     items = cm->items(); | 
| 1382 |     QCOMPARE(items.size(), 3); | 
| 1383 |     foreach (const QOrganizerEventOccurrence& curr, items) { | 
| 1384 |         if (curr.startDateTime() == QDateTime(QDate(2010, 10, 20), QTime(8, 0, 0))) { | 
| 1385 |             QVERIFY(curr.id().isNull());  // only the first occurrence is not an exception. | 
| 1386 |         } else { | 
| 1387 |             QVERIFY(!curr.id().isNull()); // we have two exceptions this time | 
| 1388 |         } | 
| 1389 |     } | 
| 1390 | } | 
| 1391 |  | 
| 1392 | void tst_QOrganizerManager::remove() | 
| 1393 | { | 
| 1394 |     QFETCH(QString, uri); | 
| 1395 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 1396 |     // for fetch results | 
| 1397 |     QList<QOrganizerItem> items; | 
| 1398 |     // for removeItems request | 
| 1399 |     QList<QOrganizerItem> itemList; | 
| 1400 |  | 
| 1401 |     // Use note & todo item depending on backend support | 
| 1402 |     QOrganizerItemType::ItemType type; | 
| 1403 |     if (cm->supportedItemTypes().contains(t: QOrganizerItemType::TypeNote)) | 
| 1404 |         type = QOrganizerItemType::TypeNote; | 
| 1405 |     else if (cm->supportedItemTypes().contains(t: QOrganizerItemType::TypeTodo)) | 
| 1406 |         type = QOrganizerItemType::TypeTodo; | 
| 1407 |     else | 
| 1408 |         QSKIP("This manager does not support note or todo item" ); | 
| 1409 |  | 
| 1410 |     // Save a new item first | 
| 1411 |     QOrganizerItem item; | 
| 1412 |     item.setType(type); | 
| 1413 |     item.setDisplayLabel("Not another note" ); | 
| 1414 |     item.setDescription("Yes, another note!" ); | 
| 1415 |     QVERIFY(cm->saveItem(&item)); | 
| 1416 |     QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 1417 |     QVERIFY(item.id() != QOrganizerItemId()); | 
| 1418 |  | 
| 1419 |     // Remove the created item | 
| 1420 |     const int itemCount = cm->itemIds().count(); | 
| 1421 |     QVERIFY(cm->removeItem(item.id())); | 
| 1422 |     QCOMPARE(cm->itemIds().count(), itemCount - 1); | 
| 1423 |     QVERIFY(cm->item(item.id()).isEmpty()); | 
| 1424 |     QCOMPARE(cm->error(), QOrganizerManager::DoesNotExistError); | 
| 1425 |  | 
| 1426 |     //delete item not exist | 
| 1427 |     QVERIFY(!cm->removeItem(item.id())); | 
| 1428 |     QCOMPARE(cm->error(), QOrganizerManager::DoesNotExistError); | 
| 1429 |  | 
| 1430 |     //delete item id is empty | 
| 1431 |     QOrganizerItemId id; | 
| 1432 |     QVERIFY(!cm->removeItem(id)); | 
| 1433 |     QCOMPARE(cm->error(), QOrganizerManager::DoesNotExistError); | 
| 1434 |  | 
| 1435 |     // delete an event by item (not id) | 
| 1436 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 1437 |     QCOMPARE(cm->items().size(), 0); | 
| 1438 |     QOrganizerEvent event1; | 
| 1439 |     event1.setDisplayLabel("first event" ); | 
| 1440 |     QOrganizerEvent event2; | 
| 1441 |     event1.setDisplayLabel("second event" ); | 
| 1442 |     QOrganizerEvent event3; | 
| 1443 |     event1.setDisplayLabel("third event" ); | 
| 1444 |     itemList << event1 << event2 << event3; | 
| 1445 |     QVERIFY(cm->saveItems(&itemList)); | 
| 1446 |     QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 1447 |     items = cm->items(); | 
| 1448 |     QCOMPARE(cm->items().size(), 3); | 
| 1449 |     QVERIFY(cm->removeItem(&(items[2]))); | 
| 1450 |     items = cm->items(); | 
| 1451 |     QCOMPARE(cm->items().size(), 2); | 
| 1452 |     QVERIFY(cm->removeItems(&items)); | 
| 1453 |     items = cm->items(); | 
| 1454 |     QCOMPARE(cm->items().size(), 0); | 
| 1455 |  | 
| 1456 |     /* Create a recurring event, save an exception, remove the recurring event should remove all children occurrences incl. persisted exceptions. */ | 
| 1457 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 1458 |     QOrganizerEvent recEvent; | 
| 1459 |     recEvent.setDescription("a recurring event" ); | 
| 1460 |     recEvent.setStartDateTime(QDateTime(QDate(2010, 10, 20), QTime(8, 0, 0))); | 
| 1461 |     recEvent.setEndDateTime(QDateTime(QDate(2010, 10, 20), QTime(10, 0, 0))); | 
| 1462 |     QOrganizerRecurrenceRule rrule; | 
| 1463 |     rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 1464 |     rrule.setLimit(3); | 
| 1465 |     recEvent.setRecurrenceRule(rrule); | 
| 1466 |     QVERIFY(cm->saveItem(&recEvent)); | 
| 1467 |     items = cm->items(); | 
| 1468 |     QCOMPARE(items.size(), 3); | 
| 1469 |     QOrganizerEventOccurrence exception = items.at(i: 1); | 
| 1470 |     exception.setStartDateTime(QDateTime(QDate(2010, 10, 21), QTime(7, 0, 0))); | 
| 1471 |     QVERIFY(cm->saveItem(&exception)); | 
| 1472 |     items = cm->items(); | 
| 1473 |     QCOMPARE(items.size(), 3); | 
| 1474 |     QCOMPARE(cm->itemsForExport().size(), 2); | 
| 1475 |     QVERIFY(cm->removeItem(recEvent.id())); | 
| 1476 |     QCOMPARE(cm->itemsForExport().size(), 0); | 
| 1477 |     QCOMPARE(cm->items().size(), 0); | 
| 1478 |  | 
| 1479 |     /* Create a recurring event, save an exception, remove the saved exception should remove the persisted exception, but the exdate should remain in the parent */ | 
| 1480 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 1481 |     recEvent.setId(QOrganizerItemId()); | 
| 1482 |     recEvent.setDescription("a recurring event" ); | 
| 1483 |     recEvent.setStartDateTime(QDateTime(QDate(2010, 10, 20), QTime(8, 0, 0))); | 
| 1484 |     recEvent.setEndDateTime(QDateTime(QDate(2010, 10, 20), QTime(10, 0, 0))); | 
| 1485 |     rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 1486 |     rrule.setLimit(3); | 
| 1487 |     recEvent.setRecurrenceRule(rrule); | 
| 1488 |     QVERIFY(cm->saveItem(&recEvent)); | 
| 1489 |     items = cm->items(); | 
| 1490 |     QCOMPARE(items.size(), 3); | 
| 1491 |     exception = items.at(i: 1); | 
| 1492 |     exception.setStartDateTime(QDateTime(QDate(2010, 10, 21), QTime(7, 0, 0))); | 
| 1493 |     QVERIFY(cm->saveItem(&exception)); | 
| 1494 |     items = cm->items(); | 
| 1495 |     QCOMPARE(items.size(), 3); | 
| 1496 |     QCOMPARE(cm->itemsForExport().size(), 2); | 
| 1497 |     QVERIFY(cm->removeItem(exception.id())); | 
| 1498 |     QCOMPARE(cm->itemsForExport().size(), 1); // only parent remains as persistent | 
| 1499 |     items = cm->items(); | 
| 1500 |     QCOMPARE(items.size(), 2);          // the exception date remains in parent, so only 2 occurrences are generated. | 
| 1501 |  | 
| 1502 |     // Create a recurring event, remove a generated occurrence should add an exdate in the parent | 
| 1503 |     QOrganizerItem itemOccurrence = items[0]; | 
| 1504 |     cm->removeItem(item: &itemOccurrence); | 
| 1505 |     items = cm->items(); | 
| 1506 |     QCOMPARE(items.size(), 1); | 
| 1507 |  | 
| 1508 |     // Remove both parent item and generated occurrence in the same request | 
| 1509 |     // --> request should fail because | 
| 1510 |     itemList.clear(); | 
| 1511 |     itemList << recEvent << items[0]; | 
| 1512 |     QVERIFY(cm->removeItems(&itemList)); | 
| 1513 |     items = cm->items(); | 
| 1514 |     QCOMPARE(cm->items().size(), 0); | 
| 1515 | } | 
| 1516 |  | 
| 1517 | void tst_QOrganizerManager::batch() | 
| 1518 | { | 
| 1519 |     QFETCH(QString, uri); | 
| 1520 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 1521 |  | 
| 1522 |     /* First test null pointer operations */ | 
| 1523 |     QVERIFY(!cm->saveItems(NULL)); | 
| 1524 |     QVERIFY(cm->error() == QOrganizerManager::BadArgumentError); | 
| 1525 |  | 
| 1526 |     QVERIFY(!cm->removeItems(QList<QOrganizerItemId>())); | 
| 1527 |     QVERIFY(cm->error() == QOrganizerManager::BadArgumentError); | 
| 1528 |  | 
| 1529 |     // Use note & todo item depending on backend support | 
| 1530 |     QOrganizerItemType::ItemType type; | 
| 1531 |     if (cm->supportedItemTypes().contains(t: QOrganizerItemType::TypeNote)) | 
| 1532 |         type = QOrganizerItemType::TypeNote; | 
| 1533 |     else if (cm->supportedItemTypes().contains(t: QOrganizerItemType::TypeTodo)) | 
| 1534 |         type = QOrganizerItemType::TypeTodo; | 
| 1535 |     else | 
| 1536 |         QSKIP("This manager does not support note or todo item" ); | 
| 1537 |  | 
| 1538 |     QOrganizerItem a; | 
| 1539 |     QOrganizerItem b; | 
| 1540 |     QOrganizerItem c; | 
| 1541 |     a.setType(type); | 
| 1542 |     b.setType(type); | 
| 1543 |     c.setType(type); | 
| 1544 |  | 
| 1545 |     /* Now add 3 items, all valid */ | 
| 1546 |     QOrganizerItemDisplayLabel da; | 
| 1547 |     da.setValue(field: QOrganizerItemDisplayLabel::FieldLabel, value: "XXXXXX A Note" ); | 
| 1548 |     a.saveDetail(detail: &da); | 
| 1549 |  | 
| 1550 |     QOrganizerItemDisplayLabel db; | 
| 1551 |     db.setValue(field: QOrganizerItemDisplayLabel::FieldLabel, value: "XXXXXX B Note" ); | 
| 1552 |     b.saveDetail(detail: &db); | 
| 1553 |  | 
| 1554 |     QOrganizerItemDisplayLabel dc; | 
| 1555 |     dc.setValue(field: QOrganizerItemDisplayLabel::FieldLabel, value: "XXXXXX C Note" ); | 
| 1556 |     c.saveDetail(detail: &dc); | 
| 1557 |  | 
| 1558 |     QList<QOrganizerItem> items; | 
| 1559 |     items << a << b << c; | 
| 1560 |  | 
| 1561 |     QMap<int, QOrganizerManager::Error> errorMap; | 
| 1562 |     // Add one dummy error to test if the errors are reset | 
| 1563 |     errorMap.insert(akey: 0, avalue: QOrganizerManager::NoError); | 
| 1564 |     QVERIFY(cm->saveItems(&items)); | 
| 1565 |     QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 1566 |     errorMap = cm->errorMap(); | 
| 1567 |     QVERIFY(errorMap.count() == 0); | 
| 1568 |  | 
| 1569 |     /* Make sure our items got updated too */ | 
| 1570 |     QVERIFY(items.count() == 3); | 
| 1571 |     QVERIFY(items.at(0).id() != QOrganizerItemId()); | 
| 1572 |     QVERIFY(items.at(1).id() != QOrganizerItemId()); | 
| 1573 |     QVERIFY(items.at(2).id() != QOrganizerItemId()); | 
| 1574 |  | 
| 1575 |     QVERIFY(items.at(0).detail(QOrganizerItemDetail::TypeDisplayLabel) == da); | 
| 1576 |     QVERIFY(items.at(1).detail(QOrganizerItemDetail::TypeDisplayLabel) == db); | 
| 1577 |     QVERIFY(items.at(2).detail(QOrganizerItemDetail::TypeDisplayLabel) == dc); | 
| 1578 |  | 
| 1579 |     /* Retrieve again */ | 
| 1580 |     a = cm->item(itemId: items.at(i: 0).id()); | 
| 1581 |     b = cm->item(itemId: items.at(i: 1).id()); | 
| 1582 |     c = cm->item(itemId: items.at(i: 2).id()); | 
| 1583 |     QVERIFY(items.at(0).detail(QOrganizerItemDetail::TypeDisplayLabel) == da); | 
| 1584 |     QVERIFY(items.at(1).detail(QOrganizerItemDetail::TypeDisplayLabel) == db); | 
| 1585 |     QVERIFY(items.at(2).detail(QOrganizerItemDetail::TypeDisplayLabel) == dc); | 
| 1586 |  | 
| 1587 |     /* Now make an update to them all */ | 
| 1588 |     QOrganizerItemDescription descr; | 
| 1589 |     descr.setDescription("This note looks slightly shifty" ); | 
| 1590 |  | 
| 1591 |     QVERIFY(items[0].saveDetail(&descr)); | 
| 1592 |     descr.setDescription("This note is definitely up to no good" ); | 
| 1593 |     QVERIFY(items[1].saveDetail(&descr)); | 
| 1594 |     descr.setDescription("This note is a terrible note" ); | 
| 1595 |     QVERIFY(items[2].saveDetail(&descr)); | 
| 1596 |  | 
| 1597 |     QVERIFY(cm->saveItems(&items)); | 
| 1598 |     QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 1599 |     errorMap = cm->errorMap(); | 
| 1600 |     QVERIFY(errorMap.count() == 0); | 
| 1601 |  | 
| 1602 |     /* Retrieve them and check them again */ | 
| 1603 |     a = cm->item(itemId: items.at(i: 0).id()); | 
| 1604 |     b = cm->item(itemId: items.at(i: 1).id()); | 
| 1605 |     c = cm->item(itemId: items.at(i: 2).id()); | 
| 1606 |     QVERIFY(items.at(0).detail(QOrganizerItemDetail::TypeDisplayLabel) == da); | 
| 1607 |     QVERIFY(items.at(1).detail(QOrganizerItemDetail::TypeDisplayLabel) == db); | 
| 1608 |     QVERIFY(items.at(2).detail(QOrganizerItemDetail::TypeDisplayLabel) == dc); | 
| 1609 |  | 
| 1610 |     QVERIFY(a.details(QOrganizerItemDetail::TypeDescription).count() == 1); | 
| 1611 |     QVERIFY(b.details(QOrganizerItemDetail::TypeDescription).count() == 1); | 
| 1612 |     QVERIFY(c.details(QOrganizerItemDetail::TypeDescription).count() == 1); | 
| 1613 |  | 
| 1614 |     QVERIFY(a.details(QOrganizerItemDetail::TypeDescription).at(0).value(QOrganizerItemDescription::FieldDescription) == "This note looks slightly shifty" ); | 
| 1615 |     QVERIFY(b.details(QOrganizerItemDetail::TypeDescription).at(0).value(QOrganizerItemDescription::FieldDescription) == "This note is definitely up to no good" ); | 
| 1616 |     QVERIFY(c.details(QOrganizerItemDetail::TypeDescription).at(0).value(QOrganizerItemDescription::FieldDescription) == "This note is a terrible note" ); | 
| 1617 |  | 
| 1618 |     /* Now delete them all */ | 
| 1619 |     QList<QOrganizerItemId> ids; | 
| 1620 |     ids << a.id() << b.id() << c.id(); | 
| 1621 |     QVERIFY(cm->removeItems(ids)); | 
| 1622 |     errorMap = cm->errorMap(); | 
| 1623 |     QVERIFY(errorMap.count() == 0); | 
| 1624 |     QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 1625 |  | 
| 1626 |     /* Make sure the items really don't exist any more */ | 
| 1627 |     QVERIFY(cm->item(a.id()).id() == QOrganizerItemId()); | 
| 1628 |     QVERIFY(cm->item(a.id()).isEmpty()); | 
| 1629 |     QVERIFY(cm->error() == QOrganizerManager::DoesNotExistError); | 
| 1630 |     QVERIFY(cm->item(b.id()).id() == QOrganizerItemId()); | 
| 1631 |     QVERIFY(cm->item(b.id()).isEmpty()); | 
| 1632 |     QVERIFY(cm->error() == QOrganizerManager::DoesNotExistError); | 
| 1633 |     QVERIFY(cm->item(c.id()).id() == QOrganizerItemId()); | 
| 1634 |     QVERIFY(cm->item(c.id()).isEmpty()); | 
| 1635 |     QVERIFY(cm->error() == QOrganizerManager::DoesNotExistError); | 
| 1636 |  | 
| 1637 |     /* Now try removing with all invalid ids (e.g. the ones we just removed) */ | 
| 1638 |     ids.clear(); | 
| 1639 |     ids << a.id() << b.id() << c.id(); | 
| 1640 |     QVERIFY(!cm->removeItems(ids)); | 
| 1641 |     QVERIFY(cm->error() == QOrganizerManager::DoesNotExistError); | 
| 1642 |     errorMap = cm->errorMap(); | 
| 1643 |     QVERIFY(errorMap.count() == 3); | 
| 1644 |     QVERIFY(errorMap.values().at(0) == QOrganizerManager::DoesNotExistError); | 
| 1645 |     QVERIFY(errorMap.values().at(1) == QOrganizerManager::DoesNotExistError); | 
| 1646 |     QVERIFY(errorMap.values().at(2) == QOrganizerManager::DoesNotExistError); | 
| 1647 |  | 
| 1648 |     /* Try adding some new ones again, this time one with an error */ | 
| 1649 |     items.clear(); | 
| 1650 |     a.setId(QOrganizerItemId()); | 
| 1651 |     b.setId(QOrganizerItemId()); | 
| 1652 |     c.setId(QOrganizerItemId()); | 
| 1653 |  | 
| 1654 |     items << a << b << c; | 
| 1655 |  | 
| 1656 | //    /* Make B the bad guy */ | 
| 1657 | //    QOrganizerItemDetail bad("does not exist and will break if you add it"); | 
| 1658 | //    bad.setValue("This is also bad", "Very bad"); | 
| 1659 | //    b.saveDetail(&bad); | 
| 1660 |  | 
| 1661 | //    QVERIFY(!cm->saveItems(&items)); // since we don't setCollectionId() in any of the items, they go in default collection. | 
| 1662 | //    /* We can't really say what the error will be.. maybe bad argument, maybe invalid detail */ | 
| 1663 | //    QVERIFY(cm->error() != QOrganizerManager::NoError); | 
| 1664 |  | 
| 1665 | //    /* It's permissible to fail all the adds, or to add the successful ones */ | 
| 1666 | //    errorMap = cm->errorMap(); | 
| 1667 | //    QVERIFY(errorMap.count() > 0); | 
| 1668 | //    QVERIFY(errorMap.count() <= 3); | 
| 1669 |  | 
| 1670 | //    // A might have gone through | 
| 1671 | //    if (errorMap.keys().contains(0)) { | 
| 1672 | //        QVERIFY(errorMap.value(0) != QOrganizerManager::NoError); | 
| 1673 | //        QVERIFY(items.at(0).id() == QOrganizerItemId()); | 
| 1674 | //    } else { | 
| 1675 | //        QVERIFY(items.at(0).id() != QOrganizerItemId()); | 
| 1676 | //    } | 
| 1677 |  | 
| 1678 | //    // B should have failed | 
| 1679 | //    QVERIFY(errorMap.value(1) == QOrganizerManager::InvalidDetailError); | 
| 1680 | //    QVERIFY(items.at(1).id() == QOrganizerItemId()); | 
| 1681 |  | 
| 1682 | //    // C might have gone through | 
| 1683 | //    if (errorMap.keys().contains(2)) { | 
| 1684 | //        QVERIFY(errorMap.value(2) != QOrganizerManager::NoError); | 
| 1685 | //        QVERIFY(items.at(2).id() == QOrganizerItemId()); | 
| 1686 | //    } else { | 
| 1687 | //        QVERIFY(items.at(2).id() != QOrganizerItemId()); | 
| 1688 | //    } | 
| 1689 |  | 
| 1690 | //    /* Fix up B and re save it */ | 
| 1691 | //    QVERIFY(items[1].removeDetail(&bad)); | 
| 1692 | //    QVERIFY(cm->saveItems(&items)); | 
| 1693 | //    errorMap = cm->errorMap(); | 
| 1694 | //    QVERIFY(errorMap.count() == 0); | 
| 1695 | //    QVERIFY(cm->error() == QOrganizerManager::NoError); | 
| 1696 |  | 
| 1697 |     // Save and remove a fourth item. Store the id. | 
| 1698 |     QOrganizerItem d; | 
| 1699 |     d.setType(type); | 
| 1700 |     d.setDisplayLabel("XXXXXX D Note" ); | 
| 1701 |     QVERIFY(cm->saveItem(&d)); | 
| 1702 |     QOrganizerItemId removedId = d.id(); | 
| 1703 |     QVERIFY(cm->removeItem(removedId)); | 
| 1704 |  | 
| 1705 |     /* Now delete 3 items, but with one bad argument */ | 
| 1706 |     ids.clear(); | 
| 1707 |     ids << items.at(i: 0).id(); | 
| 1708 |     ids << removedId; | 
| 1709 |     ids << items.at(i: 2).id(); | 
| 1710 |  | 
| 1711 |     QVERIFY(!cm->removeItems(ids)); | 
| 1712 |     QVERIFY(cm->error() != QOrganizerManager::NoError); | 
| 1713 |  | 
| 1714 |     /* Again, the backend has the choice of either removing the successful ones, or not */ | 
| 1715 |     errorMap = cm->errorMap(); | 
| 1716 |     QVERIFY(errorMap.count() > 0); | 
| 1717 |     QVERIFY(errorMap.count() <= 3); | 
| 1718 |  | 
| 1719 |     // A might have gone through | 
| 1720 |     if (errorMap.keys().contains(t: 0)) { | 
| 1721 |         QVERIFY(errorMap.value(0) != QOrganizerManager::NoError); | 
| 1722 |         QVERIFY(items.at(0).id() == QOrganizerItemId()); | 
| 1723 |     } else { | 
| 1724 |         QVERIFY(items.at(0).id() != QOrganizerItemId()); | 
| 1725 |     } | 
| 1726 |  | 
| 1727 |     /* B should definitely have failed */ | 
| 1728 |     QVERIFY(errorMap.value(1) == QOrganizerManager::DoesNotExistError); | 
| 1729 |     QVERIFY(ids.at(1) == removedId); | 
| 1730 |  | 
| 1731 |     // A might have gone through | 
| 1732 |     if (errorMap.keys().contains(t: 2)) { | 
| 1733 |         QVERIFY(errorMap.value(2) != QOrganizerManager::NoError); | 
| 1734 |         QVERIFY(items.at(2).id() == QOrganizerItemId()); | 
| 1735 |     } else { | 
| 1736 |         QVERIFY(items.at(2).id() != QOrganizerItemId()); | 
| 1737 |     } | 
| 1738 | } | 
| 1739 |  | 
| 1740 | void tst_QOrganizerManager::invalidManager() | 
| 1741 | { | 
| 1742 |     /* Create an invalid manager */ | 
| 1743 |     QOrganizerManager manager("this should never work" ); | 
| 1744 |     QVERIFY(manager.managerName() == "invalid" ); | 
| 1745 |  | 
| 1746 |     /* Now test that all the operations fail */ | 
| 1747 |     QVERIFY(manager.itemIds().count() == 0); | 
| 1748 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1749 |  | 
| 1750 |     QOrganizerItem foo; | 
| 1751 |     QOrganizerItemDisplayLabel dl; | 
| 1752 |     dl.setLabel("some label" ); | 
| 1753 |     foo.saveDetail(detail: &dl); | 
| 1754 |  | 
| 1755 |     QVERIFY(manager.saveItem(&foo) == false); | 
| 1756 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1757 |     QVERIFY(foo.id() == QOrganizerItemId()); | 
| 1758 |     QVERIFY(manager.itemIds().count() == 0); | 
| 1759 |  | 
| 1760 |     QVERIFY(manager.item(foo.id()).id() == QOrganizerItemId()); | 
| 1761 |     QVERIFY(manager.item(foo.id()).isEmpty()); | 
| 1762 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1763 |  | 
| 1764 |     QVERIFY(manager.removeItem(foo.id()) == false); | 
| 1765 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1766 |  | 
| 1767 |     QMap<int, QOrganizerManager::Error> errorMap; | 
| 1768 |     errorMap.insert(akey: 0, avalue: QOrganizerManager::NoError); | 
| 1769 |     QVERIFY(!manager.saveItems(0)); | 
| 1770 |     errorMap = manager.errorMap(); | 
| 1771 |     QVERIFY(errorMap.count() == 0); | 
| 1772 |     QVERIFY(manager.error() == QOrganizerManager::BadArgumentError); | 
| 1773 |  | 
| 1774 |     /* filters */ | 
| 1775 |     QOrganizerItemFilter f; // matches everything | 
| 1776 |     QOrganizerItemDetailFieldFilter dff; | 
| 1777 |     dff.setDetail(detailType: QOrganizerItemDetail::TypeDisplayLabel, field: QOrganizerItemDisplayLabel::FieldLabel); | 
| 1778 |     QVERIFY(manager.itemIds(QDateTime(), QDateTime(), QOrganizerItemFilter()).count() == 0); | 
| 1779 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1780 |     QVERIFY(manager.itemIds(QDateTime(), QDateTime(), dff).count() == 0); | 
| 1781 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1782 |     QVERIFY(manager.itemIds(QDateTime(), QDateTime(), f | f).count() == 0); | 
| 1783 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1784 |     QVERIFY(manager.itemIds(QDateTime(), QDateTime(), dff | dff).count() == 0); | 
| 1785 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1786 |  | 
| 1787 |     QVERIFY(manager.supportedFilters().size() == 0); | 
| 1788 |  | 
| 1789 |     QList<QOrganizerItem> list; | 
| 1790 |     list << foo; | 
| 1791 |  | 
| 1792 |     QVERIFY(!manager.saveItems(&list)); | 
| 1793 |     errorMap = manager.errorMap(); | 
| 1794 |     QVERIFY(errorMap.count() == 0); | 
| 1795 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1796 |  | 
| 1797 |     QVERIFY(!manager.removeItems(QList<QOrganizerItemId>())); | 
| 1798 |     errorMap = manager.errorMap(); | 
| 1799 |     QVERIFY(errorMap.count() == 0); | 
| 1800 |     QVERIFY(manager.error() == QOrganizerManager::BadArgumentError); | 
| 1801 |  | 
| 1802 |     QList<QOrganizerItemId> idlist; | 
| 1803 |     idlist << foo.id(); | 
| 1804 |     QVERIFY(!manager.removeItems(idlist)); | 
| 1805 |     errorMap = manager.errorMap(); | 
| 1806 |     QVERIFY(errorMap.count() == 0); | 
| 1807 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1808 |  | 
| 1809 |     /* Collections */ | 
| 1810 |     QOrganizerCollection testCollection; | 
| 1811 |     testCollection.setExtendedMetaData(key: "test" , value: "example" ); | 
| 1812 |     QVERIFY(!manager.saveCollection(&testCollection)); | 
| 1813 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError || manager.error() == QOrganizerManager::InvalidCollectionError); | 
| 1814 |     QVERIFY(!manager.removeCollection(testCollection.id())); | 
| 1815 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError || manager.error() == QOrganizerManager::DoesNotExistError); | 
| 1816 |     QVERIFY(manager.collection(manager.defaultCollectionId()) == QOrganizerCollection()); | 
| 1817 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1818 |     QVERIFY(manager.collections().isEmpty()); | 
| 1819 |     QVERIFY(manager.error() == QOrganizerManager::NotSupportedError); | 
| 1820 |  | 
| 1821 |     /* Requests */ | 
| 1822 |     QOrganizerItemFetchRequest ifr; | 
| 1823 |     QOrganizerItemFetchForExportRequest ifer; | 
| 1824 |     QOrganizerItemSaveRequest isr; | 
| 1825 |     QOrganizerItemRemoveRequest irr; | 
| 1826 |     QOrganizerItemRemoveByIdRequest irbir; | 
| 1827 |     QOrganizerCollectionFetchRequest cfr; | 
| 1828 |     QOrganizerCollectionSaveRequest csr; | 
| 1829 |     QOrganizerCollectionRemoveRequest crr; | 
| 1830 |  | 
| 1831 |     ifr.setManager(&manager); | 
| 1832 |     QVERIFY(!ifr.start()); | 
| 1833 |     QVERIFY(!ifr.cancel()); | 
| 1834 |     ifr.waitForFinished(); | 
| 1835 |     //QVERIFY(ifr.error() == QOrganizerManager::NotSupportedError); // XXX TODO: if start fails, should be not supported error... | 
| 1836 |  | 
| 1837 |     ifer.setManager(&manager); | 
| 1838 |     QVERIFY(!ifer.start()); | 
| 1839 |     QVERIFY(!ifer.cancel()); | 
| 1840 |     ifer.waitForFinished(); | 
| 1841 |     //QVERIFY(ifer.error() == QOrganizerManager::NotSupportedError); // XXX TODO: if start fails, should be not supported error... | 
| 1842 |  | 
| 1843 |     isr.setManager(&manager); | 
| 1844 |     isr.setItem(foo); | 
| 1845 |     QVERIFY(!isr.start()); | 
| 1846 |     QVERIFY(!isr.cancel()); | 
| 1847 |     isr.waitForFinished(); | 
| 1848 |     //QVERIFY(isr.error() == QOrganizerManager::NotSupportedError); // XXX TODO: if start fails, should be not supported error... | 
| 1849 |  | 
| 1850 |     irr.setManager(&manager); | 
| 1851 |     irr.setItem(foo); | 
| 1852 |  | 
| 1853 |     QVERIFY(!irr.start()); | 
| 1854 |     QVERIFY(!irr.cancel()); | 
| 1855 |     irr.waitForFinished(); | 
| 1856 |     //QVERIFY(irr.error() == QOrganizerManager::NotSupportedError); // XXX TODO: if start fails, should be not supported error... | 
| 1857 |  | 
| 1858 |     irbir.setManager(&manager); | 
| 1859 |     irbir.setItemId(foo.id()); | 
| 1860 |  | 
| 1861 |     qDebug() << foo.id(); | 
| 1862 |     QVERIFY(!irbir.start()); | 
| 1863 |     QVERIFY(!irbir.cancel()); | 
| 1864 |     irbir.waitForFinished(); | 
| 1865 |     //QVERIFY(irr.error() == QOrganizerManager::NotSupportedError); // XXX TODO: if start fails, should be not supported error... | 
| 1866 |  | 
| 1867 |  | 
| 1868 |     cfr.setManager(&manager); | 
| 1869 |     QVERIFY(!cfr.start()); | 
| 1870 |     QVERIFY(!cfr.cancel()); | 
| 1871 |     cfr.waitForFinished(); | 
| 1872 |     //QVERIFY(cfr.error() == QOrganizerManager::NotSupportedError); // XXX TODO: if start fails, should be not supported error... | 
| 1873 |  | 
| 1874 |     csr.setManager(&manager); | 
| 1875 |     csr.setCollection(testCollection); | 
| 1876 |     QVERIFY(!csr.start()); | 
| 1877 |     QVERIFY(!csr.cancel()); | 
| 1878 |     csr.waitForFinished(); | 
| 1879 |     //QVERIFY(csr.error() == QOrganizerManager::NotSupportedError); // XXX TODO: if start fails, should be not supported error... | 
| 1880 |  | 
| 1881 |     crr.setManager(&manager); | 
| 1882 |     crr.setCollectionId(testCollection.id()); | 
| 1883 |     QVERIFY(!crr.start()); | 
| 1884 |     QVERIFY(!crr.cancel()); | 
| 1885 |     crr.waitForFinished(); | 
| 1886 |     //QVERIFY(crr.error() == QOrganizerManager::NotSupportedError); // XXX TODO: if start fails, should be not supported error... | 
| 1887 | } | 
| 1888 |  | 
| 1889 | void tst_QOrganizerManager::memoryManager() | 
| 1890 | { | 
| 1891 |     QMap<QString, QString> params; | 
| 1892 |     QOrganizerManager m1("memory" ); | 
| 1893 |     params.insert(akey: "random" , avalue: "shouldNotBeUsed" ); | 
| 1894 |     QOrganizerManager m2("memory" , params); | 
| 1895 |     params.insert(akey: "id" , avalue: "shouldBeUsed" ); | 
| 1896 |     QOrganizerManager m3("memory" , params); | 
| 1897 |     QOrganizerManager m4("memory" , params); | 
| 1898 |     params.insert(akey: "id" , avalue: QString("" )); | 
| 1899 |     QOrganizerManager m5("memory" , params); | 
| 1900 |  | 
| 1901 |     // add a item to each of m1, m2, m3 | 
| 1902 |     QOrganizerEvent c; | 
| 1903 |     QOrganizerItemDisplayLabel c1dl; | 
| 1904 |     c1dl.setLabel("c1dl" ); | 
| 1905 |     c.saveDetail(detail: &c1dl); | 
| 1906 |     QVERIFY(m1.saveItem(&c)); | 
| 1907 |     c.setId(QOrganizerItemId()); | 
| 1908 |     QOrganizerItem c2; | 
| 1909 |     QOrganizerItemDisplayLabel c2dl = c2.detail(detailType: QOrganizerItemDetail::TypeDisplayLabel); | 
| 1910 |     c2 = c; | 
| 1911 |     c2dl.setLabel("c2dl" ); | 
| 1912 |     c2.saveDetail(detail: &c2dl); | 
| 1913 |     c2.setCollectionId(QOrganizerCollectionId()); | 
| 1914 |     c.setCollectionId(QOrganizerCollectionId()); | 
| 1915 |     QVERIFY(m2.saveItem(&c2));            // save c2 first; c will be given a higher id | 
| 1916 |     QVERIFY(m2.saveItem(&c));             // save c to m2 | 
| 1917 |     c.setId(QOrganizerItemId()); | 
| 1918 |     c1dl.setLabel("c3dl" ); | 
| 1919 |     c.saveDetail(detail: &c1dl); | 
| 1920 |     c.setCollectionId(QOrganizerCollectionId()); | 
| 1921 |     QVERIFY(m3.saveItem(&c)); | 
| 1922 |  | 
| 1923 |     /* test that m1 != m2 != m3 and that m3 == m4 */ | 
| 1924 |  | 
| 1925 |     // check the counts are correct - especially note m4 and m3. | 
| 1926 |     QCOMPARE(m1.itemIds().count(), 1); | 
| 1927 |     QCOMPARE(m2.itemIds().count(), 2); | 
| 1928 |     QCOMPARE(m3.itemIds().count(), 1); | 
| 1929 |     QCOMPARE(m4.itemIds().count(), 1); | 
| 1930 |     QCOMPARE(m5.itemIds().count(), 0); | 
| 1931 |  | 
| 1932 |     // remove c2 from m2 - ensure that this doesn't affect any other manager. | 
| 1933 |     m2.removeItem(itemId: c2.id()); | 
| 1934 |     QCOMPARE(m1.itemIds().count(), 1); | 
| 1935 |     QCOMPARE(m2.itemIds().count(), 1); | 
| 1936 |     QCOMPARE(m3.itemIds().count(), 1); | 
| 1937 |     QCOMPARE(m4.itemIds().count(), 1); | 
| 1938 |     QCOMPARE(m5.itemIds().count(), 0); | 
| 1939 |  | 
| 1940 |     // check that the items contained within are different. | 
| 1941 |     // note that in the m1->m2 case, only the id will be different! | 
| 1942 |     QVERIFY(m1.item(m1.itemIds().at(0)) != m2.item(m2.itemIds().at(0))); | 
| 1943 |     QVERIFY(m1.item(m1.itemIds().at(0)) != m3.item(m3.itemIds().at(0))); | 
| 1944 |     QVERIFY(m2.item(m2.itemIds().at(0)) != m3.item(m3.itemIds().at(0))); | 
| 1945 |     QVERIFY(m3.item(m3.itemIds().at(0)) == m4.item(m4.itemIds().at(0))); | 
| 1946 |  | 
| 1947 |     // now, we should be able to remove from m4, and have m3 empty | 
| 1948 |     QVERIFY(m4.removeItem(c.id())); | 
| 1949 |     QCOMPARE(m3.itemIds().count(), 0); | 
| 1950 |     QCOMPARE(m4.itemIds().count(), 0); | 
| 1951 |     QCOMPARE(m5.itemIds().count(), 0); | 
| 1952 | } | 
| 1953 |  | 
| 1954 | void tst_QOrganizerManager::recurrenceWithGenerator_data() | 
| 1955 | { | 
| 1956 |     QTest::addColumn<QString>(name: "uri" ); | 
| 1957 |     QTest::addColumn<QDate>(name: "generatorDate" ); | 
| 1958 |     QTest::addColumn<QOrganizerRecurrenceRule>(name: "recurrenceRule" ); | 
| 1959 |     QTest::addColumn<QOrganizerRecurrenceRule>(name: "exceptionRule" ); | 
| 1960 |     QTest::addColumn<QSet<QDate> >(name: "recurrenceDates" ); | 
| 1961 |     QTest::addColumn<QSet<QDate> >(name: "exceptionDates" ); | 
| 1962 |     QTest::addColumn<QDate>(name: "startDate" ); | 
| 1963 |     QTest::addColumn<QDate>(name: "endDate" ); | 
| 1964 |     QTest::addColumn<QList<QDate> >(name: "occurrenceDates" ); | 
| 1965 |  | 
| 1966 |     QStringList managers = QOrganizerManager::availableManagers(); | 
| 1967 |  | 
| 1968 |     /* Known one that will not pass */ | 
| 1969 |     managers.removeAll(t: "invalid" ); | 
| 1970 |     managers.removeAll(t: "testdummy" ); | 
| 1971 |     managers.removeAll(t: "teststaticdummy" ); | 
| 1972 |     managers.removeAll(t: "maliciousplugin" ); | 
| 1973 |     managers.removeAll(t: "skeleton" ); | 
| 1974 |  | 
| 1975 |     QOrganizerRecurrenceRule exrule; | 
| 1976 |     QSet<QDate> rdates; | 
| 1977 |     QSet<QDate> exdates; | 
| 1978 |     foreach(QString mgr, managers) { | 
| 1979 |         QString managerUri = QOrganizerManager::buildUri(managerName: mgr, params: QMap<QString, QString>()); | 
| 1980 |  | 
| 1981 |         { | 
| 1982 |             QOrganizerRecurrenceRule rrule; | 
| 1983 |             rrule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 1984 |             rrule.setLimit(QDate(2010, 1, 22)); | 
| 1985 |             QTest::newRow(dataTag: QString("mgr=%1, weekly recurrence" ).arg(a: mgr).toLatin1().constData()) | 
| 1986 |                 << managerUri << QDate(2010, 1, 1) | 
| 1987 |                 << rrule << exrule << rdates << exdates | 
| 1988 |                 << QDate(2010, 1, 1) << QDate(2010, 1, 20) | 
| 1989 |                 // stops at the 15th because the query end date is the 20th | 
| 1990 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 8) << QDate(2010, 1, 15)); | 
| 1991 |  | 
| 1992 |             // change the end date of the query to 2010-02-01 | 
| 1993 |             QTest::newRow(dataTag: QString("mgr=%1, weekly recurrence, end date is inclusive" ).arg(a: mgr).toLatin1().constData()) | 
| 1994 |                 << managerUri << QDate(2010, 1, 1) | 
| 1995 |                 << rrule << exrule << rdates << exdates | 
| 1996 |                 << QDate(2010, 1, 1) << QDate(2010, 2, 1) | 
| 1997 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 8) << QDate(2010, 1, 15) << QDate(2010, 1, 22)); | 
| 1998 |  | 
| 1999 |             // Now let's fiddle with the recurrence end date and see what happens | 
| 2000 |             rrule.setLimit(QDate(2010, 1, 23)); | 
| 2001 |             QTest::newRow(dataTag: QString("mgr=%1, weekly recurrence, end date observed (+1)" ).arg(a: mgr).toLatin1().constData()) | 
| 2002 |                 << managerUri << QDate(2010, 1, 1) | 
| 2003 |                 << rrule << exrule << rdates << exdates | 
| 2004 |                 << QDate(2010, 1, 1) << QDate(2010, 2, 1) | 
| 2005 |                 // now stop on the 22nd | 
| 2006 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 8) << QDate(2010, 1, 15) << QDate(2010, 1, 22)); | 
| 2007 |  | 
| 2008 |             rrule.setLimit(QDate(2010, 1, 21)); | 
| 2009 |             QTest::newRow(dataTag: QString("mgr=%1, weekly recurrence, end date observed (-1)" ).arg(a: mgr).toLatin1().constData()) | 
| 2010 |                 << managerUri << QDate(2010, 1, 1) | 
| 2011 |                 << rrule << exrule << rdates << exdates | 
| 2012 |                 << QDate(2010, 1, 1) << QDate(2010, 2, 1) | 
| 2013 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 8) << QDate(2010, 1, 15)); | 
| 2014 |  | 
| 2015 |             rrule.setLimit(QDate()); | 
| 2016 |             rrule.setLimit(2); | 
| 2017 |             QTest::newRow(dataTag: QString("mgr=%1, weekly recurrence, count" ).arg(a: mgr).toLatin1().constData()) | 
| 2018 |                 << managerUri << QDate(2010, 1, 1) | 
| 2019 |                 << rrule << exrule << rdates << exdates | 
| 2020 |                 << QDate(2010, 1, 1) << QDate(2010, 2, 1) | 
| 2021 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 8)); | 
| 2022 |         } | 
| 2023 |  | 
| 2024 |         { | 
| 2025 |             QOrganizerRecurrenceRule rrule; | 
| 2026 |             rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 2027 |             rrule.setLimit(QDate(2010, 1, 5)); | 
| 2028 |             QTest::newRow(dataTag: QString("mgr=%1, daily" ).arg(a: mgr).toLatin1().constData()) | 
| 2029 |                 << managerUri << QDate(2010, 1, 1) | 
| 2030 |                 << rrule << exrule << rdates << exdates | 
| 2031 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2032 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 2) | 
| 2033 |                                    << QDate(2010, 1, 3) << QDate(2010, 1, 4) | 
| 2034 |                                    << QDate(2010, 1, 5)); | 
| 2035 |  | 
| 2036 |             rrule.setInterval(3); | 
| 2037 |             QTest::newRow(dataTag: QString("mgr=%1, daily, interval" ).arg(a: mgr).toLatin1().constData()) | 
| 2038 |                 << managerUri << QDate(2010, 1, 1) | 
| 2039 |                 << rrule << exrule << rdates << exdates | 
| 2040 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2041 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 4)); | 
| 2042 |         } | 
| 2043 |  | 
| 2044 |         { | 
| 2045 |             QOrganizerRecurrenceRule rrule; | 
| 2046 |             rrule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 2047 |             rrule.setFirstDayOfWeek(Qt::Monday); | 
| 2048 |             rrule.setDaysOfWeek(QSet<Qt::DayOfWeek>() << Qt::Friday << Qt::Saturday << Qt::Sunday); | 
| 2049 |             rrule.setLimit(QDate(2010, 1, 27)); | 
| 2050 |             QTest::newRow(dataTag: QString("mgr=%1, weekly, days of week" ).arg(a: mgr).toLatin1().constData()) | 
| 2051 |                 << managerUri << QDate(2010, 1, 1) | 
| 2052 |                 << rrule << exrule << rdates << exdates | 
| 2053 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2054 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 2) << QDate(2010, 1, 3) | 
| 2055 |                                    << QDate(2010, 1, 8) << QDate(2010, 1, 9) << QDate(2010, 1, 10) | 
| 2056 |                                    << QDate(2010, 1, 15) << QDate(2010, 1, 16) << QDate(2010, 1, 17) | 
| 2057 |                                    << QDate(2010, 1, 22) << QDate(2010, 1, 23) << QDate(2010, 1, 24)); | 
| 2058 |  | 
| 2059 |             rrule.setInterval(3); | 
| 2060 |             QTest::newRow(dataTag: QString("mgr=%1, weekly, days of week, interval" ).arg(a: mgr).toLatin1().constData()) | 
| 2061 |                 << managerUri << QDate(2010, 1, 1) | 
| 2062 |                 << rrule << exrule << rdates << exdates | 
| 2063 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2064 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 2) << QDate(2010, 1, 3) | 
| 2065 |                                    << QDate(2010, 1, 22) << QDate(2010, 1, 23) << QDate(2010, 1, 24)); | 
| 2066 |         } | 
| 2067 |  | 
| 2068 |         { | 
| 2069 |             QOrganizerRecurrenceRule rrule; | 
| 2070 |             rrule.setFrequency(QOrganizerRecurrenceRule::Monthly); | 
| 2071 |             rrule.setDaysOfMonth(QSet<int>() << 1 << 10); | 
| 2072 |             rrule.setLimit(QDate(2010, 4, 15)); | 
| 2073 |             QTest::newRow(dataTag: QString("mgr=%1, monthly recurrence" ).arg(a: mgr).toLatin1().constData()) | 
| 2074 |                 << managerUri << QDate(2010, 1, 1) | 
| 2075 |                 << rrule << exrule << rdates << exdates | 
| 2076 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2077 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 10) | 
| 2078 |                                    << QDate(2010, 2, 1) << QDate(2010, 2, 10) | 
| 2079 |                                    << QDate(2010, 3, 1) << QDate(2010, 3, 10) | 
| 2080 |                                    << QDate(2010, 4, 1) << QDate(2010, 4, 10)); | 
| 2081 |  | 
| 2082 |             rrule.setInterval(3); | 
| 2083 |             QTest::newRow(dataTag: QString("mgr=%1, monthly recurrence, interval" ).arg(a: mgr).toLatin1().constData()) | 
| 2084 |                 << managerUri << QDate(2010, 1, 1) | 
| 2085 |                 << rrule << exrule << rdates << exdates | 
| 2086 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2087 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 1, 10) | 
| 2088 |                                    << QDate(2010, 4, 1) << QDate(2010, 4, 10)); | 
| 2089 |         } | 
| 2090 |  | 
| 2091 |         { | 
| 2092 |             QOrganizerRecurrenceRule rrule; | 
| 2093 |             rrule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 2094 |             rrule.setDaysOfYear(QSet<int>() << 1 << 32); | 
| 2095 |             rrule.setLimit(QDate(2012, 3, 15)); | 
| 2096 |             QTest::newRow(dataTag: QString("mgr=%1, yearly recurrence" ).arg(a: mgr).toLatin1().constData()) | 
| 2097 |                 << managerUri << QDate(2010, 1, 1) | 
| 2098 |                 << rrule << exrule << rdates << exdates | 
| 2099 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2100 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 2, 1) | 
| 2101 |                                    << QDate(2011, 1, 1) << QDate(2011, 2, 1) | 
| 2102 |                                    << QDate(2012, 1, 1) << QDate(2012, 2, 1)); | 
| 2103 |  | 
| 2104 |             rrule.setLimit(QDate(2013, 3, 15)); | 
| 2105 |             rrule.setInterval(3); | 
| 2106 |             QTest::newRow(dataTag: QString("mgr=%1, yearly recurrence, interval" ).arg(a: mgr).toLatin1().constData()) | 
| 2107 |                 << managerUri << QDate(2010, 1, 1) | 
| 2108 |                 << rrule << exrule << rdates << exdates | 
| 2109 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2110 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 2, 1) | 
| 2111 |                                    << QDate(2013, 1, 1) << QDate(2013, 2, 1)); | 
| 2112 |         } | 
| 2113 |  | 
| 2114 |         { | 
| 2115 |             QOrganizerRecurrenceRule rrule; | 
| 2116 |             rrule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 2117 |             rrule.setMonthsOfYear(QSet<QOrganizerRecurrenceRule::Month>() | 
| 2118 |                     << QOrganizerRecurrenceRule::January | 
| 2119 |                     << QOrganizerRecurrenceRule::March); | 
| 2120 |             rrule.setLimit(QDate(2011, 3, 15)); | 
| 2121 |             QTest::newRow(dataTag: QString("mgr=%1, yearly recurrence, by month" ).arg(a: mgr).toLatin1().constData()) | 
| 2122 |                 << managerUri << QDate(2010, 1, 1) | 
| 2123 |                 << rrule << exrule << rdates << exdates | 
| 2124 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2125 |                 << (QList<QDate>() << QDate(2010, 1, 1) << QDate(2010, 3, 1) | 
| 2126 |                                    << QDate(2011, 1, 1) << QDate(2011, 3, 1)); | 
| 2127 |             // The day-of-month should be inferred from the day-of-month of the original event | 
| 2128 |         } | 
| 2129 |  | 
| 2130 |         { | 
| 2131 |             QOrganizerRecurrenceRule rrule; | 
| 2132 |             rrule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 2133 |             rrule.setWeeksOfYear(QSet<int>() << 1 << 4); | 
| 2134 |             rrule.setDaysOfWeek(QSet<Qt::DayOfWeek>() << Qt::Thursday); | 
| 2135 |             rrule.setLimit(QDate(2011, 3, 15)); | 
| 2136 |             QTest::newRow(dataTag: QString("mgr=%1, yearly recurrence, by week" ).arg(a: mgr).toLatin1().constData()) | 
| 2137 |                 << managerUri << QDate(2010, 1, 7) // this is the first day of week 1 | 
| 2138 |                 << rrule << exrule << rdates << exdates | 
| 2139 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2140 |                 << (QList<QDate>() << QDate(2010, 1, 7) << QDate(2010, 1, 28) | 
| 2141 |                                    << QDate(2011, 1, 6) << QDate(2011, 1, 27)); | 
| 2142 |         } | 
| 2143 |  | 
| 2144 |         { | 
| 2145 |             QOrganizerRecurrenceRule rrule; | 
| 2146 |             rrule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 2147 |             rrule.setMonthsOfYear(QSet<QOrganizerRecurrenceRule::Month>() | 
| 2148 |                     << QOrganizerRecurrenceRule::April); | 
| 2149 |             rrule.setDaysOfWeek(QSet<Qt::DayOfWeek>() << Qt::Sunday); | 
| 2150 |             rrule.setPositions(QSet<int>() << 1); | 
| 2151 |             QTest::newRow(dataTag: QString("mgr=%1, yearly recurrence, first Sunday of April" ).arg(a: mgr).toLatin1().constData()) | 
| 2152 |                 << managerUri << QDate(2010, 4, 4) // this is the first Sunday of April 2010 | 
| 2153 |                 << rrule << exrule << rdates << exdates | 
| 2154 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2155 |                 << (QList<QDate>() << QDate(2010, 4, 4) | 
| 2156 |                                    << QDate(2011, 4, 3) | 
| 2157 |                                    << QDate(2012, 4, 1) | 
| 2158 |                                    << QDate(2013, 4, 7) | 
| 2159 |                                    << QDate(2014, 4, 6)); | 
| 2160 |         } | 
| 2161 |  | 
| 2162 |         { | 
| 2163 |             QOrganizerRecurrenceRule rrule; | 
| 2164 |             rrule.setFrequency(QOrganizerRecurrenceRule::Yearly); | 
| 2165 |             rrule.setMonthsOfYear(QSet<QOrganizerRecurrenceRule::Month>() | 
| 2166 |                     << QOrganizerRecurrenceRule::October); | 
| 2167 |             rrule.setDaysOfWeek(QSet<Qt::DayOfWeek>() << Qt::Sunday); | 
| 2168 |             rrule.setPositions(QSet<int>() << -1); | 
| 2169 |             QTest::newRow(dataTag: QString("mgr=%1, yearly recurrence, last Sunday of October" ).arg(a: mgr).toLatin1().constData()) | 
| 2170 |                 << managerUri << QDate(2010, 10, 31) // this is the last Sunday of October 2010 | 
| 2171 |                 << rrule << exrule << rdates << exdates | 
| 2172 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2173 |                 << (QList<QDate>() << QDate(2010, 10, 31) | 
| 2174 |                                    << QDate(2011, 10, 30) | 
| 2175 |                                    << QDate(2012, 10, 28) | 
| 2176 |                                    << QDate(2013, 10, 27) | 
| 2177 |                                    << QDate(2014, 10, 26)); | 
| 2178 |         } | 
| 2179 |  | 
| 2180 |         { | 
| 2181 |             QOrganizerRecurrenceRule rrule; // empty | 
| 2182 |             QSet<QDate> rdates; | 
| 2183 |             rdates << QDate(2010, 1, 5) << QDate(2010, 1, 8); | 
| 2184 |             QTest::newRow(dataTag: QString("mgr=%1, rdates" ).arg(a: mgr).toLatin1().constData()) | 
| 2185 |                 << managerUri << QDate(2010, 1, 1) | 
| 2186 |                 << rrule << exrule << rdates << exdates | 
| 2187 |                 << QDate(2010, 1, 1) << QDate(2015, 1, 1) | 
| 2188 |                 << (QList<QDate>() << QDate(2010, 1, 1) | 
| 2189 |                                    << QDate(2010, 1, 5) | 
| 2190 |                                    << QDate(2010, 1, 8)); | 
| 2191 |         } | 
| 2192 |  | 
| 2193 |         { | 
| 2194 |             QOrganizerRecurrenceRule rrule; | 
| 2195 |             rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 2196 |             QSet<QDate> exdates; | 
| 2197 |             exdates << QDate(2010, 1, 2) << QDate(2010, 1, 3); | 
| 2198 |             QTest::newRow(dataTag: QString("mgr=%1, exdates" ).arg(a: mgr).toLatin1().constData()) | 
| 2199 |                 << managerUri << QDate(2010, 1, 1) | 
| 2200 |                 << rrule << exrule << rdates << exdates | 
| 2201 |                 << QDate(2010, 1, 1) << QDate(2010, 1, 5) | 
| 2202 |                 << (QList<QDate>() << QDate(2010, 1, 1) | 
| 2203 |                                    << QDate(2010, 1, 4) | 
| 2204 |                                    << QDate(2010, 1, 5)); | 
| 2205 |         } | 
| 2206 |  | 
| 2207 |         { | 
| 2208 |             QOrganizerRecurrenceRule rrule; | 
| 2209 |             rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 2210 |             QOrganizerRecurrenceRule exrule; | 
| 2211 |             exrule.setFrequency(QOrganizerRecurrenceRule::Monthly); | 
| 2212 |             exrule.setDaysOfMonth(QSet<int>() << 2 << 3); | 
| 2213 |             QTest::newRow(dataTag: QString("mgr=%1, exrule" ).arg(a: mgr).toLatin1().constData()) | 
| 2214 |                 << managerUri << QDate(2010, 1, 1) | 
| 2215 |                 << rrule << exrule << rdates << exdates | 
| 2216 |                 << QDate(2010, 1, 1) << QDate(2010, 1, 5) | 
| 2217 |                 << (QList<QDate>() << QDate(2010, 1, 1) | 
| 2218 |                                    << QDate(2010, 1, 4) | 
| 2219 |                                    << QDate(2010, 1, 5)); | 
| 2220 |         } | 
| 2221 |  | 
| 2222 |         { | 
| 2223 |             QOrganizerRecurrenceRule rrule; | 
| 2224 |             rrule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 2225 |             rrule.setLimit(8); | 
| 2226 |             rrule.setDaysOfWeek(QSet<Qt::DayOfWeek>() | 
| 2227 |                                 << Qt::Monday | 
| 2228 |                                 << Qt::Tuesday | 
| 2229 |                                 << Qt::Wednesday); | 
| 2230 |             QOrganizerRecurrenceRule exrule; | 
| 2231 |             QTest::newRow(dataTag: QString("mgr=%1, weekly, count, days of week" ).arg(a: mgr).toLatin1().constData()) | 
| 2232 |                 << managerUri << QDate(2014, 1, 22) | 
| 2233 |                 << rrule << exrule << rdates << exdates | 
| 2234 |                 << QDate(2014, 1, 1) << QDate(2014, 5, 1) | 
| 2235 |                 << (QList<QDate>() << QDate(2014, 1, 22) << QDate(2014, 1, 27) | 
| 2236 |                                    << QDate(2014, 1, 28) << QDate(2014, 1, 29) | 
| 2237 |                                    << QDate(2014, 2,  3) << QDate(2014, 2,  4) | 
| 2238 |                                    << QDate(2014, 2,  5) << QDate(2014, 2, 10)); | 
| 2239 |         } | 
| 2240 |     } | 
| 2241 | } | 
| 2242 |  | 
| 2243 | void tst_QOrganizerManager::recurrenceWithGenerator() | 
| 2244 | { | 
| 2245 |     QFETCH(QString, uri); | 
| 2246 |     QFETCH(QDate, generatorDate); | 
| 2247 |     QFETCH(QOrganizerRecurrenceRule, recurrenceRule); | 
| 2248 |     QFETCH(QOrganizerRecurrenceRule, exceptionRule); | 
| 2249 |     QFETCH(QSet<QDate>, recurrenceDates); | 
| 2250 |     QFETCH(QSet<QDate>, exceptionDates); | 
| 2251 |     QFETCH(QDate, startDate); | 
| 2252 |     QFETCH(QDate, endDate); | 
| 2253 |     QFETCH(QList<QDate>, occurrenceDates); | 
| 2254 |  | 
| 2255 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 2256 |  | 
| 2257 |     QOrganizerEvent event; | 
| 2258 |     event.setDisplayLabel("event" ); | 
| 2259 |     event.setStartDateTime(QDateTime(generatorDate, QTime(11, 0, 0))); | 
| 2260 |     event.setEndDateTime(QDateTime(generatorDate, QTime(11, 30, 0))); | 
| 2261 |     event.setRecurrenceRule(recurrenceRule); | 
| 2262 |     event.setExceptionRule(exceptionRule); | 
| 2263 |     event.setRecurrenceDates(recurrenceDates); | 
| 2264 |     event.setExceptionDates(exceptionDates); | 
| 2265 |  | 
| 2266 |     if (cm->saveItem(item: &event)) { | 
| 2267 |         QList<QOrganizerItem> items = cm->itemOccurrences(parentItem: event, | 
| 2268 |                 startDateTime: QDateTime(startDate, QTime(0, 0, 0)), | 
| 2269 |                 endDateTime: QDateTime(endDate, QTime(23, 59, 59, 999))); | 
| 2270 |  | 
| 2271 |         QList<QDate> actualDates; | 
| 2272 |         for (int i = 0; i < items.size(); i++) { | 
| 2273 |             QOrganizerItem item = items.at(i); | 
| 2274 |             QCOMPARE(item.type(), QOrganizerItemType::TypeEventOccurrence); | 
| 2275 |             QDate occurrenceDate = item.detail(detailType: QOrganizerItemDetail::TypeEventTime).value(field: QOrganizerEventTime::FieldStartDateTime).toDateTime().date(); | 
| 2276 |             //QCOMPARE(occurrenceDate, occurrenceDates.at(i)); | 
| 2277 |             actualDates << occurrenceDate; | 
| 2278 |         } | 
| 2279 |         if (actualDates != occurrenceDates) { | 
| 2280 |             qDebug() << "Actual: "  << actualDates; | 
| 2281 |             qDebug() << "Expected: "  << occurrenceDates; | 
| 2282 |             QCOMPARE(actualDates, occurrenceDates); | 
| 2283 |         } | 
| 2284 |     } else { | 
| 2285 |         // Allow backend specific limitations | 
| 2286 |         QCOMPARE(cm->error(), QOrganizerManager::NotSupportedError); | 
| 2287 |         qWarning() << "The event not supported by the backend" ; | 
| 2288 |     } | 
| 2289 | } | 
| 2290 |  | 
| 2291 | void tst_QOrganizerManager::todoRecurrenceWithGenerator_data() | 
| 2292 | { | 
| 2293 |     recurrenceWithGenerator_data(); | 
| 2294 | } | 
| 2295 |  | 
| 2296 | // This is just a copy of recurrenceWithGenerator, but for todos, not events | 
| 2297 | void tst_QOrganizerManager::todoRecurrenceWithGenerator() | 
| 2298 | { | 
| 2299 |     QFETCH(QString, uri); | 
| 2300 |     QFETCH(QDate, generatorDate); | 
| 2301 |     QFETCH(QOrganizerRecurrenceRule, recurrenceRule); | 
| 2302 |     QFETCH(QOrganizerRecurrenceRule, exceptionRule); | 
| 2303 |     QFETCH(QSet<QDate>, recurrenceDates); | 
| 2304 |     QFETCH(QSet<QDate>, exceptionDates); | 
| 2305 |     QFETCH(QDate, startDate); | 
| 2306 |     QFETCH(QDate, endDate); | 
| 2307 |     QFETCH(QList<QDate>, occurrenceDates); | 
| 2308 |  | 
| 2309 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 2310 |  | 
| 2311 |     QOrganizerTodo todo; | 
| 2312 |     todo.setDisplayLabel("todo" ); | 
| 2313 |     todo.setStartDateTime(QDateTime(generatorDate, QTime(11, 0, 0))); | 
| 2314 |     todo.setDueDateTime(QDateTime(generatorDate, QTime(11, 30, 0))); | 
| 2315 |     todo.setRecurrenceRule(recurrenceRule); | 
| 2316 |     todo.setExceptionRule(exceptionRule); | 
| 2317 |     todo.setRecurrenceDates(recurrenceDates); | 
| 2318 |     todo.setExceptionDates(exceptionDates); | 
| 2319 |  | 
| 2320 |     if (cm->saveItem(item: &todo)) { | 
| 2321 |         QList<QOrganizerItem> items = cm->itemOccurrences(parentItem: todo, | 
| 2322 |                 startDateTime: QDateTime(startDate, QTime(0, 0, 0)), | 
| 2323 |                 endDateTime: QDateTime(endDate, QTime(23, 59, 59, 999))); | 
| 2324 |  | 
| 2325 |         QList<QDate> actualDates; | 
| 2326 |         for (int i = 0; i < items.size(); i++) { | 
| 2327 |             QOrganizerItem item = items.at(i); | 
| 2328 |             QCOMPARE(item.type(), QOrganizerItemType::TypeTodoOccurrence); | 
| 2329 |             QDate occurrenceDate = item.detail(detailType: QOrganizerItemDetail::TypeTodoTime).value(field: QOrganizerTodoTime::FieldStartDateTime).toDateTime().date(); | 
| 2330 |             //QCOMPARE(occurrenceDate, occurrenceDates.at(i)); | 
| 2331 |             actualDates << occurrenceDate; | 
| 2332 |         } | 
| 2333 |  | 
| 2334 |         if (actualDates != occurrenceDates) { | 
| 2335 |             qDebug() << "Actual: "  << actualDates; | 
| 2336 |             qDebug() << "Expected: "  << occurrenceDates; | 
| 2337 |             QCOMPARE(actualDates, occurrenceDates); | 
| 2338 |         } | 
| 2339 |     } else { | 
| 2340 |         // Allow backend specific limitations | 
| 2341 |         QCOMPARE(cm->error(), QOrganizerManager::NotSupportedError); | 
| 2342 |         qWarning() << "The todo not supported by the backend" ; | 
| 2343 |     } | 
| 2344 | } | 
| 2345 |  | 
| 2346 | void tst_QOrganizerManager::observerDeletion() | 
| 2347 | { | 
| 2348 |     QOrganizerManager *manager = new QOrganizerManager("memory" ); | 
| 2349 |     QOrganizerEvent c; | 
| 2350 |     QVERIFY(manager->saveItem(&c)); | 
| 2351 |     QOrganizerItemId id = c.id(); | 
| 2352 |     QOrganizerItemObserver *observer = new QOrganizerItemObserver(manager, id); | 
| 2353 |     Q_UNUSED(observer) | 
| 2354 |     delete manager; | 
| 2355 |     delete observer; | 
| 2356 |     // Test for bug MOBILITY-2566 - that QOrganizerItemObserver doesn't crash when it is | 
| 2357 |     // destroyed after the associated QOrganizerManager | 
| 2358 | } | 
| 2359 |  | 
| 2360 | void tst_QOrganizerManager::signalEmission() | 
| 2361 | { | 
| 2362 |     QTest::qWait(ms: 500); // clear the signal queue | 
| 2363 |     QFETCH(QString, uri); | 
| 2364 |     QScopedPointer<QOrganizerManager> m1(QOrganizerManager::fromUri(uri)); | 
| 2365 |  | 
| 2366 |     qRegisterMetaType<QOrganizerItemId>(typeName: "QOrganizerItemId" ); | 
| 2367 |     qRegisterMetaType<QList<QOrganizerItemId> >(typeName: "QList<QOrganizerItemId>" ); | 
| 2368 |     qRegisterMetaType<QList<QOrganizerItemDetail::DetailType> >(typeName: "QList<QOrganizerItemDetail::DetailType>" ); | 
| 2369 |     QSignalSpy spyAdded(m1.data(), SIGNAL(itemsAdded(QList<QOrganizerItemId>))); | 
| 2370 |     QSignalSpy spyModified(m1.data(), SIGNAL(itemsChanged(QList<QOrganizerItemId>, QList<QOrganizerItemDetail::DetailType>))); | 
| 2371 |     QSignalSpy spyRemoved(m1.data(), SIGNAL(itemsRemoved(QList<QOrganizerItemId>))); | 
| 2372 |     QSignalSpy spyChanged(m1.data(), SIGNAL(dataChanged())); | 
| 2373 |  | 
| 2374 |     QList<QVariant> args; | 
| 2375 |     QList<QOrganizerItemId> arg; | 
| 2376 |     QOrganizerTodo todo; | 
| 2377 |     QList<QOrganizerItem> batchAdd; | 
| 2378 |     QList<QOrganizerItemId> batchRemove; | 
| 2379 |     int addSigCount = 0; // the expected signal counts. | 
| 2380 |     int modSigCount = 0; | 
| 2381 |     int remSigCount = 0; | 
| 2382 |  | 
| 2383 |     // verify add emits signal added | 
| 2384 |     QOrganizerItemDisplayLabel nc; | 
| 2385 |     nc.setLabel("label me this" ); | 
| 2386 |     QVERIFY(todo.saveDetail(&nc)); | 
| 2387 |     QVERIFY(m1->saveItem(&todo)); | 
| 2388 |     QOrganizerItemId cid = todo.id(); | 
| 2389 |     QTRY_VERIFY(spyAdded.count() > addSigCount); | 
| 2390 |     ++addSigCount; | 
| 2391 |     args = spyAdded.takeFirst(); | 
| 2392 |     --addSigCount; | 
| 2393 |     arg = args.first().value<QList<QOrganizerItemId> >(); | 
| 2394 |     QVERIFY(arg.count() == 1); | 
| 2395 |     QCOMPARE(QOrganizerItemId(arg.at(0)), cid); | 
| 2396 |  | 
| 2397 |     QScopedPointer<QOrganizerItemObserver> todo1Observer(new QOrganizerItemObserver(m1.data(), cid)); | 
| 2398 |     QScopedPointer<QSignalSpy> spyObserverModified1(new QSignalSpy(todo1Observer.data(), SIGNAL(itemChanged(QList<QOrganizerItemDetail::DetailType>)))); | 
| 2399 |     QScopedPointer<QSignalSpy> spyObserverRemoved1(new QSignalSpy(todo1Observer.data(), SIGNAL(itemRemoved()))); | 
| 2400 |  | 
| 2401 |     // verify save modified emits signal changed | 
| 2402 |     nc.setLabel("label me that" ); | 
| 2403 |     QVERIFY(todo.saveDetail(&nc)); | 
| 2404 |     QVERIFY(m1->saveItem(&todo)); | 
| 2405 |     QTRY_VERIFY(spyModified.count() > modSigCount); | 
| 2406 |     ++modSigCount; | 
| 2407 |     QTRY_VERIFY(spyObserverModified1->count() > 0); | 
| 2408 |     args = spyModified.takeFirst(); | 
| 2409 |     --modSigCount; | 
| 2410 |     arg = args.first().value<QList<QOrganizerItemId> >(); | 
| 2411 |     QVERIFY(arg.count() == 1); | 
| 2412 |     QCOMPARE(QOrganizerItemId(arg.at(0)), cid); | 
| 2413 |  | 
| 2414 |     // verify remove emits signal removed | 
| 2415 |     QVERIFY(m1->removeItem(todo.id())); | 
| 2416 |     QTRY_VERIFY(spyRemoved.count() > remSigCount); | 
| 2417 |     QTRY_VERIFY(spyObserverRemoved1->count() > 0); | 
| 2418 |     args = spyRemoved.takeFirst(); | 
| 2419 |     --remSigCount; | 
| 2420 |     arg = args.first().value<QList<QOrganizerItemId> >(); | 
| 2421 |     QVERIFY(arg.count() == 1); | 
| 2422 |     QCOMPARE(QOrganizerItemId(arg.at(0)), cid); | 
| 2423 |  | 
| 2424 |     // verify multiple adds works as advertised | 
| 2425 |     QOrganizerTodo todo2, todo3; | 
| 2426 |     QOrganizerItemDisplayLabel nc2, nc3; | 
| 2427 |     nc2.setLabel("Mark" ); | 
| 2428 |     nc3.setLabel("Garry" ); | 
| 2429 |     QVERIFY(todo2.saveDetail(&nc2)); | 
| 2430 |     QVERIFY(todo3.saveDetail(&nc3)); | 
| 2431 |     QVERIFY(m1->saveItem(&todo2)); | 
| 2432 |     QVERIFY(m1->saveItem(&todo3)); | 
| 2433 |     QTRY_COMPARE(spyModified.count(), modSigCount); | 
| 2434 |     QTRY_VERIFY(spyAdded.count() > addSigCount); | 
| 2435 |     addSigCount = spyAdded.count(); | 
| 2436 |  | 
| 2437 |     spyObserverModified1->clear(); | 
| 2438 |     spyObserverRemoved1->clear(); | 
| 2439 |     QScopedPointer<QOrganizerItemObserver> todo2Observer(new QOrganizerItemObserver(m1.data(), todo2.id())); | 
| 2440 |     QScopedPointer<QOrganizerItemObserver> todo3Observer(new QOrganizerItemObserver(m1.data(), todo3.id())); | 
| 2441 |     QScopedPointer<QSignalSpy> spyObserverModified2(new QSignalSpy(todo2Observer.data(), SIGNAL(itemChanged(QList<QOrganizerItemDetail::DetailType>)))); | 
| 2442 |     QScopedPointer<QSignalSpy> spyObserverModified3(new QSignalSpy(todo3Observer.data(), SIGNAL(itemChanged(QList<QOrganizerItemDetail::DetailType>)))); | 
| 2443 |     QScopedPointer<QSignalSpy> spyObserverRemoved2(new QSignalSpy(todo2Observer.data(), SIGNAL(itemRemoved()))); | 
| 2444 |     QScopedPointer<QSignalSpy> spyObserverRemoved3(new QSignalSpy(todo3Observer.data(), SIGNAL(itemRemoved()))); | 
| 2445 |  | 
| 2446 |     // verify multiple modifies works as advertised | 
| 2447 |     nc2.setLabel("M." ); | 
| 2448 |     QVERIFY(todo2.saveDetail(&nc2)); | 
| 2449 |     QVERIFY(m1->saveItem(&todo2)); | 
| 2450 |     nc2.setLabel("Mark" ); | 
| 2451 |     nc3.setLabel("G." ); | 
| 2452 |     QVERIFY(todo2.saveDetail(&nc2)); | 
| 2453 |     QVERIFY(todo3.saveDetail(&nc3)); | 
| 2454 |     QVERIFY(m1->saveItem(&todo2)); | 
| 2455 |     QVERIFY(m1->saveItem(&todo3)); | 
| 2456 |     QTRY_VERIFY(spyModified.count() > modSigCount); | 
| 2457 |     modSigCount = spyModified.count(); | 
| 2458 |     QTRY_VERIFY(spyObserverModified2->count() > 0); | 
| 2459 |     QTRY_VERIFY(spyObserverModified3->count() > 0); | 
| 2460 |     QCOMPARE(spyObserverModified1->count(), 0); | 
| 2461 |  | 
| 2462 |     // verify multiple removes works as advertised | 
| 2463 |     m1->removeItem(itemId: todo3.id()); | 
| 2464 |     m1->removeItem(itemId: todo2.id()); | 
| 2465 |     QTRY_VERIFY(spyRemoved.count() > remSigCount); | 
| 2466 |     remSigCount = spyRemoved.count(); | 
| 2467 |     QTRY_VERIFY(spyObserverRemoved2->count() > 0); | 
| 2468 |     QTRY_VERIFY(spyObserverRemoved3->count() > 0); | 
| 2469 |     QCOMPARE(spyObserverRemoved1->count(), 0); | 
| 2470 |  | 
| 2471 |     QVERIFY(!m1->removeItem(todo.id())); // not saved. | 
| 2472 |  | 
| 2473 |     /* Now test the batch equivalents */ | 
| 2474 |     spyAdded.clear(); | 
| 2475 |     spyModified.clear(); | 
| 2476 |     spyRemoved.clear(); | 
| 2477 |  | 
| 2478 |     /* Batch adds - set ids to zero so add succeeds. */ | 
| 2479 |     todo.setId(QOrganizerItemId()); | 
| 2480 |     todo2.setId(QOrganizerItemId()); | 
| 2481 |     todo3.setId(QOrganizerItemId()); | 
| 2482 |     batchAdd << todo << todo2 << todo3; | 
| 2483 |     QMap<int, QOrganizerManager::Error> errorMap; | 
| 2484 |     QVERIFY(m1->saveItems(&batchAdd)); | 
| 2485 |     errorMap = m1->errorMap(); | 
| 2486 |  | 
| 2487 |     QVERIFY(batchAdd.count() == 3); | 
| 2488 |     todo = batchAdd.at(i: 0); | 
| 2489 |     todo2 = batchAdd.at(i: 1); | 
| 2490 |     todo3 = batchAdd.at(i: 2); | 
| 2491 |  | 
| 2492 |     // We want to see one itemsAdded signal listing the id's for all three items | 
| 2493 |     QTRY_COMPARE(spyAdded.count(), 1); | 
| 2494 |     { | 
| 2495 |         QList<QOrganizerItemId> sigids = spyAdded.takeFirst().at(i: 0).value<QList<QOrganizerItemId> >(); | 
| 2496 |         QVERIFY(sigids.contains(todo.id())); | 
| 2497 |         QVERIFY(sigids.contains(todo2.id())); | 
| 2498 |         QVERIFY(sigids.contains(todo3.id())); | 
| 2499 |     } | 
| 2500 |     QTRY_COMPARE(spyModified.count(), 0); | 
| 2501 |  | 
| 2502 |     todo1Observer.reset(other: new QOrganizerItemObserver(m1.data(), todo.id())); | 
| 2503 |     todo2Observer.reset(other: new QOrganizerItemObserver(m1.data(), todo2.id())); | 
| 2504 |     todo3Observer.reset(other: new QOrganizerItemObserver(m1.data(), todo3.id())); | 
| 2505 |     spyObserverModified1.reset(other: new QSignalSpy(todo1Observer.data(), SIGNAL(itemChanged(QList<QOrganizerItemDetail::DetailType>)))); | 
| 2506 |     spyObserverModified2.reset(other: new QSignalSpy(todo2Observer.data(), SIGNAL(itemChanged(QList<QOrganizerItemDetail::DetailType>)))); | 
| 2507 |     spyObserverModified3.reset(other: new QSignalSpy(todo3Observer.data(), SIGNAL(itemChanged(QList<QOrganizerItemDetail::DetailType>)))); | 
| 2508 |     spyObserverRemoved1.reset(other: new QSignalSpy(todo1Observer.data(), SIGNAL(itemRemoved()))); | 
| 2509 |     spyObserverRemoved2.reset(other: new QSignalSpy(todo2Observer.data(), SIGNAL(itemRemoved()))); | 
| 2510 |     spyObserverRemoved3.reset(other: new QSignalSpy(todo3Observer.data(), SIGNAL(itemRemoved()))); | 
| 2511 |     QTRY_COMPARE(spyRemoved.count(), 0); | 
| 2512 |  | 
| 2513 |     /* Batch modifies */ | 
| 2514 |     QOrganizerItemDisplayLabel modifiedName = todo.detail(detailType: QOrganizerItemDetail::TypeDisplayLabel); | 
| 2515 |     modifiedName.setLabel("Modified number 1" ); | 
| 2516 |     modifiedName = todo2.detail(detailType: QOrganizerItemDetail::TypeDisplayLabel); | 
| 2517 |     modifiedName.setLabel("Modified number 2" ); | 
| 2518 |     modifiedName = todo3.detail(detailType: QOrganizerItemDetail::TypeDisplayLabel); | 
| 2519 |     modifiedName.setLabel("Modified number 3" ); | 
| 2520 |  | 
| 2521 |     batchAdd.clear(); | 
| 2522 |     batchAdd << todo << todo2 << todo3; | 
| 2523 |     QVERIFY(m1->saveItems(&batchAdd)); | 
| 2524 |     errorMap = m1->errorMap(); | 
| 2525 |  | 
| 2526 |     // We want to see one itemsChanged signal listing the id's for all three items. | 
| 2527 |     QTRY_COMPARE(spyModified.count(), 1); | 
| 2528 |     { | 
| 2529 |         QList<QOrganizerItemId> sigids = spyModified.takeFirst().at(i: 0).value<QList<QOrganizerItemId> >(); | 
| 2530 |         QVERIFY(sigids.contains(todo.id())); | 
| 2531 |         QVERIFY(sigids.contains(todo2.id())); | 
| 2532 |         QVERIFY(sigids.contains(todo3.id())); | 
| 2533 |     } | 
| 2534 |     QTRY_COMPARE(spyObserverModified1->count(), 1); | 
| 2535 |     QTRY_COMPARE(spyObserverModified2->count(), 1); | 
| 2536 |     QTRY_COMPARE(spyObserverModified3->count(), 1); | 
| 2537 |  | 
| 2538 |     /* Batch removes */ | 
| 2539 |     batchRemove << todo.id() << todo2.id() << todo3.id(); | 
| 2540 |     QVERIFY(m1->removeItems(batchRemove)); | 
| 2541 |     errorMap = m1->errorMap(); | 
| 2542 |  | 
| 2543 |     // We want to see one itemsRemoved signal listing the id's for all three items. | 
| 2544 |     QTRY_COMPARE(spyRemoved.count(), 1); | 
| 2545 |     { | 
| 2546 |         QList<QOrganizerItemId> sigids = spyRemoved.takeFirst().at(i: 0).value<QList<QOrganizerItemId> >(); | 
| 2547 |         QVERIFY(sigids.contains(todo.id())); | 
| 2548 |         QVERIFY(sigids.contains(todo2.id())); | 
| 2549 |         QVERIFY(sigids.contains(todo3.id())); | 
| 2550 |     } | 
| 2551 |     QTRY_COMPARE(spyObserverRemoved1->count(), 1); | 
| 2552 |     QTRY_COMPARE(spyObserverRemoved2->count(), 1); | 
| 2553 |     QTRY_COMPARE(spyObserverRemoved3->count(), 1); | 
| 2554 |  | 
| 2555 |     QTRY_COMPARE(spyAdded.count(), 0); | 
| 2556 |     QTRY_COMPARE(spyModified.count(), 0); | 
| 2557 |  | 
| 2558 |     /* Now some cross manager testing */ | 
| 2559 |     if (m1->managerName() == QStringLiteral("memory" )) | 
| 2560 |         QSKIP("Not supported by memory back-end" ); | 
| 2561 |  | 
| 2562 |     spyAdded.clear(); | 
| 2563 |     spyModified.clear(); | 
| 2564 |     spyRemoved.clear(); | 
| 2565 |     spyChanged.clear(); | 
| 2566 |  | 
| 2567 |  | 
| 2568 |     // verify that signals are emitted for modifications made to other managers (same id). | 
| 2569 |     QScopedPointer<QOrganizerManager> m2(QOrganizerManager::fromUri(uri)); | 
| 2570 |  | 
| 2571 |     // add one new item | 
| 2572 |     QOrganizerEvent newEvent; | 
| 2573 |     newEvent.setStartDateTime(QDateTime::currentDateTime()); | 
| 2574 |     newEvent.setEndDateTime(QDateTime::currentDateTime()); | 
| 2575 |     newEvent.setDisplayLabel(QStringLiteral("a new event" )); | 
| 2576 |  | 
| 2577 |     QVERIFY(m2->saveItem(&newEvent)); | 
| 2578 |     QTRY_VERIFY(spyChanged.count() || (spyAdded.count() > 0)); | 
| 2579 |  | 
| 2580 |     spyAdded.clear(); | 
| 2581 |     spyModified.clear(); | 
| 2582 |     spyRemoved.clear(); | 
| 2583 |     spyChanged.clear(); | 
| 2584 |  | 
| 2585 |     // modify the item | 
| 2586 |     newEvent.setEndDateTime(QDateTime::currentDateTime().addDays(days: 1)); | 
| 2587 |  | 
| 2588 |     QVERIFY(m2->saveItem(&newEvent)); | 
| 2589 |     QTRY_VERIFY(spyChanged.count() || (spyModified.count() > 0)); | 
| 2590 |  | 
| 2591 |     spyAdded.clear(); | 
| 2592 |     spyModified.clear(); | 
| 2593 |     spyRemoved.clear(); | 
| 2594 |     spyChanged.clear(); | 
| 2595 |  | 
| 2596 |     // remove the item | 
| 2597 |     QVERIFY(m2->removeItem(newEvent.id())); | 
| 2598 |     QTRY_VERIFY(spyChanged.count() || (spyRemoved.count() > 0)); | 
| 2599 |  | 
| 2600 |     spyAdded.clear(); | 
| 2601 |     spyModified.clear(); | 
| 2602 |     spyRemoved.clear(); | 
| 2603 |     spyChanged.clear(); | 
| 2604 |  | 
| 2605 |     // add several new items | 
| 2606 |     QOrganizerEvent moreEvents[10]; | 
| 2607 |     for (int i = 0; i < 10; ++i) {; | 
| 2608 |         moreEvents[i].setStartDateTime(QDateTime::currentDateTime()); | 
| 2609 |         moreEvents[i].setEndDateTime(QDateTime::currentDateTime()); | 
| 2610 |         moreEvents[i].setDisplayLabel(QStringLiteral("yet another event" )); | 
| 2611 |  | 
| 2612 |         QVERIFY(m2->saveItem(&moreEvents[i])); | 
| 2613 |     } | 
| 2614 |     QTRY_VERIFY(spyChanged.count() || (spyAdded.count() > 0)); | 
| 2615 |  | 
| 2616 |     spyAdded.clear(); | 
| 2617 |     spyModified.clear(); | 
| 2618 |     spyRemoved.clear(); | 
| 2619 |     spyChanged.clear(); | 
| 2620 |  | 
| 2621 |     // modify several items | 
| 2622 |     for (int i = 0; i < 10; ++i) { | 
| 2623 |         moreEvents[i].setEndDateTime(QDateTime::currentDateTime().addDays(days: i + 1)); | 
| 2624 |         QVERIFY(m2->saveItem(&moreEvents[i])); | 
| 2625 |     } | 
| 2626 |     QTRY_VERIFY(spyChanged.count() || (spyModified.count() > 0)); | 
| 2627 |  | 
| 2628 |     spyAdded.clear(); | 
| 2629 |     spyModified.clear(); | 
| 2630 |     spyRemoved.clear(); | 
| 2631 |     spyChanged.clear(); | 
| 2632 |  | 
| 2633 |     // remove several items | 
| 2634 |     for (int i = 0; i < 10; ++i) | 
| 2635 |         QVERIFY(m2->removeItem(moreEvents[i].id())); | 
| 2636 |     QTRY_VERIFY(spyChanged.count() || (spyRemoved.count() > 0)); | 
| 2637 |  | 
| 2638 |     spyChanged.clear(); | 
| 2639 |  | 
| 2640 |     QSignalSpy spyCollectionAdded(m1.data(), SIGNAL(collectionsAdded(QList<QOrganizerCollectionId>))); | 
| 2641 |     QSignalSpy spyCollectionModified(m1.data(), SIGNAL(collectionsChanged(QList<QOrganizerCollectionId>))); | 
| 2642 |     QSignalSpy spyCollectionRemoved(m1.data(), SIGNAL(collectionsRemoved(QList<QOrganizerCollectionId>))); | 
| 2643 |  | 
| 2644 |     // add one collection | 
| 2645 |     QOrganizerCollection newCollection; | 
| 2646 |     newCollection.setMetaData(key: QOrganizerCollection::KeyName, value: QVariant(QStringLiteral("a new collection" ))); | 
| 2647 |  | 
| 2648 |     QVERIFY(m2->saveCollection(&newCollection)); | 
| 2649 |     QTRY_VERIFY(spyChanged.count() || (spyCollectionAdded.count() > 0)); | 
| 2650 |  | 
| 2651 |     spyCollectionAdded.clear(); | 
| 2652 |     spyCollectionModified.clear(); | 
| 2653 |     spyCollectionRemoved.clear(); | 
| 2654 |     spyChanged.clear(); | 
| 2655 |  | 
| 2656 |     // modify one collection | 
| 2657 |     newCollection.setMetaData(key: QOrganizerCollection::KeyName, value: QVariant(QStringLiteral("a new collection, modified" ))); | 
| 2658 |  | 
| 2659 |     QVERIFY(m2->saveCollection(&newCollection)); | 
| 2660 |     QTRY_VERIFY(spyChanged.count() || (spyCollectionModified.count() > 0)); | 
| 2661 |  | 
| 2662 |     spyCollectionAdded.clear(); | 
| 2663 |     spyCollectionModified.clear(); | 
| 2664 |     spyCollectionRemoved.clear(); | 
| 2665 |     spyChanged.clear(); | 
| 2666 |  | 
| 2667 |     // remove one collection | 
| 2668 |     QVERIFY(m2->removeCollection(newCollection.id())); | 
| 2669 |     QTRY_VERIFY(spyChanged.count() || (spyCollectionRemoved.count() > 0)); | 
| 2670 | } | 
| 2671 |  | 
| 2672 | void tst_QOrganizerManager::errorStayingPut() | 
| 2673 | { | 
| 2674 |     /* Make sure that when we clone a manager, we don't clone the error */ | 
| 2675 |     QMap<QString, QString> params; | 
| 2676 |     params.insert(akey: "id" , avalue: "error isolation test" ); | 
| 2677 |     QOrganizerManager m1("memory" ,params); | 
| 2678 |  | 
| 2679 |     QVERIFY(m1.error() == QOrganizerManager::NoError); | 
| 2680 |  | 
| 2681 |     /* Remove an invalid item to get an error */ | 
| 2682 |     QVERIFY(m1.removeItem(QOrganizerItemId()) == false); | 
| 2683 |     QVERIFY(m1.error() == QOrganizerManager::DoesNotExistError); | 
| 2684 |  | 
| 2685 |     /* Create a new manager with hopefully the same backend */ | 
| 2686 |     QOrganizerManager m2("memory" , params); | 
| 2687 |  | 
| 2688 |     QVERIFY(m1.error() == QOrganizerManager::DoesNotExistError); | 
| 2689 |     QVERIFY(m2.error() == QOrganizerManager::NoError); | 
| 2690 |  | 
| 2691 |     /* Cause an error on the other ones and check the first is not affected */ | 
| 2692 |     m2.saveItems(items: 0); | 
| 2693 |     QVERIFY(m1.error() == QOrganizerManager::DoesNotExistError); | 
| 2694 |     QVERIFY(m2.error() == QOrganizerManager::BadArgumentError); | 
| 2695 |  | 
| 2696 |     QOrganizerItem c; | 
| 2697 |     QOrganizerItemDetail d(QOrganizerItemDetail::TypeUndefined); | 
| 2698 |     d.setValue(field: 101, value: 5); | 
| 2699 |     c.saveDetail(detail: &d); | 
| 2700 |  | 
| 2701 | //    QVERIFY(m1.saveItem(&c) == false); | 
| 2702 | //    QVERIFY(m1.error() == QOrganizerManager::InvalidDetailError); | 
| 2703 |     QVERIFY(m2.error() == QOrganizerManager::BadArgumentError); | 
| 2704 | } | 
| 2705 |  | 
| 2706 | void tst_QOrganizerManager::changeSet() | 
| 2707 | { | 
| 2708 |     QOrganizerItemId id; | 
| 2709 |  | 
| 2710 |     QOrganizerItemChangeSet changeSet; | 
| 2711 |     QVERIFY(changeSet.addedItems().isEmpty()); | 
| 2712 |     QVERIFY(changeSet.changedItems().isEmpty()); | 
| 2713 |     QVERIFY(changeSet.removedItems().isEmpty()); | 
| 2714 |  | 
| 2715 |     changeSet.insertAddedItem(itemId: id); | 
| 2716 |     QVERIFY(!changeSet.addedItems().isEmpty()); | 
| 2717 |     QVERIFY(changeSet.changedItems().isEmpty()); | 
| 2718 |     QVERIFY(changeSet.removedItems().isEmpty()); | 
| 2719 |     QVERIFY(changeSet.addedItems().contains(id)); | 
| 2720 |     changeSet.clearAddedItems(); | 
| 2721 |     changeSet.insertAddedItems(itemIds: QList<QOrganizerItemId>() << id); | 
| 2722 |  | 
| 2723 |     changeSet.insertChangedItem(itemId: id, typesChanged: QList<QOrganizerItemDetail::DetailType>()); | 
| 2724 |     changeSet.insertChangedItems(itemIds: QList<QOrganizerItemId>() << id, typesChanged: QList<QOrganizerItemDetail::DetailType>()); | 
| 2725 |     QCOMPARE(changeSet.changedItems().size(), 1); // set, should only be added once. | 
| 2726 |     QCOMPARE(changeSet.changedItems().first().second.size(), 1); // only one changed item ID | 
| 2727 |     QVERIFY(!changeSet.addedItems().isEmpty()); | 
| 2728 |     QVERIFY(!changeSet.changedItems().isEmpty()); | 
| 2729 |     QVERIFY(changeSet.removedItems().isEmpty()); | 
| 2730 |  | 
| 2731 |     changeSet.clearChangedItems(); | 
| 2732 |     changeSet.insertChangedItems(itemIds: QList<QOrganizerItemId>() << id, typesChanged: QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeDescription); | 
| 2733 |     changeSet.insertChangedItems(itemIds: QList<QOrganizerItemId>() << id, typesChanged: QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeTag); | 
| 2734 |     QCOMPARE(changeSet.changedItems().size(), 2); // should be added twice with differing change types | 
| 2735 |     QVERIFY(!changeSet.addedItems().isEmpty()); | 
| 2736 |     QVERIFY(!changeSet.changedItems().isEmpty()); | 
| 2737 |     QVERIFY(changeSet.removedItems().isEmpty()); | 
| 2738 |     QSet<QOrganizerItemId> changedIds; | 
| 2739 |     QSet<QOrganizerItemDetail::DetailType> changedTypes; | 
| 2740 |     foreach (const QOrganizerItemChangeSet::ItemChangeList &changes, changeSet.changedItems()) { | 
| 2741 |         changedIds |= changes.second.toSet(); | 
| 2742 |         if (changes.second.contains(t: id)) { | 
| 2743 |             changedTypes |= changes.first.toSet(); | 
| 2744 |         } | 
| 2745 |     } | 
| 2746 |     QCOMPARE(changedIds, (QList<QOrganizerItemId>() << id).toSet()); | 
| 2747 |     QCOMPARE(changedTypes, (QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeDescription << QOrganizerItemDetail::TypeTag).toSet()); | 
| 2748 |     changeSet.clearChangedItems(); | 
| 2749 |     QVERIFY(changeSet.changedItems().isEmpty()); | 
| 2750 |  | 
| 2751 |     QList<QOrganizerItemId> l1, l2; | 
| 2752 |     foreach (int n, QList<int>() << 1 << 1 << 1 << 2 << 2 << 3 << 3 << 4 << 4 << 4 << 5 << 10 << 9 << 8 << 8 << 8 << 7 << 7 << 6) { | 
| 2753 |         ((qrand() % 2) ? l1 : l2).append(t: makeItemId(id: n)); | 
| 2754 |     } | 
| 2755 |     changeSet.clearChangedItems(); | 
| 2756 |     changeSet.insertChangedItems(itemIds: l1, typesChanged: QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeDescription << QOrganizerItemDetail::TypeTag); | 
| 2757 |     changeSet.insertChangedItems(itemIds: l2, typesChanged: QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeTag << QOrganizerItemDetail::TypeDescription << QOrganizerItemDetail::TypeTag); | 
| 2758 |     QCOMPARE(changeSet.changedItems().size(), 1); | 
| 2759 |     QList<QOrganizerItemId> expected((l1.toSet() | l2.toSet()).toList()); | 
| 2760 |     qSort(c&: expected); | 
| 2761 |     QCOMPARE(changeSet.changedItems().first().second, expected); | 
| 2762 |  | 
| 2763 |     changeSet.insertRemovedItems(itemIds: QList<QOrganizerItemId>() << id); | 
| 2764 |     QVERIFY(changeSet.removedItems().contains(id)); | 
| 2765 |     changeSet.clearRemovedItems(); | 
| 2766 |     QVERIFY(changeSet.removedItems().isEmpty()); | 
| 2767 |  | 
| 2768 |     QVERIFY(changeSet.dataChanged() == false); | 
| 2769 |     QOrganizerItemChangeSet changeSet2; | 
| 2770 |     changeSet2 = changeSet; | 
| 2771 |     QVERIFY(changeSet.addedItems() == changeSet2.addedItems()); | 
| 2772 |     changeSet.emitSignals(engine: 0); | 
| 2773 |  | 
| 2774 |     changeSet2.clearAddedItems(); | 
| 2775 |     QVERIFY(changeSet2.addedItems().isEmpty()); | 
| 2776 |     changeSet2.insertAddedItems(itemIds: changeSet.addedItems().toList()); | 
| 2777 |     QVERIFY(changeSet.addedItems() == changeSet2.addedItems()); | 
| 2778 |  | 
| 2779 |     changeSet2.clearAll(); | 
| 2780 |     QVERIFY(changeSet.addedItems() != changeSet2.addedItems()); | 
| 2781 |  | 
| 2782 |     QOrganizerItemChangeSet changeSet3(changeSet2); | 
| 2783 |     QVERIFY(changeSet.addedItems() != changeSet3.addedItems()); | 
| 2784 |     QVERIFY(changeSet2.addedItems() == changeSet3.addedItems()); | 
| 2785 |  | 
| 2786 |     changeSet.setDataChanged(true); | 
| 2787 |     QVERIFY(changeSet.dataChanged() == true); | 
| 2788 |     QVERIFY(changeSet.dataChanged() != changeSet2.dataChanged()); | 
| 2789 |     QVERIFY(changeSet.dataChanged() != changeSet3.dataChanged()); | 
| 2790 |     changeSet.emitSignals(engine: 0); | 
| 2791 |  | 
| 2792 |     QOrganizerCollectionId colId; | 
| 2793 |  | 
| 2794 |     QOrganizerCollectionChangeSet colChangeSet; | 
| 2795 |     QVERIFY(colChangeSet.addedCollections().isEmpty()); | 
| 2796 |     QVERIFY(colChangeSet.changedCollections().isEmpty()); | 
| 2797 |     QVERIFY(colChangeSet.removedCollections().isEmpty()); | 
| 2798 |  | 
| 2799 |     colChangeSet.insertAddedCollection(collectionId: colId); | 
| 2800 |     QVERIFY(!changeSet.addedItems().isEmpty()); | 
| 2801 |     QVERIFY(colChangeSet.changedCollections().isEmpty()); | 
| 2802 |     QVERIFY(colChangeSet.removedCollections().isEmpty()); | 
| 2803 |     QVERIFY(colChangeSet.addedCollections().contains(colId)); | 
| 2804 |     colChangeSet.clearAddedCollections(); | 
| 2805 |     colChangeSet.insertAddedCollections(collectionIds: QList<QOrganizerCollectionId>() << colId); | 
| 2806 |  | 
| 2807 |     colChangeSet.insertChangedCollection(collectionId: colId); | 
| 2808 |     colChangeSet.insertChangedCollections(collectionIds: QList<QOrganizerCollectionId>() << colId); | 
| 2809 |     QVERIFY(colChangeSet.changedCollections().size() == 1); // set, should only be added once. | 
| 2810 |     QVERIFY(!colChangeSet.addedCollections().isEmpty()); | 
| 2811 |     QVERIFY(!colChangeSet.changedCollections().isEmpty()); | 
| 2812 |     QVERIFY(colChangeSet.removedCollections().isEmpty()); | 
| 2813 |     QVERIFY(colChangeSet.changedCollections().contains(colId)); | 
| 2814 |     colChangeSet.clearChangedCollections(); | 
| 2815 |     QVERIFY(colChangeSet.changedCollections().isEmpty()); | 
| 2816 |  | 
| 2817 |     colChangeSet.insertRemovedCollections(collectionIds: QList<QOrganizerCollectionId>() << colId); | 
| 2818 |     QVERIFY(colChangeSet.removedCollections().contains(colId)); | 
| 2819 |     colChangeSet.clearRemovedCollections(); | 
| 2820 |     QVERIFY(colChangeSet.removedCollections().isEmpty()); | 
| 2821 |  | 
| 2822 |     QVERIFY(colChangeSet.dataChanged() == false); | 
| 2823 |     QOrganizerCollectionChangeSet colChangeSet2; | 
| 2824 |     colChangeSet2 = colChangeSet; | 
| 2825 |     QVERIFY(colChangeSet.addedCollections() == colChangeSet2.addedCollections()); | 
| 2826 |     colChangeSet.emitSignals(engine: 0); | 
| 2827 |  | 
| 2828 |     colChangeSet2.clearAddedCollections(); | 
| 2829 |     QVERIFY(colChangeSet2.addedCollections().isEmpty()); | 
| 2830 |     colChangeSet2.insertAddedCollections(collectionIds: colChangeSet.addedCollections().toList()); | 
| 2831 |     QVERIFY(colChangeSet.addedCollections() == colChangeSet2.addedCollections()); | 
| 2832 |  | 
| 2833 |     colChangeSet2.clearAll(); | 
| 2834 |     QVERIFY(colChangeSet.addedCollections() != colChangeSet2.addedCollections()); | 
| 2835 |  | 
| 2836 |     QOrganizerCollectionChangeSet colChangeSet3(colChangeSet2); | 
| 2837 |     QVERIFY(colChangeSet.addedCollections() != colChangeSet3.addedCollections()); | 
| 2838 |     QVERIFY(colChangeSet2.addedCollections() == colChangeSet3.addedCollections()); | 
| 2839 |  | 
| 2840 |     colChangeSet.setDataChanged(true); | 
| 2841 |     QVERIFY(colChangeSet.dataChanged() == true); | 
| 2842 |     QVERIFY(colChangeSet.dataChanged() != colChangeSet2.dataChanged()); | 
| 2843 |     QVERIFY(colChangeSet.dataChanged() != colChangeSet3.dataChanged()); | 
| 2844 |     colChangeSet.emitSignals(engine: 0); | 
| 2845 | } | 
| 2846 |  | 
| 2847 | void tst_QOrganizerManager::fetchHint() | 
| 2848 | { | 
| 2849 |     QOrganizerItemFetchHint hint; | 
| 2850 |     hint.setOptimizationHints(QOrganizerItemFetchHint::NoBinaryBlobs); | 
| 2851 |     QCOMPARE(hint.optimizationHints(), QOrganizerItemFetchHint::NoBinaryBlobs); | 
| 2852 | } | 
| 2853 |  | 
| 2854 | void tst_QOrganizerManager::testFilterFunction() | 
| 2855 | { | 
| 2856 |     QOrganizerEvent item; | 
| 2857 |     item.setId(makeItemId(id: 10)); | 
| 2858 |     item.setStartDateTime(QDateTime(QDate(2010,10,10), QTime(10,10))); | 
| 2859 |     item.setEndDateTime(QDateTime(QDate(2010,10,10), QTime(12,10))); | 
| 2860 |     item.setDisplayLabel("test" ); | 
| 2861 |     item.setCollectionId(makeCollectionId(id: 1)); | 
| 2862 |  | 
| 2863 |     // Test for QOrganizerItemFilter::InvalidFilter | 
| 2864 |     QOrganizerItemInvalidFilter fif; | 
| 2865 |     QVERIFY(!QOrganizerManagerEngine::testFilter(fif, item)); | 
| 2866 |  | 
| 2867 |     // Test for QOrganizerItemFilter::IdFilter: | 
| 2868 |     QOrganizerItemIdFilter fidf; | 
| 2869 |     fidf.setIds(QList<QOrganizerItemId>() << makeItemId(id: 10)); | 
| 2870 |     QVERIFY(QOrganizerManagerEngine::testFilter(fidf, item)); | 
| 2871 |  | 
| 2872 |     // test for nonexistent id | 
| 2873 |     fidf.setIds(QList<QOrganizerItemId>() << makeItemId(id: 11)); | 
| 2874 |     QVERIFY(!QOrganizerManagerEngine::testFilter(fidf, item)); | 
| 2875 |  | 
| 2876 |     // Test for QOrganizerItemFilter::DefaultFilter: | 
| 2877 |     QOrganizerItemFilter fdf; | 
| 2878 |     QVERIFY(fdf.type() == QOrganizerItemFilter::DefaultFilter); | 
| 2879 |     QVERIFY(QOrganizerManagerEngine::testFilter(fdf, item)); | 
| 2880 |  | 
| 2881 |     // Test for QOrganizerItemFilter::OrganizerItemDetailFieldFilter: | 
| 2882 |     QOrganizerItemDetailFieldFilter fdef; | 
| 2883 |     fdef.setDetail(detailType: QOrganizerItemDetail::TypeDisplayLabel, field: QOrganizerItemDisplayLabel::FieldLabel); | 
| 2884 |     fdef.setValue("invalid" ); | 
| 2885 |     // test for nonexistent label | 
| 2886 |     QVERIFY(!QOrganizerManagerEngine::testFilter(fdef, item)); | 
| 2887 |  | 
| 2888 |     fdef.setValue("test" ); | 
| 2889 |     // test for existent label | 
| 2890 |     QVERIFY(QOrganizerManagerEngine::testFilter(fdef, item)); | 
| 2891 |  | 
| 2892 |     // Test for QOrganizerItemFilter::OrganizerItemDetailRangeFilter: | 
| 2893 |     QOrganizerItemDetailRangeFilter fdrf; | 
| 2894 |     fdrf.setDetail(detailType: QOrganizerItemDetail::TypeEventTime, field: QOrganizerEventTime::FieldStartDateTime); | 
| 2895 |     fdrf.setRange(min: QDateTime(QDate(2010,10,9)), max: QDateTime(QDate(2010,10,11))); | 
| 2896 |     // test for a valid range | 
| 2897 |     QVERIFY(QOrganizerManagerEngine::testFilter(fdrf, item)); | 
| 2898 |  | 
| 2899 |     fdrf.setRange(min: QDateTime(QDate(2010,10,11)), max: QDateTime(QDate(2010,10,12))); | 
| 2900 |     // test for item not in the range | 
| 2901 |     QVERIFY(!QOrganizerManagerEngine::testFilter(fdrf, item)); | 
| 2902 |  | 
| 2903 |     // Test for QOrganizerItemFilter::IntersectionFilter: | 
| 2904 |     QOrganizerItemIntersectionFilter oiif; | 
| 2905 |     oiif.setFilters(QList<QOrganizerItemFilter>() << fif << fdf); | 
| 2906 |     // check for an invalid filter and default filter intersection | 
| 2907 |     QVERIFY(!QOrganizerManagerEngine::testFilter(oiif, item)); | 
| 2908 |  | 
| 2909 |     oiif.setFilters(QList<QOrganizerItemFilter>() << fdef << fdf); | 
| 2910 |     // check for a detail filter and default filter intersection | 
| 2911 |     QVERIFY(QOrganizerManagerEngine::testFilter(oiif, item)); | 
| 2912 |  | 
| 2913 |     // Test for QOrganizerItemFilter::UnionFilter: | 
| 2914 |     QOrganizerItemUnionFilter oiuf; | 
| 2915 |     oiuf.setFilters(QList<QOrganizerItemFilter>() << fif << fdf); | 
| 2916 |     // check for an invalid filter and default filter union | 
| 2917 |     QVERIFY(QOrganizerManagerEngine::testFilter(oiuf, item)); | 
| 2918 |  | 
| 2919 |     oiuf.setFilters(QList<QOrganizerItemFilter>() << fdef << fdf); | 
| 2920 |     // check for a detail filter and default filter union | 
| 2921 |     QVERIFY(QOrganizerManagerEngine::testFilter(oiuf, item)); | 
| 2922 |  | 
| 2923 |     // Test for QOrganizerItemFilter::CollectionFilter: | 
| 2924 |     QOrganizerItemCollectionFilter oicf; | 
| 2925 |     oicf.setCollectionId(makeCollectionId(id: 1)); | 
| 2926 |     // check for existing collection id | 
| 2927 |     QVERIFY(QOrganizerManagerEngine::testFilter(oicf, item)); | 
| 2928 |  | 
| 2929 |     oicf.setCollectionId(makeCollectionId(id: 2)); | 
| 2930 |     // check for nonexisting collection id | 
| 2931 |     QVERIFY(!QOrganizerManagerEngine::testFilter(oicf, item)); | 
| 2932 | } | 
| 2933 |  | 
| 2934 |  | 
| 2935 | void tst_QOrganizerManager::dataSerialization() | 
| 2936 | { | 
| 2937 |     QFETCH(QString, uri); | 
| 2938 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 2939 |  | 
| 2940 |     QOrganizerEvent event; | 
| 2941 |     event.setDisplayLabel("event" ); | 
| 2942 |     event.setStartDateTime(QDateTime(QDate(2010, 9, 9), QTime(11, 0, 0))); | 
| 2943 |     event.setEndDateTime(QDateTime(QDate(2010, 9, 9), QTime(11, 30, 0))); | 
| 2944 |  | 
| 2945 |     if (cm->saveItem(item: &event)) { | 
| 2946 |         QByteArray buffer; | 
| 2947 |         QDataStream outBufferStream(&buffer, QIODevice::WriteOnly); | 
| 2948 |         outBufferStream << event.id().toString(); | 
| 2949 |         QVERIFY(buffer.length() > 0); | 
| 2950 |  | 
| 2951 |         QDataStream inBufferStream(buffer); | 
| 2952 |         QString inString; | 
| 2953 |         inBufferStream >> inString; | 
| 2954 |         QOrganizerItemId id = QOrganizerItemId::fromString(idString: inString); | 
| 2955 |  | 
| 2956 |         QVERIFY(id == event.id()); | 
| 2957 |     } | 
| 2958 | } | 
| 2959 |  | 
| 2960 | void tst_QOrganizerManager::itemFilterFetch() | 
| 2961 | { | 
| 2962 |     // Some of the tests present on itemFetch()-tests, but this test extends the cases a bit | 
| 2963 |     // Preparations | 
| 2964 |     QFETCH(QString, uri); | 
| 2965 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 2966 |     QOrganizerItemExtendedDetail extDetail; | 
| 2967 |     QOrganizerItemComment ; | 
| 2968 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 2969 |     for (int i=0; i<6; i++) { | 
| 2970 |         QOrganizerEvent event; | 
| 2971 |         event.setDisplayLabel(QString("event %1" ).arg(a: i)); | 
| 2972 |         event.setStartDateTime(QDateTime(QDate(2010, 9, 9), QTime(11, 0, 0))); | 
| 2973 |         event.setEndDateTime(QDateTime(QDate(2010, 9, 9), QTime(11, 30, 0))); | 
| 2974 |         if (i==0) { | 
| 2975 |             // 1 | 
| 2976 |             event.setPriority(QOrganizerItemPriority::VeryLowPriority); | 
| 2977 |         } else if (i==1) { | 
| 2978 |             // 2 | 
| 2979 |             comment.setComment("my comment" ); | 
| 2980 |             event.saveDetail(detail: &comment); | 
| 2981 |         } else if (i==2) { | 
| 2982 |             // 3 | 
| 2983 |             QOrganizerItemDisplayLabel label; | 
| 2984 |             label.setLabel("my 3rd event!" ); | 
| 2985 |             event.saveDetail(detail: &label); | 
| 2986 |         } else if (i==3) { | 
| 2987 |             // 4 | 
| 2988 |             QOrganizerItemDisplayLabel label; | 
| 2989 |             label.setLabel("my 4th event!" ); | 
| 2990 |             event.saveDetail(detail: &label); | 
| 2991 |         } else if (i==4) { | 
| 2992 |             // 5 | 
| 2993 |             event.setEndDateTime(QDateTime(QDate(2010, 10, 10), QTime(11, 0, 0))); | 
| 2994 |         } else if (i==5) { | 
| 2995 |             // 6 | 
| 2996 |             extDetail.setName("DetailOfMine" ); | 
| 2997 |             extDetail.setData(42); | 
| 2998 |             event.saveDetail(detail: &extDetail); | 
| 2999 |         } | 
| 3000 |         QVERIFY(cm->saveItem(&event)); | 
| 3001 |     } | 
| 3002 |     QCOMPARE(cm->items().count(), 6); | 
| 3003 |  | 
| 3004 |     // DetailFieldFilter Checks | 
| 3005 |     QOrganizerItemDetailFieldFilter dFieldFilter; | 
| 3006 |     // 1 | 
| 3007 |     dFieldFilter.setDetail(detailType: QOrganizerItemDetail::TypePriority, field: QOrganizerItemPriority::FieldPriority); | 
| 3008 |     dFieldFilter.setValue(QOrganizerItemPriority::VeryHighPriority); | 
| 3009 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 0); | 
| 3010 |     dFieldFilter.setValue(QOrganizerItemPriority::VeryLowPriority); | 
| 3011 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 1); | 
| 3012 |     // 2 | 
| 3013 |     dFieldFilter.setDetail(detailType: QOrganizerItemDetail::TypeComment, field: QOrganizerItemComment::FieldComment); | 
| 3014 |     dFieldFilter.setValue("my comment" ); | 
| 3015 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 1); | 
| 3016 |     // 3-4 | 
| 3017 |     dFieldFilter.setDetail(detailType: QOrganizerItemDetail::TypeDisplayLabel, field: QOrganizerItemDisplayLabel::FieldLabel); | 
| 3018 |     dFieldFilter.setValue("my 3rd event!" ); | 
| 3019 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 1); | 
| 3020 |     dFieldFilter.setMatchFlags(QOrganizerItemFilter::MatchEndsWith); | 
| 3021 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 1); | 
| 3022 |     dFieldFilter.setValue("event!" ); | 
| 3023 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 2); | 
| 3024 |     dFieldFilter.setValue("event" ); | 
| 3025 |     dFieldFilter.setMatchFlags(QOrganizerItemFilter::MatchContains); | 
| 3026 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), cm->items().count()); | 
| 3027 |     dFieldFilter.setValue("my" ); | 
| 3028 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 2); | 
| 3029 |     dFieldFilter.setMatchFlags(QOrganizerItemFilter::MatchStartsWith); | 
| 3030 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 2); | 
| 3031 |     dFieldFilter.setValue("event" ); | 
| 3032 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 4); | 
| 3033 |     // 5 | 
| 3034 |     dFieldFilter.setMatchFlags(QOrganizerItemFilter::MatchExactly); | 
| 3035 |     dFieldFilter.setDetail(detailType: QOrganizerItemDetail::TypeEventTime, field: QOrganizerEventTime::FieldEndDateTime); | 
| 3036 |     dFieldFilter.setValue(QDateTime(QDate(2010, 10, 10), QTime(11, 0, 0))); | 
| 3037 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 1); | 
| 3038 |     // 6 | 
| 3039 |     dFieldFilter.setDetail(detailType: QOrganizerItemDetail::TypeExtendedDetail, field: QOrganizerItemExtendedDetail::FieldName); | 
| 3040 |     dFieldFilter.setValue("DetailOfMine" ); | 
| 3041 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dFieldFilter).count(), 1); | 
| 3042 |  | 
| 3043 |     // DetailFilter Checks | 
| 3044 |     if (cm->managerName() == QStringLiteral("memory" )) { | 
| 3045 |         QOrganizerItemDetailFilter dFilter; | 
| 3046 |         // 1 | 
| 3047 |         QOrganizerItemPriority priority; | 
| 3048 |         priority.setPriority(QOrganizerItemPriority::VeryHighPriority); | 
| 3049 |         dFilter.setDetail(priority); | 
| 3050 |         QCOMPARE(cm->items(QDateTime(), QDateTime(), dFilter).count(), 0); | 
| 3051 |         priority.setPriority(QOrganizerItemPriority::VeryLowPriority); | 
| 3052 |         dFilter.setDetail(priority); | 
| 3053 |         QCOMPARE(cm->items(QDateTime(), QDateTime(), dFilter).count(), 1); | 
| 3054 |         // 2 | 
| 3055 |         dFilter.setDetail(comment); | 
| 3056 |         QCOMPARE(cm->items(QDateTime(), QDateTime(), dFilter).count(), 1); | 
| 3057 |         // 3-4 | 
| 3058 |         QOrganizerItemDisplayLabel displayLabel; | 
| 3059 |         displayLabel.setLabel(QStringLiteral("my 3rd event!" )); | 
| 3060 |         dFilter.setDetail(displayLabel); | 
| 3061 |         QCOMPARE(cm->items(QDateTime(), QDateTime(), dFilter).count(), 1); | 
| 3062 |         displayLabel.setLabel(QStringLiteral("my non existing event!" )); | 
| 3063 |         dFilter.setDetail(displayLabel); | 
| 3064 |         QCOMPARE(cm->items(QDateTime(), QDateTime(), dFilter).count(), 0); | 
| 3065 |         // 5 | 
| 3066 |         QOrganizerEventTime eventTime; | 
| 3067 |         eventTime.setEndDateTime(QDateTime(QDate(2010, 10, 10), QTime(11, 0, 0))); | 
| 3068 |         eventTime.setStartDateTime(QDateTime(QDate(2010, 9, 9), QTime(11, 0, 0))); | 
| 3069 |         dFilter.setDetail(eventTime); | 
| 3070 |         QCOMPARE(cm->items(QDateTime(), QDateTime(), dFilter).count(), 1); | 
| 3071 |         // 6 | 
| 3072 |         dFilter.setDetail(extDetail); | 
| 3073 |         QCOMPARE(cm->items(QDateTime(), QDateTime(), dFilter).count(), 1); | 
| 3074 |     } | 
| 3075 |  | 
| 3076 | } | 
| 3077 |  | 
| 3078 | void tst_QOrganizerManager::itemFetch() | 
| 3079 | { | 
| 3080 |     QFETCH(QString, uri); | 
| 3081 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 3082 |  | 
| 3083 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3084 |  | 
| 3085 |     QOrganizerEvent event; | 
| 3086 |     event.setDisplayLabel("event" ); | 
| 3087 |     event.setStartDateTime(QDateTime(QDate(2010, 9, 9), QTime(11, 0, 0))); | 
| 3088 |     event.setEndDateTime(QDateTime(QDate(2010, 9, 9), QTime(11, 30, 0))); | 
| 3089 |     QVERIFY(cm->saveItem(&event)); | 
| 3090 |  | 
| 3091 |     QOrganizerEvent recEvent; | 
| 3092 |     recEvent.setDisplayLabel("daily event" ); | 
| 3093 |     recEvent.setStartDateTime(QDateTime(QDate(2010, 9, 1), QTime(16, 0, 0))); | 
| 3094 |     recEvent.setEndDateTime(QDateTime(QDate(2010, 9, 1), QTime(16, 30, 0))); | 
| 3095 |     QOrganizerRecurrenceRule rrule; | 
| 3096 |     rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 3097 |     rrule.setLimit(QDate(2010, 9, 10)); | 
| 3098 |     recEvent.setRecurrenceRule(rrule); | 
| 3099 |     QVERIFY(cm->saveItem(&recEvent)); | 
| 3100 |  | 
| 3101 |     //fetch all recurrences | 
| 3102 |     QList<QOrganizerItem> items = cm->items(startDateTime: QDateTime(QDate(2010, 9, 8)), endDateTime: QDateTime(QDate(2010, 9, 12))); | 
| 3103 |     QCOMPARE(items.count(), 4); // should return event + 3 x occurrencesOfRecEvent | 
| 3104 |  | 
| 3105 |     //fetch only the originating items | 
| 3106 |     items = cm->itemsForExport(startDateTime: QDateTime(QDate(2010, 9, 8)), endDateTime: QDateTime(QDate(2010, 9, 12)), | 
| 3107 |                                filter: QOrganizerItemFilter(), sortOrders: QList<QOrganizerItemSortOrder>(), fetchHint: QOrganizerItemFetchHint()); | 
| 3108 |     QCOMPARE(items.count(), 2); | 
| 3109 |  | 
| 3110 |     // test semantics of items(): | 
| 3111 |     // first - save event with multiple occurrences; call items() -- should get back just occurrences. | 
| 3112 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3113 |     rrule.setLimit(QDate(2010, 9, 3)); | 
| 3114 |     recEvent.setRecurrenceRule(rrule); | 
| 3115 |     recEvent.setId(QOrganizerItemId()); | 
| 3116 |     cm->saveItem(item: &recEvent); | 
| 3117 |     items = cm->items(); | 
| 3118 |     QCOMPARE(items.count(), 3); | 
| 3119 |     foreach (const QOrganizerItem &item, items) | 
| 3120 |         QVERIFY(item.type() == QOrganizerItemType::TypeEventOccurrence); | 
| 3121 |  | 
| 3122 |     // second - the same situation, but giving a time span that only covers the first day - should get back a single occurrence. | 
| 3123 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 9, 1), QTime(15, 0, 0)), endDateTime: QDateTime(QDate(2010, 9, 1), QTime(18, 0, 0))); | 
| 3124 |     QCOMPARE(items.count(), 1); | 
| 3125 |     foreach (const QOrganizerItem& item, items) { | 
| 3126 |         QVERIFY(item.type() == QOrganizerItemType::TypeEventOccurrence); | 
| 3127 |     } | 
| 3128 |  | 
| 3129 |     // third - save event with no recurrence; call items() -- should get back that parent, not an occurrence. | 
| 3130 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3131 |     recEvent.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>()); // clear rrule. | 
| 3132 |     recEvent.setId(QOrganizerItemId()); | 
| 3133 |     cm->saveItem(item: &recEvent); | 
| 3134 |     items = cm->items(); | 
| 3135 |     QCOMPARE(items.count(), 1); | 
| 3136 |     foreach (const QOrganizerItem &item, items) | 
| 3137 |         QVERIFY(item.type() == QOrganizerItemType::TypeEvent); | 
| 3138 |  | 
| 3139 |     // fourth - the same situation, but giving a time span.  should still get back the parent. | 
| 3140 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 9, 1), QTime(15, 0, 0)), endDateTime: QDateTime(QDate(2010, 9, 1), QTime(18, 0, 0))); | 
| 3141 |     QCOMPARE(items.count(), 1); | 
| 3142 |     foreach (const QOrganizerItem &item, items) | 
| 3143 |         QVERIFY(item.type() == QOrganizerItemType::TypeEvent); | 
| 3144 |  | 
| 3145 |     // test semantics of itemsForExport(): | 
| 3146 |     // first - save event with multiple occurrences; call ife() -- get back that parent | 
| 3147 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3148 |     recEvent.setRecurrenceRule(rrule); | 
| 3149 |     recEvent.setId(QOrganizerItemId()); | 
| 3150 |     cm->saveItem(item: &recEvent); | 
| 3151 |     items = cm->itemsForExport(); | 
| 3152 |     QCOMPARE(items.count(), 1); | 
| 3153 |     foreach (const QOrganizerItem& item, items) { | 
| 3154 |         QVERIFY(item.type() == QOrganizerItemType::TypeEvent); | 
| 3155 |     } | 
| 3156 |  | 
| 3157 |     // second - call items, resave only the first occurrence as an exception, | 
| 3158 |     // call ife() -- get back parent + exception | 
| 3159 |     items = cm->items(); | 
| 3160 |     QCOMPARE(items.size(), 3); // 3 occurrences. | 
| 3161 |     int eventCount = 0; | 
| 3162 |     int eventOccurrenceCount = 0; | 
| 3163 |     foreach (const QOrganizerItem& item, items) { | 
| 3164 |         if (item.type() == QOrganizerItemType::TypeEventOccurrence) { | 
| 3165 |             if (eventOccurrenceCount == 0) { | 
| 3166 |                 QOrganizerEventOccurrence exception(item); | 
| 3167 |                 exception.setDisplayLabel("exception" ); | 
| 3168 |                 QVERIFY(cm->saveItem(&exception)); | 
| 3169 |             } | 
| 3170 |             eventOccurrenceCount++; | 
| 3171 |         } else if (item.type() == QOrganizerItemType::TypeEvent) { | 
| 3172 |             eventCount++; | 
| 3173 |         } | 
| 3174 |     } | 
| 3175 |     QCOMPARE(eventOccurrenceCount, 3); | 
| 3176 |     QCOMPARE(eventCount, 0); | 
| 3177 |     items = cm->items(); // reload items after saving exception | 
| 3178 |     QCOMPARE(items.size(), 3); // saving the exception shouldn't have added more items. | 
| 3179 |     items = cm->itemsForExport(); | 
| 3180 |     QCOMPARE(items.count(), 2); | 
| 3181 |     eventCount = 0; | 
| 3182 |     eventOccurrenceCount = 0; | 
| 3183 |     foreach (const QOrganizerItem& item, items) { | 
| 3184 |         if (item.type() == QOrganizerItemType::TypeEvent) { | 
| 3185 |             eventCount += 1; | 
| 3186 |         } else if (item.type() == QOrganizerItemType::TypeEventOccurrence) { | 
| 3187 |             eventOccurrenceCount += 1; | 
| 3188 |         } | 
| 3189 |         QVERIFY(!item.id().isNull()); // should NEVER be null, since that would be a generated occurrence. | 
| 3190 |     } | 
| 3191 |     QCOMPARE(eventCount, 1); | 
| 3192 |     QCOMPARE(eventOccurrenceCount, 1); | 
| 3193 |  | 
| 3194 |     //make a parent filter and test item count | 
| 3195 |     QOrganizerItemDetailFieldFilter dff; | 
| 3196 |     dff.setDetail(detailType: QOrganizerItemDetail::TypeParent, field: QOrganizerItemParent::FieldParentId); | 
| 3197 |     dff.setValue(QVariant::fromValue(value: recEvent.id())); | 
| 3198 |     QCOMPARE(cm->items(QDateTime(), QDateTime(), dff).count(), 3); | 
| 3199 |     QCOMPARE(cm->itemsForExport(QDateTime(), QDateTime(), dff).count(), 2); | 
| 3200 |  | 
| 3201 |     // third, have all occurrences persisted | 
| 3202 |     items = cm->items(); | 
| 3203 |     QCOMPARE(items.size(), 3); // should be three occurrences | 
| 3204 |     foreach (const QOrganizerItem& item, items) { | 
| 3205 |         if (item.type() == QOrganizerItemType::TypeEventOccurrence) { | 
| 3206 |             QOrganizerEventOccurrence exception(item); | 
| 3207 |             exception.setDisplayLabel("exception" ); | 
| 3208 |             QVERIFY(cm->saveItem(&exception)); | 
| 3209 |         } | 
| 3210 |     } | 
| 3211 |     items = cm->itemsForExport(); | 
| 3212 |     QCOMPARE(items.size(), 4); // parent + 3 persisted exceptions | 
| 3213 |     eventCount = 0; | 
| 3214 |     eventOccurrenceCount = 0; | 
| 3215 |     foreach (const QOrganizerItem& item, items) { | 
| 3216 |         if (item.type() == QOrganizerItemType::TypeEvent) { | 
| 3217 |             eventCount += 1; | 
| 3218 |         } else if (item.type() == QOrganizerItemType::TypeEventOccurrence) { | 
| 3219 |             eventOccurrenceCount += 1; | 
| 3220 |         } | 
| 3221 |         QVERIFY(!item.id().isNull()); // should NEVER be null, since that would be a generated occurrence. | 
| 3222 |     } | 
| 3223 |     QCOMPARE(eventCount, 1); | 
| 3224 |     QCOMPARE(eventOccurrenceCount, 3); | 
| 3225 |  | 
| 3226 |     // fourth, all occurrences persisted, time period excludes parent item, but it's still fetched | 
| 3227 |     items = cm->itemsForExport(startDateTime: QDateTime(QDate(2010, 9, 2)), | 
| 3228 |                                endDateTime: QDateTime(QDate(2010, 9, 4))); | 
| 3229 |     QCOMPARE(items.size(), 3); // parent + 2 persisted exceptions | 
| 3230 |     eventCount = 0; | 
| 3231 |     eventOccurrenceCount = 0; | 
| 3232 |     foreach (const QOrganizerItem& item, items) { | 
| 3233 |         if (item.type() == QOrganizerItemType::TypeEvent) { | 
| 3234 |             eventCount += 1; | 
| 3235 |         } else if (item.type() == QOrganizerItemType::TypeEventOccurrence) { | 
| 3236 |             eventOccurrenceCount += 1; | 
| 3237 |         } | 
| 3238 |         QVERIFY(!item.id().isNull()); // should NEVER be null, since that would be a generated occurrence. | 
| 3239 |     } | 
| 3240 |     QCOMPARE(eventCount, 1); | 
| 3241 |     QCOMPARE(eventOccurrenceCount, 2); | 
| 3242 |  | 
| 3243 |  | 
| 3244 | } | 
| 3245 |  | 
| 3246 | // This is mostly a copy of itemFetch(), but for todos | 
| 3247 | void tst_QOrganizerManager::todoItemFetch() | 
| 3248 | { | 
| 3249 |     QFETCH(QString, uri); | 
| 3250 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 3251 |     QList<QOrganizerItem> items; | 
| 3252 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3253 |  | 
| 3254 |     QOrganizerTodo todoStartDueDate; | 
| 3255 |     todoStartDueDate.setDisplayLabel("todo startdue" ); | 
| 3256 |     todoStartDueDate.setStartDateTime(QDateTime(QDate(2011, 3, 27), QTime(11, 0, 0))); | 
| 3257 |     todoStartDueDate.setDueDateTime(QDateTime(QDate(2011, 3, 29), QTime(11, 30, 0))); | 
| 3258 |     QVERIFY(cm->saveItem(&todoStartDueDate)); | 
| 3259 |  | 
| 3260 |     QOrganizerTodo todoStartDate; | 
| 3261 |     todoStartDate.setDisplayLabel("todo start" ); | 
| 3262 |     todoStartDate.setStartDateTime(QDateTime(QDate(2011, 3, 25), QTime(11, 0, 0))); | 
| 3263 |     QVERIFY(cm->saveItem(&todoStartDate)); | 
| 3264 |  | 
| 3265 |     QOrganizerTodo todoDueDate; | 
| 3266 |     todoDueDate.setDisplayLabel("todo due" ); | 
| 3267 |     todoDueDate.setDueDateTime(QDateTime(QDate(2011, 3, 25), QTime(11, 30, 0))); | 
| 3268 |     QVERIFY(cm->saveItem(&todoDueDate)); | 
| 3269 |  | 
| 3270 |     QOrganizerTodo todoNoDate; | 
| 3271 |     todoNoDate.setDisplayLabel("todo nodate" ); | 
| 3272 |     QVERIFY(cm->saveItem(&todoNoDate)); | 
| 3273 |  | 
| 3274 |     items = cm->items(); | 
| 3275 |     QCOMPARE(items.count(), 4); | 
| 3276 |  | 
| 3277 |     items = cm->items(startDateTime: QDateTime(), endDateTime: QDateTime(QDate(2011, 3, 25), QTime(13, 0, 0))); | 
| 3278 |     QCOMPARE(items.count(), 2); | 
| 3279 |  | 
| 3280 |     items = cm->items(startDateTime: QDateTime(), endDateTime: QDateTime(QDate(2011, 3, 25), QTime(11, 15, 0))); | 
| 3281 |     QCOMPARE(items.count(), 1); | 
| 3282 |  | 
| 3283 |     items = cm->items(startDateTime: QDateTime(QDate(2011, 3, 27), QTime(10, 0, 0)), endDateTime: QDateTime()); | 
| 3284 |     QCOMPARE(items.count(), 1); | 
| 3285 |  | 
| 3286 |     items = cm->items(startDateTime: QDateTime(QDate(2011, 3, 29), QTime(13, 0, 0)), endDateTime: QDateTime()); | 
| 3287 |     QCOMPARE(items.count(), 0); | 
| 3288 |  | 
| 3289 |     items = cm->items(startDateTime: QDateTime(QDate(2011, 3, 26), QTime(11, 0, 0)), | 
| 3290 |                       endDateTime: QDateTime(QDate(2011, 3, 28), QTime(11, 0, 0))); | 
| 3291 |     QCOMPARE(items.count(), 1); | 
| 3292 |  | 
| 3293 |     items = cm->items(startDateTime: QDateTime(QDate(2011, 3, 28), QTime(11, 0, 0)), | 
| 3294 |                       endDateTime: QDateTime(QDate(2011, 3, 30), QTime(11, 0, 0))); | 
| 3295 |     QCOMPARE(items.count(), 1); | 
| 3296 |  | 
| 3297 |     items = cm->items(startDateTime: QDateTime(QDate(2011, 3, 28), QTime(11, 0, 0)), | 
| 3298 |                       endDateTime: QDateTime(QDate(2011, 3, 28), QTime(11, 0, 0))); | 
| 3299 |     QCOMPARE(items.count(), 1); | 
| 3300 |  | 
| 3301 |  | 
| 3302 |     cm->removeItems(itemIds: cm->itemIds()); | 
| 3303 |  | 
| 3304 |     QOrganizerTodo todo; | 
| 3305 |     todo.setDisplayLabel("todo" ); | 
| 3306 |     todo.setStartDateTime(QDateTime(QDate(2010, 9, 9), QTime(11, 0, 0))); | 
| 3307 |     todo.setDueDateTime(QDateTime(QDate(2010, 9, 9), QTime(11, 30, 0))); | 
| 3308 |     QVERIFY(cm->saveItem(&todo)); | 
| 3309 |  | 
| 3310 |     QOrganizerTodo recTodo; | 
| 3311 |     recTodo.setDisplayLabel("daily todo" ); | 
| 3312 |     recTodo.setStartDateTime(QDateTime(QDate(2010, 9, 1), QTime(16, 0, 0))); | 
| 3313 |     recTodo.setDueDateTime(QDateTime(QDate(2010, 9, 1), QTime(16, 30, 0))); | 
| 3314 |     QOrganizerRecurrenceRule rrule; | 
| 3315 |     rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 3316 |     rrule.setLimit(QDate(2010, 9, 10)); | 
| 3317 |     recTodo.setRecurrenceRule(rrule); | 
| 3318 |     QVERIFY(cm->saveItem(&recTodo)); | 
| 3319 |  | 
| 3320 |     //fetch all recurrences | 
| 3321 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 9, 8)), endDateTime: QDateTime(QDate(2010, 9, 12))); | 
| 3322 |     QCOMPARE(items.count(), 4); // should return todo + 3 x occurrencesOfRecTodo | 
| 3323 |  | 
| 3324 |     //fetch only the originating items | 
| 3325 |     items = cm->itemsForExport(startDateTime: QDateTime(QDate(2010, 9, 8)), endDateTime: QDateTime(QDate(2010, 9, 12)), | 
| 3326 |                                filter: QOrganizerItemFilter(), sortOrders: QList<QOrganizerItemSortOrder>(), fetchHint: QOrganizerItemFetchHint()); | 
| 3327 |     QCOMPARE(items.count(), 2); | 
| 3328 |  | 
| 3329 |     // test semantics of items(): | 
| 3330 |     // first - save todo with multiple occurrences; call items() -- should get back just occurrences. | 
| 3331 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3332 |     rrule.setLimit(QDate(2010, 9, 3)); | 
| 3333 |     recTodo.setRecurrenceRule(rrule); | 
| 3334 |     recTodo.setId(QOrganizerItemId()); | 
| 3335 |     cm->saveItem(item: &recTodo); | 
| 3336 |     items = cm->items(); | 
| 3337 |     QCOMPARE(items.count(), 3); | 
| 3338 |     foreach (const QOrganizerItem& item, items) { | 
| 3339 |         QVERIFY(item.type() == QOrganizerItemType::TypeTodoOccurrence); | 
| 3340 |     } | 
| 3341 |  | 
| 3342 |     // second - the same situation, but giving a time span that only covers the first day - should get back a single occurrence. | 
| 3343 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 9, 1), QTime(15, 0, 0)), endDateTime: QDateTime(QDate(2010, 9, 1), QTime(18, 0, 0))); | 
| 3344 |     QCOMPARE(items.count(), 1); | 
| 3345 |     foreach (const QOrganizerItem& item, items) { | 
| 3346 |         QVERIFY(item.type() == QOrganizerItemType::TypeTodoOccurrence); | 
| 3347 |     } | 
| 3348 |  | 
| 3349 |     // third - save event with no recurrence; call items() -- should get back that parent, not an occurrence. | 
| 3350 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3351 |     recTodo.setRecurrenceRules(QSet<QOrganizerRecurrenceRule>()); // clear rrule. | 
| 3352 |     recTodo.setId(QOrganizerItemId()); | 
| 3353 |     cm->saveItem(item: &recTodo); | 
| 3354 |     items = cm->items(); | 
| 3355 |     QCOMPARE(items.count(), 1); | 
| 3356 |     foreach (const QOrganizerItem& item, items) { | 
| 3357 |         QVERIFY(item.type() == QOrganizerItemType::TypeTodo); | 
| 3358 |     } | 
| 3359 |  | 
| 3360 |     // fourth - the same situation, but giving a time span.  should still get back the parent. | 
| 3361 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 9, 1), QTime(15, 0, 0)), endDateTime: QDateTime(QDate(2010, 9, 1), QTime(18, 0, 0))); | 
| 3362 |     QCOMPARE(items.count(), 1); | 
| 3363 |     foreach (const QOrganizerItem& item, items) { | 
| 3364 |         QVERIFY(item.type() == QOrganizerItemType::TypeTodo); | 
| 3365 |     } | 
| 3366 |  | 
| 3367 |     // test semantics of itemsForExport(): | 
| 3368 |     // first - save event with multiple occurrences; call ife() -- get back that parent | 
| 3369 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3370 |     recTodo.setRecurrenceRule(rrule); | 
| 3371 |     recTodo.setId(QOrganizerItemId()); | 
| 3372 |     cm->saveItem(item: &recTodo); | 
| 3373 |     items = cm->itemsForExport(); | 
| 3374 |     QCOMPARE(items.count(), 1); | 
| 3375 |     foreach (const QOrganizerItem& item, items) { | 
| 3376 |         QVERIFY(item.type() == QOrganizerItemType::TypeTodo); | 
| 3377 |     } | 
| 3378 |  | 
| 3379 |     // second - call items, resave only the first occurrence as an exception, | 
| 3380 |     // call ife() -- get back parent + exception | 
| 3381 |     items = cm->items(); | 
| 3382 |     int todoCount = 0; | 
| 3383 |     int todoOccurrenceCount = 0; | 
| 3384 |     foreach (const QOrganizerItem& item, items) { | 
| 3385 |         if (item.type() == QOrganizerItemType::TypeTodoOccurrence) { | 
| 3386 |             if (todoOccurrenceCount == 0) { | 
| 3387 |                 QOrganizerTodoOccurrence exception(item); | 
| 3388 |                 exception.setDisplayLabel("exception" ); | 
| 3389 |                 QVERIFY(cm->saveItem(&exception)); | 
| 3390 |             } | 
| 3391 |             todoOccurrenceCount++; | 
| 3392 |         } else if (item.type() == QOrganizerItemType::TypeTodo) { | 
| 3393 |             todoCount++; | 
| 3394 |         } | 
| 3395 |     } | 
| 3396 |     QCOMPARE(todoOccurrenceCount, 3); | 
| 3397 |     QCOMPARE(todoCount, 0); | 
| 3398 |     items = cm->itemsForExport(); | 
| 3399 |     QCOMPARE(items.count(), 2); | 
| 3400 |     todoCount = 0; | 
| 3401 |     todoOccurrenceCount = 0; | 
| 3402 |     foreach (const QOrganizerItem& item, items) { | 
| 3403 |         if (item.type() == QOrganizerItemType::TypeTodo) { | 
| 3404 |             todoCount += 1; | 
| 3405 |         } else if (item.type() == QOrganizerItemType::TypeTodoOccurrence) { | 
| 3406 |             todoOccurrenceCount += 1; | 
| 3407 |         } | 
| 3408 |         QVERIFY(!item.id().isNull()); // should NEVER be null, since that would be a generated occurrence. | 
| 3409 |     } | 
| 3410 |     QCOMPARE(todoCount, 1); | 
| 3411 |     QCOMPARE(todoOccurrenceCount, 1); | 
| 3412 |  | 
| 3413 |     // third, have all occurrences persisted | 
| 3414 |     items = cm->items(); | 
| 3415 |     foreach (const QOrganizerItem& item, items) { | 
| 3416 |         if (item.type() == QOrganizerItemType::TypeTodoOccurrence) { | 
| 3417 |             QOrganizerTodoOccurrence exception(item); | 
| 3418 |             exception.setDisplayLabel("exception" ); | 
| 3419 |             QVERIFY(cm->saveItem(&exception)); | 
| 3420 |         } | 
| 3421 |     } | 
| 3422 |     items = cm->itemsForExport(); | 
| 3423 |     QCOMPARE(items.size(), 4); | 
| 3424 |     todoCount = 0; | 
| 3425 |     todoOccurrenceCount = 0; | 
| 3426 |     foreach (const QOrganizerItem& item, items) { | 
| 3427 |         if (item.type() == QOrganizerItemType::TypeTodo) { | 
| 3428 |             todoCount += 1; | 
| 3429 |         } else if (item.type() == QOrganizerItemType::TypeTodoOccurrence) { | 
| 3430 |             todoOccurrenceCount += 1; | 
| 3431 |         } | 
| 3432 |         QVERIFY(!item.id().isNull()); // should NEVER be null, since that would be a generated occurrence. | 
| 3433 |     } | 
| 3434 |     QCOMPARE(todoCount, 1); | 
| 3435 |     QCOMPARE(todoOccurrenceCount, 3); | 
| 3436 | } | 
| 3437 |  | 
| 3438 | void tst_QOrganizerManager::itemFetchV2() | 
| 3439 | { | 
| 3440 |     QFETCH(QString, uri); | 
| 3441 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 3442 |  | 
| 3443 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3444 |  | 
| 3445 |     QOrganizerEvent event1; | 
| 3446 |     event1.setDisplayLabel("event1" ); | 
| 3447 |     event1.setStartDateTime(QDateTime(QDate(2010, 1, 1), QTime(11, 0, 0))); | 
| 3448 |     event1.setEndDateTime(QDateTime(QDate(2010, 1, 1), QTime(11, 30, 0))); | 
| 3449 |     QOrganizerRecurrenceRule rrule; | 
| 3450 |     rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 3451 |     rrule.setLimit(QDate(2010, 1, 2)); | 
| 3452 |     event1.setRecurrenceRule(rrule); | 
| 3453 |     QVERIFY(cm->saveItem(&event1)); | 
| 3454 |  | 
| 3455 |     QOrganizerEvent event2; | 
| 3456 |     event2.setDisplayLabel("event2" ); | 
| 3457 |     event2.setStartDateTime(QDateTime(QDate(2010, 1, 1), QTime(13, 0, 0))); | 
| 3458 |     event2.setEndDateTime(QDateTime(QDate(2010, 1, 1), QTime(13, 30, 0))); | 
| 3459 |     rrule = QOrganizerRecurrenceRule(); | 
| 3460 |     rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 3461 |     rrule.setLimit(QDate(2010, 1, 2)); | 
| 3462 |     event2.setRecurrenceRule(rrule); | 
| 3463 |     QVERIFY(cm->saveItem(&event2)); | 
| 3464 |  | 
| 3465 |     // Get items without a maxCount, check that they're date sorted | 
| 3466 |     QList<QOrganizerItem> items = cm->items(startDateTime: QDateTime(QDate(2010, 1, 1), QTime(0, 0, 0)), endDateTime: QDateTime()); | 
| 3467 |     QCOMPARE(items.size(), 4); | 
| 3468 |     QCOMPARE(items[0].displayLabel(), QStringLiteral("event1" )); | 
| 3469 |     QCOMPARE(items[1].displayLabel(), QStringLiteral("event2" )); | 
| 3470 |     QCOMPARE(items[2].displayLabel(), QStringLiteral("event1" )); | 
| 3471 |     QCOMPARE(items[3].displayLabel(), QStringLiteral("event2" )); | 
| 3472 |  | 
| 3473 |     // Get the next 3 items from 2010-02-01 | 
| 3474 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 1, 1), QTime(0, 0, 0)), | 
| 3475 |                       endDateTime: QDateTime(),  // no end date limit | 
| 3476 |                       filter: QOrganizerItemFilter(), | 
| 3477 |                       maxCount: 3);           // maxCount | 
| 3478 |     QCOMPARE(items.size(), 3); | 
| 3479 |     QCOMPARE(items[0].displayLabel(), QStringLiteral("event1" )); | 
| 3480 |     QCOMPARE(items[1].displayLabel(), QStringLiteral("event2" )); | 
| 3481 |     QCOMPARE(items[2].displayLabel(), QStringLiteral("event1" )); | 
| 3482 | } | 
| 3483 |  | 
| 3484 | void tst_QOrganizerManager::spanOverDays() | 
| 3485 | { | 
| 3486 |     QFETCH(QString, uri); | 
| 3487 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 3488 |  | 
| 3489 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3490 |  | 
| 3491 |     QOrganizerEvent event; | 
| 3492 |     event.setDisplayLabel("huge event" ); | 
| 3493 |     event.setStartDateTime(QDateTime(QDate(2010, 8, 9), QTime(11, 0, 0))); | 
| 3494 |     event.setEndDateTime(QDateTime(QDate(2010, 8, 11), QTime(11, 30, 0))); | 
| 3495 |     QVERIFY(cm->saveItem(&event)); | 
| 3496 |  | 
| 3497 |     // just fetch one day from the event | 
| 3498 |     QList<QOrganizerItem> items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 9)), | 
| 3499 |                                             endDateTime: QDateTime(QDate(2010, 8, 9), QTime(23,59,59))); | 
| 3500 |     QCOMPARE(items.count(), 1); | 
| 3501 |  | 
| 3502 |     // fetch the next day | 
| 3503 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 10), QTime(0,0,0)), endDateTime: QDateTime(QDate(2010, 8, 10), QTime(23,59,59))); | 
| 3504 |     QCOMPARE(items.count(), 1); | 
| 3505 |  | 
| 3506 |     // fetch the last day | 
| 3507 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 11), QTime(0,0,0)), endDateTime: QDateTime(QDate(2010, 11, 10), QTime(23,59,59))); | 
| 3508 |     QCOMPARE(items.count(), 1); | 
| 3509 |  | 
| 3510 |     // fetch an interval starting before the event until infinity | 
| 3511 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 5), QTime(0,0,0)), endDateTime: QDateTime()); | 
| 3512 |     QCOMPARE(items.count(), 1); | 
| 3513 |  | 
| 3514 |     // fetch an interval ending after the event | 
| 3515 |     items = cm->items(startDateTime: QDateTime(), endDateTime: QDateTime(QDate(2010, 12, 10), QTime(23,59,59))); | 
| 3516 |     QCOMPARE(items.count(), 1); | 
| 3517 |  | 
| 3518 |     // fetch an interval starting before the event and ending at almost end of the year | 
| 3519 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 5), QTime(0,0,0)), endDateTime: QDateTime(QDate(2010, 12, 10), QTime(23,59,59))); | 
| 3520 |     QCOMPARE(items.count(), 1); | 
| 3521 |  | 
| 3522 |     // fetch an interval ending in the middle of the event | 
| 3523 |     items = cm->items(startDateTime: QDateTime(), endDateTime: QDateTime(QDate(2010, 8, 10), QTime(23,59,59))); | 
| 3524 |     QCOMPARE(items.count(), 1); | 
| 3525 |  | 
| 3526 |     // fetch an interval starting from the middle of the event until infinity | 
| 3527 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 10), QTime(0,0,0)), endDateTime: QDateTime()); | 
| 3528 |     QCOMPARE(items.count(), 1); | 
| 3529 |  | 
| 3530 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3531 |  | 
| 3532 |     QOrganizerEvent event2; | 
| 3533 |     QOrganizerRecurrenceRule rrule; | 
| 3534 |     event2.setDisplayLabel("huge recurring event" ); | 
| 3535 |     event2.setStartDateTime(QDateTime(QDate(2010, 8, 9), QTime(11, 0, 0))); | 
| 3536 |     event2.setEndDateTime(QDateTime(QDate(2010, 8, 11), QTime(11, 30, 0))); | 
| 3537 |     rrule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 3538 |     rrule.setLimit(QDate(2010, 9, 2)); | 
| 3539 |     event2.setRecurrenceRule(rrule); | 
| 3540 |     QVERIFY(cm->saveItem(&event2)); | 
| 3541 |  | 
| 3542 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 8)), endDateTime: QDateTime(QDate(2010, 9, 3))); | 
| 3543 |     QCOMPARE(items.count(), 4); | 
| 3544 |     QCOMPARE(static_cast<QOrganizerEventOccurrence>(items[0]).startDateTime(), QDateTime(QDate(2010, 8, 9), QTime(11, 0, 0))); | 
| 3545 |     QCOMPARE(static_cast<QOrganizerEventOccurrence>(items[0]).endDateTime(), QDateTime(QDate(2010, 8, 11), QTime(11, 30, 0))); | 
| 3546 |     QCOMPARE(static_cast<QOrganizerEventOccurrence>(items[1]).startDateTime(), QDateTime(QDate(2010, 8, 16), QTime(11, 0, 0))); | 
| 3547 |     QCOMPARE(static_cast<QOrganizerEventOccurrence>(items[1]).endDateTime(), QDateTime(QDate(2010, 8, 18), QTime(11, 30, 0))); | 
| 3548 |     QCOMPARE(static_cast<QOrganizerEventOccurrence>(items[2]).startDateTime(), QDateTime(QDate(2010, 8, 23), QTime(11, 0, 0))); | 
| 3549 |     QCOMPARE(static_cast<QOrganizerEventOccurrence>(items[2]).endDateTime(), QDateTime(QDate(2010, 8, 25), QTime(11, 30, 0))); | 
| 3550 |     QCOMPARE(static_cast<QOrganizerEventOccurrence>(items[3]).startDateTime(), QDateTime(QDate(2010, 8, 30), QTime(11, 0, 0))); | 
| 3551 |     QCOMPARE(static_cast<QOrganizerEventOccurrence>(items[3]).endDateTime(), QDateTime(QDate(2010, 9, 1), QTime(11, 30, 0))); | 
| 3552 |  | 
| 3553 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3554 |     QOrganizerTodo todo; | 
| 3555 |     QOrganizerRecurrenceRule rrule2; | 
| 3556 |     todo.setDisplayLabel("huge overlapping recurring todo" ); | 
| 3557 |     todo.setStartDateTime(QDateTime(QDate(2010, 8, 9), QTime(11, 0, 0))); | 
| 3558 |     todo.setDueDateTime(QDateTime(QDate(2010, 8, 11), QTime(11, 30, 0))); | 
| 3559 |     rrule2.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 3560 |     rrule2.setLimit(4); | 
| 3561 |     todo.setRecurrenceRule(rrule2); | 
| 3562 |     QVERIFY(cm->saveItem(&todo)); | 
| 3563 |  | 
| 3564 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 8)), endDateTime: QDateTime(QDate(2010, 9, 3))); | 
| 3565 |     QCOMPARE(items.count(), 4); | 
| 3566 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[0]).startDateTime(), QDateTime(QDate(2010, 8, 9), QTime(11, 0, 0))); | 
| 3567 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[0]).dueDateTime(), QDateTime(QDate(2010, 8, 11), QTime(11, 30, 0))); | 
| 3568 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[1]).startDateTime(), QDateTime(QDate(2010, 8, 10), QTime(11, 0, 0))); | 
| 3569 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[1]).dueDateTime(), QDateTime(QDate(2010, 8, 12), QTime(11, 30, 0))); | 
| 3570 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[2]).startDateTime(), QDateTime(QDate(2010, 8, 11), QTime(11, 0, 0))); | 
| 3571 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[2]).dueDateTime(), QDateTime(QDate(2010, 8, 13), QTime(11, 30, 0))); | 
| 3572 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[3]).startDateTime(), QDateTime(QDate(2010, 8, 12), QTime(11, 0, 0))); | 
| 3573 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[3]).dueDateTime(), QDateTime(QDate(2010, 8, 14), QTime(11, 30, 0))); | 
| 3574 | } | 
| 3575 |  | 
| 3576 |  | 
| 3577 | void tst_QOrganizerManager::incompleteTodoTime() | 
| 3578 | { | 
| 3579 |     QFETCH(QString, uri); | 
| 3580 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 3581 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3582 |     QOrganizerTodo todo; | 
| 3583 |     QOrganizerRecurrenceRule rrule; | 
| 3584 |     rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 3585 |     rrule.setLimit(4); | 
| 3586 |     todo.setDisplayLabel("recurring todo without start date" ); | 
| 3587 |     todo.setDueDateTime(QDateTime(QDate(2010, 8, 11), QTime(11, 30, 0))); | 
| 3588 |     todo.setRecurrenceRule(rrule); | 
| 3589 |     QVERIFY(cm->saveItem(&todo)); | 
| 3590 |  | 
| 3591 |     QList<QOrganizerItem> items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 8)), endDateTime: QDateTime(QDate(2010, 9, 3))); | 
| 3592 |     QCOMPARE(items.count(), 4); | 
| 3593 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[0]).dueDateTime(), QDateTime(QDate(2010, 8, 11), QTime(11, 30, 0))); | 
| 3594 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[1]).dueDateTime(), QDateTime(QDate(2010, 8, 12), QTime(11, 30, 0))); | 
| 3595 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[2]).dueDateTime(), QDateTime(QDate(2010, 8, 13), QTime(11, 30, 0))); | 
| 3596 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[3]).dueDateTime(), QDateTime(QDate(2010, 8, 14), QTime(11, 30, 0))); | 
| 3597 |  | 
| 3598 |     // same test as previous, but with date limit | 
| 3599 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3600 |     QOrganizerTodo todo2; | 
| 3601 |     todo2.setDisplayLabel("recurring todo without start date with date limit" ); | 
| 3602 |     todo2.setDueDateTime(QDateTime(QDate(2010, 8, 11), QTime(11, 30, 0))); | 
| 3603 |     QOrganizerRecurrenceRule rrule2; | 
| 3604 |     rrule2.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 3605 |     rrule2.setLimit(QDate(2010, 8, 13)); | 
| 3606 |     todo2.setRecurrenceRule(rrule2); | 
| 3607 |     QVERIFY(cm->saveItem(&todo2)); | 
| 3608 |  | 
| 3609 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 8)), endDateTime: QDateTime(QDate(2010, 9, 3))); | 
| 3610 |     QCOMPARE(items.count(), 3); | 
| 3611 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[0]).dueDateTime(), QDateTime(QDate(2010, 8, 11), QTime(11, 30, 0))); | 
| 3612 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[1]).dueDateTime(), QDateTime(QDate(2010, 8, 12), QTime(11, 30, 0))); | 
| 3613 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[2]).dueDateTime(), QDateTime(QDate(2010, 8, 13), QTime(11, 30, 0))); | 
| 3614 |  | 
| 3615 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3616 |     QOrganizerTodo todo3; | 
| 3617 |     todo3.setDisplayLabel("recurring todo without start and due date" ); | 
| 3618 |     todo3.setRecurrenceRule(rrule2); | 
| 3619 |     QVERIFY(cm->saveItem(&todo3)); | 
| 3620 |     items = cm->items(); | 
| 3621 |     QCOMPARE(items.count(), 0); | 
| 3622 |     items = cm->items(startDateTime: QDateTime(QDate(2010, 8, 8)), endDateTime: QDateTime(QDate(2010, 9, 3))); | 
| 3623 |     QCOMPARE(items.count(), 6); | 
| 3624 |  | 
| 3625 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[0]).originalDate(), QDate(2010, 8, 8)); | 
| 3626 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[1]).originalDate(), QDate(2010, 8, 9)); | 
| 3627 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[2]).dueDateTime(), QDateTime()); | 
| 3628 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[3]).dueDateTime(), QDateTime()); | 
| 3629 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[4]).originalDate(), QDate(2010, 8, 12)); | 
| 3630 |     QCOMPARE(static_cast<QOrganizerTodoOccurrence>(items[5]).originalDate(), QDate(2010, 8, 13)); | 
| 3631 |     cm->removeItem(itemId: todo3.id()); | 
| 3632 | } | 
| 3633 |  | 
| 3634 | void tst_QOrganizerManager::recurrence() | 
| 3635 | { | 
| 3636 |     QFETCH(QString, uri); | 
| 3637 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 3638 |  | 
| 3639 |     QOrganizerEvent event; | 
| 3640 |     event.setDisplayLabel("recurrent event" ); | 
| 3641 |     event.setStartDateTime(QDateTime(QDate(2012, 8, 9), QTime(11, 0, 0))); | 
| 3642 |     event.setEndDateTime(QDateTime(QDate(2012, 8, 9), QTime(11, 30, 0))); | 
| 3643 |  | 
| 3644 |     // first, test count limiting. | 
| 3645 |     QOrganizerRecurrenceRule rrule; | 
| 3646 |     rrule.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 3647 |     rrule.setLimit(3); | 
| 3648 |     event.setRecurrenceRule(rrule); | 
| 3649 |     QVERIFY(cm->saveItem(&event)); | 
| 3650 |  | 
| 3651 |     { | 
| 3652 |         // Fetch all events with occurrences | 
| 3653 |         QList<QOrganizerItem> items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 9)), | 
| 3654 |                                                 endDateTime: QDateTime(QDate(2012, 8, 12), QTime(23,59,59))); | 
| 3655 |         QCOMPARE(items.count(), 3); | 
| 3656 |  | 
| 3657 |         // Fetch events for the first day | 
| 3658 |         items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 9), QTime(0,0,0)), endDateTime: QDateTime(QDate(2012, 8, 9), QTime(23,59,59))); | 
| 3659 |         QCOMPARE(items.count(), 1); | 
| 3660 |  | 
| 3661 |         // Fetch events for the second day | 
| 3662 |         items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 10), QTime(0,0,0)), endDateTime: QDateTime(QDate(2012, 8, 10), QTime(23,59,59))); | 
| 3663 |         QCOMPARE(items.count(), 1); | 
| 3664 |  | 
| 3665 |         // Create an exception on the second day | 
| 3666 |         QOrganizerEventOccurrence ex = static_cast<QOrganizerEventOccurrence>(items.at(i: 0)); | 
| 3667 |         ex.setStartDateTime(QDateTime(QDate(2012, 8, 10), QTime(10, 30, 0))); | 
| 3668 |         QVERIFY(cm->saveItem(&ex)); | 
| 3669 |  | 
| 3670 |         // Fetch again the events for the second day | 
| 3671 |         items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 10), QTime(0,0,0)), endDateTime: QDateTime(QDate(2012, 8, 10), QTime(23,59,59))); | 
| 3672 |         QCOMPARE(items.count(), 1); | 
| 3673 |         QOrganizerItem item = items.at(i: 0); | 
| 3674 |         QVERIFY(!item.id().isNull()); | 
| 3675 |         QVERIFY(item.type() == QOrganizerItemType::TypeEventOccurrence); | 
| 3676 |  | 
| 3677 |         // Add a normal event to the first day | 
| 3678 |         QOrganizerEvent event2; | 
| 3679 |         event2.setDisplayLabel("event" ); | 
| 3680 |         event2.setStartDateTime(QDateTime(QDate(2012, 8, 9), QTime(15, 0, 0))); | 
| 3681 |         event2.setEndDateTime(QDateTime(QDate(2012, 8, 9), QTime(16, 0, 0))); | 
| 3682 |         QVERIFY(cm->saveItem(&event2)); | 
| 3683 |  | 
| 3684 |         // Fetch the whole period again | 
| 3685 |         items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 9)), endDateTime: QDateTime(QDate(2012, 8, 12), QTime(23,59,59))); | 
| 3686 |         QCOMPARE(items.count(), 4); | 
| 3687 |         foreach(QOrganizerItem item, items) { | 
| 3688 |             // check if the item is the recurrence exception | 
| 3689 |             if (item.id() == ex.id()) { | 
| 3690 |                 QOrganizerEventOccurrence exc = static_cast<QOrganizerEventOccurrence>(item); | 
| 3691 |                 QCOMPARE(exc.guid(), ex.guid()); | 
| 3692 |                 QCOMPARE(exc.startDateTime(), ex.startDateTime()); | 
| 3693 |                 QCOMPARE(exc.endDateTime(), ex.endDateTime()); | 
| 3694 |             } else if (item.id() == event2.id()) { | 
| 3695 |                 // check if the item is the normal event | 
| 3696 |                 QOrganizerEvent ev = static_cast<QOrganizerEvent>(item); | 
| 3697 |                 QCOMPARE(ev.guid(), event2.guid()); | 
| 3698 |                 QCOMPARE(ev.startDateTime(), event2.startDateTime()); | 
| 3699 |                 QCOMPARE(ev.endDateTime(), event2.endDateTime()); | 
| 3700 |             } else { | 
| 3701 |                 // item must be event occurrence type and has to be a generated one | 
| 3702 |                 QVERIFY(item.type() == QOrganizerItemType::TypeEventOccurrence); | 
| 3703 |                 QVERIFY(item.id().isNull()); | 
| 3704 |             } | 
| 3705 |         } | 
| 3706 |  | 
| 3707 |         // Fetch events on a day where the recurrence is no longer valid | 
| 3708 |         items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 12), QTime(0,0,0)), endDateTime: QDateTime(QDate(2012, 8, 12), QTime(23,59,59))); | 
| 3709 |         QCOMPARE(items.count(), 0); | 
| 3710 |     } | 
| 3711 |  | 
| 3712 |     //test for unlimited count limit | 
| 3713 |     //for bug:MOBILITY-2125 | 
| 3714 |     cm->removeItems(itemIds: cm->itemIds()); | 
| 3715 |     event.setId(QOrganizerItemId()); | 
| 3716 |     rrule.setLimit(INT_MAX); | 
| 3717 |     rrule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 3718 |     rrule.setInterval(4); | 
| 3719 |     rrule.setDaysOfWeek(QSet<Qt::DayOfWeek>() << Qt::Friday); | 
| 3720 |     event.setEndDateTime(QDateTime(QDate(2013, 8, 9), QTime(11, 30, 0))); | 
| 3721 |     event.setRecurrenceRule(rrule); | 
| 3722 |     QVERIFY(cm->saveItem(&event)); | 
| 3723 |     { | 
| 3724 |         // Fetch all events with occurrences | 
| 3725 |         QList<QOrganizerItem> items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 9)), | 
| 3726 |                                                 endDateTime: QDateTime(QDate(2013, 8, 12), QTime(23,59,59))); | 
| 3727 |         QVERIFY(items.count() > 1); | 
| 3728 |     } | 
| 3729 |     // second, test date limit.  The results should be the same as the count limit, if the limit date is the 11th. | 
| 3730 |     cm->removeItems(itemIds: cm->itemIds()); // empty the calendar to prevent the previous test from interfering this one | 
| 3731 |     QOrganizerRecurrenceRule rrule2; | 
| 3732 |     rrule2.setFrequency(QOrganizerRecurrenceRule::Daily); | 
| 3733 |     rrule2.setLimit(QDate(2012, 8, 11)); | 
| 3734 |     event.setRecurrenceRule(rrule2); | 
| 3735 |     event.setId(QOrganizerItemId()); | 
| 3736 |     QVERIFY(cm->saveItem(&event)); | 
| 3737 |  | 
| 3738 |     { | 
| 3739 |         // Fetch all events with occurrences | 
| 3740 |         QList<QOrganizerItem> items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 9)), | 
| 3741 |                                                 endDateTime: QDateTime(QDate(2012, 8, 12), QTime(23,59,59))); | 
| 3742 |         QCOMPARE(items.count(), 3); | 
| 3743 |  | 
| 3744 |         // Fetch events for the first day | 
| 3745 |         items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 9), QTime(0,0,0)), endDateTime: QDateTime(QDate(2012, 8, 9), QTime(23,59,59))); | 
| 3746 |         QCOMPARE(items.count(), 1); | 
| 3747 |  | 
| 3748 |         // Fetch events for the second day | 
| 3749 |         items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 10), QTime(0,0,0)), endDateTime: QDateTime(QDate(2012, 8, 10), QTime(23,59,59))); | 
| 3750 |         QCOMPARE(items.count(), 1); | 
| 3751 |  | 
| 3752 |         // Create an exception on the second day | 
| 3753 |         QOrganizerEventOccurrence ex = static_cast<QOrganizerEventOccurrence>(items.at(i: 0)); | 
| 3754 |         ex.setStartDateTime(QDateTime(QDate(2012, 8, 10), QTime(10, 30, 0))); | 
| 3755 |         QVERIFY(cm->saveItem(&ex)); | 
| 3756 |  | 
| 3757 |         // Fetch again the events for the second day | 
| 3758 |         items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 10), QTime(0,0,0)), endDateTime: QDateTime(QDate(2012, 8, 10), QTime(23,59,59))); | 
| 3759 |         QCOMPARE(items.count(), 1); | 
| 3760 |         QOrganizerItem item = items.at(i: 0); | 
| 3761 |         QVERIFY(!item.id().isNull()); | 
| 3762 |         QVERIFY(item.type() == QOrganizerItemType::TypeEventOccurrence); | 
| 3763 |  | 
| 3764 |         // Add a normal event to the first day | 
| 3765 |         QOrganizerEvent event2; | 
| 3766 |         event2.setDisplayLabel("event" ); | 
| 3767 |         event2.setStartDateTime(QDateTime(QDate(2012, 8, 9), QTime(15, 0, 0))); | 
| 3768 |         event2.setEndDateTime(QDateTime(QDate(2012, 8, 9), QTime(16, 0, 0))); | 
| 3769 |         QVERIFY(cm->saveItem(&event2)); | 
| 3770 |  | 
| 3771 |         // Fetch the whole period again | 
| 3772 |         items = cm->items(startDateTime: QDateTime(QDate(2012, 8, 9)), endDateTime: QDateTime(QDate(2012, 8, 12), QTime(23,59,59))); | 
| 3773 |         QCOMPARE(items.count(), 4); | 
| 3774 |         foreach(QOrganizerItem item, items) { | 
| 3775 |             // check if the item is the recurrence exception | 
| 3776 |             if (item.id() == ex.id()) { | 
| 3777 |                 QOrganizerEventOccurrence exc = static_cast<QOrganizerEventOccurrence>(item); | 
| 3778 |                 QCOMPARE(exc.guid(), ex.guid()); | 
| 3779 |                 QCOMPARE(exc.startDateTime(), ex.startDateTime()); | 
| 3780 |                 QCOMPARE(exc.endDateTime(), ex.endDateTime()); | 
| 3781 |             } else if (item.id() == event2.id()) { | 
| 3782 |                 // check if the item is the normal event | 
| 3783 |                 QOrganizerEvent ev = static_cast<QOrganizerEvent>(item); | 
| 3784 |                 QCOMPARE(ev.guid(), event2.guid()); | 
| 3785 |                 QCOMPARE(ev.startDateTime(), event2.startDateTime()); | 
| 3786 |                 QCOMPARE(ev.endDateTime(), event2.endDateTime()); | 
| 3787 |             } else { | 
| 3788 |                 // item must be event occurrence type and has to be a generated one | 
| 3789 |                 QVERIFY(item.type() == QOrganizerItemType::TypeEventOccurrence); | 
| 3790 |                 QVERIFY(item.id().isNull()); | 
| 3791 |             } | 
| 3792 |         } | 
| 3793 |     } | 
| 3794 | } | 
| 3795 |  | 
| 3796 | void tst_QOrganizerManager::idComparison() | 
| 3797 | { | 
| 3798 |     QFETCH(QString, uri); | 
| 3799 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 3800 |  | 
| 3801 |     // Can we run this test? | 
| 3802 |     if (!cm->supportedItemTypes().contains(t: QOrganizerItemType::TypeJournal)) { | 
| 3803 |         QSKIP("Backend not compatible with this test" ); | 
| 3804 |         // TODO: The test should be refactored so it could run on all platforms | 
| 3805 |     } | 
| 3806 |  | 
| 3807 |     // delete all collections in the database so that we know there can be no interference from previous test runs. | 
| 3808 |     QList<QOrganizerCollection> allCollections = cm->collections(); | 
| 3809 |     for (int i = 0; i < allCollections.size(); ++i) { | 
| 3810 |         QOrganizerCollectionId currentId = allCollections.at(i).id(); | 
| 3811 |         if (currentId != cm->defaultCollectionId()) { | 
| 3812 |             cm->removeCollection(collectionId: currentId); | 
| 3813 |         } | 
| 3814 |     } | 
| 3815 |  | 
| 3816 |     // step one: make a few items and collections to save (and harvest their ids) | 
| 3817 |     QOrganizerEvent e1; | 
| 3818 |     e1.setDescription("test event one" ); | 
| 3819 |     e1.setDisplayLabel("event one" ); | 
| 3820 |     e1.setStartDateTime(QDateTime::currentDateTime()); | 
| 3821 |     e1.setEndDateTime(QDateTime::currentDateTime().addSecs(secs: 3600)); | 
| 3822 |  | 
| 3823 |     QOrganizerEvent e2; | 
| 3824 |     e2.setDescription("test event two" ); | 
| 3825 |     e2.setDisplayLabel("event two" ); | 
| 3826 |     e2.setStartDateTime(QDateTime::currentDateTime().addDays(days: 1)); | 
| 3827 |     e2.setEndDateTime(QDateTime::currentDateTime().addDays(days: 1).addSecs(secs: 1800)); | 
| 3828 |  | 
| 3829 |     QOrganizerTodo t1; | 
| 3830 |     QOrganizerRecurrenceRule r1; | 
| 3831 |     r1.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 3832 |     t1.setDisplayLabel("todo one" ); | 
| 3833 |     t1.setDescription("test todo one" ); | 
| 3834 |     t1.setDueDateTime(QDateTime::currentDateTime().addDays(days: 5)); | 
| 3835 |     t1.setRecurrenceRule(r1); | 
| 3836 |  | 
| 3837 |     QOrganizerCollection c1; | 
| 3838 |     c1.setMetaData(key: QOrganizerCollection::KeyName, value: "IdComparisonTest" ); | 
| 3839 |  | 
| 3840 |     // step two: save and harvest the ids | 
| 3841 |     QVERIFY(cm->saveItem(&e1)); | 
| 3842 |     QVERIFY(cm->saveItem(&e2)); | 
| 3843 |     QVERIFY(cm->saveItem(&t1)); | 
| 3844 |     QVERIFY(cm->saveCollection(&c1)); | 
| 3845 |     QOrganizerItemId e1id = e1.id(); | 
| 3846 |     QOrganizerItemId e2id = e2.id(); | 
| 3847 |     QOrganizerItemId t1id = t1.id(); | 
| 3848 |     QOrganizerCollectionId c1id = c1.id(); | 
| 3849 |  | 
| 3850 |     // step three: make some basic ids as controlled data for our unit test | 
| 3851 |     QOrganizerItemId biid1 = makeItemId(id: 5); | 
| 3852 |     QOrganizerItemId biid2 = makeItemId(id: 12); | 
| 3853 |     QOrganizerCollectionId bcid1 = makeCollectionId(id: 5); | 
| 3854 |     QOrganizerCollectionId bcid2 = makeCollectionId(id: 17); | 
| 3855 |     QOrganizerCollectionId bcid3 = makeCollectionId(id: 15); | 
| 3856 |  | 
| 3857 |     // finally: do the testing. | 
| 3858 |     QVERIFY(biid1 != biid2); | 
| 3859 |     QVERIFY(bcid1 != bcid2); | 
| 3860 |  | 
| 3861 |     QVERIFY(e1id != e2id); | 
| 3862 |     QVERIFY(e1id != t1id); | 
| 3863 |  | 
| 3864 |     QList<QOrganizerItemId> idList; | 
| 3865 |     idList << e1id << t1id << biid1; | 
| 3866 |     QVERIFY(!idList.contains(biid2)); | 
| 3867 |     QVERIFY(!idList.contains(e2id)); | 
| 3868 |     QVERIFY(idList.contains(e1id)); | 
| 3869 |     QVERIFY(idList.contains(t1id)); | 
| 3870 |     QVERIFY(idList.contains(biid1)); | 
| 3871 |  | 
| 3872 |     QVERIFY(((bcid1 < bcid2) || (bcid2 < bcid1)) && (bcid1 != bcid2)); | 
| 3873 |     QVERIFY(((bcid3 < bcid2) || (bcid3 < bcid1)) && (bcid3 != bcid2)); | 
| 3874 |     QVERIFY(((e1id < e2id) || (e2id < e1id)) && (e1id != e2id)); | 
| 3875 |  | 
| 3876 |     // now we do some tests which might be unstable | 
| 3877 |     QVERIFY(bcid1 < c1id); // collectionIds: the first comparison should be manager uri, and bcid manager uri is early in the alphabet. | 
| 3878 |     QVERIFY(!(c1id < bcid1)); // collectionIds: ensure that less-than is consistent no matter which is on LHS or RHS. | 
| 3879 |     QVERIFY(biid2 < e1id); // itemIds: first comparison should be manager uri, and biid manager uri is early in the alphabet. | 
| 3880 |     QVERIFY(!(e1id < biid2)); // itemIds: ensure that less-than is consistent no matter which is on LHS or RHS. | 
| 3881 |  | 
| 3882 |     // null testing | 
| 3883 |     QOrganizerItemId n1; | 
| 3884 |     QOrganizerItemId n2; | 
| 3885 |     QVERIFY(n1 == n2);   // both null means they're equal | 
| 3886 |     QVERIFY(!(n1 < n2)); // not less than | 
| 3887 |     QVERIFY(!(n2 < n1)); // and not less than with LHS/RHS swapped. | 
| 3888 |  | 
| 3889 |     QVERIFY(n1 < biid1); // null id is always less than any other id | 
| 3890 |     QVERIFY(!(biid1 < n1)); | 
| 3891 |     QVERIFY(n2 < e2id); | 
| 3892 |     QVERIFY(!(e2id < n2)); | 
| 3893 |  | 
| 3894 |     QVERIFY(!idList.contains(n2)); | 
| 3895 |     idList << n1; | 
| 3896 |     QVERIFY(idList.contains(n2)); // any two null ids are equal, so .contains should work. | 
| 3897 |  | 
| 3898 |     QMap<QOrganizerItemId, int> testMap; | 
| 3899 |     testMap.insert(akey: e1id, avalue: 1); | 
| 3900 |     testMap.insert(akey: biid1, avalue: 12); | 
| 3901 |     testMap.insert(akey: biid2, avalue: 11); | 
| 3902 |     testMap.insert(akey: t1id, avalue: 6); | 
| 3903 |     testMap.insert(akey: n1, avalue: 12); | 
| 3904 |  | 
| 3905 |     QCOMPARE(testMap.value(e1id), 1); | 
| 3906 |     QCOMPARE(testMap.value(n2), 12); // again, n1 == n2. | 
| 3907 |     QCOMPARE(testMap.value(biid1), 12); | 
| 3908 |     QCOMPARE(testMap.value(biid2), 11); | 
| 3909 |     QCOMPARE(testMap.value(t1id), 6); | 
| 3910 |     QCOMPARE(testMap.value(QOrganizerItemId()), 12); // again, n1 == null | 
| 3911 |  | 
| 3912 |     QVERIFY(testMap.size() == 5); | 
| 3913 |     testMap.remove(akey: QOrganizerItemId()); | 
| 3914 |     QVERIFY(testMap.size() == 4); | 
| 3915 |     QVERIFY(testMap.value(QOrganizerItemId()) != 12); // removed this entry. | 
| 3916 | } | 
| 3917 |  | 
| 3918 | void tst_QOrganizerManager::emptyItemManipulation() | 
| 3919 | { | 
| 3920 |     QFETCH(QString, uri); | 
| 3921 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 3922 |  | 
| 3923 |     QOrganizerItem i; | 
| 3924 |     QOrganizerEvent e; | 
| 3925 |     QOrganizerTodo t; | 
| 3926 |  | 
| 3927 |     // attempt to save an empty item | 
| 3928 |     if (cm->saveItem(item: &i)) { | 
| 3929 |         // if the backend allowed us to save it, it should definitely allow us to remove it again. | 
| 3930 |         QVERIFY(cm->removeItem(i.id())); | 
| 3931 |     } else { | 
| 3932 |         // if the backend didn't allow us to save it, there should be nothing to remove. | 
| 3933 |         QVERIFY(!cm->removeItem(i.id())); | 
| 3934 |     } | 
| 3935 |  | 
| 3936 |     // attempt to save an empty event. | 
| 3937 |     if (cm->saveItem(item: &e)) { | 
| 3938 |         // if the backend allowed us to save it, it should definitely allow us to remove it again. | 
| 3939 |         QVERIFY(cm->removeItem(e.id())); | 
| 3940 |     } else { | 
| 3941 |         // if the backend didn't allow us to save it, there should be nothing to remove. | 
| 3942 |         QVERIFY(!cm->removeItem(e.id())); | 
| 3943 |     } | 
| 3944 |  | 
| 3945 |     // attempt to save an empty event. | 
| 3946 |     if (cm->saveItem(item: &t)) { | 
| 3947 |         // if the backend allowed us to save it, it should definitely allow us to remove it again. | 
| 3948 |         QVERIFY(cm->removeItem(t.id())); | 
| 3949 |     } else { | 
| 3950 |         // if the backend didn't allow us to save it, there should be nothing to remove. | 
| 3951 |         QVERIFY(!cm->removeItem(t.id())); | 
| 3952 |     } | 
| 3953 |  | 
| 3954 |     // now attempt to remove some invalid ids. | 
| 3955 |     QOrganizerItemId invalidId; | 
| 3956 |     QVERIFY(!cm->removeItem(invalidId)); // null id | 
| 3957 |     invalidId = makeItemId(id: 50); | 
| 3958 |     QVERIFY(!cm->removeItem(invalidId)); // id from different manager | 
| 3959 | } | 
| 3960 |  | 
| 3961 | void tst_QOrganizerManager::partialSave() | 
| 3962 | { | 
| 3963 |     QFETCH(QString, uri); | 
| 3964 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 3965 |  | 
| 3966 |     QList<QOrganizerItem> items; | 
| 3967 |     QOrganizerEvent event = QOrganizerEvent(); | 
| 3968 |     event.setDisplayLabel("One" ); | 
| 3969 |     event.setStartDateTime(QDateTime(QDate(2010, 12, 25), QTime(1, 0, 0))); | 
| 3970 |     event.setEndDateTime(QDateTime(QDate(2010, 12, 25), QTime(1, 30, 0))); | 
| 3971 |     event.setDescription("One description" ); | 
| 3972 |     items.append(t: event); | 
| 3973 |  | 
| 3974 |     event = QOrganizerEvent(); | 
| 3975 |     event.setDisplayLabel("Two" ); | 
| 3976 |     event.setStartDateTime(QDateTime(QDate(2010, 12, 25), QTime(2, 0, 0))); | 
| 3977 |     event.setEndDateTime(QDateTime(QDate(2010, 12, 25), QTime(2, 30, 0))); | 
| 3978 |     event.setDescription("Two description" ); | 
| 3979 |     items.append(t: event); | 
| 3980 |  | 
| 3981 |     event = QOrganizerEvent(); | 
| 3982 |     event.setDisplayLabel("Three" ); | 
| 3983 |     event.setStartDateTime(QDateTime(QDate(2010, 12, 25), QTime(3, 0, 0))); | 
| 3984 |     event.setEndDateTime(QDateTime(QDate(2010, 12, 25), QTime(3, 30, 0))); | 
| 3985 |     items.append(t: event); | 
| 3986 |  | 
| 3987 |     event = QOrganizerEvent(); | 
| 3988 |     event.setDisplayLabel("Four" ); | 
| 3989 |     event.setStartDateTime(QDateTime(QDate(2010, 12, 25), QTime(4, 0, 0))); | 
| 3990 |     event.setEndDateTime(QDateTime(QDate(2010, 12, 25), QTime(4, 30, 0))); | 
| 3991 |     items.append(t: event); | 
| 3992 |  | 
| 3993 |     // First save these items | 
| 3994 |     QVERIFY(cm->saveItems(&items)); | 
| 3995 |     QList<QOrganizerItem> originalItems = items; | 
| 3996 |  | 
| 3997 |     items[0].setDescription("One changed description" ); | 
| 3998 |  | 
| 3999 |     // 0) empty mask == full save | 
| 4000 |     QVERIFY(cm->saveItems(&items)); | 
| 4001 |  | 
| 4002 |     // That should have updated everything | 
| 4003 |     QOrganizerItem a = cm->item(itemId: originalItems[0].id()); | 
| 4004 |     QVERIFY(a.description() == "One changed description" ); | 
| 4005 |  | 
| 4006 |     // 1) Change the description for b, mask it out | 
| 4007 |     items[1].setDescription("Two changed description" ); | 
| 4008 |     QVERIFY(cm->saveItems(&items, QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeEventTime)); | 
| 4009 |     QVERIFY(cm->errorMap().isEmpty()); | 
| 4010 |  | 
| 4011 |     QOrganizerItem b = cm->item(itemId: originalItems[1].id()); | 
| 4012 |     QCOMPARE(b.description(), QString("Two description" )); | 
| 4013 |  | 
| 4014 |     // 2) save a modified detail in the mask | 
| 4015 |     items[1].setDescription("Two changed description" ); | 
| 4016 |  | 
| 4017 |     QVERIFY(cm->saveItems(&items, QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeDescription)); | 
| 4018 |     QVERIFY(cm->errorMap().isEmpty()); | 
| 4019 |     b = cm->item(itemId: originalItems[1].id()); | 
| 4020 |     QCOMPARE(b.description(), QString("Two changed description" )); | 
| 4021 |  | 
| 4022 |     // 3) Remove a description | 
| 4023 |     QOrganizerItemDescription desc = items[1].detail(detailType: QOrganizerItemDetail::TypeDescription); | 
| 4024 |     QVERIFY(items[1].removeDetail(&desc)); | 
| 4025 |     // Mask it out, so it shouldn't work. | 
| 4026 |     QVERIFY(cm->saveItems(&items, QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeEventTime)); | 
| 4027 |     QVERIFY(cm->errorMap().isEmpty()); | 
| 4028 |     b = cm->item(itemId: originalItems[1].id()); | 
| 4029 |     QCOMPARE(b.details(QOrganizerItemDetail::TypeDescription).count(), 1); | 
| 4030 |     // Now include it in the mask | 
| 4031 |     QVERIFY(cm->saveItems(&items, QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeDescription)); | 
| 4032 |     QVERIFY(cm->errorMap().isEmpty()); | 
| 4033 |     b = cm->item(itemId: originalItems[1].id()); | 
| 4034 |     QCOMPARE(b.details(QOrganizerItemDetail::TypeDescription).count(), 0); | 
| 4035 |  | 
| 4036 |     // 4 - New item, no details in the mask | 
| 4037 |     QOrganizerItem newItem = originalItems[3]; | 
| 4038 |     newItem.setId(QOrganizerItemId()); | 
| 4039 |  | 
| 4040 |     items.append(t: newItem); // this is items[4] | 
| 4041 |     QVERIFY(cm->saveItems(&items, QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeTag)); | 
| 4042 |     QVERIFY(cm->errorMap().isEmpty()); | 
| 4043 |     QVERIFY(!items[4].id().isNull()); // Saved | 
| 4044 |     b = cm->item(itemId: items[4].id()); | 
| 4045 |     QCOMPARE(b.details(QOrganizerItemDetail::TypeDisplayLabel).count(), 0); // not saved | 
| 4046 |     QCOMPARE(b.details(QOrganizerItemDetail::TypeEventTime).count(), 0); // not saved | 
| 4047 |  | 
| 4048 |     // 5 - New item, some details in the mask | 
| 4049 |     newItem = originalItems[2]; | 
| 4050 |     newItem.setId(QOrganizerItemId()); | 
| 4051 |     items.append(t: newItem); // this is items[5] | 
| 4052 |     QVERIFY(cm->saveItems(&items, QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeDisplayLabel)); | 
| 4053 |     QVERIFY(cm->errorMap().isEmpty()); | 
| 4054 |     QVERIFY(!items[5].id().isNull()); // Saved | 
| 4055 |     b = cm->item(itemId: items[5].id()); | 
| 4056 |     QCOMPARE(b.details(QOrganizerItemDetail::TypeDisplayLabel).count(), 1); | 
| 4057 |     QCOMPARE(b.details(QOrganizerItemDetail::TypeEventTime).count(), 0); // not saved | 
| 4058 |  | 
| 4059 |     // 6 Have a non existing item in the middle followed by a save error | 
| 4060 |     cm->removeItem(itemId: items[4].id()); | 
| 4061 |     QOrganizerItemDetail badDetail(QOrganizerItemDetail::TypeUndefined); | 
| 4062 |     badDetail.setValue(field: 101, value: "BadValue" ); | 
| 4063 |     items[5].saveDetail(detail: &badDetail); | 
| 4064 |     QVERIFY(!cm->saveItems(&items, QList<QOrganizerItemDetail::DetailType>() << QOrganizerItemDetail::TypeUndefined)); | 
| 4065 |     QMap<int, QOrganizerManager::Error> errorMap = cm->errorMap(); | 
| 4066 | //    QCOMPARE(errorMap.count(), 2); | 
| 4067 |     QCOMPARE(errorMap[4], QOrganizerManager::DoesNotExistError); | 
| 4068 | //    QCOMPARE(errorMap[5], QOrganizerManager::InvalidDetailError); | 
| 4069 | } | 
| 4070 |  | 
| 4071 | void tst_QOrganizerManager::dateRange() | 
| 4072 | { | 
| 4073 |     QFETCH(QOrganizerItem, item); | 
| 4074 |     QFETCH(QDateTime, startPeriod); | 
| 4075 |     QFETCH(QDateTime, endPeriod); | 
| 4076 |     QFETCH(bool, result); | 
| 4077 |     QCOMPARE(QOrganizerManagerEngine::isItemBetweenDates(item, startPeriod, endPeriod), result); | 
| 4078 | } | 
| 4079 |  | 
| 4080 | void tst_QOrganizerManager::dateRange_data() | 
| 4081 | { | 
| 4082 |     QTest::addColumn<QOrganizerItem>(name: "item" ); | 
| 4083 |     QTest::addColumn<QDateTime>(name: "startPeriod" ); | 
| 4084 |     QTest::addColumn<QDateTime>(name: "endPeriod" ); | 
| 4085 |     QTest::addColumn<bool>(name: "result" ); | 
| 4086 |  | 
| 4087 |     QOrganizerEvent ev; | 
| 4088 |     ev.setStartDateTime(QDateTime(QDate(2010, 10, 10), QTime(10,0,0))); | 
| 4089 |     ev.setEndDateTime(QDateTime(QDate(2010, 10, 12), QTime(11,0,0))); | 
| 4090 |  | 
| 4091 |     QTest::newRow(dataTag: "event - month" ) << QOrganizerItem(ev) << QDateTime(QDate(2010,10,1)) << QDateTime(QDate(2010,10,31)) << true; | 
| 4092 |     QTest::newRow(dataTag: "event - first day" ) << QOrganizerItem(ev) << QDateTime(QDate(2010,10,10)) << QDateTime(QDate(2010,10,10), QTime(23,59,59)) << true; | 
| 4093 |     QTest::newRow(dataTag: "event - second day" ) << QOrganizerItem(ev) << QDateTime(QDate(2010,10,11)) << QDateTime(QDate(2010,10,11), QTime(23,59,59)) << true; | 
| 4094 |     QTest::newRow(dataTag: "event - last day" ) << QOrganizerItem(ev) << QDateTime(QDate(2010,10,12)) << QDateTime(QDate(2010,10,12), QTime(23,59,59)) << true; | 
| 4095 |     QTest::newRow(dataTag: "event - undefined period" ) << QOrganizerItem(ev) << QDateTime() << QDateTime() << true; | 
| 4096 |     QTest::newRow(dataTag: "event - undefined start" ) << QOrganizerItem(ev) << QDateTime() << QDateTime(QDate(2010,10,11)) << true; | 
| 4097 |     QTest::newRow(dataTag: "event - undefined end" ) << QOrganizerItem(ev) << QDateTime(QDate(2010,10,11)) << QDateTime() << true; | 
| 4098 |     QTest::newRow(dataTag: "event - before" ) << QOrganizerItem(ev) << QDateTime(QDate(2010,10,8)) << QDateTime(QDate(2010,10,9)) << false; | 
| 4099 |     QTest::newRow(dataTag: "event - after" ) << QOrganizerItem(ev) << QDateTime(QDate(2010,10,13)) << QDateTime(QDate(2010,10,14)) << false; | 
| 4100 |  | 
| 4101 |     QOrganizerTodo todo; | 
| 4102 |     todo.setStartDateTime(QDateTime(QDate(2010, 10, 10), QTime(10,0,0))); | 
| 4103 |     todo.setDueDateTime(QDateTime(QDate(2010, 10, 12), QTime(11,0,0))); | 
| 4104 |  | 
| 4105 |     QTest::newRow(dataTag: "todo - month" ) << QOrganizerItem(todo) << QDateTime(QDate(2010,10,1)) << QDateTime(QDate(2010,10,31)) << true; | 
| 4106 |     QTest::newRow(dataTag: "todo - first day" ) << QOrganizerItem(todo) << QDateTime(QDate(2010,10,10)) << QDateTime(QDate(2010,10,10), QTime(23,59,59)) << true; | 
| 4107 |     QTest::newRow(dataTag: "todo - second day" ) << QOrganizerItem(todo) << QDateTime(QDate(2010,10,11)) << QDateTime(QDate(2010,10,11), QTime(23,59,59)) << true; | 
| 4108 |     QTest::newRow(dataTag: "todo - last day" ) << QOrganizerItem(todo) << QDateTime(QDate(2010,10,12)) << QDateTime(QDate(2010,10,12), QTime(23,59,59)) << true; | 
| 4109 |     QTest::newRow(dataTag: "todo - undefined period" ) << QOrganizerItem(todo) << QDateTime() << QDateTime() << true; | 
| 4110 |     QTest::newRow(dataTag: "todo - undefined start" ) << QOrganizerItem(todo) << QDateTime() << QDateTime(QDate(2010,10,11)) << true; | 
| 4111 |     QTest::newRow(dataTag: "todo - undefined end" ) << QOrganizerItem(todo) << QDateTime(QDate(2010,10,11)) << QDateTime() << true; | 
| 4112 |     QTest::newRow(dataTag: "todo - before" ) << QOrganizerItem(todo) << QDateTime(QDate(2010,10,8)) << QDateTime(QDate(2010,10,9)) << false; | 
| 4113 |     QTest::newRow(dataTag: "todo - after" ) << QOrganizerItem(todo) << QDateTime(QDate(2010,10,13)) << QDateTime(QDate(2010,10,14)) << false; | 
| 4114 |  | 
| 4115 |     todo.setDueDateTime(QDateTime()); | 
| 4116 |     QTest::newRow(dataTag: "todo missing due date - undefined start" ) << QOrganizerItem(todo) << QDateTime() << QDateTime(QDate(2010,10,11)) << true; | 
| 4117 |     QTest::newRow(dataTag: "todo missing due date - undefined end" ) << QOrganizerItem(todo) << QDateTime(QDate(2010,10,10)) << QDateTime() << true; | 
| 4118 |  | 
| 4119 |     todo.setStartDateTime(QDateTime()); | 
| 4120 |     todo.setDueDateTime(QDateTime(QDate(2010, 10, 12), QTime(11,0,0))); | 
| 4121 |     QTest::newRow(dataTag: "todo missing start date - undefined start" ) << QOrganizerItem(todo) << QDateTime() << QDateTime(QDate(2010,10,13)) << true; | 
| 4122 |     QTest::newRow(dataTag: "todo missing start date - undefined end" ) << QOrganizerItem(todo) << QDateTime(QDate(2010,10,11)) << QDateTime() << true; | 
| 4123 |  | 
| 4124 |     QOrganizerJournal journal; | 
| 4125 |     journal.setDateTime(QDateTime(QDate(2010, 10, 10), QTime(10,0,0))); | 
| 4126 |     QTest::newRow(dataTag: "journal - month" ) << QOrganizerItem(journal) << QDateTime(QDate(2010,10,1)) << QDateTime(QDate(2010,10,31)) << true; | 
| 4127 |     QTest::newRow(dataTag: "journal - first day" ) << QOrganizerItem(journal) << QDateTime(QDate(2010,10,10)) << QDateTime(QDate(2010,10,10), QTime(23,59,59)) << true; | 
| 4128 |     QTest::newRow(dataTag: "journal - second day" ) << QOrganizerItem(journal) << QDateTime(QDate(2010,10,11)) << QDateTime(QDate(2010,10,11), QTime(23,59,59)) << false; | 
| 4129 |     QTest::newRow(dataTag: "journal - undefined period" ) << QOrganizerItem(journal) << QDateTime() << QDateTime() << true; | 
| 4130 |     QTest::newRow(dataTag: "journal - undefined start" ) << QOrganizerItem(journal) << QDateTime() << QDateTime(QDate(2010,10,11)) << true; | 
| 4131 |     QTest::newRow(dataTag: "journal - undefined end" ) << QOrganizerItem(journal) << QDateTime(QDate(2010,10,10)) << QDateTime() << true; | 
| 4132 |     QTest::newRow(dataTag: "journal - before" ) << QOrganizerItem(journal) << QDateTime(QDate(2010,10,8)) << QDateTime(QDate(2010,10,9)) << false; | 
| 4133 |     QTest::newRow(dataTag: "journal - after" ) << QOrganizerItem(journal) << QDateTime(QDate(2010,10,13)) << QDateTime(QDate(2010,10,14)) << false; | 
| 4134 |  | 
| 4135 |     QOrganizerNote note; | 
| 4136 |     QTest::newRow(dataTag: "note" ) << QOrganizerItem(note) << QDateTime(QDate(2010,10,1)) << QDateTime() << false; | 
| 4137 |     QTest::newRow(dataTag: "note - undefined period" ) << QOrganizerItem(note) << QDateTime() << QDateTime() << true; | 
| 4138 | } | 
| 4139 |  | 
| 4140 | QList<QOrganizerItemDetail> tst_QOrganizerManager::removeAllDefaultDetails(const QList<QOrganizerItemDetail>& details) | 
| 4141 | { | 
| 4142 |     QList<QOrganizerItemDetail> newlist; | 
| 4143 |     foreach (const QOrganizerItemDetail d, details) { | 
| 4144 |         if (d.type() != QOrganizerItemDetail::TypeDisplayLabel | 
| 4145 |                 && d.type() != QOrganizerItemDetail::TypeItemType | 
| 4146 |                 && d.type() != QOrganizerItemDetail::TypeTimestamp) { | 
| 4147 |             newlist << d; | 
| 4148 |         } | 
| 4149 |     } | 
| 4150 |     return newlist; | 
| 4151 | } | 
| 4152 |  | 
| 4153 | void tst_QOrganizerManager::detailOrders() | 
| 4154 | { | 
| 4155 |     QFETCH(QString, uri); | 
| 4156 |     QScopedPointer<QOrganizerManager> cm(QOrganizerManager::fromUri(uri)); | 
| 4157 |  | 
| 4158 |     QOrganizerEvent a; | 
| 4159 |  | 
| 4160 |     // comments | 
| 4161 |     QOrganizerItemComment , , ; | 
| 4162 |  | 
| 4163 |     comment1.setComment("11111111" ); | 
| 4164 |     comment2.setComment("22222222" ); | 
| 4165 |     comment3.setComment("33333333" ); | 
| 4166 |  | 
| 4167 |     a.saveDetail(detail: &comment1); | 
| 4168 |     a.saveDetail(detail: &comment2); | 
| 4169 |     a.saveDetail(detail: &comment3); | 
| 4170 |  | 
| 4171 |     QVERIFY(cm->saveItem(&a)); | 
| 4172 |     a = cm->item(itemId: a.id()); | 
| 4173 |  | 
| 4174 |     QList<QOrganizerItemDetail> details = a.details(detailType: QOrganizerItemDetail::TypeComment); | 
| 4175 |     QVERIFY(details.count() == 3); | 
| 4176 |  | 
| 4177 |     comment2 = a.details(detailType: QOrganizerItemDetail::TypeComment).at(i: 1); | 
| 4178 |     QVERIFY(a.removeDetail(&comment2)); | 
| 4179 |     QVERIFY(cm->saveItem(&a)); | 
| 4180 |     a = cm->item(itemId: a.id()); | 
| 4181 |     details = a.details(detailType: QOrganizerItemDetail::TypeComment); | 
| 4182 |     QVERIFY(details.count() == 2); | 
| 4183 |  | 
| 4184 |     a.saveDetail(detail: &comment2); | 
| 4185 |     QVERIFY(cm->saveItem(&a)); | 
| 4186 |     a = cm->item(itemId: a.id()); | 
| 4187 |  | 
| 4188 |     details = a.details(detailType: QOrganizerItemDetail::TypeComment); | 
| 4189 |     QVERIFY(details.count() == 3); | 
| 4190 |  | 
| 4191 |     //addresses | 
| 4192 |     { | 
| 4193 |         QOrganizerItemLocation address1, address2, address3; | 
| 4194 |  | 
| 4195 |         address1.setLabel("Brandl St" ); | 
| 4196 |         address3 = address2 = address1; | 
| 4197 |  | 
| 4198 |         a.saveDetail(detail: &address1); | 
| 4199 |         a.saveDetail(detail: &address2); | 
| 4200 |         a.saveDetail(detail: &address3); | 
| 4201 |  | 
| 4202 |         QVERIFY(cm->saveItem(&a)); | 
| 4203 |         a = cm->item(itemId: a.id()); | 
| 4204 |  | 
| 4205 |         QList<QOrganizerItemDetail> details = a.details(detailType: QOrganizerItemDetail::TypeLocation); | 
| 4206 |         QVERIFY(details.count() == 1); // 1 location - they're unique | 
| 4207 |  | 
| 4208 |         // Detail keys for the moment are not persistent through an item save / fetch | 
| 4209 |         address3 = details.at(i: 0); | 
| 4210 |  | 
| 4211 |         QVERIFY(a.removeDetail(&address3)); // remove the most recent. | 
| 4212 |         QVERIFY(cm->saveItem(&a)); | 
| 4213 |         a = cm->item(itemId: a.id()); | 
| 4214 |         details = a.details(detailType: QOrganizerItemDetail::TypeLocation); | 
| 4215 |         QVERIFY(details.count() == 0); // unique, remove one means none left. | 
| 4216 |  | 
| 4217 |         a.saveDetail(detail: &address2); | 
| 4218 |         QVERIFY(cm->saveItem(&a)); | 
| 4219 |         a = cm->item(itemId: a.id()); | 
| 4220 |  | 
| 4221 |         details = a.details(detailType: QOrganizerItemDetail::TypeLocation); | 
| 4222 |         QVERIFY(details.count() == 1); // add one back. | 
| 4223 |     } | 
| 4224 | } | 
| 4225 |  | 
| 4226 | void tst_QOrganizerManager::itemType() | 
| 4227 | { | 
| 4228 |     // XXX TODO! | 
| 4229 | } | 
| 4230 |  | 
| 4231 | void tst_QOrganizerManager::collections() | 
| 4232 | { | 
| 4233 |     // XXX TODO: break test into smaller sub-tests (per operation). | 
| 4234 |  | 
| 4235 |     QFETCH(QString, uri); | 
| 4236 |     QScopedPointer<QOrganizerManager> oim(QOrganizerManager::fromUri(uri)); | 
| 4237 |  | 
| 4238 |     // delete all collections in the database so that we know there can be no interference from previous test runs. | 
| 4239 |     QList<QOrganizerCollection> allCollections = oim->collections(); | 
| 4240 |     for (int i = 0; i < allCollections.size(); ++i) { | 
| 4241 |         QOrganizerCollectionId currentId = allCollections.at(i).id(); | 
| 4242 |         if (currentId != oim->defaultCollectionId()) { | 
| 4243 |             oim->removeCollection(collectionId: currentId); | 
| 4244 |         } | 
| 4245 |     } | 
| 4246 |  | 
| 4247 |     QOrganizerCollection c1, c2, c3, sc1; | 
| 4248 |     c1.setMetaData(key: QOrganizerCollection::KeyName, value: "Test One" ); | 
| 4249 |     c1.setMetaData(key: QOrganizerCollection::KeyDescription, value: "This collection is for testing purposes." ); | 
| 4250 |     c1.setExtendedMetaData(key: "key" , value: "value" ); | 
| 4251 |     c2.setMetaData(key: QOrganizerCollection::KeyName, value: "Test Two" ); | 
| 4252 |     c2.setMetaData(key: QOrganizerCollection::KeyColor, value: QColor(Qt::blue)); | 
| 4253 |     // c3 doesn't have any meta-data, just an id. | 
| 4254 |  | 
| 4255 |     QOrganizerEvent i1, i2, i3, i4, i5; | 
| 4256 |     i1.setDisplayLabel("one" ); | 
| 4257 |     i2.setDisplayLabel("two" ); | 
| 4258 |     i2.setDescription("this is the second item" ); | 
| 4259 |     i3.setDisplayLabel("three" ); | 
| 4260 |     i4.setDisplayLabel("four" ); | 
| 4261 |     i4.setGuid(QUuid::createUuid().toString()); | 
| 4262 |     i5.setDisplayLabel("five" ); | 
| 4263 | //    i5.setLocation("test location address"); | 
| 4264 |  | 
| 4265 |     // modify default collection | 
| 4266 |     if (oim->managerName() != "memory" ) // modifying default collection is not allowed in memory engine | 
| 4267 |     { | 
| 4268 |         int initialCollectionCount = oim->collections().size(); | 
| 4269 |         QOrganizerCollectionId defaultCollectionId = oim->defaultCollectionId(); | 
| 4270 |         QOrganizerCollection defaultCollection = oim->collection(collectionId: defaultCollectionId); | 
| 4271 |         defaultCollection.setMetaData(key: QOrganizerCollection::KeyName, value: "NewName" ); | 
| 4272 |         QCOMPARE(defaultCollection.id(), defaultCollectionId); | 
| 4273 |         QVERIFY(oim->saveCollection(&defaultCollection)); | 
| 4274 |         int finalCollectionCount = oim->collections().size(); | 
| 4275 |         QCOMPARE(finalCollectionCount, initialCollectionCount); | 
| 4276 |         QCOMPARE(oim->collection(defaultCollectionId).metaData(QOrganizerCollection::KeyName).toString(), QString("NewName" )); | 
| 4277 |         QCOMPARE(defaultCollection.id(), defaultCollectionId); | 
| 4278 |     } | 
| 4279 |  | 
| 4280 |     // first test | 
| 4281 |     { | 
| 4282 |         // save a collection | 
| 4283 |         QVERIFY(c1.id().isNull()); // should have a null id to start with. | 
| 4284 |         QVERIFY(oim->saveCollection(&c1)); | 
| 4285 |         QVERIFY(!c1.id().isNull()); // should have been set by the save operation | 
| 4286 |         QVERIFY(oim->collections().contains(c1)); | 
| 4287 |         sc1 = oim->collection(collectionId: c1.id()); | 
| 4288 |         QVERIFY(sc1.metaData(QOrganizerCollection::KeyName) == "Test One" ); | 
| 4289 |         QVERIFY(sc1.metaData(QOrganizerCollection::KeyDescription) == "This collection is for testing purposes." ); | 
| 4290 |         QVERIFY(sc1.extendedMetaData("key" ) == "value" ); | 
| 4291 |  | 
| 4292 |         // save an item in that collection | 
| 4293 |         QOrganizerItemCollectionFilter fil; | 
| 4294 |         fil.setCollectionId(c1.id()); | 
| 4295 |         i1.setCollectionId(c1.id()); | 
| 4296 |         QVERIFY(oim->saveItem(&i1)); | 
| 4297 |         QVERIFY(i1.collectionId() == c1.id()); | 
| 4298 |  | 
| 4299 |         QList<QOrganizerItem> c1Items = oim->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: fil); | 
| 4300 |         int itemIndex = -1; | 
| 4301 |         for (int i = 0; i < c1Items.count(); i++) { | 
| 4302 |             if (c1Items.at(i).id() == i1.id()) { | 
| 4303 |                 itemIndex = i; | 
| 4304 |                 break; | 
| 4305 |             } | 
| 4306 |         } | 
| 4307 |         QVERIFY(itemIndex >= 0); | 
| 4308 |         QVERIFY(oim->items(QDateTime(), QDateTime(), fil).contains(i1) || isSuperset(c1Items.at(itemIndex), i1)); | 
| 4309 |  | 
| 4310 |         fil.setCollectionId(oim->defaultCollectionId()); | 
| 4311 |         QVERIFY(!oim->items(QDateTime(), QDateTime(), fil).contains(i1)); // it should not be in the default collection. | 
| 4312 |     } | 
| 4313 |  | 
| 4314 |     // second test | 
| 4315 |     { | 
| 4316 |         // save multiple collections. // XXX TODO: batch save for collections? | 
| 4317 |         int originalColCount = oim->collections().count(); | 
| 4318 |         QVERIFY(oim->saveCollection(&c2)); | 
| 4319 |         QVERIFY(oim->saveCollection(&c3)); | 
| 4320 |         QVERIFY(oim->collections().count() == (originalColCount + 2)); | 
| 4321 |  | 
| 4322 |         // save i5 in c3 as a canary value. | 
| 4323 |         i5.setCollectionId(c3.id()); | 
| 4324 |  | 
| 4325 |         // save multiple items in collection c2 | 
| 4326 |         QList<QOrganizerItem> saveList; | 
| 4327 |         i2.setCollectionId(c2.id()); | 
| 4328 |         i3.setCollectionId(c2.id()); | 
| 4329 |         i4.setCollectionId(c2.id()); | 
| 4330 |         saveList << i2 << i3 << i4 << i5; | 
| 4331 |         int originalItemCount = oim->items().count(); | 
| 4332 |         QVERIFY(oim->saveItems(&saveList)); | 
| 4333 |         i2 = saveList.at(i: 0); // update from save list because manager might have added details / set ids etc. | 
| 4334 |         i3 = saveList.at(i: 1); | 
| 4335 |         i4 = saveList.at(i: 2); | 
| 4336 |         i5 = saveList.at(i: 3); | 
| 4337 |         QList<QOrganizerItem> fetchedItems = oim->items(); | 
| 4338 |         QCOMPARE(fetchedItems.count(), originalItemCount + 4); | 
| 4339 |         //fails here | 
| 4340 |         QVERIFY(fetchedItems.contains(i2)); // these three should have been added | 
| 4341 |         QVERIFY(fetchedItems.contains(i3)); | 
| 4342 |         QVERIFY(fetchedItems.contains(i4)); | 
| 4343 |         QVERIFY(fetchedItems.contains(i5)); // i5 should not have been removed. | 
| 4344 |  | 
| 4345 |         // update a collection shouldn't remove its items. | 
| 4346 |         c2.setMetaData(key: QOrganizerCollection::KeyName, value: "Test Two Updated" ); | 
| 4347 |         QVERIFY(oim->saveCollection(&c2)); | 
| 4348 |         fetchedItems = oim->items(); | 
| 4349 |         QVERIFY(fetchedItems.contains(i2)); // no items should have been removed | 
| 4350 |         QVERIFY(fetchedItems.contains(i3)); // nor should they have changed collection. | 
| 4351 |         QVERIFY(fetchedItems.contains(i4)); | 
| 4352 |         QVERIFY(fetchedItems.contains(i5)); | 
| 4353 |  | 
| 4354 |         // exceptions must be saved in the same collection as their parent. | 
| 4355 |         QOrganizerEvent recurringEvent; | 
| 4356 |         recurringEvent.setDescription("A recurring test event parent." ); | 
| 4357 |         //            recurringEvent.setLocation("Some Location"); | 
| 4358 |         recurringEvent.setStartDateTime(QDateTime(QDate(2010,10,5), QTime(10,30))); | 
| 4359 |         recurringEvent.setEndDateTime(QDateTime(QDate(2010,10,5), QTime(11,30))); | 
| 4360 |         QOrganizerRecurrenceRule rrule; | 
| 4361 |         rrule.setFrequency(QOrganizerRecurrenceRule::Weekly); | 
| 4362 |         rrule.setLimit(5); // count limited. | 
| 4363 |         recurringEvent.setRecurrenceRule(rrule); | 
| 4364 |         recurringEvent.setCollectionId(c2.id()); | 
| 4365 |         QVERIFY(oim->saveItem(&recurringEvent)); | 
| 4366 |         recurringEvent = oim->item(itemId: recurringEvent.id()); // reload it. | 
| 4367 |         QVERIFY(recurringEvent.collectionId() == c2.id()); | 
| 4368 |         QList<QOrganizerItem> occ(oim->itemOccurrences(parentItem: recurringEvent, startDateTime: QDateTime(), endDateTime: QDateTime())); | 
| 4369 |         QVERIFY(occ.size() == 5); | 
| 4370 |         QOrganizerEventOccurrence someException = occ.at(i: 2); // there should be five, so this shouldn't segfault. | 
| 4371 |         //            someException.setLocation("Other Location"); | 
| 4372 |         someException.setCollectionId(c3.id()); // different to parent. | 
| 4373 |         QVERIFY(!oim->saveItem(&someException)); // shouldn't work. | 
| 4374 |         someException.setCollectionId(c2.id()); // same as parent. | 
| 4375 |         QVERIFY(oim->saveItem(&someException)); // should work. | 
| 4376 |  | 
| 4377 |         // remove a collection, removes its items. | 
| 4378 |         QVERIFY(oim->removeCollection(c2.id())); | 
| 4379 |         fetchedItems = oim->items(); | 
| 4380 |         QCOMPARE(fetchedItems.count(), originalItemCount + 1); // i5 should remain, i2->i4 should be removed. | 
| 4381 |         QVERIFY(!fetchedItems.contains(i2)); // these three should have been removed | 
| 4382 |         QVERIFY(!fetchedItems.contains(i3)); | 
| 4383 |         QVERIFY(!fetchedItems.contains(i4)); | 
| 4384 |         QVERIFY(!fetchedItems.contains(recurringEvent)); // the parent | 
| 4385 |         QVERIFY(!fetchedItems.contains(someException));  // and exceptions too. | 
| 4386 |         QVERIFY(fetchedItems.contains(i5)); // i5 should not have been removed. | 
| 4387 |  | 
| 4388 |         // attempt to save an item in a non-existent collection should fail. | 
| 4389 |         i2.setId(QOrganizerItemId()); // reset Id so save can succeed... | 
| 4390 |         i2.setCollectionId(c2.id()); | 
| 4391 |         QVERIFY(!oim->saveItem(&i2)); | 
| 4392 |         fetchedItems = oim->items(); | 
| 4393 |         QVERIFY(!fetchedItems.contains(i2)); // shouldn't have been added. | 
| 4394 |         QVERIFY(fetchedItems.contains(i5)); // i5 should not have been removed. | 
| 4395 |     } | 
| 4396 | } | 
| 4397 |  | 
| 4398 | void tst_QOrganizerManager::testReminder() | 
| 4399 | { | 
| 4400 |     QFETCH(QString, uri); | 
| 4401 |     QScopedPointer<QOrganizerManager> oim(QOrganizerManager::fromUri(uri)); | 
| 4402 |  | 
| 4403 |     /*audible reminder test*/ | 
| 4404 |     QOrganizerItemAudibleReminder audioReminder; | 
| 4405 |     QOrganizerEvent oi; | 
| 4406 |     oi.setDisplayLabel("test reminder" ); | 
| 4407 |     audioReminder.setRepetition(count: 3, delaySeconds: 100); | 
| 4408 |     QVERIFY(oi.saveDetail(&audioReminder)); | 
| 4409 |     oi.setStartDateTime(QDateTime::currentDateTime()); | 
| 4410 |     QVERIFY(oim->saveItem(&oi)); | 
| 4411 |  | 
| 4412 |     QList<QOrganizerItem> fetchedItems = oim->items(); | 
| 4413 |     //After adding StartDateTime detail the item compare function does not work. Need fix later | 
| 4414 |     //QVERIFY(fetchedItems.contains(oi)); | 
| 4415 |     foreach (QOrganizerItem item, fetchedItems) { | 
| 4416 |         if (oi.id() == item.id()) | 
| 4417 |             QVERIFY(item.detail(QOrganizerItemDetail::TypeAudibleReminder) == audioReminder); | 
| 4418 |     } | 
| 4419 |  | 
| 4420 |     //Test SecondsBeforeStart properties | 
| 4421 |     audioReminder.setSecondsBeforeStart(30); // reminder, 30 seconds before the item is due to start. | 
| 4422 |     QVERIFY(oi.saveDetail(&audioReminder)); | 
| 4423 |     QVERIFY(oim->saveItem (&oi)); | 
| 4424 |     fetchedItems = oim->items(); | 
| 4425 |     //After adding StartDateTime detail the item compare function does not work. Need fix later | 
| 4426 |     //QVERIFY(fetchedItems.contains(oi)); | 
| 4427 |     foreach (QOrganizerItem item, fetchedItems) { | 
| 4428 |         if (oi.id() == item.id()) | 
| 4429 |             QVERIFY(item.detail(QOrganizerItemDetail::TypeAudibleReminder) == audioReminder); | 
| 4430 |     } | 
| 4431 |  | 
| 4432 |     // update | 
| 4433 |     audioReminder.setSecondsBeforeStart(300); | 
| 4434 |     audioReminder.setDataUrl(QUrl("http://www.test.com" )); | 
| 4435 |     QVERIFY(audioReminder.dataUrl() == QUrl("http://www.test.com" )); | 
| 4436 |     QVERIFY(oi.detail(QOrganizerItemDetail::TypeAudibleReminder) != audioReminder); | 
| 4437 |     QVERIFY(oi.saveDetail(&audioReminder)); | 
| 4438 |     QVERIFY(oi.details(QOrganizerItemDetail::TypeAudibleReminder).size() == 1); // should update, not add another | 
| 4439 |     QVERIFY(oi.detail(QOrganizerItemDetail::TypeAudibleReminder) == audioReminder); | 
| 4440 |     oim->saveItem (item: &oi); | 
| 4441 |     fetchedItems = oim->items(); | 
| 4442 |     // After adding StartDateTime detail the item compare function does not work. Need fix later | 
| 4443 |     //QVERIFY(fetchedItems.contains(oi)); | 
| 4444 |     foreach (QOrganizerItem item, fetchedItems) { | 
| 4445 |         if (oi.id() == item.id()) | 
| 4446 |             QVERIFY(item.detail(QOrganizerItemDetail::TypeAudibleReminder) == audioReminder); | 
| 4447 |     } | 
| 4448 |  | 
| 4449 |     // remove | 
| 4450 |     QVERIFY(oi.removeDetail(&audioReminder)); | 
| 4451 |     QVERIFY(oi.details(QOrganizerItemDetail::TypeAudibleReminder).size() == 0); | 
| 4452 |     oim->saveItem (item: &oi); | 
| 4453 |     fetchedItems = oim->items(); | 
| 4454 |     // After adding StartDateTime detail the item compare function does not work. Need fix later | 
| 4455 |     //QVERIFY(fetchedItems.contains(oi)); | 
| 4456 |     foreach (QOrganizerItem item, fetchedItems) { | 
| 4457 |         if (oi.id() == item.id()) | 
| 4458 |             QVERIFY(item.detail(QOrganizerItemDetail::TypeAudibleReminder) == oi.detail(QOrganizerItemDetail::TypeAudibleReminder)); | 
| 4459 |     } | 
| 4460 |  | 
| 4461 |     /*Email reminder test*/ | 
| 4462 |     QOrganizerItemEmailReminder emailReminder; | 
| 4463 |     QOrganizerEvent emailEvent; | 
| 4464 |     QVERIFY(emailReminder.reminderType() == QOrganizerItemReminder::EmailReminder); | 
| 4465 |     emailReminder.setRepetition(count: 3, delaySeconds: 100); | 
| 4466 |  | 
| 4467 |     QVERIFY(emailEvent.saveDetail(&emailReminder)); | 
| 4468 |     QVERIFY(oim->saveItem (&emailEvent)); | 
| 4469 |     fetchedItems = oim->items(); | 
| 4470 |  | 
| 4471 |     QVERIFY(fetchedItems.contains(emailEvent)); | 
| 4472 |  | 
| 4473 |     emailReminder.setSecondsBeforeStart(30); // reminder, 30 seconds before the item is due to start. | 
| 4474 |     QVERIFY(emailReminder.secondsBeforeStart() == 30); | 
| 4475 |     QVERIFY(emailEvent.saveDetail(&emailReminder)); | 
| 4476 |     QVERIFY(oim->saveItem (&emailEvent)); | 
| 4477 |     fetchedItems = oim->items(); | 
| 4478 |     QVERIFY(fetchedItems.contains(emailEvent)); | 
| 4479 |  | 
| 4480 |     // update | 
| 4481 |     emailReminder.setSecondsBeforeStart(300); | 
| 4482 |     emailReminder.setContents(subject: "subject" , body: "body" , attachments: QVariantList()); | 
| 4483 |     emailReminder.setRecipients(QStringList() << "recipient"  << "other recipient" ); | 
| 4484 |     QVERIFY(emailReminder.subject() == QString("subject" )); | 
| 4485 |     QVERIFY(emailReminder.body() == QString("body" )); | 
| 4486 |     QVERIFY(emailReminder.attachments() == QVariantList()); | 
| 4487 |     QVERIFY(emailReminder.recipients() == (QStringList() << "recipient"  << "other recipient" )); | 
| 4488 |     QVERIFY(emailEvent.detail(QOrganizerItemDetail::TypeEmailReminder) != emailReminder); | 
| 4489 |     QVERIFY(emailEvent.saveDetail(&emailReminder)); | 
| 4490 |     oim->saveItem (item: &emailEvent); | 
| 4491 |     fetchedItems = oim->items(); | 
| 4492 |  | 
| 4493 | //    dumpOrganizerItem (emailEvent); | 
| 4494 | //    foreach (QOrganizerItem item, fetchedItems) { | 
| 4495 | //        if (emailEvent.id() == item.id()) | 
| 4496 | //            dumpOrganizerItem (item); | 
| 4497 | //    } | 
| 4498 |  | 
| 4499 |     QVERIFY(fetchedItems.contains(emailEvent)); | 
| 4500 |  | 
| 4501 |     // remove | 
| 4502 |     QVERIFY(emailEvent.removeDetail(&emailReminder)); | 
| 4503 |     QVERIFY(emailEvent.details(QOrganizerItemDetail::TypeEmailReminder).size() == 0); | 
| 4504 |     oim->saveItem (item: &emailEvent); | 
| 4505 |     fetchedItems = oim->items(); | 
| 4506 |     QVERIFY(fetchedItems.contains(emailEvent)); | 
| 4507 |  | 
| 4508 |     /*Visual reminder test*/ | 
| 4509 |     QOrganizerItemVisualReminder visualReminder; | 
| 4510 |     QOrganizerEvent visualEvent; | 
| 4511 |     QVERIFY(visualReminder.reminderType() == QOrganizerItemReminder::VisualReminder); | 
| 4512 |     visualReminder.setRepetition(count: 3, delaySeconds: 100); | 
| 4513 |  | 
| 4514 |     QVERIFY(visualEvent.saveDetail(&visualReminder)); | 
| 4515 |     QVERIFY(oim->saveItem (&visualEvent)); | 
| 4516 |     fetchedItems = oim->items(); | 
| 4517 |     QVERIFY(fetchedItems.contains(visualEvent)); | 
| 4518 |  | 
| 4519 |     visualReminder.setSecondsBeforeStart(30); // reminder, 30 seconds before the item is due to start. | 
| 4520 |     QVERIFY(visualReminder.secondsBeforeStart() == 30); | 
| 4521 |     QVERIFY(visualEvent.saveDetail(&visualReminder)); | 
| 4522 |     QVERIFY(oim->saveItem (&visualEvent)); | 
| 4523 |     fetchedItems = oim->items(); | 
| 4524 |     QVERIFY(fetchedItems.contains(visualEvent)); | 
| 4525 |  | 
| 4526 |     // update | 
| 4527 |     visualReminder.setSecondsBeforeStart(300); | 
| 4528 |     visualReminder.setMessage("test" ); | 
| 4529 |     visualReminder.setDataUrl(QUrl("http://www.test.com" )); | 
| 4530 |     QVERIFY(visualReminder.message() == QString("test" )); | 
| 4531 |     QVERIFY(visualReminder.dataUrl() == QUrl("http://www.test.com" )); | 
| 4532 |     QVERIFY(visualEvent.detail(QOrganizerItemDetail::TypeVisualReminder) != visualReminder); | 
| 4533 |     QVERIFY(visualEvent.saveDetail(&visualReminder)); | 
| 4534 |     oim->saveItem (item: &visualEvent); | 
| 4535 |     fetchedItems = oim->items(); | 
| 4536 |     QVERIFY(fetchedItems.contains(visualEvent)); | 
| 4537 |  | 
| 4538 |     // remove | 
| 4539 |     QVERIFY(visualEvent.removeDetail(&visualReminder)); | 
| 4540 |     QVERIFY(visualEvent.details(QOrganizerItemDetail::TypeVisualReminder).size() == 0); | 
| 4541 |     oim->saveItem (item: &visualEvent); | 
| 4542 |     fetchedItems = oim->items(); | 
| 4543 |     QVERIFY(fetchedItems.contains(visualEvent)); | 
| 4544 |  | 
| 4545 |     /*Event with more reminder*/ | 
| 4546 |     QOrganizerEvent bigEvent; | 
| 4547 |     bigEvent.saveDetail(detail: &audioReminder); | 
| 4548 |     bigEvent.saveDetail(detail: &visualReminder); | 
| 4549 |     bigEvent.saveDetail(detail: &emailReminder); | 
| 4550 |     oim->saveItem (item: &bigEvent); | 
| 4551 |     fetchedItems = oim->items(); | 
| 4552 |     QVERIFY(fetchedItems.contains(bigEvent)); | 
| 4553 |  | 
| 4554 |     // remove | 
| 4555 |     QVERIFY(bigEvent.removeDetail(&visualReminder)); | 
| 4556 |     oim->saveItem (item: &bigEvent); | 
| 4557 |     fetchedItems = oim->items(); | 
| 4558 |     QVERIFY(fetchedItems.contains(bigEvent)); | 
| 4559 | } | 
| 4560 |  | 
| 4561 | void tst_QOrganizerManager::testIntersectionFilter() | 
| 4562 | { | 
| 4563 |     QFETCH(QString, uri); | 
| 4564 |     QScopedPointer<QOrganizerManager> mgr(QOrganizerManager::fromUri(uri)); | 
| 4565 |  | 
| 4566 |     // initialize db | 
| 4567 |     mgr->removeItems(itemIds: mgr->itemIds()); | 
| 4568 |     QCOMPARE(mgr->items().count(), 0); | 
| 4569 |  | 
| 4570 |     //prepare filter data | 
| 4571 |     QOrganizerCollection c1; | 
| 4572 |     QOrganizerCollection c2; | 
| 4573 |     mgr->saveCollection(collection: &c1); | 
| 4574 |     mgr->saveCollection(collection: &c2); | 
| 4575 |     QOrganizerItem event1; | 
| 4576 |     event1.setType(QOrganizerItemType::TypeEvent); | 
| 4577 |     QOrganizerItem event2; | 
| 4578 |     event2.setType(QOrganizerItemType::TypeEvent); | 
| 4579 |     event1.setCollectionId(c1.id()); | 
| 4580 |     event2.setCollectionId(c2.id()); | 
| 4581 |     mgr->saveItem(item: &event1); | 
| 4582 |     mgr->saveItem(item: &event2); | 
| 4583 |     //Test intersection filter with 2 different collection filter | 
| 4584 |     QOrganizerItemCollectionFilter cf1; | 
| 4585 |     cf1.setCollectionId(c1.id()); | 
| 4586 |     QOrganizerItemCollectionFilter cf2; | 
| 4587 |     cf2.setCollectionId(c2.id()); | 
| 4588 |     QOrganizerItemIntersectionFilter isf; | 
| 4589 |     isf.append(filter: cf1); | 
| 4590 |     isf.append(filter: cf2); | 
| 4591 |     QList<QOrganizerItem> itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: cf1); | 
| 4592 |     QCOMPARE(itemList.size(), 1); | 
| 4593 |     QCOMPARE(itemList.at(0), event1); | 
| 4594 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isf); | 
| 4595 |     QCOMPARE(itemList.size(), 0); | 
| 4596 |  | 
| 4597 |     //Test intersection filter with 2 same collection filter | 
| 4598 |     isf.remove(filter: cf2); | 
| 4599 |     cf2.setCollectionId(c1.id()); | 
| 4600 |     isf.append(filter: cf2); | 
| 4601 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isf); | 
| 4602 |     QCOMPARE(itemList.size(), 1); | 
| 4603 |  | 
| 4604 |     //Test intersection filter with 2 collection filter and one of them is bigger than another | 
| 4605 |     isf.remove(filter: cf2); | 
| 4606 |     QSet<QOrganizerCollectionId> collectionList; | 
| 4607 |     collectionList << c1.id() << c2.id(); | 
| 4608 |     cf2.setCollectionIds(collectionList); | 
| 4609 |     isf.append(filter: cf2); | 
| 4610 |     isf.append(filter: cf1); | 
| 4611 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isf); | 
| 4612 |     QCOMPARE(itemList.size(), 1); | 
| 4613 |  | 
| 4614 |     //Bad case: one empty filter | 
| 4615 |     isf.remove(filter: cf2); | 
| 4616 |     cf2.setCollectionId(QOrganizerCollectionId()); | 
| 4617 |     isf.append(filter: cf2); | 
| 4618 |     QCOMPARE(isf.filters().size(), 2); | 
| 4619 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isf); | 
| 4620 |     QCOMPARE(itemList.size(), 0); | 
| 4621 |  | 
| 4622 |     //QOrganizerItemIdFilter test | 
| 4623 |     QOrganizerItemIdFilter idFilter; | 
| 4624 |     QList<QOrganizerItemId> ids; | 
| 4625 |     QOrganizerItem event3; | 
| 4626 |     event3.setType(QOrganizerItemType::TypeEvent); | 
| 4627 |     mgr->saveItem(item: &event3); | 
| 4628 |     ids << event1.id() << event3.id(); | 
| 4629 |     idFilter.setIds(ids); | 
| 4630 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: idFilter); | 
| 4631 |     QCOMPARE(itemList.size(), 2); | 
| 4632 |     if (itemList.at(i: 0).id() == event1.id()){ | 
| 4633 |         QCOMPARE(itemList.at(0), event1); | 
| 4634 |         QCOMPARE(itemList.at(1), event3); | 
| 4635 |     } else { | 
| 4636 |         QCOMPARE(itemList.at(1), event1); | 
| 4637 |         QCOMPARE(itemList.at(0), event3); | 
| 4638 |     } | 
| 4639 |     //a bad id inside the list | 
| 4640 |     // NOTE: empty id in id filter will match all generated occurrences | 
| 4641 |     QOrganizerItem badEvent; | 
| 4642 |     ids.prepend(t: badEvent.id()); | 
| 4643 |     idFilter.setIds(ids); | 
| 4644 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: idFilter); | 
| 4645 |     QCOMPARE(itemList.size(), 2); | 
| 4646 |  | 
| 4647 |     //intersection filter contains QOrganizerItemIdFilter and QOrganizerItemCollectionFilter | 
| 4648 |     cf2.setCollectionIds(collectionList); | 
| 4649 |     isf.clear(); | 
| 4650 |     isf.append(filter: cf2);//event1 event2 | 
| 4651 |     isf.append(filter: idFilter);//event1 event3 | 
| 4652 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isf); | 
| 4653 |     QCOMPARE(itemList.size(), 1); | 
| 4654 |     QCOMPARE(itemList.at(0), event1);//expect event1 | 
| 4655 |  | 
| 4656 |     //3 filters intersection | 
| 4657 |     ids.clear(); | 
| 4658 |     ids.append(t: event1.id()); | 
| 4659 |     idFilter.setIds(ids); | 
| 4660 |     isf.append(filter: idFilter);//event1 | 
| 4661 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isf); | 
| 4662 |     QCOMPARE(itemList.size(), 1); | 
| 4663 |  | 
| 4664 |     //empty intersection | 
| 4665 |     ids.clear(); | 
| 4666 |     ids.append(t: event3.id()); | 
| 4667 |     idFilter.setIds(ids); | 
| 4668 |     isf.append(filter: idFilter);//event3 | 
| 4669 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isf); | 
| 4670 |     QCOMPARE(itemList.size(), 0); | 
| 4671 | } | 
| 4672 |  | 
| 4673 | void tst_QOrganizerManager::testNestCompoundFilter() | 
| 4674 | { | 
| 4675 |     QFETCH(QString, uri); | 
| 4676 |     QScopedPointer<QOrganizerManager> mgr(QOrganizerManager::fromUri(uri)); | 
| 4677 |     //simple case: nest intersection filter | 
| 4678 |     //prepare filter data | 
| 4679 |     QOrganizerCollection c1; | 
| 4680 |     QOrganizerCollection c2; | 
| 4681 |     mgr->saveCollection(collection: &c1); | 
| 4682 |     mgr->saveCollection(collection: &c2); | 
| 4683 |     QOrganizerItem event1; | 
| 4684 |     event1.setType(QOrganizerItemType::TypeEvent); | 
| 4685 |     QOrganizerItem event2; | 
| 4686 |     event2.setType(QOrganizerItemType::TypeEvent); | 
| 4687 |     event1.setCollectionId(c1.id()); | 
| 4688 |     event2.setCollectionId(c2.id()); | 
| 4689 |     mgr->saveItem(item: &event1); | 
| 4690 |     mgr->saveItem(item: &event2); | 
| 4691 |     //Test intersection filter with 2 different collection filter | 
| 4692 |     QOrganizerItemCollectionFilter cf1; | 
| 4693 |     cf1.setCollectionId(c1.id()); | 
| 4694 |     QOrganizerItemCollectionFilter cf2; | 
| 4695 |     cf2.setCollectionId(c2.id()); | 
| 4696 |     QOrganizerItemIntersectionFilter isf; | 
| 4697 |     isf.append(filter: cf1); | 
| 4698 |  | 
| 4699 |     QOrganizerItemIntersectionFilter isfLevel1; | 
| 4700 |     isfLevel1.append(filter: isf); | 
| 4701 |     QList<QOrganizerItem> itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isfLevel1); | 
| 4702 |     QCOMPARE(itemList.size(), 1); | 
| 4703 |  | 
| 4704 |     QOrganizerItemIntersectionFilter isfLevel2; | 
| 4705 |     isfLevel2.append(filter: isfLevel1); | 
| 4706 |  | 
| 4707 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isfLevel2); | 
| 4708 |     QCOMPARE(itemList.size(), 1); | 
| 4709 |  | 
| 4710 |     QOrganizerItemIntersectionFilter isfLevel3; | 
| 4711 |     isfLevel3.append(filter: isfLevel2); | 
| 4712 |  | 
| 4713 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isfLevel3); | 
| 4714 |     QCOMPARE(itemList.size(), 1); | 
| 4715 |  | 
| 4716 |     // union filter nest in interseion filter | 
| 4717 |     QOrganizerItemUnionFilter unf; | 
| 4718 |     unf.append(filter: cf2); | 
| 4719 |     unf.append(filter: cf1); | 
| 4720 |  | 
| 4721 |     isfLevel1.append(filter: unf); | 
| 4722 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isfLevel1); | 
| 4723 |     QCOMPARE(itemList.size(), 1); | 
| 4724 |  | 
| 4725 |     isfLevel2.append(filter: unf); | 
| 4726 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isfLevel2); | 
| 4727 |     QCOMPARE(itemList.size(), 1); | 
| 4728 |  | 
| 4729 |     QList<QOrganizerItemId> idList; | 
| 4730 |     idList << event1.id() << event2.id(); | 
| 4731 |  | 
| 4732 |     QOrganizerItemIdFilter idf; | 
| 4733 |     idf.setIds(idList); | 
| 4734 |     isfLevel3.append(filter: idf); | 
| 4735 |  | 
| 4736 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isfLevel3); | 
| 4737 |     QCOMPARE(itemList.size(), 1); | 
| 4738 |  | 
| 4739 |     QOrganizerItemUnionFilter unfLevel4; | 
| 4740 |     unfLevel4.append(filter: isfLevel3); | 
| 4741 |     unfLevel4.append(filter: idf); | 
| 4742 |  | 
| 4743 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: unfLevel4); | 
| 4744 |     QCOMPARE(itemList.size(), 2); | 
| 4745 |  | 
| 4746 |     //attach each other | 
| 4747 |     isfLevel3.append(filter: unfLevel4); | 
| 4748 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: isfLevel3); | 
| 4749 |     QCOMPARE(itemList.size(), 1); | 
| 4750 |  | 
| 4751 |     //actual use case test | 
| 4752 |     int count = mgr->items().size(); | 
| 4753 |  | 
| 4754 |     QOrganizerTodo todo; | 
| 4755 |     todo.setDisplayLabel("myTodo" ); | 
| 4756 |     todo.setCollectionId(c1.id()); | 
| 4757 |     mgr->saveItem(item: &todo); | 
| 4758 |     itemList = mgr->items(); | 
| 4759 |     QCOMPARE(itemList.size(), ++count); | 
| 4760 |     //collection | 
| 4761 |     QOrganizerItemCollectionFilter collectionFilter; | 
| 4762 |     collectionFilter.setCollectionId(c1.id()); | 
| 4763 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: collectionFilter); | 
| 4764 |     QCOMPARE(itemList.size(), 2); | 
| 4765 |     //event | 
| 4766 |     QOrganizerItemDetailFieldFilter detailFieldFilter; | 
| 4767 |     detailFieldFilter.setDetail(detailType: QOrganizerItemDetail::TypeItemType, field: QOrganizerItemType::FieldType); | 
| 4768 |     detailFieldFilter.setValue(QOrganizerItemType::TypeEvent); | 
| 4769 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: detailFieldFilter); | 
| 4770 |     QVERIFY(itemList.size() >= 2); | 
| 4771 |     //event + collection | 
| 4772 |     QOrganizerItemIntersectionFilter intersFilter; | 
| 4773 |     intersFilter.append(filter: detailFieldFilter); | 
| 4774 |     intersFilter.append(filter: collectionFilter); | 
| 4775 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: intersFilter); | 
| 4776 |     QCOMPARE(itemList.size(), 1); | 
| 4777 |     //filter event + collection + id | 
| 4778 |     idList << event1.id() << event2.id() << todo.id(); | 
| 4779 |     QOrganizerItemIdFilter idf1; | 
| 4780 |     idf1.setIds(idList); | 
| 4781 |     QOrganizerItemIntersectionFilter intersFilter2; | 
| 4782 |     intersFilter2.append(filter: idf1); | 
| 4783 |     intersFilter2.append(filter: intersFilter); | 
| 4784 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: intersFilter); | 
| 4785 |     QCOMPARE(itemList.size(), 1); | 
| 4786 |     QCOMPARE(itemList[0].id(), event1.id()); | 
| 4787 |  | 
| 4788 |     //case 2: myTodo or event + collection + id | 
| 4789 |     QOrganizerItemDetailFieldFilter detailFieldFilter2; | 
| 4790 |     detailFieldFilter2.setDetail(detailType: QOrganizerItemDetail::TypeDisplayLabel, field: QOrganizerItemDisplayLabel::FieldLabel); | 
| 4791 |     detailFieldFilter2.setValue("myTodo" ); | 
| 4792 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: detailFieldFilter2); | 
| 4793 |     QCOMPARE(itemList.size(), 1); | 
| 4794 |  | 
| 4795 |     QOrganizerItemUnionFilter unf2; | 
| 4796 |     unf2.append(filter: detailFieldFilter2); | 
| 4797 |     unf2.append(filter: detailFieldFilter); | 
| 4798 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: unf2); | 
| 4799 |     QVERIFY(itemList.size() >= 3); | 
| 4800 |  | 
| 4801 |     //event or myTodo + collection | 
| 4802 |     QOrganizerItemIntersectionFilter intersFilter3; | 
| 4803 |     intersFilter3.append(filter: unf2); | 
| 4804 |     intersFilter3.append(filter: collectionFilter); | 
| 4805 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: intersFilter3); | 
| 4806 |     QCOMPARE(itemList.size(), 2); | 
| 4807 |     // ... + id | 
| 4808 |     QOrganizerItemIntersectionFilter intersFilter4; | 
| 4809 |     intersFilter4.append(filter: idf1); | 
| 4810 |     intersFilter4.append(filter: intersFilter3); | 
| 4811 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: intersFilter4); | 
| 4812 |     QCOMPARE(itemList.size(), 2); | 
| 4813 |     QVERIFY(itemList.contains(event1)); | 
| 4814 |     QVERIFY(itemList.contains(todo)); | 
| 4815 | } | 
| 4816 |  | 
| 4817 | void tst_QOrganizerManager::testUnionFilter() | 
| 4818 | { | 
| 4819 |     QFETCH(QString, uri); | 
| 4820 |     QScopedPointer<QOrganizerManager> mgr(QOrganizerManager::fromUri(uri)); | 
| 4821 |  | 
| 4822 |     //prepare filter data | 
| 4823 |     QOrganizerCollection c1; | 
| 4824 |     QOrganizerCollection c2; | 
| 4825 |     mgr->saveCollection(collection: &c1); | 
| 4826 |     mgr->saveCollection(collection: &c2); | 
| 4827 |     QOrganizerItem event1; | 
| 4828 |     event1.setType(QOrganizerItemType::TypeEvent); | 
| 4829 |     QOrganizerItem event2; | 
| 4830 |     event2.setType(QOrganizerItemType::TypeEvent); | 
| 4831 |     event1.setCollectionId(c1.id()); | 
| 4832 |     event2.setCollectionId(c2.id()); | 
| 4833 |     mgr->saveItem(item: &event1); | 
| 4834 |     mgr->saveItem(item: &event2); | 
| 4835 |     //Test union filter with 2 different collection filter | 
| 4836 |     QOrganizerItemCollectionFilter cf1; | 
| 4837 |     cf1.setCollectionId(c1.id()); | 
| 4838 |     QOrganizerItemCollectionFilter cf2; | 
| 4839 |     cf2.setCollectionId(c2.id()); | 
| 4840 |     QOrganizerItemUnionFilter unf; | 
| 4841 |     unf.append(filter: cf1); | 
| 4842 |     unf.append(filter: cf2); | 
| 4843 |     QList<QOrganizerItem> itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: cf1); | 
| 4844 |     QCOMPARE(itemList.size(), 1); | 
| 4845 |     QCOMPARE(itemList.at(0), event1); | 
| 4846 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: unf); | 
| 4847 |     QCOMPARE(itemList.size(), 2); | 
| 4848 |  | 
| 4849 |     //Test union filter with 2 same collection filter | 
| 4850 |     unf.remove(filter: cf2); | 
| 4851 |     cf2.setCollectionId(c1.id()); | 
| 4852 |     unf.append(filter: cf2); | 
| 4853 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: unf); | 
| 4854 |     QCOMPARE(itemList.size(), 1); | 
| 4855 |  | 
| 4856 |     //Test union filter with 2 collection filter and one of them is biger than another | 
| 4857 |     unf.remove(filter: cf2); | 
| 4858 |     QSet<QOrganizerCollectionId> collectionList; | 
| 4859 |     collectionList << c1.id() << c2.id(); | 
| 4860 |     cf2.setCollectionIds(collectionList); | 
| 4861 |     unf.append(filter: cf2); | 
| 4862 |     unf.append(filter: cf1); | 
| 4863 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: unf); | 
| 4864 |     QCOMPARE(itemList.size(), 2); | 
| 4865 |  | 
| 4866 |     //Bad case: one empty filter | 
| 4867 |     unf.remove(filter: cf2); | 
| 4868 |     cf2.setCollectionId(QOrganizerCollectionId()); | 
| 4869 |     unf.append(filter: cf2); | 
| 4870 |     QCOMPARE(unf.filters().size(), 2); | 
| 4871 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: unf); | 
| 4872 |     QCOMPARE(itemList.size(), 1); | 
| 4873 |  | 
| 4874 |     //union filter contains QOrganizerItemIdFilter and QOrganizerItemCollectionFilter | 
| 4875 |     QList<QOrganizerItemId> ids; | 
| 4876 |     QOrganizerItemIdFilter idFilter; | 
| 4877 |     QOrganizerItem event3; | 
| 4878 |     event3.setType(QOrganizerItemType::TypeEvent); | 
| 4879 |     mgr->saveItem(item: &event3); | 
| 4880 |     ids << event3.id(); | 
| 4881 |     idFilter.setIds(ids); | 
| 4882 |  | 
| 4883 |     cf2.setCollectionIds(collectionList); | 
| 4884 |     unf.clear(); | 
| 4885 |     unf.append(filter: cf2);//event1 event2 | 
| 4886 |     unf.append(filter: idFilter);// event3 | 
| 4887 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: unf); | 
| 4888 |     QCOMPARE(itemList.size(), 3);//expect event1 event2 event3 | 
| 4889 |  | 
| 4890 |     //3 filters union | 
| 4891 |     QOrganizerItem event4; | 
| 4892 |     event4.setType(QOrganizerItemType::TypeEvent); | 
| 4893 |     mgr->saveItem(item: &event4); | 
| 4894 |     ids.clear(); | 
| 4895 |     ids.append(t: event4.id()); | 
| 4896 |     idFilter.setIds(ids); | 
| 4897 |     unf.append(filter: idFilter);//event4 | 
| 4898 |     itemList = mgr->items(startDateTime: QDateTime(), endDateTime: QDateTime(), filter: unf); | 
| 4899 |     QCOMPARE(itemList.size(), 4);//expect event1 event2 event3 event4 | 
| 4900 | } | 
| 4901 |  | 
| 4902 | void tst_QOrganizerManager::testTags() | 
| 4903 | { | 
| 4904 |     QFETCH(QString, uri); | 
| 4905 |     QScopedPointer<QOrganizerManager> mgr(QOrganizerManager::fromUri(uri)); | 
| 4906 |  | 
| 4907 |     // save & load | 
| 4908 |     QOrganizerEvent event; | 
| 4909 |     event.setTags(QStringList() << QString::fromLatin1(str: "Tag1" ) << QString::fromLatin1(str: "Tag2" )); | 
| 4910 |     event.addTag(tag: QString::fromLatin1(str: "Tag3" )); | 
| 4911 |     QVERIFY(mgr->saveItem(&event)); | 
| 4912 |     QOrganizerItemId id = event.id(); | 
| 4913 |     QOrganizerItem item = mgr->item(itemId: id); | 
| 4914 |     QVERIFY(item.tags().size() == 3); | 
| 4915 |     QVERIFY(item.tags().contains(QString::fromLatin1("Tag1" ))); | 
| 4916 |     QVERIFY(item.tags().contains(QString::fromLatin1("Tag2" ))); | 
| 4917 |     QVERIFY(item.tags().contains(QString::fromLatin1("Tag3" ))); | 
| 4918 |  | 
| 4919 |     // update | 
| 4920 |     item.addTag(tag: QString::fromLatin1(str: "Tag4" ));QVERIFY(mgr->saveItem(&event)); | 
| 4921 |     QList<QOrganizerItemDetail> details = item.details(detailType: QOrganizerItemDetail::TypeTag); | 
| 4922 |     QOrganizerItemTag tag = details.at(i: 1); | 
| 4923 |     tag.setTag(QString::fromLatin1(str: "Tag222" )); | 
| 4924 |     item.saveDetail(detail: &tag); | 
| 4925 |     item.removeDetail(detail: &details[2]); | 
| 4926 |     QVERIFY(mgr->saveItem(&item)); | 
| 4927 |     QOrganizerItemId id2 = item.id(); | 
| 4928 |     QOrganizerItem item2 = mgr->item(itemId: id2); | 
| 4929 |     QVERIFY(item2.tags().size() == 3); | 
| 4930 |     QVERIFY(item2.tags().contains(QString::fromLatin1("Tag1" ))); | 
| 4931 |     QVERIFY(item2.tags().contains(QString::fromLatin1("Tag222" ))); | 
| 4932 |     QVERIFY(item2.tags().contains(QString::fromLatin1("Tag4" ))); | 
| 4933 | } | 
| 4934 |  | 
| 4935 | void tst_QOrganizerManager::testExtendedDetail() | 
| 4936 | { | 
| 4937 |     QFETCH(QString, uri); | 
| 4938 |     QScopedPointer<QOrganizerManager> mgr(QOrganizerManager::fromUri(uri)); | 
| 4939 |     QOrganizerEvent event; | 
| 4940 |  | 
| 4941 |     // simple string | 
| 4942 |     QOrganizerItemExtendedDetail basicString; | 
| 4943 |     basicString.setName(QStringLiteral("basic-string" )); | 
| 4944 |     basicString.setData(QString(QStringLiteral("Qt Everywhere" ))); | 
| 4945 |     event.saveDetail(detail: &basicString); | 
| 4946 |     QVERIFY(mgr->saveItem(&event)); | 
| 4947 |  | 
| 4948 |     event = mgr->item(itemId: event.id()); | 
| 4949 |     basicString = event.detail(detailType: QOrganizerItemDetail::TypeExtendedDetail); | 
| 4950 |     QCOMPARE(basicString.name(), QStringLiteral("basic-string" )); | 
| 4951 |     QCOMPARE(basicString.data().toString(), QStringLiteral("Qt Everywhere" )); | 
| 4952 |  | 
| 4953 |     // simple list | 
| 4954 |     QOrganizerItemExtendedDetail basicList; | 
| 4955 |     basicList.setName(QStringLiteral("basic-list" )); | 
| 4956 |     QVariantList basicListData; | 
| 4957 |     basicListData << QString(QStringLiteral("data 1" )) | 
| 4958 |                   << QString(QStringLiteral("data 2" )) | 
| 4959 |                   << QVariant(3); | 
| 4960 |     basicList.setData(basicListData); | 
| 4961 |     event.saveDetail(detail: &basicList); | 
| 4962 |     QVERIFY(mgr->saveItem(&event)); | 
| 4963 |  | 
| 4964 |     event = mgr->item(itemId: event.id()); | 
| 4965 |     QList<QOrganizerItemDetail> extendedDetails = event.details(detailType: QOrganizerItemDetail::TypeExtendedDetail); | 
| 4966 |     QCOMPARE(extendedDetails.size(), 2); | 
| 4967 |     foreach (const QOrganizerItemExtendedDetail &extendedDetail, extendedDetails) { | 
| 4968 |         if (extendedDetail.name() == QStringLiteral("basic-list" )) { | 
| 4969 |             QVariantList data = extendedDetail.data().toList(); | 
| 4970 |             QCOMPARE(data.size(), 3); | 
| 4971 |             QCOMPARE(data.at(0).toString(), QStringLiteral("data 1" )); | 
| 4972 |             QCOMPARE(data.at(1).toString(), QStringLiteral("data 2" )); | 
| 4973 |             QCOMPARE(data.at(2).toInt(), 3); | 
| 4974 |             break; | 
| 4975 |         } | 
| 4976 |     } | 
| 4977 |  | 
| 4978 |     // simple map | 
| 4979 |     QOrganizerItemExtendedDetail basicMap; | 
| 4980 |     basicMap.setName(QStringLiteral("basic map" )); | 
| 4981 |     QVariantMap basicMapData; | 
| 4982 |     basicMapData.insert(akey: QString(QStringLiteral("key1" )), avalue: QString(QStringLiteral("data-1" ))); | 
| 4983 |     basicMapData.insert(akey: QString(QStringLiteral("key-2" )), avalue: QString(QStringLiteral("data2" ))); | 
| 4984 |     basicMapData.insert(akey: QString(QStringLiteral("key_3" )), avalue: QVariant(1989)); | 
| 4985 |     basicMap.setData(basicMapData); | 
| 4986 |     event.saveDetail(detail: &basicMap); | 
| 4987 |     QVERIFY(mgr->saveItem(&event)); | 
| 4988 |  | 
| 4989 |     event = mgr->item(itemId: event.id()); | 
| 4990 |     extendedDetails = event.details(detailType: QOrganizerItemDetail::TypeExtendedDetail); | 
| 4991 |     QCOMPARE(extendedDetails.size(), 3); | 
| 4992 |     foreach (const QOrganizerItemExtendedDetail &extendedDetail, extendedDetails) { | 
| 4993 |         if (extendedDetail.name() == QStringLiteral("basic map" )) { | 
| 4994 |             QVariantMap data = extendedDetail.data().toMap(); | 
| 4995 |             QCOMPARE(data.size(), 3); | 
| 4996 |             QCOMPARE(data.value(QStringLiteral("key1" )).toString(), QStringLiteral("data-1" )); | 
| 4997 |             QCOMPARE(data.value(QStringLiteral("key-2" )).toString(), QStringLiteral("data2" )); | 
| 4998 |             QCOMPARE(data.value(QStringLiteral("key_3" )).toInt(), 1989); | 
| 4999 |             break; | 
| 5000 |         } | 
| 5001 |     } | 
| 5002 |  | 
| 5003 |     // map inside a list | 
| 5004 |     QOrganizerItemExtendedDetail mapInList; | 
| 5005 |     mapInList.setName(QStringLiteral("map in list" )); | 
| 5006 |     mapInList.setData(QVariantList() << QString(QStringLiteral("Qt is cute" )) << basicMapData); | 
| 5007 |     event.saveDetail(detail: &mapInList); | 
| 5008 |     QVERIFY(mgr->saveItem(&event)); | 
| 5009 |  | 
| 5010 |     event = mgr->item(itemId: event.id()); | 
| 5011 |     extendedDetails = event.details(detailType: QOrganizerItemDetail::TypeExtendedDetail); | 
| 5012 |     QCOMPARE(extendedDetails.size(), 4); | 
| 5013 |     foreach (const QOrganizerItemExtendedDetail &extendedDetail, extendedDetails) { | 
| 5014 |         if (extendedDetail.name() == QStringLiteral("map in list" )) { | 
| 5015 |             QVariantList data = extendedDetail.data().toList(); | 
| 5016 |             QCOMPARE(data.size(), 2); | 
| 5017 |             QCOMPARE(data.at(0).toString(), QStringLiteral("Qt is cute" )); | 
| 5018 |  | 
| 5019 |             QVariantMap map = data.at(i: 1).toMap(); | 
| 5020 |             QCOMPARE(map.value(QStringLiteral("key1" )).toString(), QStringLiteral("data-1" )); | 
| 5021 |             QCOMPARE(map.value(QStringLiteral("key-2" )).toString(), QStringLiteral("data2" )); | 
| 5022 |             QCOMPARE(map.value(QStringLiteral("key_3" )).toInt(), 1989); | 
| 5023 |             break; | 
| 5024 |         } | 
| 5025 |     } | 
| 5026 |  | 
| 5027 |     QVERIFY(mgr->removeItem(event.id())); | 
| 5028 | } | 
| 5029 |  | 
| 5030 | void tst_QOrganizerManager::testAttendee() | 
| 5031 | { | 
| 5032 |     QFETCH(QString, uri); | 
| 5033 |     QScopedPointer<QOrganizerManager> mgr(QOrganizerManager::fromUri(uri)); | 
| 5034 |     QOrganizerEvent event; | 
| 5035 |  | 
| 5036 |     // Save item and verify | 
| 5037 |     QOrganizerEventAttendee attendee; | 
| 5038 |     attendee.setName("people" ); | 
| 5039 |     attendee.setAttendeeId("123456" ); | 
| 5040 |     attendee.setEmailAddress("people@nokia.com" ); | 
| 5041 |     attendee.setParticipationRole(QOrganizerEventAttendee::RoleRequiredParticipant); | 
| 5042 |     attendee.setParticipationStatus(QOrganizerEventAttendee::StatusAccepted); | 
| 5043 |     event.saveDetail(detail: &attendee); | 
| 5044 |     QVERIFY(mgr->saveItem(&event)); | 
| 5045 |     QOrganizerItemId id = event.id(); | 
| 5046 |     QOrganizerItem item = mgr->item(itemId: id); | 
| 5047 |     QVERIFY(item.details(QOrganizerItemDetail::TypeEventAttendee).count() == 1); | 
| 5048 |     QVERIFY(item == event);//This will compare all details and their values | 
| 5049 |  | 
| 5050 |     // Update | 
| 5051 |     attendee.setName("newpeople" ); | 
| 5052 |     attendee.setAttendeeId("54321" ); | 
| 5053 |     attendee.setEmailAddress("newpeople@nokia.com" ); | 
| 5054 |     event.saveDetail(detail: &attendee); | 
| 5055 |     QVERIFY(item != event); | 
| 5056 |     QVERIFY(mgr->saveItem(&event)); | 
| 5057 |     item = mgr->item(itemId: id); | 
| 5058 |     QVERIFY(item.details(QOrganizerItemDetail::TypeEventAttendee).count() == 1); | 
| 5059 |     QVERIFY(item == event);//This will compare all details and their values | 
| 5060 |  | 
| 5061 |     // Add one more attendee | 
| 5062 |     QOrganizerEventAttendee a1; | 
| 5063 |     a1.setAttendeeId("777777" ); | 
| 5064 |     a1.setName("people1" ); | 
| 5065 |     a1.setEmailAddress("people1@nokia.com" ); | 
| 5066 |     event.saveDetail(detail: &a1); | 
| 5067 |     QVERIFY(item != event); | 
| 5068 |     QVERIFY(mgr->saveItem(&event)); | 
| 5069 |     item = mgr->item(itemId: id); | 
| 5070 |     QVERIFY(item.details(QOrganizerItemDetail::TypeEventAttendee).count() == 2); | 
| 5071 |  | 
| 5072 |     // Remove | 
| 5073 |     QVERIFY(event.removeDetail(&attendee)); | 
| 5074 |     QVERIFY(event.details(QOrganizerItemDetail::TypeEventAttendee).size() == 1); | 
| 5075 |     QVERIFY(event.removeDetail(&a1)); | 
| 5076 |     QVERIFY(event.details(QOrganizerItemDetail::TypeEventAttendee).size() == 0); | 
| 5077 |     QVERIFY(mgr->saveItem(&event)); | 
| 5078 |     item = mgr->item(itemId: id); | 
| 5079 |     QVERIFY(item.details(QOrganizerItemDetail::TypeEventAttendee).count() == 0); | 
| 5080 | } | 
| 5081 |  | 
| 5082 | void tst_QOrganizerManager::testRsvp() | 
| 5083 | { | 
| 5084 |     QFETCH(QString, uri); | 
| 5085 |     QScopedPointer<QOrganizerManager> mgr(QOrganizerManager::fromUri(uri)); | 
| 5086 |     QOrganizerEvent event; | 
| 5087 |  | 
| 5088 |     // Save item and verify | 
| 5089 |     QOrganizerEventRsvp rsvp; | 
| 5090 |     rsvp.setOrganizerName("Donald Duck" ); | 
| 5091 |     rsvp.setOrganizerEmail("don@duck.com" ); | 
| 5092 |     rsvp.setResponseDate(QDate(2010, 10, 10)); | 
| 5093 |     rsvp.setResponseDeadline(QDate(2010, 11, 11)); | 
| 5094 |     rsvp.setParticipationRole(QOrganizerEventAttendee::RoleOrganizer); | 
| 5095 |     rsvp.setParticipationStatus(QOrganizerEventAttendee::StatusAccepted); | 
| 5096 |     rsvp.setResponseRequirement(QOrganizerEventRsvp::ResponseRequired); | 
| 5097 |     QVERIFY(event.saveDetail(&rsvp)); | 
| 5098 |     QVERIFY(mgr->saveItem(&event)); | 
| 5099 |     QOrganizerItemId id = event.id(); | 
| 5100 |     QOrganizerItem item = mgr->item(itemId: id); | 
| 5101 |     QCOMPARE(1, item.details(QOrganizerItemDetail::TypeEventRsvp).count()); | 
| 5102 |     QVERIFY(item == event);//This will compare all details and their values | 
| 5103 |  | 
| 5104 |     // Update | 
| 5105 |     rsvp.setOrganizerName("Mickey Mouse" ); | 
| 5106 |     rsvp.setOrganizerEmail("mick@mouse.com" ); | 
| 5107 |     rsvp.setResponseDate(QDate(2011, 11, 11)); | 
| 5108 |     rsvp.setResponseDeadline(QDate(2011, 12, 12)); | 
| 5109 |     rsvp.setParticipationRole(QOrganizerEventAttendee::RoleChairperson); | 
| 5110 |     rsvp.setParticipationStatus(QOrganizerEventAttendee::StatusDelegated); | 
| 5111 |     rsvp.setResponseRequirement(QOrganizerEventRsvp::ResponseNotRequired); | 
| 5112 |     QVERIFY(event.saveDetail(&rsvp)); | 
| 5113 |     QVERIFY(mgr->saveItem(&event)); | 
| 5114 |     item = mgr->item(itemId: id); | 
| 5115 |     QCOMPARE(1, event.details(QOrganizerItemDetail::TypeEventRsvp).size()); | 
| 5116 |     QVERIFY(item == event);//This will compare all details and their values | 
| 5117 |  | 
| 5118 |     // Remove | 
| 5119 |     QVERIFY(event.removeDetail(&rsvp)); | 
| 5120 |     QCOMPARE(0, event.details(QOrganizerItemDetail::TypeEventRsvp).size()); | 
| 5121 |     QVERIFY(mgr->saveItem(&event)); | 
| 5122 |     item = mgr->item(itemId: id); | 
| 5123 |     QVERIFY(item.details(QOrganizerItemDetail::TypeEventRsvp).count() == 0); | 
| 5124 | } | 
| 5125 |  | 
| 5126 | void tst_QOrganizerManager::testClassification() | 
| 5127 | { | 
| 5128 |     QFETCH(QString, uri); | 
| 5129 |     QScopedPointer<QOrganizerManager> mgr(QOrganizerManager::fromUri(uri)); | 
| 5130 |     if (!mgr->supportedItemDetails(itemType: QOrganizerItemType::TypeEvent).contains(t: QOrganizerItemDetail::TypeClassification)) | 
| 5131 |         QSKIP("Classification -detail not supported by this backend." ); | 
| 5132 |  | 
| 5133 |     // Save item and verify | 
| 5134 |     QOrganizerEvent event; | 
| 5135 |     QOrganizerItemClassification classification; | 
| 5136 |     classification.setClassification(QOrganizerItemClassification::AccessPrivate); | 
| 5137 |     QVERIFY(event.saveDetail(&classification)); | 
| 5138 |     QVERIFY(mgr->saveItem(&event)); | 
| 5139 |     QOrganizerItemId id = event.id(); | 
| 5140 |     QOrganizerItem item = mgr->item(itemId: id); | 
| 5141 |     QCOMPARE(1, item.details(QOrganizerItemDetail::TypeClassification).count()); | 
| 5142 |     QVERIFY(item == event);//This will compare all details and their values | 
| 5143 |  | 
| 5144 |     // Update | 
| 5145 |     classification.setClassification(QOrganizerItemClassification::AccessConfidential); | 
| 5146 |     QVERIFY(event.saveDetail(&classification)); | 
| 5147 |     QVERIFY(mgr->saveItem(&event)); | 
| 5148 |     item = mgr->item(itemId: id); | 
| 5149 |     QCOMPARE(1, event.details(QOrganizerItemDetail::TypeClassification).size()); | 
| 5150 |     QVERIFY(item == event);//This will compare all details and their values | 
| 5151 |  | 
| 5152 |     // Remove | 
| 5153 |     QVERIFY(event.removeDetail(&classification)); | 
| 5154 |     QCOMPARE(0, event.details(QOrganizerItemDetail::TypeClassification).size()); | 
| 5155 |     QVERIFY(mgr->saveItem(&event)); | 
| 5156 |     item = mgr->item(itemId: id); | 
| 5157 |     QVERIFY(item.details(QOrganizerItemDetail::TypeClassification).count() == 0); | 
| 5158 | } | 
| 5159 |  | 
| 5160 | void tst_QOrganizerManager::testVersion() | 
| 5161 | { | 
| 5162 |     QFETCH(QString, uri); | 
| 5163 |     QScopedPointer<QOrganizerManager> mgr(QOrganizerManager::fromUri(uri)); | 
| 5164 |     if (!mgr->supportedItemDetails(itemType: QOrganizerItemType::TypeEvent).contains(t: QOrganizerItemDetail::TypeVersion)) | 
| 5165 |         QSKIP("Version detail not supported by this backend." ); | 
| 5166 |  | 
| 5167 |     QOrganizerEvent event; | 
| 5168 |     QVERIFY(event.detail(QOrganizerItemDetail::TypeVersion).isEmpty()); | 
| 5169 |     QVERIFY(mgr->saveItem(&event)); | 
| 5170 |  | 
| 5171 |     QOrganizerItemVersion version = event.detail(detailType: QOrganizerItemDetail::TypeVersion); | 
| 5172 |     QVERIFY(!version.isEmpty()); | 
| 5173 |  | 
| 5174 |     event.setDisplayLabel("Qt rules!" ); | 
| 5175 |     QVERIFY(mgr->saveItem(&event)); | 
| 5176 |  | 
| 5177 |     QOrganizerItemVersion version2 = event.detail(detailType: QOrganizerItemDetail::TypeVersion); | 
| 5178 |     QVERIFY(!version2.isEmpty()); | 
| 5179 |     QVERIFY((version2.version() > version.version()) || (version2.extendedVersion() != version.extendedVersion())); | 
| 5180 | } | 
| 5181 |  | 
| 5182 | #if 0 // This test is currently excluded; can it be reinstated? | 
| 5183 | class errorSemanticsTester : public QObject { | 
| 5184 |     Q_OBJECT; | 
| 5185 | public: | 
| 5186 |     bool initialErrorWasDoesNotExist; | 
| 5187 |     bool slotErrorWasBadArgument; | 
| 5188 |     QOrganizerManager* mManager; | 
| 5189 |  | 
| 5190 |     errorSemanticsTester(QOrganizerManager* manager) | 
| 5191 |         : initialErrorWasDoesNotExist(false), | 
| 5192 |         slotErrorWasBadArgument(false), | 
| 5193 |         mManager(manager) | 
| 5194 |     { | 
| 5195 |         connect(manager, SIGNAL(itemsAdded(QList<QOrganizerItemId>)), this, SLOT(handleAdded())); | 
| 5196 |     } | 
| 5197 |  | 
| 5198 | public slots: | 
| 5199 |     void handleAdded() | 
| 5200 |     { | 
| 5201 |         // Make sure the initial error state is correct | 
| 5202 |         initialErrorWasDoesNotExist = mManager->error() == QOrganizerManager::DoesNotExistError; | 
| 5203 |         // Now force a different error | 
| 5204 |         mManager->removeItems(QList<QOrganizerItemId>()); | 
| 5205 |         slotErrorWasBadArgument = mManager->error() == QOrganizerManager::BadArgumentError; | 
| 5206 |         // and return | 
| 5207 |     } | 
| 5208 | }; | 
| 5209 | #endif | 
| 5210 |  | 
| 5211 | QTEST_MAIN(tst_QOrganizerManager) | 
| 5212 | #include "tst_qorganizermanager.moc" | 
| 5213 |  |