|
1 #include "ut_qtcontacts_common.h" |
|
2 |
|
3 #include <QContactFetchRequest> |
|
4 #include <QContactLocalIdFilter> |
|
5 #include <QContactRemoveRequest> |
|
6 #include <QContactSaveRequest> |
|
7 |
|
8 ut_qtcontacts_common::ut_qtcontacts_common() |
|
9 : mContactManager(0) |
|
10 { |
|
11 } |
|
12 |
|
13 void ut_qtcontacts_common::initTestCase() |
|
14 { |
|
15 } |
|
16 |
|
17 void ut_qtcontacts_common::cleanupTestCase() |
|
18 { |
|
19 } |
|
20 |
|
21 void ut_qtcontacts_common::init() |
|
22 { |
|
23 QVERIFY(0 == mContactManager); |
|
24 mContactManager = new QContactManager("tracker"); |
|
25 QVERIFY(0 != mContactManager); |
|
26 } |
|
27 |
|
28 void ut_qtcontacts_common::cleanup() |
|
29 { |
|
30 if (mContactManager) { |
|
31 if (not mLocalIds.isEmpty()) { |
|
32 #if 0 // FIXME: qtcontacts-tracker doesn't implement QContactRemoveRequest yet |
|
33 QContactRemoveRequest request; |
|
34 request.setManager(mContactManager); |
|
35 request.setContactIds(mLocalIds); |
|
36 |
|
37 if (not request.start()) |
|
38 qDebug() << "error code" << request.error(); |
|
39 //QVERIFY(request.start()); |
|
40 |
|
41 waitForRequest(request); |
|
42 CHECK_CURRENT_TEST_FAILED; |
|
43 |
|
44 QVERIFY(request.isFinished()); |
|
45 QCOMPARE(request.error(), QContactManager::NoError); |
|
46 #else |
|
47 QMap<int, QContactManager::Error> errors; |
|
48 bool success = mContactManager->removeContacts(&mLocalIds, &errors); |
|
49 QCOMPARE(mContactManager->error(), QContactManager::NoError); |
|
50 QVERIFY(errors.isEmpty()); |
|
51 QVERIFY(success); |
|
52 #endif |
|
53 |
|
54 mLocalIds.clear(); |
|
55 } |
|
56 |
|
57 mContactManager->deleteLater(); |
|
58 mContactManager = 0; |
|
59 } |
|
60 } |
|
61 |
|
62 void ut_qtcontacts_common::waitForRequest(QContactAbstractRequest &request, int ms) |
|
63 { |
|
64 if (request.isFinished()) |
|
65 return; |
|
66 |
|
67 // check pre-conditions |
|
68 QCOMPARE((int) request.state(), (int) QContactAbstractRequest::ActiveState); |
|
69 |
|
70 // wait for the request to do its work (or get canceled) |
|
71 QTime timer; |
|
72 timer.start(); |
|
73 |
|
74 while (request.isActive() && timer.elapsed() < ms) { |
|
75 QTest::qWait(10); |
|
76 } |
|
77 |
|
78 // check post-conditions |
|
79 QVERIFY2(not request.isActive(), "timeout expired"); |
|
80 |
|
81 qDebug() << request.metaObject()->className() << "finished after" << timer.elapsed() << "ms"; |
|
82 } |
|
83 |
|
84 // FIXME: remove again once QtMobility provides more verbose contact validation utilities |
|
85 static bool validateContact(QContactManager *manager, const QContact &contact, QContactManager::Error &error_, QString &what) |
|
86 { |
|
87 QList<QString> uniqueDefinitionIds; |
|
88 |
|
89 // check that each detail conforms to its definition as supported by this manager. |
|
90 for (int i=0; i < contact.details().count(); i++) { |
|
91 const QContactDetail& d = contact.details().at(i); |
|
92 QVariantMap values = d.variantValues(); |
|
93 QContactDetailDefinition def = manager->detailDefinition(d.definitionName(), contact.type()); |
|
94 // check that the definition is supported |
|
95 if (def.isEmpty()) { |
|
96 error_ = QContactManager::InvalidDetailError; |
|
97 what = "Unsupported definition: " + d.definitionName(); |
|
98 return false; |
|
99 } |
|
100 |
|
101 // check uniqueness |
|
102 if (def.isUnique()) { |
|
103 if (uniqueDefinitionIds.contains(def.name())) { |
|
104 error_ = QContactManager::AlreadyExistsError; |
|
105 what = "Detail must be unique: " + d.definitionName(); |
|
106 return false; |
|
107 } |
|
108 uniqueDefinitionIds.append(def.name()); |
|
109 } |
|
110 |
|
111 QList<QString> keys = values.keys(); |
|
112 for (int i=0; i < keys.count(); i++) { |
|
113 const QString& key = keys.at(i); |
|
114 // check that no values exist for nonexistent fields. |
|
115 if (!def.fields().contains(key)) { |
|
116 error_ = QContactManager::InvalidDetailError; |
|
117 what = "Value for nonexistent field: " + d.definitionName() + "::" + key; |
|
118 return false; |
|
119 } |
|
120 |
|
121 QContactDetailFieldDefinition field = def.fields().value(key); |
|
122 // check that the type of each value corresponds to the allowable field type |
|
123 if (static_cast<int>(field.dataType()) != values.value(key).userType()) { |
|
124 error_ = QContactManager::InvalidDetailError; |
|
125 what = "Type doesn't match: " + d.definitionName() + "::" + key; |
|
126 return false; |
|
127 } |
|
128 |
|
129 // check that the value is allowable |
|
130 // if the allowable values is an empty list, any are allowed. |
|
131 if (!field.allowableValues().isEmpty()) { |
|
132 // if the field datatype is a list, check that it contains only allowable values |
|
133 if (field.dataType() == QVariant::List || field.dataType() == QVariant::StringList) { |
|
134 QList<QVariant> innerValues = values.value(key).toList(); |
|
135 for (int i = 0; i < innerValues.size(); i++) { |
|
136 if (!field.allowableValues().contains(innerValues.at(i))) { |
|
137 error_ = QContactManager::InvalidDetailError; |
|
138 what = QString("Value not allowed: %1 (%2)"). |
|
139 arg(d.definitionName() + "::" + key, |
|
140 innerValues.at(i).toString()); |
|
141 return false; |
|
142 } |
|
143 } |
|
144 } else if (!field.allowableValues().contains(values.value(key))) { |
|
145 // the datatype is not a list; the value wasn't allowed. |
|
146 error_ = QContactManager::InvalidDetailError; |
|
147 what = QString("Value not allowed: %1 (%2)"). |
|
148 arg(d.definitionName() + "::" + key, |
|
149 values.value(key).toString()); |
|
150 return false; |
|
151 } |
|
152 } |
|
153 } |
|
154 } |
|
155 |
|
156 return true; |
|
157 } |
|
158 |
|
159 void ut_qtcontacts_common::saveContact(QContact &contact, int timeout) |
|
160 { |
|
161 QList<QContact> contactList; |
|
162 contactList.append(contact); |
|
163 |
|
164 saveContacts(contactList, timeout); |
|
165 |
|
166 QCOMPARE(contactList.count(), 1); |
|
167 contact = contactList[0]; |
|
168 } |
|
169 |
|
170 void ut_qtcontacts_common::saveContacts(QList<QContact> &contacts, int timeout) |
|
171 { |
|
172 QVERIFY(not contacts.isEmpty()); |
|
173 |
|
174 foreach(const QContact &contact, contacts) { |
|
175 QContactManager::Error error; |
|
176 QString what; |
|
177 |
|
178 if (not validateContact(mContactManager, contact, error, what)) { |
|
179 foreach(const QContactDetail &d, contact.details()) { |
|
180 qDebug() << d.definitionName() << d.variantValues(); |
|
181 } |
|
182 |
|
183 QFAIL(qPrintable(QString("error %1: %2").arg(error).arg(what))); |
|
184 } |
|
185 } |
|
186 |
|
187 // add the contact to database |
|
188 QContactSaveRequest request; |
|
189 request.setManager(mContactManager); |
|
190 request.setContacts(contacts); |
|
191 QVERIFY(request.start()); |
|
192 |
|
193 qDebug() << "saving" << request.contacts().count() << "contacts"; |
|
194 waitForRequest(request, timeout); |
|
195 CHECK_CURRENT_TEST_FAILED; |
|
196 |
|
197 // verify the contact got saved |
|
198 QVERIFY(request.isFinished()); |
|
199 |
|
200 QCOMPARE((int) request.error(), |
|
201 (int) QContactManager::NoError); |
|
202 |
|
203 // copy back the saved contacts |
|
204 contacts = request.contacts(); |
|
205 |
|
206 // remember the local id so that we can remove the contact from database later |
|
207 foreach(const QContact &contact, contacts) { |
|
208 QVERIFY(contact.localId()); |
|
209 mLocalIds.append(contact.localId()); |
|
210 } |
|
211 } |
|
212 |
|
213 void ut_qtcontacts_common::fetchContact(const QContactLocalId &id, |
|
214 QContact &result, int timeout) |
|
215 { |
|
216 QList<QContact> contactList; |
|
217 fetchContacts(QList<QContactLocalId>() << id, contactList, timeout); |
|
218 QCOMPARE(contactList.count(), 1); |
|
219 result = contactList[0]; |
|
220 } |
|
221 |
|
222 void ut_qtcontacts_common::fetchContact(const QContactFilter &filter, |
|
223 QContact &result, int timeout) |
|
224 { |
|
225 QList<QContact> contactList; |
|
226 fetchContacts(filter, contactList, timeout); |
|
227 QCOMPARE(contactList.count(), 1); |
|
228 result = contactList[0]; |
|
229 } |
|
230 |
|
231 void ut_qtcontacts_common::fetchContacts(const QList<QContactLocalId> &ids, |
|
232 QList<QContact> &result, int timeout) |
|
233 { |
|
234 QContactLocalIdFilter filter; |
|
235 |
|
236 filter.setIds(ids); |
|
237 fetchContacts(filter, result, timeout); |
|
238 CHECK_CURRENT_TEST_FAILED; |
|
239 |
|
240 QCOMPARE(result.count(), ids.count()); |
|
241 } |
|
242 |
|
243 void ut_qtcontacts_common::fetchContacts(const QContactFilter &filter, |
|
244 QList<QContact> &result, int timeout) |
|
245 { |
|
246 QContactFetchRequest request; |
|
247 |
|
248 request.setManager(mContactManager); |
|
249 |
|
250 if (QContactFilter::InvalidFilter != filter.type()) |
|
251 request.setFilter(filter); |
|
252 |
|
253 QVERIFY(request.start()); |
|
254 |
|
255 qDebug() << "fetching contacts"; |
|
256 waitForRequest(request, timeout); |
|
257 CHECK_CURRENT_TEST_FAILED; |
|
258 |
|
259 QVERIFY(request.isFinished()); |
|
260 result = request.contacts(); |
|
261 } |
|
262 |
|
263 QSet<QString> ut_qtcontacts_common::testSlotNames() |
|
264 { |
|
265 QSet<QString> testSlots; |
|
266 |
|
267 for(int i = 0; i < metaObject()->methodCount(); ++i) { |
|
268 const QMetaMethod &method = metaObject()->method(i); |
|
269 |
|
270 if (QMetaMethod::Private != method.access() || |
|
271 QMetaMethod::Slot != method.methodType()) { |
|
272 continue; |
|
273 } |
|
274 |
|
275 const char *signature = method.signature(); |
|
276 const char *parenthesis = strchr(signature, '('); |
|
277 |
|
278 if (0 != qstrcmp(parenthesis, "()")) { |
|
279 continue; |
|
280 } |
|
281 |
|
282 testSlots.insert(QString::fromLatin1(signature, parenthesis - signature)); |
|
283 } |
|
284 |
|
285 return testSlots; |
|
286 } |