Merge lp:~dobey/unity-scope-click/recommends into lp:unity-scope-click/devel
- recommends
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Alejandro J. Cura |
Approved revision: | 309 |
Merged at revision: | 304 |
Proposed branch: | lp:~dobey/unity-scope-click/recommends |
Merge into: | lp:unity-scope-click/devel |
Diff against target: |
643 lines (+241/-78) 13 files modified
libclickscope/click/highlights.cpp (+2/-1) libclickscope/click/index.cpp (+31/-11) libclickscope/click/index.h (+2/-1) libclickscope/click/package.cpp (+6/-30) libclickscope/click/package.h (+1/-1) libclickscope/tests/CMakeLists.txt (+4/-3) libclickscope/tests/fake_json.h (+52/-0) libclickscope/tests/test_index.cpp (+35/-17) libclickscope/tests/test_package.cpp (+74/-0) po/unity-scope-click.pot (+6/-3) scope/clickstore/store-query.cpp (+13/-2) scope/tests/integration/webclient_integration.cpp (+2/-1) scope/tests/test_query.cpp (+13/-8) |
To merge this branch: | bzr merge lp:~dobey/unity-scope-click/recommends |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Alejandro J. Cura (community) | Approve | ||
Review via email: mp+224507@code.launchpad.net |
Commit message
Parse and show recommendations from the server in search results.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
Alejandro J. Cura (alecu) wrote : | # |
This branch is lacking many tests.
Here's a non exhaustive list of tests that would make sense adding:
- package_
- Highlight:
----
Please add names to make the callback parameters more obvious, eg:
std::function<
std::function<
----
Please refactor the following block out of Index::search into a new method, and add tests for it:
34 + if (root.isObject() && root.isMember(
35 + auto const emb = root[Package:
36 + if (emb.isObject() && emb.isMember(
37 + auto const pkg = emb[Package:
38 + pl = click::
39 +
40 + if (emb.isMember(
41 + auto const rec = emb[Package:
42 + recommends = click::
43 + }
44 + }
45 + } else if (root.isArray()) {
46 + qDebug() << "Fell back to old array mode.";
47 + pl = click::
48 + }
Also, please check if the old Array mode is really needed, and if not let's get rid of it.
---
Why are you not using push_package in 375 and below?
371 foreach (auto p, packages) {
372 push_package(
373 }
374 + foreach (auto r, recommends) {
375 + try {
If there's any reason not to use push_package, lines 375 and below should be refactored to a new method and tested.
---
Please check with design if installed packages should be shown or not on recommendations, and let's open a bug if they should be filtered.
- 302. By dobey
-
Merged tip of devel.
- 303. By dobey
-
Factor the parsing of search results and recommends to a new function.
List variable names in the callback declaration. - 304. By dobey
-
Drop the old plain array mode resource_url json key.
- 305. By dobey
-
Initial tests for package_
list_from_ json_node. - 306. By dobey
-
Use push_package instead of duplicating code.
- 307. By dobey
-
Fix up the translation template.
- 308. By dobey
-
A little more refactoring.
- 309. By dobey
-
Change the refactored function to return a pair instead of take a callback.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:303
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:309
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'libclickscope/click/highlights.cpp' |
2 | --- libclickscope/click/highlights.cpp 2014-06-18 17:37:13 +0000 |
3 | +++ libclickscope/click/highlights.cpp 2014-06-26 18:57:41 +0000 |
4 | @@ -69,7 +69,8 @@ |
5 | if (item.isObject() && item.isMember(Highlight::JsonKeys::name)) |
6 | { |
7 | auto name = item[Highlight::JsonKeys::name].asString(); |
8 | - auto pkgs = package_list_from_json_node(item); |
9 | + auto pkg_node = item[Package::JsonKeys::embedded][Package::JsonKeys::ci_package]; |
10 | + auto pkgs = package_list_from_json_node(pkg_node); |
11 | highlights.push_back(Highlight(name, pkgs)); |
12 | } |
13 | } |
14 | |
15 | === modified file 'libclickscope/click/index.cpp' |
16 | --- libclickscope/click/index.cpp 2014-06-23 10:25:44 +0000 |
17 | +++ libclickscope/click/index.cpp 2014-06-26 18:57:41 +0000 |
18 | @@ -114,7 +114,32 @@ |
19 | }; |
20 | } |
21 | |
22 | -click::web::Cancellable Index::search (const std::string& query, std::function<void(click::Packages)> callback) |
23 | +std::pair<Packages, Packages> Index::package_lists_from_json(const std::string& json) |
24 | +{ |
25 | + Json::Reader reader; |
26 | + Json::Value root; |
27 | + |
28 | + click::Packages pl; |
29 | + click::Packages recommends; |
30 | + if (reader.parse(json, root)) { |
31 | + if (root.isObject() && root.isMember(Package::JsonKeys::embedded)) { |
32 | + auto const emb = root[Package::JsonKeys::embedded]; |
33 | + if (emb.isObject() && emb.isMember(Package::JsonKeys::ci_package)) { |
34 | + auto const pkg = emb[Package::JsonKeys::ci_package]; |
35 | + pl = click::package_list_from_json_node(pkg); |
36 | + |
37 | + if (emb.isMember(Package::JsonKeys::ci_recommends)) { |
38 | + auto const rec = emb[Package::JsonKeys::ci_recommends]; |
39 | + recommends = click::package_list_from_json_node(rec); |
40 | + } |
41 | + } |
42 | + } |
43 | + } |
44 | + return std::pair<Packages, Packages>(pl, recommends); |
45 | +} |
46 | + |
47 | +click::web::Cancellable Index::search (const std::string& query, |
48 | + std::function<void(click::Packages search_results, click::Packages recommendations)> callback) |
49 | { |
50 | click::web::CallParams params; |
51 | const std::string built_query(build_index_query(query, "")); |
52 | @@ -123,21 +148,16 @@ |
53 | get_base_url() + click::SEARCH_PATH, "GET", false, build_headers(), "", params)); |
54 | |
55 | QObject::connect(response.data(), &click::web::Response::finished, [=](QString reply) { |
56 | - Json::Reader reader; |
57 | - Json::Value root; |
58 | - |
59 | - click::Packages pl; |
60 | - if (reader.parse(reply.toUtf8().constData(), root)) { |
61 | - pl = click::package_list_from_json_node(root); |
62 | - qDebug() << "found packages:" << pl.size(); |
63 | - } |
64 | - callback(pl); |
65 | + std::pair<Packages, Packages> package_lists; |
66 | + package_lists = package_lists_from_json(reply.toUtf8().constData()); |
67 | + callback(package_lists.first, package_lists.second); |
68 | }); |
69 | QObject::connect(response.data(), &click::web::Response::error, [=](QString /*description*/) { |
70 | qDebug() << "No packages found due to network error"; |
71 | click::Packages pl; |
72 | + click::Packages recommends; |
73 | qDebug() << "calling callback"; |
74 | - callback(pl); |
75 | + callback(pl, recommends); |
76 | qDebug() << " ...Done!"; |
77 | }); |
78 | return click::web::Cancellable(response); |
79 | |
80 | === modified file 'libclickscope/click/index.h' |
81 | --- libclickscope/click/index.h 2014-06-23 10:25:44 +0000 |
82 | +++ libclickscope/click/index.h 2014-06-26 18:57:41 +0000 |
83 | @@ -74,7 +74,8 @@ |
84 | enum class Error {NoError, CredentialsError, NetworkError}; |
85 | Index(const QSharedPointer<click::web::Client>& client, |
86 | const QSharedPointer<Configuration> configuration=QSharedPointer<Configuration>(new Configuration())); |
87 | - virtual click::web::Cancellable search (const std::string& query, std::function<void(Packages)> callback); |
88 | + virtual std::pair<Packages, Packages> package_lists_from_json(const std::string& json); |
89 | + virtual click::web::Cancellable search (const std::string& query, std::function<void(Packages, Packages)> callback); |
90 | virtual click::web::Cancellable get_details(const std::string& package_name, std::function<void(PackageDetails, Error)> callback); |
91 | virtual click::web::Cancellable bootstrap(std::function<void(const DepartmentList&, const HighlightList&, Error, int)> callback); |
92 | virtual click::web::Cancellable departments(const std::string& department_href, std::function<void(const DepartmentList&, const HighlightList&, Error, int)> callback); |
93 | |
94 | === modified file 'libclickscope/click/package.cpp' |
95 | --- libclickscope/click/package.cpp 2014-06-18 18:18:14 +0000 |
96 | +++ libclickscope/click/package.cpp 2014-06-26 18:57:41 +0000 |
97 | @@ -75,42 +75,18 @@ |
98 | p.price = item[Package::JsonKeys::price].asDouble(); |
99 | p.icon_url = item[Package::JsonKeys::icon_url].asString(); |
100 | p.url = item[Package::JsonKeys::links][Package::JsonKeys::self][Package::JsonKeys::href].asString(); |
101 | - if (p.url.empty()) { |
102 | - p.url = item[Package::JsonKeys::resource_url].asString(); |
103 | - } |
104 | return p; |
105 | } |
106 | |
107 | Packages package_list_from_json_node(const Json::Value& root) |
108 | { |
109 | Packages pl; |
110 | - if (root.isObject() && root.isMember(Package::JsonKeys::embedded)) |
111 | - { |
112 | - auto const emb = root[Package::JsonKeys::embedded]; |
113 | - if (emb.isObject() && emb.isMember(Package::JsonKeys::ci_package)) |
114 | - { |
115 | - auto const pkg = emb[Package::JsonKeys::ci_package]; |
116 | - for (uint i = 0; i < pkg.size(); i++) |
117 | - { |
118 | - Package p; |
119 | - const json::Value item = pkg[i]; |
120 | - p = package_from_json_node(item); |
121 | - pl.push_back(p); |
122 | - } |
123 | - } |
124 | - } |
125 | - else if (root.isArray()) |
126 | - { |
127 | - qDebug() << "Fell back to old array mode."; |
128 | - qDebug() << root.size() << "packages returned."; |
129 | - for (uint i = 0; i < root.size(); i++) |
130 | - { |
131 | - |
132 | - Package p; |
133 | - const json::Value item = root[i]; |
134 | - p = package_from_json_node(item); |
135 | - pl.push_back(p); |
136 | - } |
137 | + for (uint i = 0; i < root.size(); i++) |
138 | + { |
139 | + Package p; |
140 | + const json::Value item = root[i]; |
141 | + p = package_from_json_node(item); |
142 | + pl.push_back(p); |
143 | } |
144 | return pl; |
145 | } |
146 | |
147 | === modified file 'libclickscope/click/package.h' |
148 | --- libclickscope/click/package.h 2014-06-18 09:01:20 +0000 |
149 | +++ libclickscope/click/package.h 2014-06-26 18:57:41 +0000 |
150 | @@ -54,11 +54,11 @@ |
151 | constexpr static const char* self{"self"}; |
152 | constexpr static const char* href{"href"}; |
153 | constexpr static const char* ci_package {"clickindex:package"}; |
154 | + constexpr static const char* ci_recommends {"clickindex:recommendation"}; |
155 | constexpr static const char* name{"name"}; |
156 | constexpr static const char* title{"title"}; |
157 | constexpr static const char* price{"price"}; |
158 | constexpr static const char* icon_url{"icon_url"}; |
159 | - constexpr static const char* resource_url{"resource_url"}; |
160 | }; |
161 | |
162 | Package() = default; |
163 | |
164 | === modified file 'libclickscope/tests/CMakeLists.txt' |
165 | --- libclickscope/tests/CMakeLists.txt 2014-06-18 11:29:58 +0000 |
166 | +++ libclickscope/tests/CMakeLists.txt 2014-06-26 18:57:41 +0000 |
167 | @@ -21,15 +21,16 @@ |
168 | mock_ubuntuone_credentials.h |
169 | mock_webclient.h |
170 | |
171 | + test_bootstrap.cpp |
172 | + test_configuration.cpp |
173 | + test_departments.cpp |
174 | test_download_manager.cpp |
175 | test_index.cpp |
176 | test_interface.cpp |
177 | - test_configuration.cpp |
178 | + test_package.cpp |
179 | test_reviews.cpp |
180 | test_smartconnect.cpp |
181 | test_webclient.cpp |
182 | - test_bootstrap.cpp |
183 | - test_departments.cpp |
184 | |
185 | ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp |
186 | ) |
187 | |
188 | === modified file 'libclickscope/tests/fake_json.h' |
189 | --- libclickscope/tests/fake_json.h 2014-06-23 11:33:55 +0000 |
190 | +++ libclickscope/tests/fake_json.h 2014-06-26 18:57:41 +0000 |
191 | @@ -74,6 +74,24 @@ |
192 | } |
193 | )foo"; |
194 | |
195 | +const std::string FAKE_JSON_SEARCH_RESULT_MISSING_DATA = R"foo({ |
196 | + "_embedded": { |
197 | + "clickindex:package": [ |
198 | + { |
199 | + "name": "org.example.awesomelauncher", |
200 | + "title": "Awesome Launcher", |
201 | + "description": "This is an awesome launcher.", |
202 | + "_links": { |
203 | + "self": { |
204 | + "href": "http://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher" |
205 | + } |
206 | + } |
207 | + } |
208 | + ] |
209 | + } |
210 | + } |
211 | +)foo"; |
212 | + |
213 | const std::string FAKE_JSON_SEARCH_RESULT_MANY = R"foo({ |
214 | "_embedded": { |
215 | "clickindex:package": [ |
216 | @@ -118,6 +136,40 @@ |
217 | } |
218 | )foo"; |
219 | |
220 | +const std::string FAKE_JSON_SEARCH_RESULT_RECOMMENDS = R"foo({ |
221 | + "_embedded": { |
222 | + "clickindex:package": [ |
223 | + { |
224 | + "name": "org.example.awesomelauncher", |
225 | + "title": "Awesome Launcher", |
226 | + "description": "This is an awesome launcher.", |
227 | + "price": 1.99, |
228 | + "icon_url": "http://software-center.ubuntu.com/site_media/appmedia/2012/09/SPAZ.png", |
229 | + "_links": { |
230 | + "self": { |
231 | + "href": "http://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher" |
232 | + } |
233 | + } |
234 | + } |
235 | + ], |
236 | + "clickindex:recommendation": [ |
237 | + { |
238 | + "name": "org.example.awesomelauncher2", |
239 | + "title": "Awesome Launcher 2", |
240 | + "description": "This is an another awesome launcher.", |
241 | + "price": 1.99, |
242 | + "icon_url": "http://software-center.ubuntu.com/site_media/appmedia/2012/09/SPAZ.png", |
243 | + "_links": { |
244 | + "self": { |
245 | + "href": "http://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher2" |
246 | + } |
247 | + } |
248 | + } |
249 | + ] |
250 | + } |
251 | + } |
252 | +)foo"; |
253 | + |
254 | const std::string FAKE_JSON_PACKAGE_DETAILS = R"foo( |
255 | { |
256 | "name": "ar.com.beuno.wheather-touch", |
257 | |
258 | === modified file 'libclickscope/tests/test_index.cpp' |
259 | --- libclickscope/tests/test_index.cpp 2014-06-23 10:25:44 +0000 |
260 | +++ libclickscope/tests/test_index.cpp 2014-06-26 18:57:41 +0000 |
261 | @@ -79,7 +79,7 @@ |
262 | DefaultValue<std::map<std::string, std::string>>::Set(std::map<std::string, std::string>()); |
263 | } |
264 | public: |
265 | - MOCK_METHOD1(search_callback, void(click::Packages)); |
266 | + MOCK_METHOD2(search_callback, void(click::Packages, click::Packages)); |
267 | MOCK_METHOD2(details_callback, void(click::PackageDetails, click::Index::Error)); |
268 | }; |
269 | |
270 | @@ -100,7 +100,7 @@ |
271 | .Times(1) |
272 | .WillOnce(Return(response)); |
273 | |
274 | - indexPtr->search("", [](click::Packages) {}); |
275 | + indexPtr->search("", [](click::Packages, click::Packages) {}); |
276 | } |
277 | |
278 | TEST_F(IndexTest, testSearchSendsBuiltQueryAsParam) |
279 | @@ -120,7 +120,7 @@ |
280 | .Times(1) |
281 | .WillOnce(Return(FAKE_BUILT_QUERY)); |
282 | |
283 | - indexPtr->search(FAKE_QUERY, [](click::Packages) {}); |
284 | + indexPtr->search(FAKE_QUERY, [](click::Packages, click::Packages) {}); |
285 | } |
286 | |
287 | TEST_F(IndexTest, testSearchSendsRightPath) |
288 | @@ -133,7 +133,7 @@ |
289 | .Times(1) |
290 | .WillOnce(Return(response)); |
291 | |
292 | - indexPtr->search("", [](click::Packages) {}); |
293 | + indexPtr->search("", [](click::Packages, click::Packages) {}); |
294 | } |
295 | |
296 | TEST_F(IndexTest, testSearchCallbackIsCalled) |
297 | @@ -148,10 +148,11 @@ |
298 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) |
299 | .Times(1) |
300 | .WillOnce(Return(response)); |
301 | - EXPECT_CALL(*this, search_callback(_)).Times(1); |
302 | + EXPECT_CALL(*this, search_callback(_, _)).Times(1); |
303 | |
304 | - indexPtr->search("", [this](click::Packages packages){ |
305 | - search_callback(packages); |
306 | + indexPtr->search("", [this](click::Packages packages, |
307 | + click::Packages recommends){ |
308 | + search_callback(packages, recommends); |
309 | }); |
310 | response->replyFinished(); |
311 | } |
312 | @@ -169,10 +170,11 @@ |
313 | .Times(1) |
314 | .WillOnce(Return(response)); |
315 | click::Packages empty_package_list; |
316 | - EXPECT_CALL(*this, search_callback(empty_package_list)).Times(1); |
317 | + EXPECT_CALL(*this, search_callback(empty_package_list, _)).Times(1); |
318 | |
319 | - indexPtr->search("", [this](click::Packages packages){ |
320 | - search_callback(packages); |
321 | + indexPtr->search("", [this](click::Packages packages, |
322 | + click::Packages recommends){ |
323 | + search_callback(packages, recommends); |
324 | }); |
325 | response->replyFinished(); |
326 | } |
327 | @@ -198,10 +200,11 @@ |
328 | "http://search.apps.ubuntu.com/api/v1/package/org.example.awesomelauncher" |
329 | } |
330 | }; |
331 | - EXPECT_CALL(*this, search_callback(single_package_list)).Times(1); |
332 | + EXPECT_CALL(*this, search_callback(single_package_list, _)).Times(1); |
333 | |
334 | - indexPtr->search("", [this](click::Packages packages){ |
335 | - search_callback(packages); |
336 | + indexPtr->search("", [this](click::Packages packages, |
337 | + click::Packages recommends){ |
338 | + search_callback(packages, recommends); |
339 | }); |
340 | response->replyFinished(); |
341 | } |
342 | @@ -215,7 +218,8 @@ |
343 | .Times(1) |
344 | .WillOnce(Return(response)); |
345 | |
346 | - auto search_operation = indexPtr->search("", [](click::Packages) {}); |
347 | + auto search_operation = indexPtr->search("", [](click::Packages, |
348 | + click::Packages) {}); |
349 | EXPECT_CALL(reply.instance, abort()).Times(1); |
350 | search_operation.cancel(); |
351 | } |
352 | @@ -234,12 +238,13 @@ |
353 | .Times(1) |
354 | .WillOnce(Return(response)); |
355 | EXPECT_CALL(reply.instance, errorString()).Times(1).WillOnce(Return("fake error")); |
356 | - indexPtr->search("", [this](click::Packages packages){ |
357 | - search_callback(packages); |
358 | + indexPtr->search("", [this](click::Packages packages, |
359 | + click::Packages recommends){ |
360 | + search_callback(packages, recommends); |
361 | }); |
362 | |
363 | click::Packages empty_package_list; |
364 | - EXPECT_CALL(*this, search_callback(empty_package_list)).Times(1); |
365 | + EXPECT_CALL(*this, search_callback(empty_package_list, _)).Times(1); |
366 | |
367 | emit reply.instance.error(QNetworkReply::UnknownNetworkError); |
368 | } |
369 | @@ -441,6 +446,19 @@ |
370 | ASSERT_TRUE(unsetenv(click::SEARCH_BASE_URL_ENVVAR.c_str()) == 0); |
371 | } |
372 | |
373 | +TEST_F(IndexTest, testPackageListsFromJsonNodeNoRecommends) |
374 | +{ |
375 | + auto lists = indexPtr->package_lists_from_json(FAKE_JSON_SEARCH_RESULT_ONE); |
376 | + EXPECT_EQ(1, lists.first.size()); |
377 | + EXPECT_EQ(0, lists.second.size()); |
378 | +} |
379 | + |
380 | +TEST_F(IndexTest, testPackageListsFromJsonNodeHasRecommends) |
381 | +{ |
382 | + auto lists = indexPtr->package_lists_from_json(FAKE_JSON_SEARCH_RESULT_RECOMMENDS); |
383 | + EXPECT_EQ(1, lists.second.size()); |
384 | +} |
385 | + |
386 | TEST_F(MockPackageManager, testUninstallCommandCorrect) |
387 | { |
388 | click::Package package = { |
389 | |
390 | === added file 'libclickscope/tests/test_package.cpp' |
391 | --- libclickscope/tests/test_package.cpp 1970-01-01 00:00:00 +0000 |
392 | +++ libclickscope/tests/test_package.cpp 2014-06-26 18:57:41 +0000 |
393 | @@ -0,0 +1,74 @@ |
394 | +/* |
395 | + * Copyright (C) 2014 Canonical Ltd. |
396 | + * |
397 | + * This program is free software: you can redistribute it and/or modify it |
398 | + * under the terms of the GNU General Public License version 3, as published |
399 | + * by the Free Software Foundation. |
400 | + * |
401 | + * This program is distributed in the hope that it will be useful, but |
402 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
403 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
404 | + * PURPOSE. See the GNU General Public License for more details. |
405 | + * |
406 | + * You should have received a copy of the GNU General Public License along |
407 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
408 | + * |
409 | + * In addition, as a special exception, the copyright holders give |
410 | + * permission to link the code of portions of this program with the |
411 | + * OpenSSL library under certain conditions as described in each |
412 | + * individual source file, and distribute linked combinations |
413 | + * including the two. |
414 | + * You must obey the GNU General Public License in all respects |
415 | + * for all of the code used other than OpenSSL. If you modify |
416 | + * file(s) with this exception, you may extend this exception to your |
417 | + * version of the file(s), but you are not obligated to do so. If you |
418 | + * do not wish to do so, delete this exception statement from your |
419 | + * version. If you delete this exception statement from all source |
420 | + * files in the program, then also delete it here. |
421 | + */ |
422 | + |
423 | +#include <click/package.h> |
424 | + |
425 | +#include <gtest/gtest.h> |
426 | + |
427 | +#include "fake_json.h" |
428 | + |
429 | +using namespace click; |
430 | + |
431 | + |
432 | +class PackageTest : public ::testing::Test { |
433 | +}; |
434 | + |
435 | +TEST_F(PackageTest, testPackageListFromJsonNodeSingle) |
436 | +{ |
437 | + Json::Value root; |
438 | + Json::Reader().parse(FAKE_JSON_SEARCH_RESULT_ONE, root); |
439 | + auto const embedded = root[Package::JsonKeys::embedded]; |
440 | + auto const ci_package = embedded[Package::JsonKeys::ci_package]; |
441 | + |
442 | + Packages pl = package_list_from_json_node(ci_package); |
443 | + ASSERT_EQ(1, pl.size()); |
444 | +} |
445 | + |
446 | +TEST_F(PackageTest, testPackageListFromJsonNodeMany) |
447 | +{ |
448 | + Json::Value root; |
449 | + Json::Reader().parse(FAKE_JSON_SEARCH_RESULT_MANY, root); |
450 | + auto const embedded = root[Package::JsonKeys::embedded]; |
451 | + auto const ci_package = embedded[Package::JsonKeys::ci_package]; |
452 | + |
453 | + Packages pl = package_list_from_json_node(ci_package); |
454 | + ASSERT_GT(pl.size(), 1); |
455 | +} |
456 | + |
457 | +TEST_F(PackageTest, testPackageListFromJsonNodeMissingData) |
458 | +{ |
459 | + Json::Value root; |
460 | + Json::Reader().parse(FAKE_JSON_SEARCH_RESULT_MISSING_DATA, root); |
461 | + auto const embedded = root[Package::JsonKeys::embedded]; |
462 | + auto const ci_package = embedded[Package::JsonKeys::ci_package]; |
463 | + |
464 | + Packages pl = package_list_from_json_node(ci_package); |
465 | + ASSERT_EQ(1, pl.size()); |
466 | +} |
467 | + |
468 | |
469 | === modified file 'po/unity-scope-click.pot' |
470 | --- po/unity-scope-click.pot 2014-06-25 13:43:08 +0000 |
471 | +++ po/unity-scope-click.pot 2014-06-26 18:57:41 +0000 |
472 | @@ -8,7 +8,7 @@ |
473 | msgstr "" |
474 | "Project-Id-Version: PACKAGE VERSION\n" |
475 | "Report-Msgid-Bugs-To: \n" |
476 | -"POT-Creation-Date: 2014-06-25 09:42-0400\n" |
477 | +"POT-Creation-Date: 2014-06-26 14:08-0400\n" |
478 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
479 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
480 | "Language-Team: LANGUAGE <LL@li.org>\n" |
481 | @@ -107,11 +107,14 @@ |
482 | msgid "✔ INSTALLED" |
483 | msgstr "" |
484 | |
485 | -#. TODO: get the real price from the webservice (upcoming branch) |
486 | -#: ../scope/clickstore/store-query.cpp:236 |
487 | +#: ../scope/clickstore/store-query.cpp:235 |
488 | msgid "FREE" |
489 | msgstr "" |
490 | |
491 | #: ../scope/clickstore/store-query.cpp:331 |
492 | msgid "Available" |
493 | msgstr "" |
494 | + |
495 | +#: ../scope/clickstore/store-query.cpp:335 |
496 | +msgid "Recommended" |
497 | +msgstr "" |
498 | |
499 | === modified file 'scope/clickstore/store-query.cpp' |
500 | --- scope/clickstore/store-query.cpp 2014-06-24 16:44:03 +0000 |
501 | +++ scope/clickstore/store-query.cpp 2014-06-26 18:57:41 +0000 |
502 | @@ -232,8 +232,8 @@ |
503 | res[click::Query::ResultKeys::VERSION] = installed->version; |
504 | } else { |
505 | res[click::Query::ResultKeys::INSTALLED] = false; |
506 | + res["subtitle"] = _("FREE"); |
507 | // TODO: get the real price from the webservice (upcoming branch) |
508 | - res["subtitle"] = _("FREE"); |
509 | } |
510 | |
511 | this->push_result(searchReply, res); |
512 | @@ -330,17 +330,28 @@ |
513 | scopes::CategoryRenderer categoryRenderer(categoryTemplate); |
514 | auto category = register_category(searchReply, "appstore", _("Available"), "", categoryRenderer); |
515 | |
516 | + scopes::CategoryRenderer recommendsCatRenderer(categoryTemplate); |
517 | + auto recommendsCategory = register_category(searchReply, "recommends", |
518 | + _("Recommended"), "", |
519 | + recommendsCatRenderer); |
520 | + |
521 | assert(searchReply); |
522 | |
523 | run_under_qt([=]() |
524 | { |
525 | - auto search_cb = [this, searchReply, category, installedPackages](Packages packages) { |
526 | + auto search_cb = [this, searchReply, |
527 | + category, recommendsCategory, |
528 | + installedPackages](Packages packages, Packages recommends) { |
529 | qDebug("search callback"); |
530 | |
531 | // handle packages data |
532 | foreach (auto p, packages) { |
533 | push_package(searchReply, category, installedPackages, p); |
534 | } |
535 | + foreach (auto r, recommends) { |
536 | + push_package(searchReply, recommendsCategory, |
537 | + installedPackages, r); |
538 | + } |
539 | qDebug() << "search completed"; |
540 | this->finished(searchReply); //FIXME: this shouldn't be needed |
541 | }; |
542 | |
543 | === modified file 'scope/tests/integration/webclient_integration.cpp' |
544 | --- scope/tests/integration/webclient_integration.cpp 2014-06-23 10:25:44 +0000 |
545 | +++ scope/tests/integration/webclient_integration.cpp 2014-06-26 18:57:41 +0000 |
546 | @@ -103,7 +103,8 @@ |
547 | new click::web::Client(namPtr)); |
548 | click::Index index(clientPtr); |
549 | click::Packages packages; |
550 | - index.search("qr,architecture:armhf", [&, this](click::Packages found_packages){ |
551 | + index.search("qr", [&, this](click::Packages found_packages, |
552 | + click::Packages){ |
553 | packages = found_packages; |
554 | Quit(); |
555 | }); |
556 | |
557 | === modified file 'scope/tests/test_query.cpp' |
558 | --- scope/tests/test_query.cpp 2014-06-23 10:25:44 +0000 |
559 | +++ scope/tests/test_query.cpp 2014-06-26 18:57:41 +0000 |
560 | @@ -58,9 +58,11 @@ |
561 | |
562 | class MockIndex : public click::Index { |
563 | click::Packages packages; |
564 | + click::Packages recommends; |
565 | click::DepartmentList departments; |
566 | click::DepartmentList bootstrap_departments; |
567 | click::HighlightList bootstrap_highlights; |
568 | + |
569 | public: |
570 | MockIndex(click::Packages packages = click::Packages(), |
571 | click::DepartmentList departments = click::DepartmentList(), |
572 | @@ -73,20 +75,23 @@ |
573 | |
574 | } |
575 | |
576 | - click::web::Cancellable search(const std::string &query, std::function<void (click::Packages)> callback) override |
577 | + click::web::Cancellable search(const std::string &query, std::function<void (click::Packages, click::Packages)> callback) override |
578 | { |
579 | do_search(query, callback); |
580 | - callback(packages); |
581 | + callback(packages, recommends); |
582 | return click::web::Cancellable(); |
583 | } |
584 | |
585 | + |
586 | click::web::Cancellable bootstrap(std::function<void(const click::DepartmentList&, const click::HighlightList&, Error, int)> callback) override |
587 | { |
588 | callback(bootstrap_departments, bootstrap_highlights, click::Index::Error::NoError, 0); |
589 | return click::web::Cancellable(); |
590 | } |
591 | |
592 | - MOCK_METHOD2(do_search, void(const std::string&, std::function<void(click::Packages)>)); |
593 | + MOCK_METHOD2(do_search, |
594 | + void(const std::string&, |
595 | + std::function<void(click::Packages, click::Packages)>)); |
596 | }; |
597 | |
598 | class MockQueryBase : public click::Query { |
599 | @@ -178,7 +183,7 @@ |
600 | |
601 | scopes::CategoryRenderer renderer("{}"); |
602 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
603 | - EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); |
604 | + EXPECT_CALL(q, register_category(_, _, _, _, _)).Times(2).WillRepeatedly(Return(ptrCat)); |
605 | q.wrap_add_available_apps(reply, no_installed_packages, FAKE_CATEGORY_TEMPLATE); |
606 | } |
607 | |
608 | @@ -198,7 +203,7 @@ |
609 | |
610 | scopes::CategoryRenderer renderer("{}"); |
611 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
612 | - EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); |
613 | + EXPECT_CALL(q, register_category(_, _, _, _, _)).Times(2).WillRepeatedly(Return(ptrCat)); |
614 | |
615 | scopes::testing::MockSearchReply mock_reply; |
616 | scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){}); |
617 | @@ -224,7 +229,7 @@ |
618 | |
619 | scopes::CategoryRenderer renderer("{}"); |
620 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
621 | - EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); |
622 | + EXPECT_CALL(q, register_category(_, _, _, _, _)).Times(2).WillRepeatedly(Return(ptrCat)); |
623 | |
624 | scopes::testing::MockSearchReply mock_reply; |
625 | scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){}); |
626 | @@ -273,7 +278,7 @@ |
627 | |
628 | scopes::CategoryRenderer renderer("{}"); |
629 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
630 | - EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); |
631 | + EXPECT_CALL(q, register_category(_, _, _, _, _)).Times(2).WillRepeatedly(Return(ptrCat)); |
632 | |
633 | scopes::testing::MockSearchReply mock_reply; |
634 | scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){}); |
635 | @@ -303,7 +308,7 @@ |
636 | |
637 | scopes::CategoryRenderer renderer("{}"); |
638 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
639 | - EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); |
640 | + EXPECT_CALL(q, register_category(_, _, _, _, _)).Times(2).WillRepeatedly(Return(ptrCat)); |
641 | |
642 | scopes::testing::MockSearchReply mock_reply; |
643 | scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){}); |
PASSED: Continuous integration, rev:301 jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- ci/149/ jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- amd64-ci/ 124 jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- armhf-ci/ 123 jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- armhf-ci/ 123/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- i386-ci/ 123
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- team-unity- scope-click- devel-ci/ 149/rebuild
http://