1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #include "placemanager_utils.h"
30 
31 #include <QtCore/QDebug>
32 #include <QtLocation/QPlace>
33 #include <QtLocation/QPlaceManager>
34 #include <QtLocation/QPlaceSearchReply>
35 #include <QtLocation/QPlaceResult>
36 #include <QtTest/QSignalSpy>
37 #include <QtTest/QTest>
38 
39 //constant for timeout to verify signals
40 const int PlaceManagerUtils::Timeout(10000);
41 
PlaceManagerUtils(QObject * parent)42 PlaceManagerUtils::PlaceManagerUtils(QObject *parent)
43     : QObject(parent), placeManager(0)
44 {
45 }
46 
doSavePlace(QPlaceManager * manager,const QPlace & place,QPlaceReply::Error expectedError,QString * placeId)47 bool PlaceManagerUtils::doSavePlace(QPlaceManager *manager,
48                                     const QPlace &place,
49                                     QPlaceReply::Error expectedError,
50                                     QString *placeId)
51 {
52     Q_ASSERT(manager);
53     QPlaceIdReply *saveReply = manager->savePlace(place);
54     bool isSuccessful = checkSignals(saveReply, expectedError, manager);
55     if (placeId != 0) {
56         *placeId = saveReply->id();
57     }
58 
59     if (saveReply->id().isEmpty() && expectedError == QPlaceReply::NoError) {
60         qWarning("ID is empty in reply for save operation");
61         qWarning() << "Error string = " << saveReply->errorString();
62         isSuccessful = false;
63     }
64 
65     if (!isSuccessful)
66         qWarning() << "Error string = " << saveReply->errorString();
67 
68     return isSuccessful;
69 }
70 
doSavePlaces(QPlaceManager * manager,QList<QPlace> & places)71 void PlaceManagerUtils::doSavePlaces(QPlaceManager *manager, QList<QPlace> &places)
72 {
73     QPlaceIdReply *saveReply;
74 
75     foreach (QPlace place, places) {
76         saveReply = manager->savePlace(place);
77         QSignalSpy saveSpy(saveReply, SIGNAL(finished()));
78         QTRY_VERIFY_WITH_TIMEOUT(saveSpy.count() == 1, Timeout);
79         QCOMPARE(saveReply->error(), QPlaceReply::NoError);
80         saveSpy.clear();
81     }
82 }
83 
doSavePlaces(QPlaceManager * manager,const QList<QPlace * > & places)84 void PlaceManagerUtils::doSavePlaces(QPlaceManager *manager, const QList<QPlace *> &places)
85 {
86     QPlaceIdReply *saveReply;
87 
88     static int count= 0;
89     foreach (QPlace *place, places) {
90         count++;
91         saveReply = manager->savePlace(*place);
92         QSignalSpy saveSpy(saveReply, SIGNAL(finished()));
93         QTRY_VERIFY_WITH_TIMEOUT(saveSpy.count() == 1, Timeout);
94         QCOMPARE(saveReply->error(), QPlaceReply::NoError);
95         place->setPlaceId(saveReply->id());
96         saveSpy.clear();
97     }
98 }
99 
doSearch(QPlaceManager * manager,const QPlaceSearchRequest & request,QList<QPlaceSearchResult> * results,QPlaceReply::Error expectedError)100 bool PlaceManagerUtils::doSearch(QPlaceManager *manager,
101                                 const QPlaceSearchRequest &request,
102                                  QList<QPlaceSearchResult> *results,
103                                  QPlaceReply::Error expectedError)
104 {
105     QPlaceSearchReply *searchReply= manager->search(request);
106     bool success = checkSignals(searchReply, expectedError, manager);
107     *results = searchReply->results();
108     return success;
109 }
110 
doSearch(QPlaceManager * manager,const QPlaceSearchRequest & request,QList<QPlace> * results,QPlaceReply::Error expectedError)111 bool PlaceManagerUtils::doSearch(QPlaceManager *manager,
112                                        const QPlaceSearchRequest &request,
113                                        QList<QPlace> *results, QPlaceReply::Error expectedError)
114 {
115     bool success = false;
116     results->clear();
117     QList<QPlaceSearchResult> searchResults;
118     success = doSearch(manager, request, &searchResults, expectedError);
119     foreach (const QPlaceSearchResult &searchResult, searchResults) {
120         if (searchResult.type() == QPlaceSearchResult::PlaceResult) {
121             QPlaceResult placeResult = searchResult;
122             results->append(placeResult.place());
123         }
124     }
125     return success;
126 }
127 
doSearchSuggestions(QPlaceManager * manager,const QPlaceSearchRequest & request,QStringList * results,QPlaceReply::Error expectedError)128 bool PlaceManagerUtils::doSearchSuggestions(QPlaceManager *manager,
129                                             const QPlaceSearchRequest &request,
130                                             QStringList *results,
131                                             QPlaceReply::Error expectedError)
132 {
133     QPlaceSearchSuggestionReply *reply = manager->searchSuggestions(request);
134     bool success = checkSignals(reply, expectedError, manager);
135     *results = reply->suggestions();
136 
137     if (!success)
138         qDebug() << "Error string = " << reply->errorString();
139 
140     return success;
141 }
142 
doRemovePlace(QPlaceManager * manager,const QPlace & place,QPlaceReply::Error expectedError)143 bool PlaceManagerUtils::doRemovePlace(QPlaceManager *manager,
144                                       const QPlace &place,
145                                       QPlaceReply::Error expectedError)
146 {
147     QPlaceIdReply *removeReply = manager->removePlace(place.placeId());
148     bool isSuccessful = false;
149     isSuccessful = checkSignals(removeReply, expectedError, manager)
150                     && (removeReply->id() == place.placeId());
151 
152     if (!isSuccessful)
153         qWarning() << "Place removal unsuccessful errorString = " << removeReply->errorString();
154 
155     return isSuccessful;
156 }
157 
doFetchDetails(QPlaceManager * manager,QString placeId,QPlace * place,QPlaceReply::Error expectedError)158 bool PlaceManagerUtils::doFetchDetails(QPlaceManager *manager,
159                                              QString placeId, QPlace *place,
160                                              QPlaceReply::Error expectedError)
161 {
162     QPlaceDetailsReply *detailsReply = manager->getPlaceDetails(placeId);
163     bool success = checkSignals(detailsReply, expectedError, manager);
164     *place = detailsReply->place();
165 
166     if (!success)
167         qDebug() << "Error string = " << detailsReply->errorString();
168 
169     return success;
170 }
171 
doInitializeCategories(QPlaceManager * manager,QPlaceReply::Error expectedError)172 bool PlaceManagerUtils::doInitializeCategories(QPlaceManager *manager,
173                                                QPlaceReply::Error expectedError)
174 {
175     QPlaceReply *reply = manager->initializeCategories();
176     bool success = checkSignals(reply, expectedError, manager);
177 
178     if (!success)
179         qDebug() << "Error string = " << reply->errorString();
180 
181     delete reply;
182     return success;
183 }
184 
doSaveCategory(QPlaceManager * manager,const QPlaceCategory & category,const QString & parentId,QPlaceReply::Error expectedError,QString * categoryId)185 bool PlaceManagerUtils::doSaveCategory(QPlaceManager *manager,
186                                        const QPlaceCategory &category,
187                                        const QString &parentId,
188                                        QPlaceReply::Error expectedError,
189                                        QString *categoryId)
190 {
191     QPlaceIdReply *idReply = manager->saveCategory(category, parentId);
192     bool isSuccessful = checkSignals(idReply, expectedError, manager)
193                         && (idReply->error() == expectedError);
194 
195     if (categoryId != 0)
196         *categoryId = idReply->id();
197 
198     if (!isSuccessful)
199         qDebug() << "Error string =" << idReply->errorString();
200     return isSuccessful;
201 }
202 
doRemoveCategory(QPlaceManager * manager,const QPlaceCategory & category,QPlaceReply::Error expectedError)203 bool PlaceManagerUtils::doRemoveCategory(QPlaceManager *manager,
204                                          const QPlaceCategory &category,
205                                          QPlaceReply::Error expectedError)
206 {
207     QPlaceIdReply *idReply = manager->removeCategory(category.categoryId());
208 
209     bool isSuccessful = checkSignals(idReply, expectedError, manager) &&
210                         (idReply->error() == expectedError);
211     return isSuccessful;
212 }
213 
doFetchCategory(QPlaceManager * manager,const QString & categoryId,QPlaceCategory * category,QPlaceReply::Error expectedError)214 bool PlaceManagerUtils::doFetchCategory(QPlaceManager *manager,
215                                         const QString &categoryId,
216                                         QPlaceCategory *category,
217                                         QPlaceReply::Error expectedError)
218 {
219     Q_ASSERT(category);
220     QPlaceReply * catInitReply = manager->initializeCategories();
221     bool isSuccessful = checkSignals(catInitReply, expectedError, manager);
222     *category = manager->category(categoryId);
223 
224     if (!isSuccessful)
225         qDebug() << "Error initializing categories, error string = "
226                  << catInitReply->errorString();
227 
228     if (category->categoryId() != categoryId)
229         isSuccessful = false;
230     return isSuccessful;
231 }
232 
doFetchContent(QPlaceManager * manager,const QPlaceContentRequest & request,QPlaceContent::Collection * results,QPlaceReply::Error expectedError)233 bool PlaceManagerUtils::doFetchContent(QPlaceManager *manager,
234                                        const QPlaceContentRequest &request,
235                                        QPlaceContent::Collection *results,
236                                        QPlaceReply::Error expectedError)
237 {
238     Q_ASSERT(results);
239     QPlaceContentReply *reply = manager->getPlaceContent(request);
240     bool isSuccessful = checkSignals(reply, expectedError, manager);
241     *results = reply->content();
242 
243     if (!isSuccessful)
244         qDebug() << "Error during content fetch, error string = "
245                  << reply->errorString();
246 
247     return isSuccessful;
248 }
249 
doMatch(QPlaceManager * manager,const QPlaceMatchRequest & request,QList<QPlace> * places,QPlaceReply::Error expectedError)250 bool PlaceManagerUtils::doMatch(QPlaceManager *manager,
251                                 const QPlaceMatchRequest &request,
252                                 QList<QPlace> *places,
253                                 QPlaceReply::Error expectedError)
254 {
255     QPlaceMatchReply *reply = manager->matchingPlaces(request);
256     bool isSuccessful = checkSignals(reply, expectedError, manager) &&
257             (reply->error() == expectedError);
258     *places = reply->places();
259     if (!isSuccessful)
260         qDebug() << "Error for matching operation, error string = "
261                  << reply->errorString();
262     return isSuccessful;
263 }
264 
checkSignals(QPlaceReply * reply,QPlaceReply::Error expectedError,QPlaceManager * manager)265 bool PlaceManagerUtils::checkSignals(QPlaceReply *reply, QPlaceReply::Error expectedError,
266                                            QPlaceManager *manager)
267 {
268     Q_ASSERT(reply);
269     QSignalSpy finishedSpy(reply, SIGNAL(finished()));
270     QSignalSpy errorSpy(reply, SIGNAL(error(QPlaceReply::Error,QString)));
271     QSignalSpy managerFinishedSpy(manager, SIGNAL(finished(QPlaceReply*)));
272     QSignalSpy managerErrorSpy(manager,SIGNAL(error(QPlaceReply*,QPlaceReply::Error,QString)));
273 
274     if (expectedError != QPlaceReply::NoError) {
275         //check that we get an error signal from the reply
276         WAIT_UNTIL(errorSpy.count() == 1);
277         if (errorSpy.count() != 1) {
278             qWarning() << "Error signal for search operation not received";
279             return false;
280         }
281 
282         //check that we get the correct error from the reply's signal
283         QPlaceReply::Error actualError = qvariant_cast<QPlaceReply::Error>(errorSpy.at(0).at(0));
284         if (actualError != expectedError) {
285             qWarning() << "Actual error code in reply signal does not match expected error code";
286             qWarning() << "Actual error code = " << actualError;
287             qWarning() << "Expected error coe =" << expectedError;
288             return false;
289         }
290 
291         //check that we get an error  signal from the manager
292         WAIT_UNTIL(managerErrorSpy.count() == 1);
293         if (managerErrorSpy.count() !=1) {
294            qWarning() << "Error signal from manager for search operation not received";
295            return false;
296         }
297 
298         //check that we get the correct reply instance in the error signal from the manager
299         if (qvariant_cast<QPlaceReply*>(managerErrorSpy.at(0).at(0)) != reply)  {
300             qWarning() << "Reply instance in error signal from manager is incorrect";
301             return false;
302         }
303 
304         //check that we get the correct error from the signal of the manager
305         actualError = qvariant_cast<QPlaceReply::Error>(managerErrorSpy.at(0).at(1));
306         if (actualError != expectedError) {
307             qWarning() << "Actual error code from manager signal does not match expected error code";
308             qWarning() << "Actual error code =" << actualError;
309             qWarning() << "Expected error code = " << expectedError;
310             return false;
311         }
312     }
313 
314     //check that we get a finished signal
315     WAIT_UNTIL(finishedSpy.count() == 1);
316     if (finishedSpy.count() !=1) {
317         qWarning() << "Finished signal from reply not received";
318         return false;
319     }
320 
321     if (reply->error() != expectedError) {
322         qWarning() << "Actual error code does not match expected error code";
323         qWarning() << "Actual error code: " << reply->error();
324         qWarning() << "Expected error code" << expectedError;
325         return false;
326     }
327 
328     if (expectedError == QPlaceReply::NoError && !reply->errorString().isEmpty()) {
329         qWarning() << "Expected error was no error but error string was not empty";
330         qWarning() << "Error string=" << reply->errorString();
331         return false;
332     }
333 
334     //check that we get the finished signal from the manager
335     WAIT_UNTIL(managerFinishedSpy.count() == 1);
336     if (managerFinishedSpy.count() != 1) {
337         qWarning() << "Finished signal from manager not received";
338         return false;
339     }
340 
341     //check that the reply instance in the finished signal from the manager is correct
342     if (qvariant_cast<QPlaceReply *>(managerFinishedSpy.at(0).at(0)) != reply) {
343         qWarning() << "Reply instance in finished signal from manager is incorrect";
344         return false;
345     }
346 
347     return true;
348 }
349 
compare(const QList<QPlace> & actualResults,const QList<QPlace> & expectedResults)350 bool PlaceManagerUtils::compare(const QList<QPlace> &actualResults,
351                                       const QList<QPlace> &expectedResults)
352 {
353     QSet<QString> actualIds;
354     foreach (const QPlace &place, actualResults)
355         actualIds.insert(place.placeId());
356 
357     QSet<QString> expectedIds;
358     foreach (const QPlace &place, expectedResults)
359         expectedIds.insert(place.placeId());
360 
361     bool isMatch = (actualIds == expectedIds);
362     if (actualResults.count() != expectedResults.count() || !isMatch) {
363         qWarning() << "comparison of results by name does not match";
364         qWarning() << "actual result ids: " << actualIds;
365         qWarning() << "expected result ids : " << expectedIds;
366         return false;
367     }
368 
369     return isMatch;
370 }
371 
setVisibility(QList<QPlace * > places,QLocation::Visibility visibility)372 void PlaceManagerUtils::setVisibility(QList<QPlace *> places, QLocation::Visibility visibility)
373 {
374     foreach (QPlace *place, places)
375         place->setVisibility(visibility);
376 }
377