1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "ut_qtcontacts_fetch.h" |
|
43 |
|
44 #include <QContactManager> |
|
45 #include <QContactName> |
|
46 #include <QContactDetailFilter> |
|
47 #include <QtTest/QtTest> |
|
48 #include <QDebug> |
|
49 |
|
50 // Note that we try to avoid using any names that might already be in the database: |
|
51 const char* TESTNAME_FIRST = "ut_qtcontacts_fetch_firstname"; |
|
52 const char* TESTNAME_LAST = "ut_qtcontacts_fetch_firstlast"; |
|
53 |
|
54 ut_qtcontacts_fetch::ut_qtcontacts_fetch() |
|
55 : waiting(false), |
|
56 state(STATE_START) |
|
57 { |
|
58 } |
|
59 |
|
60 ut_qtcontacts_fetch::~ut_qtcontacts_fetch() |
|
61 { |
|
62 |
|
63 } |
|
64 |
|
65 void ut_qtcontacts_fetch::initTestCase() |
|
66 { |
|
67 } |
|
68 |
|
69 void ut_qtcontacts_fetch::cleanupTestCase() |
|
70 { |
|
71 } |
|
72 |
|
73 void ut_qtcontacts_fetch::init() |
|
74 { |
|
75 } |
|
76 |
|
77 void ut_qtcontacts_fetch::cleanup() |
|
78 { |
|
79 waiting = false; |
|
80 } |
|
81 |
|
82 void ut_qtcontacts_fetch::doNextOperation() |
|
83 { |
|
84 qDebug() << "ut_qtcontacts_fetch::doNextOperation(): state=" << state; |
|
85 |
|
86 switch(state) { |
|
87 case STATE_START: |
|
88 //qDebug() << "debug: ut_testAddContact"; |
|
89 //Make sure that the contact is not already in the database. |
|
90 getExistingContact(); |
|
91 |
|
92 //Block (allowing the mainloop to run) until we have finished. |
|
93 waitForStop(); |
|
94 break; |
|
95 case STATE_INITIAL_EXISTING_FETCHED: |
|
96 removeContact(); |
|
97 break; |
|
98 case STATE_INITIAL_EXISTING_REMOVED: |
|
99 addContact(); |
|
100 break; |
|
101 case STATE_CONTACT_SAVED: |
|
102 //Get the contact, to check that the save worked: |
|
103 getExistingContact(true /* any_contact */); |
|
104 break; |
|
105 case STATE_AFTER_SAVE_FETCHED_FOR_CHECK: |
|
106 checkSavedContact(); |
|
107 break; |
|
108 case STATE_AFTER_SAVE_CHECKED: |
|
109 //Get the saved contact, to remove it, to restore original conditions: |
|
110 getExistingContact(); |
|
111 break; |
|
112 case STATE_AFTER_SAVE_FETCHED_FOR_REMOVAL: |
|
113 removeContact(); |
|
114 break; |
|
115 case STATE_SAVED_CONTACT_REMOVED: |
|
116 //Allow our actual test function to return: |
|
117 waiting = false; //Make waitForStop() return. |
|
118 break; |
|
119 default: |
|
120 qDebug() << "ut_qtcontacts_fetch::doNextOperation(): Unexpected state: " << state; |
|
121 waiting = false; |
|
122 break; |
|
123 } |
|
124 } |
|
125 |
|
126 bool ut_qtcontacts_fetch::waitForStop() |
|
127 { |
|
128 waiting = true; |
|
129 |
|
130 const int max_secs = 100000; |
|
131 |
|
132 // wait for signal |
|
133 int i = 0; |
|
134 while(waiting && i++ < max_secs) { |
|
135 // Allow the mainloop to run: |
|
136 QTest::qWait(10); |
|
137 } |
|
138 |
|
139 return !waiting; |
|
140 } |
|
141 |
|
142 QContactManager* ut_qtcontacts_fetch::getContactManager() |
|
143 { |
|
144 static QContactManager manager("tracker"); |
|
145 return &manager; |
|
146 } |
|
147 |
|
148 void ut_qtcontacts_fetch::onContactFetchRequestProgress() |
|
149 { |
|
150 if (!contactFetchRequest.isFinished()) |
|
151 return; |
|
152 |
|
153 qDebug() << "onContactFetchRequestProgress: state=: " << state; |
|
154 |
|
155 //Store the contact so the callback can use it. |
|
156 if(!(contactFetchRequest.contacts().isEmpty())) { |
|
157 contact = contactFetchRequest.contacts()[0]; |
|
158 QVERIFY(contact.localId() != 0); |
|
159 } |
|
160 |
|
161 qDebug() << "debug: fetched localId=" << contact.localId(); |
|
162 |
|
163 //Avoid more slot calls, though this is unlikely because it has finished. |
|
164 if(contactFetchRequest.isActive()) { |
|
165 const bool cancelled = contactFetchRequest.cancel(); |
|
166 Q_ASSERT(cancelled); |
|
167 } |
|
168 |
|
169 //Choose the next state and do the next appropriate operation: |
|
170 if(state == STATE_START) |
|
171 state = STATE_INITIAL_EXISTING_FETCHED; //Or not found. |
|
172 else if(state == STATE_CONTACT_SAVED) |
|
173 state = STATE_AFTER_SAVE_FETCHED_FOR_CHECK; //Or not found. |
|
174 else if(state == STATE_AFTER_SAVE_CHECKED) |
|
175 state = STATE_AFTER_SAVE_FETCHED_FOR_REMOVAL; |
|
176 else { |
|
177 qDebug() << "ut_qtcontacts_fetch::onContactFetchRequestProgress(): Ignoring unexpected state: " << state |
|
178 << " (Probably due to progress callbacks even after contactFetchRequest.cancel())"; |
|
179 return; |
|
180 } |
|
181 QTimer::singleShot(1000, this, SLOT(doNextOperation())); |
|
182 } |
|
183 |
|
184 |
|
185 void ut_qtcontacts_fetch::getExistingContact(bool any_contact) |
|
186 { |
|
187 qDebug() << "getExistingContact: state=: " << state; |
|
188 QContactManager* manager = getContactManager(); |
|
189 Q_ASSERT(manager); |
|
190 |
|
191 // Stop pending fetch requests |
|
192 if (contactFetchRequest.isActive()) |
|
193 contactFetchRequest.cancel(); |
|
194 |
|
195 //Initialize the result: |
|
196 contact = QContact(); |
|
197 |
|
198 //TODO: How can we AND on both the first and last name? |
|
199 connect(&contactFetchRequest, SIGNAL(resultsAvailable()), |
|
200 SLOT(onContactFetchRequestProgress())); |
|
201 |
|
202 if(!any_contact) { |
|
203 QContactDetailFilter nameFilter; |
|
204 nameFilter.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldFirst); |
|
205 nameFilter.setValue(QLatin1String(TESTNAME_FIRST)); |
|
206 nameFilter.setMatchFlags(QContactFilter::MatchExactly); |
|
207 contactFetchRequest.setManager(manager); |
|
208 contactFetchRequest.setFilter(nameFilter); |
|
209 } |
|
210 |
|
211 //qDebug() << "debug: start request"; |
|
212 contactFetchRequest.start(); |
|
213 } |
|
214 |
|
215 //This is our actual test function: |
|
216 void ut_qtcontacts_fetch::ut_testAddContact() |
|
217 { |
|
218 state = STATE_START; |
|
219 doNextOperation(); |
|
220 } |
|
221 |
|
222 void ut_qtcontacts_fetch::removeContact() |
|
223 { |
|
224 qDebug() << "ut_qtcontacts_fetch::removeContact(): state:" << state; |
|
225 |
|
226 if (contact.localId() != 0) { //If it was found. |
|
227 //qDebug() << "debug: Removing the existing contact, if it exists."; |
|
228 QContactManager* manager = getContactManager(); |
|
229 Q_ASSERT(manager); |
|
230 |
|
231 //TODO: Find and use an async API that tells us when it has finished. |
|
232 qDebug() << " ut_qtcontacts_fetch::removeContact(): removing localID=" << contact.localId(); |
|
233 manager->removeContact(contact.localId()); |
|
234 } |
|
235 |
|
236 //Choose the next state and do the next appropriate operation: |
|
237 if(state == STATE_INITIAL_EXISTING_FETCHED) |
|
238 state = STATE_INITIAL_EXISTING_REMOVED; |
|
239 else if(state == STATE_AFTER_SAVE_FETCHED_FOR_REMOVAL) //Or not found. |
|
240 state = STATE_SAVED_CONTACT_REMOVED; |
|
241 else |
|
242 qDebug() << "ut_qtcontacts_fetch::removeContact: Unexpected state."; |
|
243 |
|
244 QTimer::singleShot(1000, this, SLOT(doNextOperation())); |
|
245 } |
|
246 |
|
247 void ut_qtcontacts_fetch::addContact() |
|
248 { |
|
249 //qDebug() << "debug: Trying to add contact."; |
|
250 |
|
251 // Offer a UI to edit a prefilled contact. |
|
252 QContactName name; |
|
253 name.setFirstName(QLatin1String(TESTNAME_FIRST)); |
|
254 name.setLastName(QLatin1String(TESTNAME_LAST)); |
|
255 //TODO: Find and use an async API that tells us when it has finished. |
|
256 contact.saveDetail(&name); |
|
257 //const bool saved = contact.saveDetail(&name); |
|
258 //Q_ASSERT(saved); //This won't necessarily be useful because our implementation doesn't support sync methods. |
|
259 |
|
260 //Save the contact. |
|
261 //But note that our QContactManager backend does not set localId when returning. |
|
262 QContactManager* manager = getContactManager(); |
|
263 Q_ASSERT(manager); |
|
264 |
|
265 |
|
266 //manager->saveContact(&contact); |
|
267 //This works too: |
|
268 QContact copy(contact); |
|
269 manager->saveContact(©); |
|
270 |
|
271 //Check that it was really saved: |
|
272 //qDebug() << "debug: checking that the contact was saved."; |
|
273 state = STATE_CONTACT_SAVED; |
|
274 QTimer::singleShot(1000, this, SLOT(doNextOperation())); |
|
275 } |
|
276 |
|
277 void ut_qtcontacts_fetch::checkSavedContact() |
|
278 { |
|
279 //Check that it was really saved: |
|
280 // The ContactManager::saveContact() documentation suggests that localeId=0 is for non-saved contacts. |
|
281 QVERIFY(contact.localId() != 0); |
|
282 |
|
283 //Check that the correct details were saved: |
|
284 const QContactName name = contact.detail<QContactName>(); |
|
285 QVERIFY(name.firstName() == QLatin1String(TESTNAME_FIRST)); |
|
286 QVERIFY(name.lastName() == QLatin1String(TESTNAME_LAST)); |
|
287 |
|
288 qDebug() << "ut_qtcontacts_fetch::checkSavedContact(): found contact: firstName=" << name.firstName() << |
|
289 ", lastName=" << name.lastName(); |
|
290 |
|
291 //Try to restore original conditions: |
|
292 state = STATE_AFTER_SAVE_CHECKED; |
|
293 doNextOperation(); |
|
294 } |
|
295 |
|
296 |
|
297 QTEST_MAIN(ut_qtcontacts_fetch) |
|