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
40QTCONTACTS_USE_NAMESPACE
41
42static 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
48class tst_QContact: public QObject
49{
50 Q_OBJECT
51
52public:
53 tst_QContact();
54 virtual ~tst_QContact();
55
56private 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
74tst_QContact::tst_QContact()
75{
76}
77
78tst_QContact::~tst_QContact()
79{
80}
81
82void 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
375void 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
459void 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
481void 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
499void 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
525void 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
536void 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
587void 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
606void 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
636void 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
656void 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
666void 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
676void 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
702void 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
746void 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
772QTEST_MAIN(tst_QContact)
773#include "tst_qcontact.moc"
774

source code of qtpim/tests/auto/contacts/qcontact/tst_qcontact.cpp