Merge lp:~renatofilho/address-book-service/fix-1268040_1312263_1235971 into lp:address-book-service

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Tiago Salem Herrmann
Approved revision: 126
Merged at revision: 116
Proposed branch: lp:~renatofilho/address-book-service/fix-1268040_1312263_1235971
Merge into: lp:address-book-service
Prerequisite: lp:~renatofilho/address-book-service/dummy-mode
Diff against target: 814 lines (+445/-73)
18 files modified
common/fetch-hint.cpp (+1/-0)
common/filter.cpp (+2/-1)
common/sort-clause.cpp (+10/-0)
common/sort-clause.h (+1/-0)
common/vcard-parser.cpp (+16/-0)
common/vcard-parser.h (+1/-0)
contacts/contacts-service.cpp (+0/-10)
lib/CMakeLists.txt (+2/-0)
lib/addressbook.cpp (+2/-0)
lib/contact-less-than.cpp (+47/-0)
lib/contact-less-than.h (+46/-0)
lib/qindividual.cpp (+40/-0)
lib/view.cpp (+20/-24)
tests/unittest/CMakeLists.txt (+1/-0)
tests/unittest/addressbook-test.cpp (+1/-0)
tests/unittest/qcontacts-create-source-test.cpp (+83/-0)
tests/unittest/qcontacts-test.cpp (+159/-38)
tests/unittest/sort-clause-test.cpp (+13/-0)
To merge this branch: bzr merge lp:~renatofilho/address-book-service/fix-1268040_1312263_1235971
Reviewer Review Type Date Requested Status
Tiago Salem Herrmann (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+217301@code.launchpad.net

This proposal supersedes a proposal from 2014-04-25.

Commit message

Used displayLabel with contact fullname.
Uses company name as fallback for contacts with empty names.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
117. By Renato Araujo Oliveira Filho

Export tag to be used in alphabetical section.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
118. By Renato Araujo Oliveira Filho

Sort contacts with names starting with symbols/numbers in the end of the list.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
119. By Renato Araujo Oliveira Filho

Added TAG support into hint helper class.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
120. By Renato Araujo Oliveira Filho

Make the contact tag used into the sections caseFolded string.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
121. By Renato Araujo Oliveira Filho

Added unit test for display name.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
122. By Renato Araujo Oliveira Filho

Keep contacts starting with symbols or number in the begginer or the list.

123. By Renato Araujo Oliveira Filho

Removed unecessary code.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
124. By Renato Araujo Oliveira Filho

Keep empty tags for contact names starting with symbols or numbers.

125. By Renato Araujo Oliveira Filho

Updated comments about the tag WORKAROUND.

126. By Renato Araujo Oliveira Filho

Fixed unit test.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

* Are there any related MPs required for this MP to build/function as expected? YES
 - https://code.launchpad.net/~renatofilho/address-book-app/fix-1268042/+merge/216182

* Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes): YES
* Did you perform an exploratory manual test run of your code change and any related functionality on device or emulator? YES
* Did you successfully run all tests found in your component's Test Plan on device or emulator? YES
* If you changed the UI, was the change specified/approved by design? N/A
* If you changed the packaging (debian), did you subscribe a core-dev to this MP? N/A

Revision history for this message
Tiago Salem Herrmann (tiagosh) wrote :

Did you perform an exploratory manual test run of the code change and any related functionality on device or emulator?
Yes

Did CI run pass? If not, please explain why.
Yes

Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?
Yes

review: Approve
127. By Renato Araujo Oliveira Filho

Use phone number as contact display label if the company is empty.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'common/fetch-hint.cpp'
2--- common/fetch-hint.cpp 2014-03-27 16:47:09 +0000
3+++ common/fetch-hint.cpp 2014-05-05 14:42:08 +0000
4@@ -103,6 +103,7 @@
5 map.insert("PHOTO", QContactAvatar::Type);
6 map.insert("TEL", QContactPhoneNumber::Type);
7 map.insert("URL", QContactUrl::Type);
8+ map.insert("TAG", QContactTag::Type);
9 }
10 return map;
11 }
12
13=== modified file 'common/filter.cpp'
14--- common/filter.cpp 2014-03-05 18:43:32 +0000
15+++ common/filter.cpp 2014-05-05 14:42:08 +0000
16@@ -59,7 +59,8 @@
17
18 bool Filter::isValid() const
19 {
20- return (m_filter.type() != QContactFilter::InvalidFilter);
21+ return ((m_filter.type() != QContactFilter::InvalidFilter) &&
22+ (m_filter.type() != QContactFilter::DefaultFilter));
23 }
24
25 QString Filter::toString(const QtContacts::QContactFilter &filter)
26
27=== modified file 'common/sort-clause.cpp'
28--- common/sort-clause.cpp 2014-02-04 19:12:46 +0000
29+++ common/sort-clause.cpp 2014-05-05 14:42:08 +0000
30@@ -53,6 +53,11 @@
31 initialize();
32 }
33
34+bool SortClause::isEmpty() const
35+{
36+ return m_sortOrders.isEmpty();
37+}
38+
39 QString SortClause::toString() const
40 {
41 QString result;
42@@ -128,6 +133,7 @@
43 clauseFieldMap["ADDR_POST_OFFICE_BOX"] = QPair<QContactDetail::DetailType, int>(QContactDetail::TypeAddress, QContactAddress::FieldPostOfficeBox);
44 clauseFieldMap["IM_URI"] = QPair<QContactDetail::DetailType, int>(QContactDetail::TypeOnlineAccount, QContactOnlineAccount::FieldAccountUri);
45 clauseFieldMap["IM_PROTOCOL"] = QPair<QContactDetail::DetailType, int>(QContactDetail::TypeOnlineAccount, QContactOnlineAccount::FieldProtocol);
46+ clauseFieldMap["TAG"] = QPair<QContactDetail::DetailType, int>(QContactDetail::TypeTag, QContactTag::FieldTag);
47 clauseFieldMap["URL"] = QPair<QContactDetail::DetailType, int>(QContactDetail::TypeUrl, QContactUrl::FieldUrl);
48 }
49 }
50@@ -142,6 +148,10 @@
51 }
52 }
53
54+ if (sort.isValid()) {
55+ qWarning() << "No sorting support for" << sort;
56+ }
57+
58 return "";
59 }
60
61
62=== modified file 'common/sort-clause.h'
63--- common/sort-clause.h 2013-06-18 18:40:40 +0000
64+++ common/sort-clause.h 2014-05-05 14:42:08 +0000
65@@ -35,6 +35,7 @@
66 SortClause(QList<QtContacts::QContactSortOrder> sort);
67 SortClause(const SortClause &other);
68
69+ bool isEmpty() const;
70 QString toString() const;
71 QList<QtContacts::QContactSortOrder> toContactSortOrder() const;
72
73
74=== modified file 'common/vcard-parser.cpp'
75--- common/vcard-parser.cpp 2014-03-20 22:06:09 +0000
76+++ common/vcard-parser.cpp 2014-05-05 14:42:08 +0000
77@@ -57,6 +57,14 @@
78 *toBeAdded << prop;
79 }
80
81+ if (detail.type() == QContactDetail::TypeTag) {
82+ QContactTag tag = static_cast<QContactTag>(detail);
83+ QVersitProperty prop;
84+ prop.setName(galera::VCardParser::TagFieldName);
85+ prop.setValue(tag.tag());
86+ *toBeAdded << prop;
87+ }
88+
89 if (toBeAdded->size() == 0) {
90 return;
91 }
92@@ -138,6 +146,13 @@
93 *alreadyProcessed = true;
94 }
95
96+ if (!*alreadyProcessed && (property.name() == galera::VCardParser::TagFieldName)) {
97+ QContactTag tag;
98+ tag.setTag(property.value<QString>());
99+ *updatedDetails << tag;
100+ *alreadyProcessed = true;
101+ }
102+
103 if (!*alreadyProcessed) {
104 return;
105 }
106@@ -220,6 +235,7 @@
107 const QString VCardParser::PrefParamName = QStringLiteral("PREF");
108 const QString VCardParser::IrremovableFieldName = QStringLiteral("IRREMOVABLE");
109 const QString VCardParser::ReadOnlyFieldName = QStringLiteral("READ-ONLY");
110+const QString VCardParser::TagFieldName = QStringLiteral("TAG");
111
112 static QMap<QtContacts::QContactDetail::DetailType, QString> prefferedActions()
113 {
114
115=== modified file 'common/vcard-parser.h'
116--- common/vcard-parser.h 2014-04-09 13:03:21 +0000
117+++ common/vcard-parser.h 2014-05-05 14:42:08 +0000
118@@ -46,6 +46,7 @@
119 static const QString PrefParamName;
120 static const QString IrremovableFieldName;
121 static const QString ReadOnlyFieldName;
122+ static const QString TagFieldName;
123 static const QMap<QtContacts::QContactDetail::DetailType, QString> PreferredActionNames;
124
125 static QtContacts::QContact vcardToContact(const QString &vcard);
126
127=== modified file 'contacts/contacts-service.cpp'
128--- contacts/contacts-service.cpp 2014-04-30 16:26:04 +0000
129+++ contacts/contacts-service.cpp 2014-05-05 14:42:08 +0000
130@@ -285,7 +285,6 @@
131 QString sortStr = SortClause(request->sorting()).toString();
132 QString filterStr = Filter(request->filter()).toString();
133 FetchHint fetchHint = FetchHint(request->fetchHint()).toString();
134-
135 QDBusPendingCall pcall = m_iface->asyncCall("query", filterStr, sortStr, QStringList());
136 if (pcall.isError()) {
137 qWarning() << pcall.error().name() << pcall.error().message();
138@@ -402,15 +401,6 @@
139 GaleraEngineId *engineId = new GaleraEngineId(detailId.guid(), m_managerUri);
140 QContactId newId = QContactId(engineId);
141 contact->setId(newId);
142- // set tag to be used when creating sections
143- QContactName detailName = contact->detail<QContactName>();
144- if (!detailName.firstName().isEmpty() && QString(detailName.firstName().at(0)).contains(QRegExp("([a-z]|[A-Z])"))) {
145- contact->addTag(detailName.firstName().at(0).toUpper());
146- } else if (!detailName.lastName().isEmpty() && QString(detailName.lastName().at(0)).contains(QRegExp("([a-z]|[A-Z])"))) {
147- contact->addTag(detailName.lastName().at(0).toUpper());
148- } else {
149- contact->addTag("#");
150- }
151 }
152 }
153
154
155=== modified file 'lib/CMakeLists.txt'
156--- lib/CMakeLists.txt 2014-03-19 16:44:03 +0000
157+++ lib/CMakeLists.txt 2014-05-05 14:42:08 +0000
158@@ -5,6 +5,7 @@
159 set(CONTACTS_SERVICE_LIB_SRC
160 addressbook.cpp
161 addressbook-adaptor.cpp
162+ contact-less-than.cpp
163 contacts-map.cpp
164 detail-context-parser.cpp
165 dirtycontact-notify.cpp
166@@ -18,6 +19,7 @@
167 set(CONTACTS_SERVICE_LIB_HEADERS
168 addressbook.h
169 addressbook-adaptor.h
170+ contact-less-than.h
171 contacts-map.h
172 detail-context-parser.h
173 dirtycontact-notify.h
174
175=== modified file 'lib/addressbook.cpp'
176--- lib/addressbook.cpp 2014-04-09 13:03:21 +0000
177+++ lib/addressbook.cpp 2014-05-05 14:42:08 +0000
178@@ -405,6 +405,7 @@
179 QContact qcontact = VCardParser::vcardToContact(contact);
180 if (!qcontact.isEmpty()) {
181 GHashTable *details = QIndividual::parseDetails(qcontact);
182+ Q_ASSERT(details);
183 CreateContactData *data = new CreateContactData;
184 data->m_message = message;
185 data->m_addressbook = this;
186@@ -464,6 +465,7 @@
187
188 if (!result) {
189 result = folks_individual_aggregator_get_primary_store(m_individualAggregator);
190+ Q_ASSERT(result);
191 g_object_ref(result);
192 }
193 return result;
194
195=== added file 'lib/contact-less-than.cpp'
196--- lib/contact-less-than.cpp 1970-01-01 00:00:00 +0000
197+++ lib/contact-less-than.cpp 2014-05-05 14:42:08 +0000
198@@ -0,0 +1,47 @@
199+/*
200+ * Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
201+ * Copyright (C) 2013 Canonical Ltd.
202+ *
203+ * This file is part of contact-service-app.
204+ *
205+ * contact-service-app is free software; you can redistribute it and/or modify
206+ * it under the terms of the GNU General Public License as published by
207+ * the Free Software Foundation; version 3.
208+ *
209+ * contact-service-app is distributed in the hope that it will be useful,
210+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
211+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
212+ * GNU General Public License for more details.
213+ *
214+ * You should have received a copy of the GNU General Public License
215+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
216+ *
217+ * Based on QContactManagerEngine code by Digia
218+ */
219+
220+#include "contact-less-than.h"
221+#include "contacts-map.h"
222+#include "qindividual.h"
223+
224+#include <QtCore/QTime>
225+#include <QtCore/QDebug>
226+
227+#include <QtContacts/QContactManagerEngine>
228+
229+using namespace QtContacts;
230+
231+namespace galera {
232+
233+ContactLessThan::ContactLessThan(const galera::SortClause &sortClause)
234+ : m_sortClause(sortClause)
235+{
236+}
237+
238+bool ContactLessThan::operator()(ContactEntry *entryA, ContactEntry *entryB)
239+{
240+ return QContactManagerEngine::compareContact(entryA->individual()->contact(),
241+ entryB->individual()->contact(),
242+ m_sortClause.toContactSortOrder()) < 0;
243+}
244+
245+} // namespace
246
247=== added file 'lib/contact-less-than.h'
248--- lib/contact-less-than.h 1970-01-01 00:00:00 +0000
249+++ lib/contact-less-than.h 2014-05-05 14:42:08 +0000
250@@ -0,0 +1,46 @@
251+/*
252+ * Copyright 2013 Canonical Ltd.
253+ *
254+ * This file is part of contact-service-app.
255+ *
256+ * contact-service-app is free software; you can redistribute it and/or modify
257+ * it under the terms of the GNU General Public License as published by
258+ * the Free Software Foundation; version 3.
259+ *
260+ * contact-service-app is distributed in the hope that it will be useful,
261+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
262+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
263+ * GNU General Public License for more details.
264+ *
265+ * You should have received a copy of the GNU General Public License
266+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
267+ */
268+
269+#ifndef __GALERA_CONTACT_LESS_THAN_H__
270+#define __GALERA_CONTACT_LESS_THAN_H__
271+
272+#include "common/sort-clause.h"
273+
274+#include <QtCore/QString>
275+#include <QtCore/QVariant>
276+
277+#include <QtContacts/QContact>
278+
279+namespace galera {
280+
281+class ContactEntry;
282+
283+class ContactLessThan
284+{
285+public:
286+ ContactLessThan(const SortClause &sortClause);
287+
288+ bool operator()(ContactEntry *entryA, ContactEntry *entryB);
289+
290+private:
291+ SortClause m_sortClause;
292+};
293+
294+} // namespace
295+
296+#endif //__GALERA_CONTACT_LESS_THAN_H__
297
298=== modified file 'lib/qindividual.cpp'
299--- lib/qindividual.cpp 2014-04-04 15:48:16 +0000
300+++ lib/qindividual.cpp 2014-05-05 14:42:08 +0000
301@@ -275,10 +275,12 @@
302 displayName += QString::fromUtf8(name);
303 }
304 }
305+
306 if (!displayName.isEmpty()) {
307 detail.setLabel(displayName);
308 detail.setDetailUri(QString("%1.1").arg(index));
309 }
310+
311 return detail;
312 }
313
314@@ -751,6 +753,12 @@
315 }
316 }
317
318+ if (fields.contains(QContactDetail::TypeTag)) {
319+ Q_FOREACH(QContactDetail det, fullContact.details<QContactTag>()) {
320+ details << det;
321+ }
322+ }
323+
324 Q_FOREACH(QContactDetail det, details) {
325 result.appendDetail(det);
326 }
327@@ -883,8 +891,40 @@
328 VCardParser::PreferredActionNames[QContactUrl::Type],
329 prefDetail,
330 !wPropList.contains("urls"));
331+
332 personaIndex++;
333 }
334+
335+ // if contact name is empty use org name otherwise try phone number as fallback
336+ QContactDisplayLabel displayName = contact->detail<QContactDisplayLabel>();
337+ QString label = displayName.label().trimmed();
338+
339+ if (label.isEmpty()) {
340+ QContactOrganization org = contact->detail<QContactOrganization>();
341+ label = org.name().trimmed();
342+ if (label.isEmpty()) {
343+ QContactPhoneNumber phone = contact->detail<QContactPhoneNumber>();
344+ label = phone.number().trimmed();
345+ }
346+
347+ displayName.setLabel(label);
348+ contact->saveDetail(&displayName);
349+ }
350+
351+ // WORKAROUND: add a extra tag to help on alphabetic list
352+ // On the Ubuntu Address Book, contacts which the name starts with
353+ // number or symbol should be moved to bottom of the list. Since the standard
354+ // string sort put symbols and numbers on the top, we use the tag to sort,
355+ // and keep empty tags for the especial case.
356+ QContactTag tag;
357+ label = label.toUpper();
358+ if (label.isEmpty() ||
359+ !label.at(0).isLetter()) {
360+ tag.setTag("");
361+ } else {
362+ tag.setTag(label);
363+ }
364+ contact->saveDetail(&tag);
365 }
366
367 bool QIndividual::update(const QtContacts::QContact &newContact, QObject *object, const char *slot)
368
369=== modified file 'lib/view.cpp'
370--- lib/view.cpp 2014-04-09 12:57:07 +0000
371+++ lib/view.cpp 2014-05-05 14:42:08 +0000
372@@ -19,6 +19,7 @@
373 #include "view.h"
374 #include "view-adaptor.h"
375 #include "contacts-map.h"
376+#include "contact-less-than.h"
377 #include "qindividual.h"
378
379 #include "common/vcard-parser.h"
380@@ -38,24 +39,6 @@
381
382 namespace galera
383 {
384-class ContactLessThan
385-{
386-public:
387- ContactLessThan(const SortClause &sortClause)
388- : m_sortClause(sortClause)
389- {
390-
391- }
392-
393- bool operator()(galera::ContactEntry *entryA, galera::ContactEntry *entryB)
394- {
395- return QContactManagerEngine::compareContact(entryA->individual()->contact(),
396- entryB->individual()->contact(),
397- m_sortClause.toContactSortOrder()) < 0;
398- }
399-private:
400- SortClause m_sortClause;
401-};
402
403 class FilterThread: public QThread
404 {
405@@ -80,8 +63,7 @@
406 bool appendContact(ContactEntry *entry)
407 {
408 if (checkContact(entry)) {
409- //TODO: append sorted
410- m_contacts << entry;
411+ addSorted(&m_contacts, entry, m_sortClause);
412 return true;
413 }
414 return false;
415@@ -95,8 +77,22 @@
416 void chageSort(SortClause clause)
417 {
418 m_sortClause = clause;
419- ContactLessThan lessThan(m_sortClause);
420- qSort(m_contacts.begin(), m_contacts.end(), lessThan);
421+ if (!clause.isEmpty()) {
422+ ContactLessThan lessThan(m_sortClause);
423+ qSort(m_contacts.begin(), m_contacts.end(), lessThan);
424+ }
425+ }
426+
427+ void addSorted(QList<ContactEntry*>* sorted, ContactEntry* toAdd, const SortClause& sortOrder)
428+ {
429+ if (!sortOrder.isEmpty()) {
430+ ContactLessThan lessThan(sortOrder);
431+ QList<ContactEntry*>::iterator it(std::upper_bound(sorted->begin(), sorted->end(), toAdd, lessThan));
432+ sorted->insert(it, toAdd);
433+ } else {
434+ // no sort order? just add it to the end
435+ sorted->append(toAdd);
436+ }
437 }
438
439 void stop()
440@@ -124,14 +120,14 @@
441 m_stoppedLock.unlock();
442
443 if (checkContact(entry)) {
444- m_contacts << entry;
445+ addSorted(&m_contacts, entry, m_sortClause);
446 }
447 }
448 } else {
449 m_contacts = m_allContacts->values();
450+ chageSort(m_sortClause);
451 }
452
453- chageSort(m_sortClause);
454 m_allContacts->unlock();
455 }
456
457
458=== modified file 'tests/unittest/CMakeLists.txt'
459--- tests/unittest/CMakeLists.txt 2014-03-19 16:44:03 +0000
460+++ tests/unittest/CMakeLists.txt 2014-05-05 14:42:08 +0000
461@@ -75,6 +75,7 @@
462 declare_test(readonly-prop-test True ${BASE_CLIENT_TEST_SRC})
463 declare_test(contact-link-test True ${BASE_CLIENT_TEST_SRC})
464 declare_test(qcontacts-test True ${BASE_CLIENT_TEST_SRC})
465+ declare_test(qcontacts-create-source-test True ${BASE_CLIENT_TEST_SRC})
466 elseif()
467 message(STATUS "DBus test runner not found. Some tests will be disabled")
468 endif()
469
470=== modified file 'tests/unittest/addressbook-test.cpp'
471--- tests/unittest/addressbook-test.cpp 2014-03-24 20:11:26 +0000
472+++ tests/unittest/addressbook-test.cpp 2014-05-05 14:42:08 +0000
473@@ -147,6 +147,7 @@
474 << "ORG_TITLE"
475 << "PHONE"
476 << "PHOTO"
477+ << "TAG"
478 << "URL";
479 QDBusReply<QStringList> reply = m_serverIface->call("sortFields");
480 QCOMPARE(reply.value(), defaultSortFields);
481
482=== added file 'tests/unittest/qcontacts-create-source-test.cpp'
483--- tests/unittest/qcontacts-create-source-test.cpp 1970-01-01 00:00:00 +0000
484+++ tests/unittest/qcontacts-create-source-test.cpp 2014-05-05 14:42:08 +0000
485@@ -0,0 +1,83 @@
486+/*
487+ * Copyright 2013 Canonical Ltd.
488+ *
489+ * This file is part of contact-service-app.
490+ *
491+ * contact-service-app is free software; you can redistribute it and/or modify
492+ * it under the terms of the GNU General Public License as published by
493+ * the Free Software Foundation; version 3.
494+ *
495+ * contact-service-app is distributed in the hope that it will be useful,
496+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
497+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
498+ * GNU General Public License for more details.
499+ *
500+ * You should have received a copy of the GNU General Public License
501+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
502+ */
503+
504+#include "base-client-test.h"
505+#include "common/source.h"
506+#include "common/dbus-service-defs.h"
507+#include "common/vcard-parser.h"
508+
509+#include <QObject>
510+#include <QtDBus>
511+#include <QtTest>
512+#include <QDebug>
513+#include <QtContacts>
514+
515+#include "config.h"
516+
517+using namespace QtContacts;
518+
519+class QContactsCreateSourceTest : public BaseClientTest
520+{
521+ Q_OBJECT
522+private Q_SLOTS:
523+ void initTestCase()
524+ {
525+ BaseClientTest::initTestCase();
526+ QCoreApplication::setLibraryPaths(QStringList() << QT_PLUGINS_BINARY_DIR);
527+ }
528+
529+ /*
530+ * Test create a contact source using the contact group
531+ */
532+ void testCreateGroup()
533+ {
534+ QContactManager manager("galera");
535+
536+ // create a contact
537+ QContact contact;
538+ contact.setType(QContactType::TypeGroup);
539+
540+ QContactDisplayLabel label;
541+ label.setLabel("test group");
542+ contact.saveDetail(&label);
543+
544+ bool result = manager.saveContact(&contact);
545+ QCOMPARE(result, true);
546+
547+ // query for new contacts
548+ QContactDetailFilter filter;
549+ filter.setDetailType(QContactDetail::TypeType, QContactType::FieldType);
550+ filter.setValue(QContactType::TypeGroup);
551+ QList<QContact> contacts = manager.contacts(filter);
552+
553+ // will be two sources since we have the main source already created
554+ QCOMPARE(contacts.size(), 2);
555+
556+ QContact createdContact = contacts[0];
557+ // id
558+ QVERIFY(!createdContact.id().isNull());
559+
560+ // label
561+ QContactDisplayLabel createdlabel = createdContact.detail<QContactDisplayLabel>();
562+ QCOMPARE(createdlabel.label(), label.label());
563+ }
564+};
565+
566+QTEST_MAIN(QContactsCreateSourceTest)
567+
568+#include "qcontacts-create-source-test.moc"
569
570=== modified file 'tests/unittest/qcontacts-test.cpp'
571--- tests/unittest/qcontacts-test.cpp 2014-03-20 22:06:09 +0000
572+++ tests/unittest/qcontacts-test.cpp 2014-05-05 14:42:08 +0000
573@@ -121,7 +121,7 @@
574 QContactSyncTarget target = contact.detail<QContactSyncTarget>();
575 QCOMPARE(target.syncTarget(), QString("Dummy personas"));
576 }
577-#if 0
578+
579 /*
580 * Test create a new contact
581 */
582@@ -160,42 +160,6 @@
583 }
584
585 /*
586- * Test create a contact source using the contact group
587- */
588- void testCreateGroup()
589- {
590- QContactManager manager("galera");
591-
592- // create a contact
593- QContact contact;
594- contact.setType(QContactType::TypeGroup);
595-
596- QContactDisplayLabel label;
597- label.setLabel("test group");
598- contact.saveDetail(&label);
599-
600- bool result = manager.saveContact(&contact);
601- QCOMPARE(result, true);
602-
603- // query for new contacts
604- QContactDetailFilter filter;
605- filter.setDetailType(QContactDetail::TypeType, QContactType::FieldType);
606- filter.setValue(QContactType::TypeGroup);
607- QList<QContact> contacts = manager.contacts(filter);
608-
609- // will be two sources since we have the main source already created
610- QCOMPARE(contacts.size(), 2);
611-
612- QContact createdContact = contacts[0];
613- // id
614- QVERIFY(!createdContact.id().isNull());
615-
616- // label
617- QContactDisplayLabel createdlabel = createdContact.detail<QContactDisplayLabel>();
618- QCOMPARE(createdlabel.label(), label.label());
619- }
620-
621- /*
622 * Test query a contact source using the contact group
623 */
624 void testQueryGroups()
625@@ -216,7 +180,164 @@
626 QContactDisplayLabel label = contacts[0].detail(QContactDisplayLabel::Type);
627 QCOMPARE(label.label(), QStringLiteral("Dummy personas"));
628 }
629-#endif
630+
631+ /*
632+ * Test sort contacts by with symbols in the end
633+ */
634+ void testQuerySortedWithSymbolsInTheEnd()
635+ {
636+ QSignalSpy spyContactAdded(m_manager, SIGNAL(contactsAdded(QList<QContactId>)));
637+
638+ // create a contact ""
639+ QContact contact;
640+ QContactName name = contact.detail<QContactName>();
641+ name.setFirstName("");
642+ name.setMiddleName("");
643+ name.setLastName("");
644+ contact.saveDetail(&name);
645+ bool result = m_manager->saveContact(&contact);
646+ QCOMPARE(result, true);
647+
648+ // create contact "Aa"
649+ contact = QContact();
650+ name = contact.detail<QContactName>();
651+ name.setFirstName("Aa");
652+ contact.saveDetail(&name);
653+ result = m_manager->saveContact(&contact);
654+ QCOMPARE(result, true);
655+
656+ // create contact "Ba"
657+ contact = QContact();
658+ name = contact.detail<QContactName>();
659+ name.setFirstName("Ba");
660+ contact.saveDetail(&name);
661+ result = m_manager->saveContact(&contact);
662+ QCOMPARE(result, true);
663+
664+ // create contact "Bb"
665+ contact = QContact();
666+ name = contact.detail<QContactName>();
667+ name.setFirstName("Bb");
668+ contact.saveDetail(&name);
669+ result = m_manager->saveContact(&contact);
670+ QCOMPARE(result, true);
671+
672+ // create contact "321"
673+ contact = QContact();
674+ name = contact.detail<QContactName>();
675+ name.setFirstName("321");
676+ contact.saveDetail(&name);
677+ result = m_manager->saveContact(&contact);
678+ QCOMPARE(result, true);
679+
680+ // create contact "*"
681+ contact = QContact();
682+ name = contact.detail<QContactName>();
683+ name.setFirstName("*");
684+ contact.saveDetail(&name);
685+ result = m_manager->saveContact(&contact);
686+ QCOMPARE(result, true);
687+
688+ // create contact "" with company "x"
689+ contact = QContact();
690+ name = contact.detail<QContactName>();
691+ name.setFirstName("");
692+ name.setMiddleName("");
693+ name.setLastName("");
694+ contact.saveDetail(&name);
695+
696+ QContactOrganization org;
697+ org.setName("x");
698+ contact.saveDetail(&org);
699+ result = m_manager->saveContact(&contact);
700+ QCOMPARE(result, true);
701+
702+ QTRY_COMPARE(spyContactAdded.count(), 1);
703+
704+ // sort contact by tag and display name
705+ QContactFilter filter;
706+ QContactSortOrder sortTag;
707+ sortTag.setDetailType(QContactDetail::TypeTag, QContactTag::FieldTag);
708+ sortTag.setDirection(Qt::AscendingOrder);
709+ sortTag.setCaseSensitivity(Qt::CaseInsensitive);
710+ sortTag.setBlankPolicy(QContactSortOrder::BlanksLast);
711+
712+ QContactSortOrder sortDisplayName;
713+ sortDisplayName.setDetailType(QContactDetail::TypeDisplayLabel, QContactDisplayLabel::FieldLabel);
714+ sortDisplayName.setDirection(Qt::AscendingOrder);
715+ sortDisplayName.setCaseSensitivity(Qt::CaseInsensitive);
716+ sortDisplayName.setBlankPolicy(QContactSortOrder::BlanksLast);
717+
718+ QList<QContactSortOrder> sortOrders;
719+ sortOrders << sortTag << sortDisplayName;
720+
721+ // check result
722+ QList<QContact> contacts = m_manager->contacts(filter, sortOrders);
723+ QCOMPARE(contacts.size(), 7);
724+ QCOMPARE(contacts[0].detail(QContactDetail::TypeDisplayLabel).value(QContactDisplayLabel::FieldLabel).toString(),
725+ QStringLiteral("Aa"));
726+ QCOMPARE(contacts[1].detail(QContactDetail::TypeDisplayLabel).value(QContactDisplayLabel::FieldLabel).toString(),
727+ QStringLiteral("Ba"));
728+ QCOMPARE(contacts[2].detail(QContactDetail::TypeDisplayLabel).value(QContactDisplayLabel::FieldLabel).toString(),
729+ QStringLiteral("Bb"));
730+ QCOMPARE(contacts[3].detail(QContactDetail::TypeDisplayLabel).value(QContactDisplayLabel::FieldLabel).toString(),
731+ QStringLiteral("x"));
732+ QCOMPARE(contacts[4].detail(QContactDetail::TypeDisplayLabel).value(QContactDisplayLabel::FieldLabel).toString(),
733+ QStringLiteral("*"));
734+ QCOMPARE(contacts[5].detail(QContactDetail::TypeDisplayLabel).value(QContactDisplayLabel::FieldLabel).toString(),
735+ QStringLiteral("321"));
736+ QCOMPARE(contacts[6].detail(QContactDetail::TypeDisplayLabel).value(QContactDisplayLabel::FieldLabel).toString(),
737+ QStringLiteral(""));
738+ }
739+
740+ void testContactDisplayName()
741+ {
742+ // create a contact ""
743+ QContact contact;
744+ QContactName name = contact.detail<QContactName>();
745+ name.setFirstName("");
746+ name.setMiddleName("");
747+ name.setLastName("");
748+ contact.saveDetail(&name);
749+ bool result = m_manager->saveContact(&contact);
750+ QCOMPARE(result, true);
751+
752+ // create contact "Aa"
753+ contact = QContact();
754+ name = contact.detail<QContactName>();
755+ name.setFirstName("Aa");
756+ contact.saveDetail(&name);
757+ result = m_manager->saveContact(&contact);
758+ QCOMPARE(result, true);
759+
760+ // create contact "" with company "x"
761+ contact = QContact();
762+ name = contact.detail<QContactName>();
763+ name.setFirstName("");
764+ name.setMiddleName("");
765+ name.setLastName("");
766+ contact.saveDetail(&name);
767+ QContactOrganization org;
768+ org.setName("x");
769+ contact.saveDetail(&org);
770+ result = m_manager->saveContact(&contact);
771+
772+ QCOMPARE(result, true);
773+
774+ // check result
775+ QContactFilter filter;
776+ QList<QContact> contacts = m_manager->contacts(filter);
777+
778+ QStringList expectedContacts;
779+ expectedContacts << ""
780+ << "Aa"
781+ << "x";
782+ QCOMPARE(contacts.size(), 3);
783+ Q_FOREACH(const QContact &c, contacts) {
784+ expectedContacts.removeAll(c.detail<QContactDisplayLabel>().label());
785+ }
786+ QCOMPARE(expectedContacts.size(), 0);
787+ }
788 };
789
790 QTEST_MAIN(QContactsTest)
791
792=== modified file 'tests/unittest/sort-clause-test.cpp'
793--- tests/unittest/sort-clause-test.cpp 2013-06-11 20:13:09 +0000
794+++ tests/unittest/sort-clause-test.cpp 2014-05-05 14:42:08 +0000
795@@ -113,6 +113,19 @@
796 QCOMPARE(clause.toContactSortOrder().size(), 0);
797 }
798
799+ void testTagSourtClause()
800+ {
801+ const QString strClause = QString("TAG ASC");
802+ SortClause clause(strClause);
803+
804+ QList<QContactSortOrder> cClauseList;
805+ QContactSortOrder sortTag;
806+ sortTag.setDetailType(QContactDetail::TypeTag, QContactTag::FieldTag);
807+ sortTag.setDirection(Qt::AscendingOrder);
808+ sortTag.setCaseSensitivity(Qt::CaseInsensitive);
809+ cClauseList << sortTag;
810+ QVERIFY(clause.toContactSortOrder() == cClauseList);
811+ }
812 };
813
814 QTEST_MAIN(SortClauseTest)

Subscribers

People subscribed via source and target branches