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 <QCoreApplication>
30#include <QString>
31#include <QtTest/QtTest>
32
33#if QT_CONFIG(process)
34#include <QtCore/QProcessEnvironment>
35#endif
36#include <QtPositioning/QGeoCircle>
37#include <QtLocation/QGeoServiceProvider>
38#include <QtLocation/QPlaceEditorial>
39#include <QtLocation/QPlaceImage>
40#include <QtLocation/QPlaceManager>
41#include <QtLocation/QPlaceResult>
42#include <QtLocation/QPlaceReview>
43#include <QtLocation/QPlaceSearchReply>
44#include "../../placemanager_utils/placemanager_utils.h"
45
46QT_USE_NAMESPACE
47
48class tst_QPlaceManagerNokia : public PlaceManagerUtils
49{
50 Q_OBJECT
51public:
52 enum ExpectedResults {
53 AnyResults, //zero or more results expected
54 SomeResults, //at least one result expected
55 NoResults // zero results expected
56 };
57
58 tst_QPlaceManagerNokia();
59
60private Q_SLOTS:
61 void initTestCase();
62 void search();
63 void search_data();
64 void searchResultFields();
65 void recommendations();
66 void recommendations_data();
67 void details();
68 void categories();
69 void suggestions();
70 void suggestions_data();
71 void suggestionsMisc();
72 void locale();
73 void content();
74 void content_data();
75 void unsupportedFunctions();
76
77private:
78 void commonAreas(QList<QByteArray> *dataTags, QList<QGeoShape> *areas,
79 QList<QPlaceReply::Error> *errors,
80 QList<ExpectedResults> *results);
81
82 static const QLatin1String ValidKnownPlaceId;
83 static const QLatin1String ProxyEnv;
84 static const QLatin1String AppIdEnv;
85 static const QLatin1String TokenEnv;
86
87 QGeoServiceProvider *provider;
88};
89
90Q_DECLARE_METATYPE(tst_QPlaceManagerNokia::ExpectedResults)
91
92// ValidKnownPlaceId is the id of a place with a full complement of place content. Editorials,
93// reviews, images, recommendations. If it disappears these tests will fail.
94// Currently it is set to an Eiffel Tower tourist office.
95const QLatin1String tst_QPlaceManagerNokia::ValidKnownPlaceId("250u09tu-4561b8da952f4fd79c4e1998c3fcf032");
96
97const QLatin1String tst_QPlaceManagerNokia::ProxyEnv("NOKIA_PLUGIN_PROXY");
98const QLatin1String tst_QPlaceManagerNokia::AppIdEnv("NOKIA_APPID");
99const QLatin1String tst_QPlaceManagerNokia::TokenEnv("NOKIA_TOKEN");
100
101tst_QPlaceManagerNokia::tst_QPlaceManagerNokia()
102{
103}
104
105void tst_QPlaceManagerNokia::initTestCase()
106{
107 QVariantMap params;
108 QStringList providers = QGeoServiceProvider::availableServiceProviders();
109 QVERIFY(providers.contains("here"));
110#if QT_CONFIG(process)
111 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
112
113 if (!(env.contains(name: AppIdEnv) && env.contains(name: TokenEnv)))
114 QSKIP("NOKIA_APPID and NOKIA_TOKEN environment variables not set");\
115
116 params.insert(QStringLiteral("here.app_id"), avalue: env.value(name: AppIdEnv));
117 params.insert(QStringLiteral("here.token"), avalue: env.value(name: TokenEnv));
118
119 if (env.contains(name: ProxyEnv))
120 params.insert(QStringLiteral("here.proxy"), avalue: env.value(name: ProxyEnv));
121#else
122 QSKIP("Cannot parse process environment, NOKIA_APPID and NOKIA_TOKEN not set");
123#endif
124 provider = new QGeoServiceProvider("here", params);
125 placeManager = provider->placeManager();
126 QVERIFY(placeManager);
127}
128
129void tst_QPlaceManagerNokia::search()
130{
131 QFETCH(QGeoShape, area);
132 QFETCH(QString, searchTerm);
133 QFETCH(QList<QPlaceCategory>, categories);
134 QFETCH(QPlaceReply::Error, error);
135 QFETCH(ExpectedResults, expectedResults);
136
137 QPlaceSearchRequest searchRequest;
138 searchRequest.setSearchArea(area);
139 searchRequest.setSearchTerm(searchTerm);
140 if (categories.count() == 1)
141 searchRequest.setCategory(categories.first());
142 else
143 searchRequest.setCategories(categories);
144
145 QList<QPlace> results;
146 QVERIFY(doSearch(searchRequest, &results, error));
147
148 if (expectedResults == NoResults)
149 QVERIFY(results.count() == 0);
150 else if (expectedResults == SomeResults)
151 QVERIFY(results.count() > 0);
152}
153
154void tst_QPlaceManagerNokia::search_data()
155{
156 QTest::addColumn<QGeoShape>(name: "area");
157 QTest::addColumn<QString>(name: "searchTerm");
158 QTest::addColumn<QList<QPlaceCategory> >(name: "categories");
159 QTest::addColumn<QPlaceSearchRequest::RelevanceHint>(name: "hint");
160 QTest::addColumn<QPlaceReply::Error> (name: "error");
161 QTest::addColumn<ExpectedResults>(name: "expectedResults");
162
163 for (int i = 0; i < 3; i++) {
164 QByteArray suffix;
165 QGeoShape area;
166 if (i==0) {
167 area = QGeoCircle(QGeoCoordinate(-27.5, 153));
168 suffix = " (Circle - center only)";
169 } else if (i==1) {
170 area = QGeoCircle(QGeoCoordinate(-27.5, 153), 5000);
171 suffix = " (Circle - with radius specified)";
172 } else {
173 area = QGeoRectangle(QGeoCoordinate(-26.5, 152), QGeoCoordinate(-28.5, 154));
174 suffix = " (Rectangle)";
175 }
176
177 QByteArray dataTag = QByteArray("coordinate only") + suffix;
178 QTest::newRow(dataTag) << area
179 << QString()
180 << QList<QPlaceCategory>()
181 << QPlaceSearchRequest::UnspecifiedHint
182 << QPlaceReply::NoError
183 << SomeResults;
184
185 dataTag = QByteArray("seach term") + suffix;
186 QTest::newRow(dataTag) << area
187 << "sushi"
188 << QList<QPlaceCategory>()
189 << QPlaceSearchRequest::UnspecifiedHint
190 << QPlaceReply::NoError
191 << SomeResults;
192
193 QPlaceCategory eatDrinkCat;
194 eatDrinkCat.setCategoryId(QStringLiteral("eat-drink"));
195 dataTag = QByteArray("single valid category") + suffix;
196 QTest::newRow(dataTag) << area
197 << QString()
198 << (QList<QPlaceCategory>()
199 << eatDrinkCat)
200 << QPlaceSearchRequest::UnspecifiedHint
201 << QPlaceReply::NoError
202 << SomeResults;
203
204 QPlaceCategory accommodationCat;
205 accommodationCat.setCategoryId(QStringLiteral("accommodation"));
206 dataTag = QByteArray("multiple valid categories") + suffix;
207 QTest::newRow(dataTag) << area
208 << QString()
209 << (QList<QPlaceCategory>()
210 << eatDrinkCat
211 << accommodationCat)
212 << QPlaceSearchRequest::UnspecifiedHint
213 << QPlaceReply::NoError
214 << SomeResults;
215
216 QPlaceCategory nonExistentCat;
217 nonExistentCat.setCategoryId(QStringLiteral("klingon cuisine"));
218 dataTag = QByteArray("non-existent category") + suffix;
219 QTest::newRow(dataTag) << area
220 << QString()
221 << (QList<QPlaceCategory>()
222 << nonExistentCat)
223 << QPlaceSearchRequest::UnspecifiedHint
224 << QPlaceReply::NoError
225 << NoResults;
226
227 dataTag = QByteArray("search term and category") + suffix;
228 QTest::newRow(dataTag) << area
229 << "sushi"
230 << (QList<QPlaceCategory>()
231 << eatDrinkCat)
232 << QPlaceSearchRequest::UnspecifiedHint
233 << QPlaceReply::BadArgumentError
234 << NoResults;
235 }
236
237
238 //invalid areas and boundary testing
239 QList<QByteArray> dataTags;
240 QList<QGeoShape> areas;
241 QList<QPlaceReply::Error> errors;
242 QList<ExpectedResults> results;
243 commonAreas(dataTags: &dataTags, areas: &areas, errors: &errors, results: &results);
244
245 for (int i = 0; i < dataTags.count(); ++i) {
246 QTest::newRow(dataTag: dataTags.at(i)) << areas.at(i)
247 << "sushi"
248 << QList<QPlaceCategory>()
249 << QPlaceSearchRequest::UnspecifiedHint
250 << errors.at(i)
251 << results.at(i);
252 }
253
254 //relevancy hints will be ignored by the backend, but should give a valid result
255 QTest::newRow(dataTag: "check using a distance relevancy hint")
256 << static_cast<QGeoShape>(QGeoCircle(QGeoCoordinate(-27.5, 153)))
257 << QStringLiteral("sushi")
258 << QList<QPlaceCategory>()
259 << QPlaceSearchRequest::DistanceHint
260 << QPlaceReply::NoError
261 << AnyResults;
262
263 QTest::newRow(dataTag: "check using lexical place name hint")
264 << static_cast<QGeoShape>(QGeoCircle(QGeoCoordinate(-27.5, 153)))
265 << QStringLiteral("sushi")
266 << QList<QPlaceCategory>()
267 << QPlaceSearchRequest::LexicalPlaceNameHint
268 << QPlaceReply::NoError
269 << AnyResults;
270}
271
272void tst_QPlaceManagerNokia::searchResultFields()
273{
274 //check that using a distance relevancy hint will give a valid result
275 //even though it will be ignored by the backend.
276 QPlaceSearchRequest searchRequest;
277 searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(-27.5, 153)));
278 searchRequest.setSearchTerm(QStringLiteral("sushi"));
279
280 QPlaceSearchReply *reply = placeManager->search(query: searchRequest);
281 QSignalSpy spy(reply, SIGNAL(finished()));
282 QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, Timeout);
283 QVERIFY(reply->results().count() > 0);
284
285 //check that search results have basic data filled in
286 QPlaceResult result= reply->results().at(i: 0);
287 QVERIFY(!result.title().isEmpty());
288 QVERIFY(!result.icon().url().isEmpty());
289 QVERIFY(!qIsNaN(result.distance()));
290 QVERIFY(!result.place().name().isEmpty());
291 QVERIFY(result.place().location().coordinate().isValid());
292 QVERIFY(!result.place().location().address().text().isEmpty());
293 QVERIFY(!result.place().location().address().isTextGenerated());
294 QVERIFY(result.place().categories().count() == 1);//only primary category retrieved on
295 //search
296
297 //sponsored and ratings fields are optional and thus have not been explicitly tested.
298}
299
300void tst_QPlaceManagerNokia::recommendations()
301{
302 QFETCH(QString, recommendationId);
303 QFETCH(QString, searchTerm);
304 QFETCH(QGeoShape, searchArea);
305 QFETCH(QList<QPlaceCategory>, categories);
306 QFETCH(QPlaceReply::Error, error);
307
308 QPlaceSearchRequest searchRequest;
309 searchRequest.setRecommendationId(recommendationId);
310 searchRequest.setSearchTerm(searchTerm);
311 searchRequest.setSearchArea(searchArea);
312 searchRequest.setCategories(categories);
313
314 QList<QPlace> results;
315 QVERIFY(doSearch(searchRequest, &results, error));
316
317 if (error == QPlaceReply::NoError)
318 QVERIFY(results.count() > 0);
319}
320
321void tst_QPlaceManagerNokia::recommendations_data()
322{
323 QTest::addColumn<QString>(name: "recommendationId");
324 QTest::addColumn<QString>(name: "searchTerm");
325 QTest::addColumn<QGeoShape>(name: "searchArea");
326 QTest::addColumn<QList<QPlaceCategory> >(name: "categories");
327 QTest::addColumn<QPlaceReply::Error>(name: "error");
328
329 QPlaceCategory eatDrinkCat;
330 eatDrinkCat.setCategoryId(QStringLiteral("eat-drink"));
331
332 QTest::newRow(dataTag: "search recommendations with valid id")
333 << QString(ValidKnownPlaceId)
334 << QString()
335 << QGeoShape()
336 << QList<QPlaceCategory>()
337 << QPlaceReply::NoError;
338
339 QTest::newRow(dataTag: "search for recommendations with invalid id")
340 << QStringLiteral("does_not_exist_id")
341 << QString()
342 << QGeoShape()
343 << QList<QPlaceCategory>()
344 << QPlaceReply::PlaceDoesNotExistError;
345
346 QTest::newRow(dataTag: "search for recommendations with id and search term")
347 << QString(ValidKnownPlaceId)
348 << QStringLiteral("sushi")
349 << QGeoShape()
350 << QList<QPlaceCategory>()
351 << QPlaceReply::BadArgumentError;
352
353 QTest::newRow(dataTag: "search for recommendations with an id and category")
354 << QString(ValidKnownPlaceId)
355 << QString()
356 << QGeoShape()
357 << (QList<QPlaceCategory>() << eatDrinkCat)
358 << QPlaceReply::BadArgumentError;
359
360 QTest::newRow(dataTag: "search for recommendations with id, search term and category")
361 << QString(ValidKnownPlaceId)
362 << QStringLiteral("sushi")
363 << QGeoShape()
364 << (QList<QPlaceCategory>() << eatDrinkCat)
365 << QPlaceReply::BadArgumentError;
366
367 QTest::newRow(dataTag: "search for recommendations with an id and search area")
368 << QString(ValidKnownPlaceId)
369 << QString()
370 << static_cast<QGeoShape>(QGeoCircle(QGeoCoordinate(-27.5, 153)))
371 << QList<QPlaceCategory>()
372 << QPlaceReply::BadArgumentError;
373}
374
375void tst_QPlaceManagerNokia::details()
376{
377 QSKIP("Fetching details from HERE place server always fails - QTBUG-44837");
378 //fetch the details of a valid place
379 QPlace place;
380 QVERIFY(doFetchDetails(ValidKnownPlaceId, &place));
381 QVERIFY(!place.name().isEmpty());
382 QVERIFY(!place.icon().url().isEmpty());
383 QStringList contactTypes = place.contactTypes();
384 QVERIFY(!contactTypes.isEmpty());
385 foreach (const QString &contactType, contactTypes) {
386 QList<QPlaceContactDetail> details = place.contactDetails(contactType);
387 QVERIFY(details.count() > 0);
388 foreach (const QPlaceContactDetail &detail, details) {
389 QVERIFY(!detail.label().isEmpty());
390 QVERIFY(!detail.value().isEmpty());
391 }
392 }
393
394 QVERIFY(place.location().coordinate().isValid());
395 QVERIFY(!place.location().address().isEmpty());
396 QVERIFY(!place.location().address().text().isEmpty());
397 QVERIFY(!place.location().address().isTextGenerated());
398
399 QVERIFY(place.ratings().average() >= 1 && place.ratings().average() <= 5);
400 QVERIFY(place.ratings().maximum() == 5);
401 QVERIFY(place.ratings().count() > 0);
402
403 QVERIFY(place.categories().count() > 0);
404 foreach (const QPlaceCategory &category, place.categories()) {
405 QVERIFY(!category.name().isEmpty());
406 QVERIFY(!category.categoryId().isEmpty());
407 QVERIFY(!category.icon().url().isEmpty());
408 }
409
410 QVERIFY(!place.extendedAttributeTypes().isEmpty());
411 QVERIFY(place.visibility() == QLocation::PublicVisibility);
412 QVERIFY(place.detailsFetched());
413
414 //attributions are optional and thus have not been explicitly tested.
415
416 //fetch the details of a non-existent place
417 QVERIFY(doFetchDetails(QStringLiteral("does_not_exist"), &place,
418 QPlaceReply::PlaceDoesNotExistError));
419}
420
421void tst_QPlaceManagerNokia::categories()
422{
423 QVERIFY(doInitializeCategories());
424
425 QList<QPlaceCategory> categories = placeManager->childCategories();
426 QVERIFY(categories.count() > 0);
427 foreach (const QPlaceCategory &category, categories) {
428 //check that we have valid fields
429 QVERIFY(!category.categoryId().isEmpty());
430 QVERIFY(!category.name().isEmpty());
431 QVERIFY(!category.icon().url().isEmpty());
432
433 //check we can retrieve the very same category by id
434 QCOMPARE(placeManager->category(category.categoryId()), category);
435
436 //the here plugin supports a two-level level category tree
437 QVERIFY(placeManager->parentCategoryId(category.categoryId()).isEmpty());
438 const QList<QPlaceCategory> childCats =
439 placeManager->childCategories(parentId: category.categoryId());
440 if (!childCats.isEmpty()) {
441 foreach (const QPlaceCategory &child, childCats) {
442 // only two levels of categories hence 2.nd level has no further children
443 QVERIFY(placeManager->childCategories(child.categoryId()).isEmpty());
444 QVERIFY(placeManager->parentCategoryId(child.categoryId()) == category.categoryId());
445 }
446 }
447 }
448}
449
450void tst_QPlaceManagerNokia::suggestions()
451{
452 QFETCH(QGeoShape, area);
453 QFETCH(QString, searchTerm);
454 QFETCH(QPlaceReply::Error, error);
455 QFETCH(ExpectedResults, expectedResults);
456
457 QPlaceSearchRequest searchRequest;
458 searchRequest.setSearchArea(area);
459 searchRequest.setSearchTerm(searchTerm);
460
461 QStringList results;
462 QVERIFY(doSearchSuggestions(searchRequest, &results, error));
463
464 if (expectedResults == NoResults)
465 QVERIFY(results.count() == 0);
466 else if (expectedResults == SomeResults)
467 QVERIFY(results.count() > 0);
468}
469
470
471void tst_QPlaceManagerNokia::suggestions_data()
472{
473 QTest::addColumn<QGeoShape>(name: "area");
474 QTest::addColumn<QString>(name: "searchTerm");
475 QTest::addColumn<QPlaceReply::Error> (name: "error");
476 QTest::addColumn<ExpectedResults>(name: "expectedResults");
477
478 for (int i = 0; i < 3; i++) {
479 QByteArray suffix;
480 QGeoShape area;
481 if (i == 0) {
482 area = QGeoCircle(QGeoCoordinate(-27.5, 153));
483 suffix = " (Circle - center only)";
484 } else if (i == 1) {
485 area = QGeoCircle(QGeoCoordinate(-27.5, 153), 5000);
486 suffix = " (Circle - with radius specified)";
487 } else {
488 area = QGeoRectangle(QGeoCoordinate(-26.5, 152), QGeoCoordinate(-28.5, 154));
489 suffix = " (Rectangle)";
490 }
491
492 QByteArray dataTag = QByteArray("valid usage") + suffix;
493 QTest::newRow(dataTag) << area
494 << "sus"
495 << QPlaceReply::NoError
496 << SomeResults;
497 }
498
499 //invalid areas and boundary testing
500 QList<QByteArray> dataTags;
501 QList<QGeoShape> areas;
502 QList<QPlaceReply::Error> errors;
503 QList<ExpectedResults> results;
504 commonAreas(dataTags: &dataTags, areas: &areas, errors: &errors, results: &results);
505
506 for (int i = 0; i < dataTags.count(); ++i) {
507 QTest::newRow(dataTag: dataTags.at(i)) << areas.at(i)
508 << "sus"
509 << errors.at(i)
510 << results.at(i);
511 }
512
513 QTest::newRow(dataTag: "no text") << static_cast<QGeoShape>(QGeoCircle(QGeoCoordinate(-27.5, 153)))
514 << QString()
515 << QPlaceReply::NoError
516 << NoResults;
517}
518
519void tst_QPlaceManagerNokia::suggestionsMisc()
520{
521 //check providing a distance relevancy hint (should be ignored)
522 QPlaceSearchRequest searchRequest;
523 QStringList results;
524 searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(-27.5, 153)));
525 searchRequest.setSearchTerm(QStringLiteral("sus"));
526 searchRequest.setRelevanceHint(QPlaceSearchRequest::DistanceHint);
527 QVERIFY(doSearchSuggestions(searchRequest, &results, QPlaceReply::NoError));
528 QVERIFY(results.count() > 0);
529 searchRequest.clear();
530
531 //check porviding a lexical place name relevancy hint (should be ignored)
532 searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(-27.5, 153)));
533 searchRequest.setSearchTerm(QStringLiteral("sus"));
534 searchRequest.setRelevanceHint(QPlaceSearchRequest::LexicalPlaceNameHint);
535 QVERIFY(doSearchSuggestions(searchRequest, &results, QPlaceReply::NoError));
536 QVERIFY(results.count() > 0);
537 searchRequest.clear();
538
539 //check providing a category
540 QPlaceCategory eatDrinkCat;
541 eatDrinkCat.setCategoryId(QStringLiteral("eat-drink"));
542 searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(-27.5, 153)));
543 searchRequest.setSearchTerm(QStringLiteral("sus"));
544 searchRequest.setCategory(eatDrinkCat);
545 QVERIFY(doSearchSuggestions(searchRequest, &results, QPlaceReply::BadArgumentError));
546 QCOMPARE(results.count(), 0);
547 searchRequest.clear();
548
549 //check providing a recommendation id
550 searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(-27.5, 153)));
551 searchRequest.setSearchTerm(QStringLiteral("sus"));
552 searchRequest.setRecommendationId("id");
553 QVERIFY(doSearchSuggestions(searchRequest, &results, QPlaceReply::BadArgumentError));
554}
555
556void tst_QPlaceManagerNokia::locale()
557{
558 //check that the defualt locale is set
559 QCOMPARE(placeManager->locales().count(), 1);
560 QCOMPARE(placeManager->locales().at(0), QLocale());
561
562 //check that we can set different locales for the categories
563 placeManager->setLocale(QLocale("en"));
564 QVERIFY(doInitializeCategories());
565 QList<QPlaceCategory> enCategories = placeManager->childCategories();
566 QVERIFY(enCategories.count() > 0);
567
568 placeManager->setLocale(QLocale("fi"));
569 QVERIFY(doInitializeCategories());
570 QList<QPlaceCategory> fiCategories = placeManager->childCategories();
571
572 foreach (const QPlaceCategory enCat, enCategories) {
573 foreach (const QPlaceCategory fiCat, fiCategories) {
574 if (enCat.categoryId() == fiCat.categoryId()) {
575 QVERIFY(fiCat.name() != enCat.name());
576 QVERIFY(fiCat == placeManager->category(fiCat.categoryId()));
577 }
578 }
579 }
580
581 // we are skipping the check below because we are requesting
582 // details for a place without a search before. This implies
583 // URL templating must be possible which the HERE place
584 // server refuses.
585
586 QSKIP("remainder of test skipped due to QTBUG-44837");
587
588 //check that setting a locale will affect place detail fetches.
589 QPlace place;
590 placeManager->setLocale(QLocale("en"));
591 QVERIFY(doFetchDetails(ValidKnownPlaceId,
592 &place));
593 QString englishName = place.name();
594 placeManager->setLocale(QLocale("fr"));
595 QVERIFY(doFetchDetails(ValidKnownPlaceId,
596 &place));
597 QVERIFY(englishName != place.name());
598}
599
600void tst_QPlaceManagerNokia::content()
601{
602 QFETCH(QPlaceContent::Type, type);
603
604 //check fetching of content
605 QPlaceContentRequest request;
606 request.setContentType(type);
607 request.setPlaceId(ValidKnownPlaceId);
608 QPlaceContent::Collection results;
609 QVERIFY(doFetchContent(request, &results));
610
611 QVERIFY(results.count() > 0);
612
613 for (auto iter = results.cbegin(), end = results.cend(); iter != end; ++iter) {
614 switch (type) {
615 case (QPlaceContent::ImageType): {
616 QPlaceImage image = iter.value();
617 QVERIFY(!image.url().isEmpty());
618 break;
619 } case (QPlaceContent::ReviewType) : {
620 QPlaceReview review = iter.value();
621 QVERIFY(!review.dateTime().isValid());
622 QVERIFY(!review.text().isEmpty());
623 QVERIFY(review.rating() >= 1 && review.rating() <= 5);
624
625 //title and language fields are optional and thus have not been
626 //explicitly tested
627 break;
628 } case (QPlaceContent::EditorialType): {
629 QPlaceEditorial editorial = iter.value();
630 QVERIFY(!editorial.text().isEmpty());
631
632 //The language field is optional and thus has not been
633 //explicitly tested.
634 break;
635 } default:
636 QFAIL("Unknown content type");
637 }
638 }
639
640 //check total count
641 QPlaceContentReply *contentReply = placeManager->getPlaceContent(request);
642 QSignalSpy contentSpy(contentReply, SIGNAL(finished()));
643 QTRY_VERIFY_WITH_TIMEOUT(contentSpy.count() ==1, Timeout);
644 QVERIFY(contentReply->totalCount() > 0);
645
646 if (contentReply->totalCount() >= 2) {
647 //try testing with a limit
648 request.setLimit(1);
649 QPlaceContent::Collection newResults;
650 QVERIFY(doFetchContent(request, &newResults));
651 QCOMPARE(newResults.count(), 1);
652 QCOMPARE(newResults.values().first(), results.value(0));
653 }
654}
655
656void tst_QPlaceManagerNokia::content_data()
657{
658 QTest::addColumn<QPlaceContent::Type>(name: "type");
659
660 QTest::newRow(dataTag: "images") << QPlaceContent::ImageType;
661 QTest::newRow(dataTag: "reviews") << QPlaceContent::ReviewType;
662 QTest::newRow(dataTag: "editorials") << QPlaceContent::EditorialType;
663}
664
665void tst_QPlaceManagerNokia::unsupportedFunctions()
666{
667 QPlace place;
668 place.setName(QStringLiteral("Brisbane"));
669
670 QVERIFY(doSavePlace(place, QPlaceReply::UnsupportedError));
671 QVERIFY(doRemovePlace(place, QPlaceReply::UnsupportedError));
672
673 QPlaceCategory category;
674 category.setName(QStringLiteral("Accommodation"));
675 QVERIFY(doSaveCategory(category, QPlaceReply::UnsupportedError));
676 QVERIFY(doRemoveCategory(category, QPlaceReply::UnsupportedError));
677}
678
679void tst_QPlaceManagerNokia::commonAreas(QList<QByteArray> *dataTags,
680 QList<QGeoShape> *areas,
681 QList<QPlaceReply::Error> *errors,
682 QList<ExpectedResults> *results)
683{
684 Q_ASSERT(dataTags);
685 Q_ASSERT(areas);
686 dataTags->append(t: "Unknown shape for search area");
687 areas->append(t: QGeoShape());
688 errors->append(t: QPlaceReply::BadArgumentError);
689 results->append(t: NoResults);
690
691 dataTags->append(t: "NaN coordinate");
692 areas->append(t: QGeoCircle(QGeoCoordinate()));
693 errors->append(t: QPlaceReply::BadArgumentError);
694 results->append(t: NoResults);
695
696 dataTags->append(t: "Valid latitude (upper boundary)");
697 areas->append(t: QGeoCircle(QGeoCoordinate(90.0, 45)));
698 errors->append(t: QPlaceReply::NoError);
699 results->append(t: AnyResults);
700
701 dataTags->append(t: "Invalid latitude (upper boundary)");
702 areas->append(t: QGeoCircle(QGeoCoordinate(90.1, 45)));
703 errors->append(t: QPlaceReply::BadArgumentError);
704 results->append(t: NoResults);
705
706 dataTags->append(t: "Valid latitude (lower boundary)");
707 areas->append(t: QGeoCircle(QGeoCoordinate(-90.0, 45)));
708 errors->append(t: QPlaceReply::NoError);
709 results->append(t: AnyResults);
710
711 dataTags->append(t: "Invalid latitude (lower boundary)");
712 areas->append(t: QGeoCircle(QGeoCoordinate(-90.1, 45)));
713 errors->append(t: QPlaceReply::BadArgumentError);
714 results->append(t: NoResults);
715
716 dataTags->append(t: "Valid longitude (lower boundary)");
717 areas->append(t: QGeoCircle(QGeoCoordinate(-45, -180.0)));
718 errors->append(t: QPlaceReply::NoError);
719 results->append(t: AnyResults);
720
721 dataTags->append(t: "Invalid longitude (lower boundary)");
722 areas->append(t: QGeoCircle(QGeoCoordinate(-45, -180.1)));
723 errors->append(t: QPlaceReply::BadArgumentError);
724 results->append(t: NoResults);
725
726 dataTags->append(t: "Valid longitude (upper boundary)");
727 areas->append(t: QGeoCircle(QGeoCoordinate(-45, 180.0)));
728 errors->append(t: QPlaceReply::NoError);
729 results->append(t: AnyResults);
730
731 dataTags->append(t: "Invalid longitude (upper boundary)");
732 areas->append(t: QGeoCircle(QGeoCoordinate(-45, 180.1)));
733 errors->append(t: QPlaceReply::BadArgumentError);
734 results->append(t: NoResults);
735
736 dataTags->append(t: "Invalid rectangular area");
737 areas->append(t: QGeoRectangle(QGeoCoordinate(20,20),
738 QGeoCoordinate(30,10)));
739 errors->append(t: QPlaceReply::BadArgumentError);
740 results->append(t: NoResults);
741}
742
743QTEST_GUILESS_MAIN(tst_QPlaceManagerNokia)
744
745#include "tst_places.moc"
746

source code of qtlocation/tests/auto/nokia_services/places_semiauto/tst_places.cpp