| 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 | #include <QtTest/QtTest> |
| 35 | #include <QtContacts/qcontacts.h> |
| 36 | #include <QSet> |
| 37 | |
| 38 | //TESTED_COMPONENT=src/contacts |
| 39 | |
| 40 | QTCONTACTS_USE_NAMESPACE |
| 41 | |
| 42 | static inline QContactId makeId(const QString &managerName, uint id) |
| 43 | { |
| 44 | return QContactId(QStringLiteral("qtcontacts:basic%1:" ).arg(a: managerName), QByteArray(reinterpret_cast<const char *>(&id), sizeof(uint))); |
| 45 | } |
| 46 | |
| 47 | |
| 48 | class tst_QContact: public QObject |
| 49 | { |
| 50 | Q_OBJECT |
| 51 | |
| 52 | public: |
| 53 | tst_QContact(); |
| 54 | virtual ~tst_QContact(); |
| 55 | |
| 56 | private slots: |
| 57 | void details(); |
| 58 | void preferences(); |
| 59 | void relationships(); |
| 60 | void type(); |
| 61 | void tags(); |
| 62 | void emptiness(); |
| 63 | void idComparison(); |
| 64 | void idHash(); |
| 65 | void hash(); |
| 66 | void datastream(); |
| 67 | void traits(); |
| 68 | void idTraits(); |
| 69 | void equality(); |
| 70 | void inequality(); |
| 71 | void preferredDetails(); |
| 72 | }; |
| 73 | |
| 74 | tst_QContact::tst_QContact() |
| 75 | { |
| 76 | } |
| 77 | |
| 78 | tst_QContact::~tst_QContact() |
| 79 | { |
| 80 | } |
| 81 | |
| 82 | void tst_QContact::details() |
| 83 | { |
| 84 | // Check that detail keys are unique, regardless of order of initialisation |
| 85 | // First, construct the detail first, then the contact |
| 86 | QContactOrganization org; |
| 87 | org.setTitle("Example Title" ); |
| 88 | QContact keyTest; |
| 89 | QVERIFY(keyTest.saveDetail(&org)); |
| 90 | QList<QContactDetail> allDetails = keyTest.details(); |
| 91 | QList<int> detailKeys; |
| 92 | foreach (const QContactDetail& det, allDetails) { |
| 93 | int currKey = det.key(); |
| 94 | QVERIFY(!detailKeys.contains(currKey)); |
| 95 | detailKeys.append(t: currKey); |
| 96 | } |
| 97 | // Second, construct the detail after the contact has been constructed |
| 98 | QContactPhoneNumber num; |
| 99 | num.setNumber("123456" ); |
| 100 | QVERIFY(keyTest.saveDetail(&num)); |
| 101 | allDetails = keyTest.details(); |
| 102 | detailKeys.clear(); |
| 103 | foreach (const QContactDetail& det, allDetails) { |
| 104 | int currKey = det.key(); |
| 105 | QVERIFY(!detailKeys.contains(currKey)); |
| 106 | detailKeys.append(t: currKey); |
| 107 | } |
| 108 | |
| 109 | // now test for default construction sanity |
| 110 | QContact c; |
| 111 | |
| 112 | // Test there are no details (apart from type) by default |
| 113 | QVERIFY(c.isEmpty() == true); |
| 114 | QVERIFY(c.details().count() == 1); |
| 115 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 0); |
| 116 | QVERIFY(c.details<QContactPhoneNumber>().count() == 0); |
| 117 | QVERIFY(c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 118 | QVERIFY(c.detail<QContactPhoneNumber>().isEmpty()); |
| 119 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 0); |
| 120 | QVERIFY(c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 121 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 0); |
| 122 | QVERIFY(c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 123 | |
| 124 | // Test retrieving the first detail (the contact type) |
| 125 | QList<QContactDetail> details = c.details(); |
| 126 | QVERIFY(details.at(0).type() == QContactType::Type); |
| 127 | |
| 128 | // Fetch non existent detail |
| 129 | QContactDetail detail = c.detail(type: QContactDetail::TypeAddress); |
| 130 | |
| 131 | QVERIFY(detail.isEmpty()); |
| 132 | QVERIFY(detail.type() == QContactDetail::TypeUndefined); |
| 133 | |
| 134 | // retrieve the first detail using the undefined type accessor. |
| 135 | detail = c.detail(type: QContactDetail::TypeUndefined); |
| 136 | QVERIFY(detail == details.at(0)); |
| 137 | |
| 138 | QVERIFY(c.details(QContactDetail::TypeAddress).count() == 0); |
| 139 | |
| 140 | // Add a detail |
| 141 | QContactPhoneNumber p; |
| 142 | p.setNumber("12345678" ); |
| 143 | QVERIFY(c.saveDetail(&p)); |
| 144 | QVERIFY(c.isEmpty() == false); |
| 145 | |
| 146 | QVERIFY(c.details().count() == 2); |
| 147 | |
| 148 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 1); |
| 149 | QVERIFY(c.details<QContactPhoneNumber>().count() == 1); |
| 150 | QVERIFY(!c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 151 | QVERIFY(!c.detail<QContactPhoneNumber>().isEmpty()); |
| 152 | QCOMPARE(c.detail<QContactPhoneNumber>(), p); |
| 153 | |
| 154 | // Remove detail |
| 155 | QVERIFY(c.removeDetail(&p)); |
| 156 | QVERIFY(c.details().count() == 1); |
| 157 | QVERIFY(c.isEmpty() == true); |
| 158 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 0); |
| 159 | QVERIFY(c.details<QContactPhoneNumber>().count() == 0); |
| 160 | QVERIFY(c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 161 | QVERIFY(c.detail<QContactPhoneNumber>().isEmpty()); |
| 162 | |
| 163 | // Try removing it again |
| 164 | QVERIFY(!c.removeDetail(&p)); |
| 165 | |
| 166 | // Add again, and remove a different way (retrieved copy) |
| 167 | QVERIFY(c.saveDetail(&p)); |
| 168 | QVERIFY(c.isEmpty() == false); |
| 169 | QVERIFY(c.details().count() == 2); |
| 170 | QContactPhoneNumber p2 = c.detail(type: QContactPhoneNumber::Type); |
| 171 | QCOMPARE(p, p2); |
| 172 | |
| 173 | QVERIFY(c.removeDetail(&p2)); |
| 174 | QVERIFY(c.details().count() == 1); |
| 175 | QVERIFY(c.isEmpty() == true); |
| 176 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 0); |
| 177 | QVERIFY(c.details<QContactPhoneNumber>().count() == 0); |
| 178 | QVERIFY(c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 179 | QVERIFY(c.detail<QContactPhoneNumber>().isEmpty()); |
| 180 | |
| 181 | QCOMPARE(p, p2); |
| 182 | |
| 183 | // Add again again, and remove a different way (base class) |
| 184 | QVERIFY(c.saveDetail(&p)); |
| 185 | QVERIFY(c.details().count() == 2); |
| 186 | QContactDetail p3 = c.detail(type: QContactPhoneNumber::Type); |
| 187 | QVERIFY(p == p3); |
| 188 | |
| 189 | QVERIFY(c.removeDetail(&p3)); |
| 190 | QVERIFY(c.details().count() == 1); |
| 191 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 0); |
| 192 | QVERIFY(c.details<QContactPhoneNumber>().count() == 0); |
| 193 | QVERIFY(c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 194 | QVERIFY(c.detail<QContactPhoneNumber>().isEmpty()); |
| 195 | |
| 196 | QVERIFY(p == p3); |
| 197 | |
| 198 | // now we want to add multiple details of the same type, and test that retrieval works correctly. |
| 199 | p2 = QContactPhoneNumber(); |
| 200 | p2.setNumber("22222" ); |
| 201 | c.saveDetail(detail: &p); |
| 202 | c.saveDetail(detail: &p2); |
| 203 | QVERIFY(c.details().count() == 3); |
| 204 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 2); |
| 205 | QVERIFY(c.details<QContactPhoneNumber>().count() == 2); |
| 206 | QVERIFY(!c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 207 | QVERIFY(!c.detail<QContactPhoneNumber>().isEmpty()); |
| 208 | QCOMPARE(c.detail<QContactPhoneNumber>(), p); |
| 209 | QVERIFY(c.removeDetail(&p2)); |
| 210 | |
| 211 | // now try removing a detail for which we've set a preference |
| 212 | QContactEmailAddress pref; |
| 213 | pref.setEmailAddress("test@test" ); |
| 214 | c.saveDetail(detail: &pref); |
| 215 | c.setPreferredDetail(actionName: "SendEmail" , preferredDetail: pref); |
| 216 | QVERIFY(c.isPreferredDetail(QString(), pref)); |
| 217 | QVERIFY(c.removeDetail(&pref)); |
| 218 | QVERIFY(!c.isPreferredDetail(QString(), pref)); |
| 219 | |
| 220 | // Now try adding a detail to multiple contacts |
| 221 | |
| 222 | QContact c2; |
| 223 | QVERIFY(c2.isEmpty() == true); |
| 224 | QVERIFY(c.saveDetail(&p)); |
| 225 | QVERIFY(c2.saveDetail(&p)); |
| 226 | QVERIFY(c2.isEmpty() == false); |
| 227 | |
| 228 | QVERIFY(c.details().count() == 2); |
| 229 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 1); |
| 230 | QVERIFY(c.details<QContactPhoneNumber>().count() == 1); |
| 231 | QVERIFY(!c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 232 | QVERIFY(!c.detail<QContactPhoneNumber>().isEmpty()); |
| 233 | QCOMPARE(c.detail<QContactPhoneNumber>(), p); |
| 234 | |
| 235 | QVERIFY(c2.details().count() == 2); |
| 236 | QVERIFY(c2.details(QContactPhoneNumber::Type).count() == 1); |
| 237 | QVERIFY(c2.details<QContactPhoneNumber>().count() == 1); |
| 238 | QVERIFY(!c2.detail(QContactPhoneNumber::Type).isEmpty()); |
| 239 | QVERIFY(!c2.detail<QContactPhoneNumber>().isEmpty()); |
| 240 | QCOMPARE(c2.detail<QContactPhoneNumber>(), p); |
| 241 | |
| 242 | // Now try removing it from one |
| 243 | QVERIFY(c.removeDetail(&p)); |
| 244 | |
| 245 | // Make sure it's gone from the first contact |
| 246 | QVERIFY(c.isEmpty() == true); |
| 247 | QVERIFY(c.details().count() == 1); |
| 248 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 0); |
| 249 | QVERIFY(c.details<QContactPhoneNumber>().count() == 0); |
| 250 | QVERIFY(c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 251 | QVERIFY(c.detail<QContactPhoneNumber>().isEmpty()); |
| 252 | |
| 253 | // but not the second |
| 254 | QVERIFY(c2.isEmpty() == false); |
| 255 | QVERIFY(c2.details().count() == 2); |
| 256 | QVERIFY(c2.details(QContactPhoneNumber::Type).count() == 1); |
| 257 | QVERIFY(c2.details<QContactPhoneNumber>().count() == 1); |
| 258 | QVERIFY(!c2.detail(QContactPhoneNumber::Type).isEmpty()); |
| 259 | QVERIFY(!c2.detail<QContactPhoneNumber>().isEmpty()); |
| 260 | QCOMPARE(c2.detail<QContactPhoneNumber>(), p); |
| 261 | |
| 262 | // Now remove it from the second as well |
| 263 | QVERIFY(c2.removeDetail(&p)); |
| 264 | |
| 265 | // Make sure it's gone from both |
| 266 | QVERIFY(c.details().count() == 1); |
| 267 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 0); |
| 268 | QVERIFY(c.details<QContactPhoneNumber>().count() == 0); |
| 269 | QVERIFY(c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 270 | QVERIFY(c.detail<QContactPhoneNumber>().isEmpty()); |
| 271 | |
| 272 | QVERIFY(c2.details().count() == 1); |
| 273 | QVERIFY(c2.details(QContactPhoneNumber::Type).count() == 0); |
| 274 | QVERIFY(c2.details<QContactPhoneNumber>().count() == 0); |
| 275 | QVERIFY(c2.detail(QContactPhoneNumber::Type).isEmpty()); |
| 276 | QVERIFY(c2.detail<QContactPhoneNumber>().isEmpty()); |
| 277 | |
| 278 | // add a, add b, remove a, add a, remove b, remove a |
| 279 | QVERIFY(c.saveDetail(&p)); |
| 280 | QVERIFY(c2.saveDetail(&p)); |
| 281 | QVERIFY(c.removeDetail(&p)); |
| 282 | QVERIFY(c.saveDetail(&p)); |
| 283 | QVERIFY(c2.removeDetail(&p)); |
| 284 | QVERIFY(c.removeDetail(&p)); |
| 285 | |
| 286 | // Now add a detail with the same values twice |
| 287 | QContactPhoneNumber one; |
| 288 | QContactPhoneNumber two; |
| 289 | |
| 290 | one.setNumber("12345" ); |
| 291 | two.setNumber("12345" ); |
| 292 | |
| 293 | // add it once |
| 294 | QVERIFY(c.saveDetail(&one)); |
| 295 | QVERIFY(c.details().count() == 2); |
| 296 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 1); |
| 297 | QVERIFY(c.details<QContactPhoneNumber>().count() == 1); |
| 298 | QVERIFY(!c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 299 | QVERIFY(!c.detail<QContactPhoneNumber>().isEmpty()); |
| 300 | QCOMPARE(c.detail<QContactPhoneNumber>(), one); |
| 301 | |
| 302 | // add it twice |
| 303 | QVERIFY(c.saveDetail(&two)); |
| 304 | QVERIFY(c.details().count() == 3); |
| 305 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 2); |
| 306 | QVERIFY(c.details<QContactPhoneNumber>().count() == 2); |
| 307 | QVERIFY(!c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 308 | QVERIFY(!c.detail<QContactPhoneNumber>().isEmpty()); |
| 309 | QCOMPARE(c.detail<QContactPhoneNumber>(), one); |
| 310 | QCOMPARE(c.details<QContactPhoneNumber>()[0], one); |
| 311 | QCOMPARE(c.details<QContactPhoneNumber>()[1], two); |
| 312 | |
| 313 | // Remove it once |
| 314 | QVERIFY(c.removeDetail(&one)); |
| 315 | QVERIFY(c.details().count() == 2); |
| 316 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 1); |
| 317 | QVERIFY(c.details<QContactPhoneNumber>().count() == 1); |
| 318 | QVERIFY(!c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 319 | QVERIFY(!c.detail<QContactPhoneNumber>().isEmpty()); |
| 320 | QCOMPARE(c.detail<QContactPhoneNumber>(), two); |
| 321 | |
| 322 | // Remove it twice |
| 323 | QVERIFY(c.removeDetail(&two)); |
| 324 | QVERIFY(c.details().count() == 1); |
| 325 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 0); |
| 326 | QVERIFY(c.details<QContactPhoneNumber>().count() == 0); |
| 327 | QVERIFY(c.detail(QContactPhoneNumber::Type).isEmpty()); |
| 328 | QVERIFY(c.detail<QContactPhoneNumber>().isEmpty()); |
| 329 | |
| 330 | // Null pointer tests |
| 331 | QVERIFY(c.saveDetail(0) == false); |
| 332 | QVERIFY(c.removeDetail(0) == false); |
| 333 | |
| 334 | // Reference tests... |
| 335 | QContactDetail& ref = one; |
| 336 | QVERIFY(c.saveDetail(&one)); |
| 337 | QVERIFY(ref == one); |
| 338 | one.setNumber("56678" ); |
| 339 | QVERIFY(c.saveDetail(&one)); |
| 340 | QVERIFY(ref == one); |
| 341 | |
| 342 | // Retrieve the detail again and modify it |
| 343 | QContactPhoneNumber three = c.detail<QContactPhoneNumber>(); |
| 344 | QVERIFY(ref == three); |
| 345 | QVERIFY(one == three); |
| 346 | three.setNumber("542343" ); |
| 347 | QVERIFY(c.saveDetail(&three)); |
| 348 | |
| 349 | // Now see if we got any updates to ref/one |
| 350 | QVERIFY(ref == one); |
| 351 | QVERIFY(ref != three); |
| 352 | |
| 353 | // test saving of a detail with an empty field. |
| 354 | QContactPhoneNumber four; |
| 355 | four.setNumber("" ); |
| 356 | c.saveDetail(detail: &four); |
| 357 | QVERIFY(c.details(QContactPhoneNumber::Type).count() == 2); |
| 358 | QVERIFY(!four.values().isEmpty()); // an empty qstring is not invalid; make sure it exists in the detail. |
| 359 | |
| 360 | // ensure that clearing a contact's details works correctly |
| 361 | QContactName nameDetail; |
| 362 | nameDetail.setFirstName("test" ); |
| 363 | c.saveDetail(detail: &nameDetail); |
| 364 | QCOMPARE(c.detail(QContactName::Type).value(QContactName::FieldFirstName).toString(), QString("test" )); |
| 365 | QVERIFY(c.details().size() > 0); |
| 366 | QVERIFY(!c.isEmpty()); |
| 367 | QContactId oldId = c.id(); |
| 368 | c.clearDetails(); |
| 369 | QVERIFY(c.details().size() == 1); // contact type. |
| 370 | QCOMPARE(c.detail(QContactName::Type).value(QContactName::FieldFirstName).toString(), QString()); |
| 371 | QVERIFY(c.isEmpty()); |
| 372 | QCOMPARE(c.id(), oldId); // id shouldn't change. |
| 373 | } |
| 374 | |
| 375 | void tst_QContact::preferences() |
| 376 | { |
| 377 | QContact c; |
| 378 | |
| 379 | // test first set |
| 380 | QContactDetail det(QContactDetail::TypeExtendedDetail); |
| 381 | c.saveDetail(detail: &det); |
| 382 | QCOMPARE(c.isPreferredDetail("testAction" , det), false); |
| 383 | |
| 384 | QCOMPARE(c.setPreferredDetail("testAction" , det), true); |
| 385 | |
| 386 | QCOMPARE(c.isPreferredDetail("testAction" , det), true); |
| 387 | |
| 388 | QCOMPARE(c.isPreferredDetail(QString(), det), true); |
| 389 | |
| 390 | QCOMPARE(c.preferredDetail("testAction" ), det); |
| 391 | |
| 392 | // test replacement |
| 393 | QContactDetail det2(QContactDetail::TypeExtendedDetail); |
| 394 | c.saveDetail(detail: &det2); |
| 395 | QCOMPARE(c.isPreferredDetail("testAction" , det2), false); |
| 396 | |
| 397 | QCOMPARE(c.setPreferredDetail("testAction" , det2), true); |
| 398 | |
| 399 | QCOMPARE(c.isPreferredDetail("testAction" , det2), true); |
| 400 | |
| 401 | QCOMPARE(c.isPreferredDetail("testAction" , det), false); |
| 402 | |
| 403 | QCOMPARE(c.preferredDetail("testAction" ), det2); |
| 404 | |
| 405 | // test for detail that is not part of the contact |
| 406 | QContactDetail det3(QContactDetail::TypeEmailAddress); |
| 407 | QCOMPARE(c.setPreferredDetail("testAction" , det3), false); |
| 408 | |
| 409 | QCOMPARE(c.preferredDetail("testAction" ), det2); // shouldn't have changed. |
| 410 | |
| 411 | // test invalid set |
| 412 | QCOMPARE(c.setPreferredDetail(QString(), det3), false); |
| 413 | |
| 414 | QCOMPARE(c.setPreferredDetail(QString(), QContactDetail()), false); |
| 415 | |
| 416 | QCOMPARE(c.setPreferredDetail("testAction" , QContactDetail()), false); |
| 417 | |
| 418 | QCOMPARE(c.preferredDetail("testAction" ), det2); // shouldn't have changed. |
| 419 | |
| 420 | // test invalid query |
| 421 | QContactDetail det4; |
| 422 | c.saveDetail(detail: &det4); |
| 423 | QCOMPARE(c.isPreferredDetail(QString(), QContactDetail()), false); |
| 424 | |
| 425 | QCOMPARE(c.isPreferredDetail(QString(), det4), false); // valid detail, but no pref set. |
| 426 | |
| 427 | QCOMPARE(c.isPreferredDetail("testAction" , QContactDetail()), false); |
| 428 | |
| 429 | // test retrieving preferred details |
| 430 | QContactDetail pd = c.preferredDetail(actionName: QString()); |
| 431 | QVERIFY(pd.isEmpty()); |
| 432 | pd = c.preferredDetail(actionName: "testAction" ); |
| 433 | QVERIFY(pd == det2); // shouldn't have changed. |
| 434 | |
| 435 | // test for preference for action that hasn't been added |
| 436 | QVERIFY(c.preferredDetail("NonexistentAction" ).isEmpty()); |
| 437 | |
| 438 | // Remove a non preferred detail |
| 439 | QContactDetail det2copy(QContactDetail::TypeExtendedDetail); |
| 440 | QVERIFY(c.saveDetail(&det2copy)); |
| 441 | |
| 442 | QVERIFY(c.isPreferredDetail("testAction" , det2) == true); |
| 443 | QVERIFY(c.isPreferredDetail("testAction" , det2copy) == false); |
| 444 | QVERIFY(c.removeDetail(&det2copy)); |
| 445 | QVERIFY(c.isPreferredDetail("testAction" , det2) == true); |
| 446 | QVERIFY(c.isPreferredDetail("testAction" , det2copy) == false); |
| 447 | |
| 448 | // Add it again |
| 449 | QVERIFY(c.saveDetail(&det2copy)); |
| 450 | QVERIFY(c.isPreferredDetail("testAction" , det2) == true); |
| 451 | QVERIFY(c.isPreferredDetail("testAction" , det2copy) == false); |
| 452 | |
| 453 | // Remove the preferred detail (the copy should not become preferred) |
| 454 | QVERIFY(c.removeDetail(&det2)); |
| 455 | QVERIFY(c.isPreferredDetail("testAction" , det2) == false); |
| 456 | QVERIFY(c.isPreferredDetail("testAction" , det2copy) == false); |
| 457 | } |
| 458 | |
| 459 | void tst_QContact::relationships() |
| 460 | { |
| 461 | QContact c; |
| 462 | |
| 463 | // boring test, because the default contact has no relationships |
| 464 | // we test this more convincingly in the QContactManager tests. |
| 465 | QList<QContactId> related = c.relatedContacts(); |
| 466 | QVERIFY(related.isEmpty()); |
| 467 | |
| 468 | related = c.relatedContacts(relationshipType: QContactRelationship::HasMember()); |
| 469 | QVERIFY(related.isEmpty()); |
| 470 | |
| 471 | related = c.relatedContacts(relationshipType: QContactRelationship::HasMember(), role: QContactRelationship::First); |
| 472 | QVERIFY(related.isEmpty()); |
| 473 | |
| 474 | QList<QContactRelationship> relationshipList = c.relationships(); |
| 475 | QVERIFY(relationshipList.isEmpty()); |
| 476 | |
| 477 | relationshipList = c.relationships(relationshipType: QContactRelationship::HasMember()); |
| 478 | QVERIFY(relationshipList.isEmpty()); |
| 479 | } |
| 480 | |
| 481 | void tst_QContact::type() |
| 482 | { |
| 483 | QContact c; |
| 484 | QVERIFY(c.isEmpty() == true); |
| 485 | |
| 486 | // ensure that the default type is the QContactType::TypeContact type |
| 487 | QVERIFY(c.type() == QContactType::TypeContact); |
| 488 | |
| 489 | // now set it to be a group via the type mutator, and test that it works |
| 490 | c.setType(QContactType::TypeGroup); |
| 491 | QCOMPARE(c.type(), QContactType::TypeGroup); |
| 492 | |
| 493 | // set it back to a contact, via the string mutator |
| 494 | c.setType(QContactType::TypeContact); |
| 495 | QCOMPARE(c.type(), QContactType::TypeContact); |
| 496 | QVERIFY(c.isEmpty() == true); // type doesn't affect emptiness |
| 497 | } |
| 498 | |
| 499 | void tst_QContact::tags() |
| 500 | { |
| 501 | QContact c; |
| 502 | QVERIFY(c.tags().isEmpty()); |
| 503 | |
| 504 | c.addTag(tag: "tag 1" ); |
| 505 | QStringList tags; |
| 506 | tags.append(t: "tag 1" ); |
| 507 | QCOMPARE(c.tags(), tags); |
| 508 | QList<QContactTag> tagDetails = c.details<QContactTag>(); |
| 509 | QCOMPARE(tagDetails.size(), 1); |
| 510 | QCOMPARE(tagDetails.first().tag(), QStringLiteral("tag 1" )); |
| 511 | |
| 512 | c.clearTags(); |
| 513 | QVERIFY(c.tags().isEmpty()); |
| 514 | QVERIFY(c.details<QContactTag>().isEmpty()); |
| 515 | |
| 516 | tags.append(t: "tag 2" ); // tags is now "tag 1", "tag 2" |
| 517 | c.setTags(tags); |
| 518 | QCOMPARE(c.tags(), tags); |
| 519 | tagDetails = c.details<QContactTag>(); |
| 520 | QCOMPARE(tagDetails.size(), 2); |
| 521 | QCOMPARE(tagDetails.at(0).tag(), QStringLiteral("tag 1" )); |
| 522 | QCOMPARE(tagDetails.at(1).tag(), QStringLiteral("tag 2" )); |
| 523 | } |
| 524 | |
| 525 | void tst_QContact::emptiness() |
| 526 | { |
| 527 | QContact c; |
| 528 | QVERIFY(c.isEmpty() == true); |
| 529 | QVERIFY(c.id().isNull() == true); |
| 530 | |
| 531 | c.setType(QContactType::TypeContact); |
| 532 | QVERIFY(c.type() == QContactType::TypeContact); |
| 533 | QVERIFY(c.isEmpty() == true); // type doesn't affect emptiness |
| 534 | } |
| 535 | |
| 536 | void tst_QContact::idComparison() |
| 537 | { |
| 538 | QContactId id1(makeId(managerName: "a" , id: 1)); |
| 539 | QContactId id2(makeId(managerName: "a" , id: 1)); |
| 540 | QVERIFY(!(id1 < id2)); |
| 541 | QVERIFY(!(id2 < id1)); |
| 542 | QVERIFY(id1 == id2); |
| 543 | |
| 544 | QContactId id3(makeId(managerName: "a" , id: 2)); |
| 545 | QContactId id4(makeId(managerName: "b" , id: 1)); |
| 546 | QContactId id5(makeId(managerName: "b" , id: 2)); |
| 547 | QVERIFY((((id1 < id3) && !(id3 < id1)) || ((id3 < id1) && !(id1 < id3))) && (id1 != id3)); |
| 548 | QVERIFY((((id1 < id4) && !(id4 < id1)) || ((id4 < id1) && !(id1 < id4))) && (id1 != id4)); |
| 549 | QVERIFY((((id3 < id4) && !(id4 < id3)) || ((id4 < id3) && !(id3 < id4))) && (id3 != id4)); |
| 550 | QVERIFY((((id1 < id5) && !(id5 < id1)) || ((id5 < id1) && !(id1 < id5))) && (id3 != id4)); |
| 551 | |
| 552 | QContactId id6; |
| 553 | QContactId id7(QString(), "1" ); |
| 554 | QContactId id8(QString(), "2" ); |
| 555 | QContactId id9(QStringLiteral("qtcontacts:basic:" ), "" ); |
| 556 | QVERIFY(id6.isNull()); |
| 557 | QVERIFY(id7.isNull()); |
| 558 | QVERIFY(id8.isNull()); |
| 559 | QVERIFY(id9.isNull()); |
| 560 | QVERIFY(id6 == id7); |
| 561 | QVERIFY(!(id6 < id7)); |
| 562 | QVERIFY(id7 == id6); |
| 563 | QVERIFY(!(id7 < id6)); |
| 564 | QVERIFY(id7 == id8); |
| 565 | QVERIFY(!(id7 < id8)); |
| 566 | QVERIFY(id8 == id7); |
| 567 | QVERIFY(!(id9 < id8)); |
| 568 | QVERIFY(id8 == id9); |
| 569 | QVERIFY(!(id8 < id9)); |
| 570 | QVERIFY(id9 == id8); |
| 571 | QVERIFY(!(id9 < id8)); |
| 572 | |
| 573 | QVERIFY(!(id1 == id6)); |
| 574 | QVERIFY(!(id1 < id6)); |
| 575 | QVERIFY(id6 < id1); |
| 576 | QVERIFY(!(id1 == id7)); |
| 577 | QVERIFY(!(id1 < id7)); |
| 578 | QVERIFY(id7 < id1); |
| 579 | QVERIFY(!(id1 == id8)); |
| 580 | QVERIFY(!(id1 < id8)); |
| 581 | QVERIFY(id8 < id1); |
| 582 | QVERIFY(!(id1 == id9)); |
| 583 | QVERIFY(!(id1 < id9)); |
| 584 | QVERIFY(id9 < id1); |
| 585 | } |
| 586 | |
| 587 | void tst_QContact::idHash() |
| 588 | { |
| 589 | QContactId id1(makeId(managerName: "a" , id: 1)); |
| 590 | QContactId id2(makeId(managerName: "a" , id: 1)); |
| 591 | QContactId id3(makeId(managerName: "b" , id: 1)); |
| 592 | QContactId id4(makeId(managerName: "a" , id: 2)); |
| 593 | // note that the hash function ignores the managerUri |
| 594 | QCOMPARE(qHash(id1), qHash(id2)); |
| 595 | QCOMPARE(qHash(id1), qHash(id3)); |
| 596 | QVERIFY(qHash(id1) != qHash(id4)); |
| 597 | |
| 598 | QSet<QContactId> set; |
| 599 | set.insert(value: id1); |
| 600 | set.insert(value: id2); |
| 601 | set.insert(value: id3); |
| 602 | set.insert(value: id4); |
| 603 | QCOMPARE(set.size(), 3); |
| 604 | } |
| 605 | |
| 606 | void tst_QContact::hash() |
| 607 | { |
| 608 | QContactId id = makeId(managerName: "a" , id: 1); |
| 609 | QContact contact1; |
| 610 | contact1.setId(id); |
| 611 | QContactDetail detail1(QContactDetail::TypeExtendedDetail); |
| 612 | detail1.setValue(field: QContactExtendedDetail::FieldData, value: "value" ); |
| 613 | contact1.saveDetail(detail: &detail1); |
| 614 | QContact contact2; |
| 615 | contact2.setId(id); |
| 616 | contact2.saveDetail(detail: &detail1); |
| 617 | QContact contact3; |
| 618 | contact3.setId(id); |
| 619 | QContactDetail detail3(QContactDetail::TypeExtendedDetail); |
| 620 | detail3.setValue(field: QContactExtendedDetail::FieldData, value: "another value" ); |
| 621 | contact3.saveDetail(detail: &detail3); |
| 622 | QContact contact4; // no details |
| 623 | contact4.setId(id); |
| 624 | QContact contact5; // preferred details and relationships shouldn't affect the hash |
| 625 | contact5.setId(id); |
| 626 | contact5.saveDetail(detail: &detail1); |
| 627 | contact5.setPreferredDetail(actionName: "action" , preferredDetail: detail1); |
| 628 | QContactRelationship rel; |
| 629 | QContactManagerEngine::setContactRelationships(contact: &contact5, relationships: QList<QContactRelationship>() << rel); |
| 630 | QVERIFY(qHash(contact1) == qHash(contact2)); |
| 631 | QVERIFY(qHash(contact1) != qHash(contact3)); |
| 632 | QVERIFY(qHash(contact1) != qHash(contact4)); |
| 633 | QVERIFY(qHash(contact1) == qHash(contact5)); |
| 634 | } |
| 635 | |
| 636 | void tst_QContact::datastream() |
| 637 | { |
| 638 | QByteArray buffer; |
| 639 | QDataStream stream1(&buffer, QIODevice::WriteOnly); |
| 640 | QContact contactIn; |
| 641 | QContactId id = makeId(managerName: "manager" , id: 1234); |
| 642 | contactIn.setId(id); |
| 643 | QContactPhoneNumber phone; |
| 644 | phone.setNumber("5678" ); |
| 645 | contactIn.saveDetail(detail: &phone); |
| 646 | stream1 << contactIn; |
| 647 | |
| 648 | QVERIFY(buffer.size() > 0); |
| 649 | |
| 650 | QDataStream stream2(buffer); |
| 651 | QContact contactOut; |
| 652 | stream2 >> contactOut; |
| 653 | QCOMPARE(contactOut, contactIn); |
| 654 | } |
| 655 | |
| 656 | void tst_QContact::traits() |
| 657 | { |
| 658 | QCOMPARE(sizeof(QContact), sizeof(void *)); |
| 659 | QVERIFY(QTypeInfo<QContact>::isComplex); |
| 660 | QVERIFY(!QTypeInfo<QContact>::isStatic); |
| 661 | QVERIFY(!QTypeInfo<QContact>::isLarge); |
| 662 | QVERIFY(!QTypeInfo<QContact>::isPointer); |
| 663 | QVERIFY(!QTypeInfo<QContact>::isDummy); |
| 664 | } |
| 665 | |
| 666 | void tst_QContact::idTraits() |
| 667 | { |
| 668 | QCOMPARE(sizeof(QContactId), 2*sizeof(void *)); |
| 669 | QVERIFY(QTypeInfo<QContactId>::isComplex); |
| 670 | QVERIFY(!QTypeInfo<QContactId>::isStatic); |
| 671 | QVERIFY(QTypeInfo<QContactId>::isLarge); |
| 672 | QVERIFY(!QTypeInfo<QContactId>::isPointer); |
| 673 | QVERIFY(!QTypeInfo<QContactId>::isDummy); |
| 674 | } |
| 675 | |
| 676 | void tst_QContact::equality() |
| 677 | { |
| 678 | QContactName name; |
| 679 | name.setFirstName("John" ); |
| 680 | name.setLastName("Doe" ); |
| 681 | QContactPhoneNumber number; |
| 682 | number.setNumber("7654321" ); |
| 683 | QContactEmailAddress email; |
| 684 | email.setEmailAddress("john.doe@nokia.com" ); |
| 685 | QContactExtendedDetail xdetail; |
| 686 | xdetail.setName("shoesize" ); |
| 687 | xdetail.setData("45" ); |
| 688 | // Setup two identical contacts |
| 689 | QContact one, two; |
| 690 | one.saveDetail(detail: &name); |
| 691 | one.saveDetail(detail: &number); |
| 692 | one.saveDetail(detail: &email); |
| 693 | one.saveDetail(detail: &xdetail); |
| 694 | two.saveDetail(detail: &xdetail); |
| 695 | two.saveDetail(detail: &email); |
| 696 | two.saveDetail(detail: &number); |
| 697 | two.saveDetail(detail: &name); |
| 698 | |
| 699 | QVERIFY(one == two); |
| 700 | } |
| 701 | |
| 702 | void tst_QContact::inequality() |
| 703 | { |
| 704 | QContactId id = makeId(managerName: "a" , id: 123); |
| 705 | QContactName name; |
| 706 | name.setFirstName("John" ); |
| 707 | name.setLastName("Doe" ); |
| 708 | QContactPhoneNumber number; |
| 709 | number.setNumber("7654321" ); |
| 710 | QContactEmailAddress email; |
| 711 | email.setEmailAddress("john.doe@nokia.com" ); |
| 712 | QContactExtendedDetail xdetail; |
| 713 | xdetail.setName("shoesize" ); |
| 714 | xdetail.setData("45" ); |
| 715 | // Setup two contacts |
| 716 | QContact one, two; |
| 717 | one.setId(id); |
| 718 | QVERIFY(one != two); |
| 719 | two.setId(id); |
| 720 | QVERIFY(one == two); |
| 721 | // insert different amount of details |
| 722 | one.saveDetail(detail: &name); |
| 723 | one.saveDetail(detail: &number); |
| 724 | two.saveDetail(detail: &number); |
| 725 | QVERIFY(one != two); |
| 726 | two.clearDetails(); |
| 727 | // same amount of details with different types |
| 728 | two.saveDetail(detail: &number); |
| 729 | two.saveDetail(detail: &email); |
| 730 | QVERIFY(one != two); |
| 731 | two.clearDetails(); |
| 732 | // same amount of details with different value |
| 733 | name.setFirstName("Jim" ); |
| 734 | two.saveDetail(detail: &name); |
| 735 | two.saveDetail(detail: &number); |
| 736 | QVERIFY(one != two); |
| 737 | two.clearDetails(); |
| 738 | name.setFirstName("John" ); |
| 739 | // different types of details with same value |
| 740 | email.setEmailAddress("7654321" ); |
| 741 | two.saveDetail(detail: &name); |
| 742 | two.saveDetail(detail: &email); |
| 743 | QVERIFY(one != two); |
| 744 | } |
| 745 | |
| 746 | void tst_QContact::preferredDetails() |
| 747 | { |
| 748 | QContactPhoneNumber number; |
| 749 | number.setNumber("7654321" ); |
| 750 | QContactEmailAddress email; |
| 751 | email.setEmailAddress("john.doe@nokia.com" ); |
| 752 | QContactPhoneNumber number2; |
| 753 | number2.setNumber("1234567" ); |
| 754 | |
| 755 | QContact one; |
| 756 | one.saveDetail(detail: &email); |
| 757 | one.saveDetail(detail: &number); |
| 758 | one.saveDetail(detail: &number2); |
| 759 | |
| 760 | one.setPreferredDetail(actionName: "EMAIL" , preferredDetail: email); |
| 761 | one.setPreferredDetail(actionName: "PHONE" , preferredDetail: number); |
| 762 | |
| 763 | QVERIFY(one.preferredDetail("EMAIL" ) == email); |
| 764 | QVERIFY(one.preferredDetail("PHONE" ) == number); |
| 765 | |
| 766 | QMap<QString, QContactDetail> prefDetails = one.preferredDetails(); |
| 767 | QCOMPARE(prefDetails.count(), 2); |
| 768 | QVERIFY(prefDetails["EMAIL" ] == email); |
| 769 | QVERIFY(prefDetails["PHONE" ] == number); |
| 770 | } |
| 771 | |
| 772 | QTEST_MAIN(tst_QContact) |
| 773 | #include "tst_qcontact.moc" |
| 774 | |