Update license headers of new unit tests
[qtcontacts-tracker:qtcontacts-tracker.git] / tests / ut_qtcontacts_fetch / ut_qtcontacts_fetch.cpp
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(&copy);
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)