Merge lp:~alecu/unity-scope-click/verify-sha512 into lp:unity-scope-click/devel

Proposed by Alejandro J. Cura
Status: Merged
Approved by: Paweł Stołowski
Approved revision: 396
Merged at revision: 409
Proposed branch: lp:~alecu/unity-scope-click/verify-sha512
Merge into: lp:unity-scope-click/devel
Diff against target: 686 lines (+217/-54)
18 files modified
libclickscope/click/download-manager.cpp (+11/-10)
libclickscope/click/download-manager.h (+3/-3)
libclickscope/click/package.cpp (+5/-0)
libclickscope/click/package.h (+2/-0)
libclickscope/click/preview.cpp (+37/-13)
libclickscope/click/preview.h (+23/-10)
libclickscope/tests/fake_json.cpp (+1/-0)
libclickscope/tests/test_download_manager.cpp (+3/-2)
libclickscope/tests/test_index.cpp (+2/-0)
libclickscope/tests/test_preview.cpp (+39/-0)
scope/clickapps/apps-query.h (+0/-1)
scope/clickapps/apps-scope.cpp (+3/-1)
scope/clickstore/store-query.h (+0/-1)
scope/clickstore/store-scope.cpp (+7/-1)
scope/tests/CMakeLists.txt (+1/-0)
scope/tests/download_manager_tool/download_manager_tool.cpp (+10/-10)
scope/tests/download_manager_tool/download_manager_tool.h (+2/-2)
scope/tests/test_store_scope.cpp (+68/-0)
To merge this branch: bzr merge lp:~alecu/unity-scope-click/verify-sha512
Reviewer Review Type Date Requested Status
Paweł Stołowski (community) Approve
dobey (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Alejandro J. Cura (community) Abstain
Review via email: mp+230369@code.launchpad.net

Commit message

Pass the sha512 hash from the details webservice to download manager

Description of the change

*********** READY FOR REVIEW! *********

Ignore the "still needs more testing message", that's done:

I've refactored a bit of preview.cpp to add proper unit testing to this branch, and have tested the successful verification of the hash and installation in staging with the app that already has the matching hash (demo4), and with some others where the verification fails.

To post a comment you must log in.
Revision history for this message
Alejandro J. Cura (alecu) wrote :

**** STILL NEEDS MORE TESTING *****

I'm setting the branch to Needs Review so Jenkins builds it, and I can test it on the device, but it's not ready to land until more tests are added and until all apps in production have proper hashes.

review: Needs Fixing
394. By Alejandro J. Cura

Merged with tip of /devel

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
395. By Alejandro J. Cura

Refactoring in preview.cpp to accomodate new tests

396. By Alejandro J. Cura

Add lp bug

Revision history for this message
Alejandro J. Cura (alecu) wrote :

*********** READY FOR REVIEW! *********

I've refactored a bit of preview.cpp to add proper unit testing to this branch, and have tested the successful verification of the hash and installation in staging with the app that already has the matching hash (demo4), and with some others where the verification fails.

review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
dobey (dobey) wrote :

I'm approving this, as the code looks ok, and it isn't breaking install of packages on production, nor the purchasing of an app. However, I was unable to get a clear verification of what happens when a package has an invalid hash.

review: Approve
Revision history for this message
Paweł Stołowski (stolowski) wrote :

Code looks good but yeah, I second Rodney's question: what happens when hash is invalid? Will we report a download failure?

review: Needs Information
Revision history for this message
Alejandro J. Cura (alecu) wrote :

> Code looks good but yeah, I second Rodney's question: what happens when hash
> is invalid? Will we report a download failure?

There's no way to distinguish a wrong hash, from a good hash but the wrong download (ie, because some cache is serving the wrong content, or with some flipped bits).
That's a failure in the download and in many cases it's a retryable error, so I think the current error shown by the scope is ok, but I agree that the wording could be improved.

Revision history for this message
Alejandro J. Cura (alecu) wrote :

The "demo4" app in staging now has an incorrect hash, so this case can be better tested.

Revision history for this message
Paweł Stołowski (stolowski) wrote :

Ok, works fine on the phone. +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libclickscope/click/download-manager.cpp'
2--- libclickscope/click/download-manager.cpp 2014-06-20 03:23:40 +0000
3+++ libclickscope/click/download-manager.cpp 2014-08-13 14:49:17 +0000
4@@ -54,8 +54,7 @@
5
6 static const QString DOWNLOAD_COMMAND = CLICK_INSTALL_HELPER;
7
8-static const QString DOWNLOAD_MANAGER_DO_NOT_HASH = "";
9-static const QString DOWNLOAD_MANAGER_IGNORE_HASH_ALGORITHM = "";
10+static const QString DOWNLOAD_MANAGER_SHA512 = "sha512";
11 }
12
13 struct click::DownloadManager::Private
14@@ -78,6 +77,7 @@
15 QSharedPointer<udm::Manager> systemDownloadManager;
16 QSharedPointer<click::network::Reply> reply;
17 QString downloadUrl;
18+ QString download_sha512;
19 QString package_name;
20 };
21
22@@ -121,7 +121,7 @@
23 click::DownloadManager::~DownloadManager(){
24 }
25
26-void click::DownloadManager::startDownload(const QString& downloadUrl, const QString& package_name)
27+void click::DownloadManager::startDownload(const QString& downloadUrl, const QString& download_sha512, const QString& package_name)
28 {
29 impl->package_name = package_name;
30
31@@ -133,7 +133,7 @@
32 QObject::connect(this, SIGNAL(clickTokenFetchError(QString)),
33 this, SLOT(handleClickTokenFetchError(QString)),
34 Qt::UniqueConnection);
35- fetchClickToken(downloadUrl);
36+ fetchClickToken(downloadUrl, download_sha512);
37 }
38
39 void click::DownloadManager::handleClickTokenFetched(const QString& clickToken)
40@@ -149,8 +149,8 @@
41 headers[CLICK_TOKEN_HEADER()] = clickToken;
42
43 udm::DownloadStruct downloadStruct(impl->downloadUrl,
44- DOWNLOAD_MANAGER_DO_NOT_HASH,
45- DOWNLOAD_MANAGER_IGNORE_HASH_ALGORITHM,
46+ impl->download_sha512,
47+ DOWNLOAD_MANAGER_SHA512,
48 metadata,
49 headers);
50
51@@ -175,9 +175,10 @@
52 }
53 }
54
55-void click::DownloadManager::fetchClickToken(const QString& downloadUrl)
56+void click::DownloadManager::fetchClickToken(const QString& downloadUrl, const QString& download_sha512)
57 {
58 impl->downloadUrl = downloadUrl;
59+ impl->download_sha512 = download_sha512;
60 impl->updateCredentialsFromService();
61 }
62
63@@ -323,10 +324,10 @@
64 };
65 }
66
67-void click::Downloader::startDownload(std::string url, std::string package_name,
68+void click::Downloader::startDownload(const std::string& url, const std::string& download_sha512, const std::string& package_name,
69 const std::function<void (std::pair<std::string, click::InstallError >)>& callback)
70 {
71- qt::core::world::enter_with_task([this, callback, url, package_name] ()
72+ qt::core::world::enter_with_task([this, callback, url, download_sha512, package_name] ()
73 {
74 auto& dm = downloadManagerInstance(networkAccessManager);
75
76@@ -342,7 +343,7 @@
77 QObject::connect(&dm, &click::DownloadManager::downloadError,
78 cb, &Callback::onDownloadError);
79
80- dm.startDownload(QString::fromStdString(url),
81+ dm.startDownload(QString::fromStdString(url), QString::fromStdString(download_sha512),
82 QString::fromStdString(package_name));
83 });
84 }
85
86=== modified file 'libclickscope/click/download-manager.h'
87--- libclickscope/click/download-manager.h 2014-06-19 21:22:53 +0000
88+++ libclickscope/click/download-manager.h 2014-08-13 14:49:17 +0000
89@@ -66,8 +66,8 @@
90 virtual ~DownloadManager();
91
92 public slots:
93- virtual void startDownload(const QString& downloadUrl, const QString& package_name);
94- virtual void fetchClickToken(const QString& downloadUrl);
95+ virtual void startDownload(const QString& downloadUrl, const QString& download_sha512, const QString& package_name);
96+ virtual void fetchClickToken(const QString& downloadUrl, const QString& download_sha512);
97
98 signals:
99
100@@ -98,7 +98,7 @@
101 public:
102 Downloader(const QSharedPointer<click::network::AccessManager>& networkAccessManager);
103 void get_download_progress(std::string package_name, const std::function<void (std::string)>& callback);
104- void startDownload(std::string url, std::string package_name,
105+ void startDownload(const std::string& url, const std::string& download_sha512, const std::string& package_name,
106 const std::function<void (std::pair<std::string, InstallError>)>& callback);
107 private:
108 QSharedPointer<click::network::AccessManager> networkAccessManager;
109
110=== modified file 'libclickscope/click/package.cpp'
111--- libclickscope/click/package.cpp 2014-08-05 19:00:03 +0000
112+++ libclickscope/click/package.cpp 2014-08-13 14:49:17 +0000
113@@ -52,6 +52,7 @@
114 return lhs.package == rhs.package &&
115 lhs.description == rhs.description &&
116 lhs.download_url == rhs.download_url &&
117+ lhs.download_sha512 == rhs.download_sha512 &&
118 lhs.rating == rhs.rating &&
119 // TODO: keywords should be a list of strings
120 lhs.keywords == rhs.keywords &&
121@@ -144,6 +145,9 @@
122 }
123
124 // Optional details go here.
125+ if (root[JsonKeys::download_sha512].isString())
126+ details.download_sha512 = root[JsonKeys::download_sha512].asString();
127+
128 if (root[JsonKeys::version].isString())
129 details.version = root[JsonKeys::version].asString();
130
131@@ -245,6 +249,7 @@
132 << print_string_if_not_empty(details.package.icon_url) << ", "
133 << print_string_if_not_empty(details.description) << ", "
134 << print_string_if_not_empty(details.download_url) << ", "
135+ << print_string_if_not_empty(details.download_sha512) << ", "
136 << details.rating << ", "
137 << print_string_if_not_empty(details.keywords) << ", "
138 << print_string_if_not_empty(details.terms_of_service) << ", "
139
140=== modified file 'libclickscope/click/package.h'
141--- libclickscope/click/package.h 2014-08-05 22:30:30 +0000
142+++ libclickscope/click/package.h 2014-08-13 14:49:17 +0000
143@@ -126,6 +126,7 @@
144 constexpr static const char* icon_url{"icon_url"};
145 constexpr static const char* description{"description"};
146 constexpr static const char* download_url{"download_url"};
147+ constexpr static const char* download_sha512{"download_sha512"};
148 constexpr static const char* rating{"rating"};
149 constexpr static const char* keywords{"keywords"};
150
151@@ -155,6 +156,7 @@
152
153 std::string description;
154 std::string download_url;
155+ std::string download_sha512;
156 double rating;
157 std::string keywords;
158
159
160=== modified file 'libclickscope/click/preview.cpp'
161--- libclickscope/click/preview.cpp 2014-07-25 20:25:49 +0000
162+++ libclickscope/click/preview.cpp 2014-08-13 14:49:17 +0000
163@@ -95,16 +95,34 @@
164 // Preview base class
165
166 Preview::Preview(const unity::scopes::Result& result,
167- const unity::scopes::ActionMetadata& metadata,
168- const QSharedPointer<click::web::Client>& client,
169- const QSharedPointer<click::network::AccessManager>& nam,
170- std::shared_ptr<click::DepartmentsDb> depts)
171- : PreviewQueryBase(result, metadata)
172-{
173- strategy.reset(choose_strategy(result, metadata, client, nam, depts));
174-}
175-
176-PreviewStrategy* Preview::choose_strategy(const unity::scopes::Result &result,
177+ const unity::scopes::ActionMetadata& metadata)
178+ : PreviewQueryBase(result, metadata), result(result), metadata(metadata)
179+{
180+}
181+
182+Preview::~Preview()
183+{
184+}
185+
186+void Preview::choose_strategy(const QSharedPointer<web::Client> &client,
187+ const QSharedPointer<click::network::AccessManager>& nam,
188+ std::shared_ptr<click::DepartmentsDb> depts)
189+{
190+ strategy.reset(build_strategy(result, metadata, client, nam, depts));
191+}
192+
193+PreviewStrategy* Preview::build_installing(const std::string& download_url,
194+ const std::string& download_sha512,
195+ const unity::scopes::Result& result,
196+ const QSharedPointer<click::web::Client>& client,
197+ const QSharedPointer<click::network::AccessManager>& nam,
198+ std::shared_ptr<click::DepartmentsDb> depts)
199+{
200+ return new InstallingPreview(download_url, download_sha512, result, client, nam, depts);
201+}
202+
203+
204+PreviewStrategy* Preview::build_strategy(const unity::scopes::Result &result,
205 const unity::scopes::ActionMetadata &metadata,
206 const QSharedPointer<web::Client> &client,
207 const QSharedPointer<click::network::AccessManager>& nam,
208@@ -126,8 +144,9 @@
209 } else if (metadict.count("action_id") != 0 && metadict.count("download_url") != 0) {
210 std::string action_id = metadict["action_id"].get_string();
211 std::string download_url = metadict["download_url"].get_string();
212+ std::string download_sha512 = metadict["download_sha512"].get_string();
213 if (action_id == click::Preview::Actions::INSTALL_CLICK) {
214- return new InstallingPreview(download_url, result, client, nam, depts);
215+ return build_installing(download_url, download_sha512, result, client, nam, depts);
216 } else {
217 qWarning() << "unexpected action id " << QString::fromStdString(action_id)
218 << " given with download_url" << QString::fromStdString(download_url);
219@@ -447,12 +466,14 @@
220 // class InstallingPreview
221
222 InstallingPreview::InstallingPreview(const std::string &download_url,
223+ const std::string &download_sha512,
224 const unity::scopes::Result &result,
225 const QSharedPointer<click::web::Client>& client,
226 const QSharedPointer<click::network::AccessManager> &nam,
227 std::shared_ptr<click::DepartmentsDb> depts)
228 : PreviewStrategy(result, client), DepartmentUpdater(depts),
229 download_url(download_url),
230+ download_sha512(download_sha512),
231 downloader(new click::Downloader(nam)),
232 depts_db(depts)
233 {
234@@ -473,7 +494,8 @@
235
236 void InstallingPreview::run(const unity::scopes::PreviewReplyProxy &reply)
237 {
238- downloader->startDownload(download_url, result["name"].get_string(),
239+ qDebug() << "Starting installation" << QString(download_url.c_str()) << QString(download_sha512.c_str());
240+ downloader->startDownload(download_url, download_sha512, result["name"].get_string(),
241 [this, reply] (std::pair<std::string, click::InstallError> rc){
242 // NOTE: details not needed by fooErrorWidgets, so no need to populateDetails():
243 switch (rc.second)
244@@ -832,6 +854,7 @@
245 tuple["price"] = scopes::Variant(details.package.price);
246 tuple["store_item_id"] = details.package.name;
247 tuple["download_url"] = details.download_url;
248+ tuple["download_sha512"] = details.download_sha512;
249 payments.add_attribute_value("source", scopes::Variant(tuple));
250 widgets.push_back(payments);
251 } else {
252@@ -841,7 +864,8 @@
253 {
254 {"id", scopes::Variant(click::Preview::Actions::INSTALL_CLICK)},
255 {"label", scopes::Variant(_("Install"))},
256- {"download_url", scopes::Variant(details.download_url)}
257+ {"download_url", scopes::Variant(details.download_url)},
258+ {"download_sha512", scopes::Variant(details.download_sha512)},
259 });
260 buttons.add_attribute_value("actions", builder.end());
261 widgets.push_back(buttons);
262
263=== modified file 'libclickscope/click/preview.h'
264--- libclickscope/click/preview.h 2014-07-24 04:25:22 +0000
265+++ libclickscope/click/preview.h 2014-08-13 14:49:17 +0000
266@@ -42,6 +42,7 @@
267 #include <unity/scopes/PreviewWidget.h>
268 #include <unity/scopes/Result.h>
269 #include <unity/scopes/ScopeBase.h>
270+#include <unity/util/DefinesPtrs.h>
271
272 namespace scopes = unity::scopes;
273
274@@ -67,12 +68,21 @@
275 {
276 protected:
277 std::unique_ptr<PreviewStrategy> strategy;
278- PreviewStrategy* choose_strategy(const unity::scopes::Result& result,
279- const unity::scopes::ActionMetadata& metadata,
280- const QSharedPointer<web::Client> &client,
281- const QSharedPointer<click::network::AccessManager>& nam,
282- std::shared_ptr<click::DepartmentsDb> depts);
283+ const unity::scopes::Result& result;
284+ const unity::scopes::ActionMetadata& metadata;
285+ PreviewStrategy* build_strategy(const unity::scopes::Result& result,
286+ const unity::scopes::ActionMetadata& metadata,
287+ const QSharedPointer<web::Client> &client,
288+ const QSharedPointer<click::network::AccessManager>& nam,
289+ std::shared_ptr<click::DepartmentsDb> depts);
290+ virtual PreviewStrategy* build_installing(const std::string& download_url,
291+ const std::string& download_sha512,
292+ const unity::scopes::Result& result,
293+ const QSharedPointer<click::web::Client>& client,
294+ const QSharedPointer<click::network::AccessManager>& nam,
295+ std::shared_ptr<click::DepartmentsDb> depts);
296 public:
297+ UNITY_DEFINES_PTRS(Preview);
298 struct Actions
299 {
300 Actions() = delete;
301@@ -94,10 +104,11 @@
302
303 Preview(const unity::scopes::Result& result);
304 Preview(const unity::scopes::Result& result,
305- const unity::scopes::ActionMetadata& metadata,
306- const QSharedPointer<click::web::Client>& client,
307- const QSharedPointer<click::network::AccessManager>& nam,
308- std::shared_ptr<click::DepartmentsDb> depts);
309+ const unity::scopes::ActionMetadata& metadata);
310+ virtual ~Preview();
311+ void choose_strategy(const QSharedPointer<web::Client> &client,
312+ const QSharedPointer<click::network::AccessManager>& nam,
313+ std::shared_ptr<click::DepartmentsDb> depts);
314 // From unity::scopes::PreviewQuery
315 void cancelled() override;
316 virtual void run(unity::scopes::PreviewReplyProxy const& reply) override;
317@@ -163,7 +174,8 @@
318 {
319 public:
320 InstallingPreview(const unity::scopes::Result& result) : PreviewStrategy(result) {}
321- InstallingPreview(std::string const& download_url,
322+ InstallingPreview(const std::string& download_url,
323+ const std::string& download_sha512,
324 const unity::scopes::Result& result,
325 const QSharedPointer<click::web::Client>& client,
326 const QSharedPointer<click::network::AccessManager>& nam,
327@@ -176,6 +188,7 @@
328 protected:
329 virtual scopes::PreviewWidgetList progressBarWidget(const std::string& object_path);
330 std::string download_url;
331+ std::string download_sha512;
332 QSharedPointer<click::Downloader> downloader;
333 std::shared_ptr<click::DepartmentsDb> depts_db;
334 void startLauncherAnimation(const PackageDetails& details);
335
336=== modified file 'libclickscope/tests/fake_json.cpp'
337--- libclickscope/tests/fake_json.cpp 2014-08-05 19:00:03 +0000
338+++ libclickscope/tests/fake_json.cpp 2014-08-13 14:49:17 +0000
339@@ -194,6 +194,7 @@
340 "title": "\u1F4A9 Weather",
341 "description": "\u1F4A9 Weather\nA weather application.",
342 "download_url": "https://public.apps.staging.ubuntu.com/download/ar.com.beuno/wheather-touch/ar.com.beuno.wheather-touch-0.2",
343+ "download_sha512": "fake_sha512",
344 "rating": 3.5,
345 "keywords": "these, are, key, words",
346
347
348=== modified file 'libclickscope/tests/test_download_manager.cpp'
349--- libclickscope/tests/test_download_manager.cpp 2014-06-19 21:22:53 +0000
350+++ libclickscope/tests/test_download_manager.cpp 2014-08-13 14:49:17 +0000
351@@ -58,6 +58,7 @@
352 namespace
353 {
354 const QString TEST_URL("http://test.local/");
355+const QString TEST_SHA512("fake_hash");
356 const QString TEST_HEADER_VALUE("test header value");
357 const QString TEST_APP_ID("test_app_id");
358 const QString TEST_CLICK_TOKEN_VALUE("test token value");
359@@ -326,7 +327,7 @@
360 QTimer timer;
361 timer.setSingleShot(true);
362 QObject::connect(&timer, &QTimer::timeout, [&dm]() {
363- dm.fetchClickToken(TEST_URL);
364+ dm.fetchClickToken(TEST_URL, TEST_SHA512);
365 } );
366 timer.start(0);
367
368@@ -466,7 +467,7 @@
369 QTimer timer;
370 timer.setSingleShot(true);
371 QObject::connect(&timer, &QTimer::timeout, [&dm]() {
372- dm.startDownload(TEST_URL, TEST_APP_ID);
373+ dm.startDownload(TEST_URL, TEST_SHA512, TEST_APP_ID);
374 } );
375 timer.start(0);
376
377
378=== modified file 'libclickscope/tests/test_index.cpp'
379--- libclickscope/tests/test_index.cpp 2014-08-05 19:00:03 +0000
380+++ libclickscope/tests/test_index.cpp 2014-08-13 14:49:17 +0000
381@@ -342,6 +342,7 @@
382 },
383 "\u1F4A9 Weather\nA weather application.",
384 "https://public.apps.staging.ubuntu.com/download/ar.com.beuno/wheather-touch/ar.com.beuno.wheather-touch-0.2",
385+ "fake_sha512",
386 3.5,
387 "these, are, key, words",
388
389@@ -407,6 +408,7 @@
390 },
391 (std::string("\u1F4A9 ") + std::string(appname_utf8.constData()) + "\nA weather application.").c_str(),
392 "https://public.apps.staging.ubuntu.com/download/ar.com.beuno/wheather-touch/ar.com.beuno.wheather-touch-0.2",
393+ "fake_sha512",
394 3.5,
395 "these, are, key, words",
396
397
398=== modified file 'libclickscope/tests/test_preview.cpp'
399--- libclickscope/tests/test_preview.cpp 2014-07-24 04:25:22 +0000
400+++ libclickscope/tests/test_preview.cpp 2014-08-13 14:49:17 +0000
401@@ -28,6 +28,7 @@
402 */
403
404 #include <unity/scopes/testing/MockPreviewReply.h>
405+#include <unity/scopes/testing/Result.h>
406
407 #include <gtest/gtest.h>
408 #include <click/preview.h>
409@@ -171,3 +172,41 @@
410 std::vector<std::string> expected_order {"header", "screenshots"};
411 ASSERT_EQ(expected_order, preview.call_order);
412 }
413+
414+class StrategyChooserTest : public Test {
415+protected:
416+ unity::scopes::testing::Result result;
417+ unity::scopes::ActionMetadata metadata;
418+ unity::scopes::VariantMap metadict;
419+ QSharedPointer<click::web::Client> client;
420+ QSharedPointer<click::network::AccessManager> nam;
421+ std::shared_ptr<click::DepartmentsDb> depts;
422+ const std::string FAKE_SHA512 = "FAKE_SHA512";
423+
424+public:
425+ StrategyChooserTest() : metadata("en_EN", "phone") {
426+ }
427+};
428+
429+class MockablePreview : public click::Preview {
430+public:
431+ MockablePreview(const unity::scopes::Result& result, const unity::scopes::ActionMetadata& metadata) :
432+ click::Preview(result, metadata)
433+ {
434+
435+ }
436+
437+ MOCK_METHOD6(build_installing, click::PreviewStrategy*(const std::string&, const std::string&,
438+ const unity::scopes::Result&, const QSharedPointer<click::web::Client>&,
439+ const QSharedPointer<click::network::AccessManager>&, std::shared_ptr<click::DepartmentsDb>));
440+};
441+
442+TEST_F(StrategyChooserTest, testSha512IsUsed) {
443+ metadict["action_id"] = click::Preview::Actions::INSTALL_CLICK;
444+ metadict["download_url"] = "fake_download_url";
445+ metadict["download_sha512"] = FAKE_SHA512;
446+ metadata.set_scope_data(unity::scopes::Variant(metadict));
447+ MockablePreview preview(result, metadata);
448+ EXPECT_CALL(preview, build_installing(_, FAKE_SHA512, _, _, _, _));
449+ preview.choose_strategy(client, nam, depts);
450+}
451
452=== modified file 'scope/clickapps/apps-query.h'
453--- scope/clickapps/apps-query.h 2014-07-22 13:17:28 +0000
454+++ scope/clickapps/apps-query.h 2014-08-13 14:49:17 +0000
455@@ -61,7 +61,6 @@
456 constexpr static const char* DESCRIPTION{"description"};
457 constexpr static const char* MAIN_SCREENSHOT{"main_screenshot"};
458 constexpr static const char* INSTALLED{"installed"};
459- constexpr static const char* DOWNLOAD_URL{"download_url"};
460 constexpr static const char* VERSION{"version"};
461 };
462
463
464=== modified file 'scope/clickapps/apps-scope.cpp'
465--- scope/clickapps/apps-scope.cpp 2014-08-06 21:48:26 +0000
466+++ scope/clickapps/apps-scope.cpp 2014-08-13 14:49:17 +0000
467@@ -98,7 +98,9 @@
468 unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,
469 const unity::scopes::ActionMetadata& metadata) {
470 qDebug() << "Scope::preview() called.";
471- return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam, depts_db)};
472+ auto preview = new click::Preview(result, metadata);
473+ preview->choose_strategy(client, nam, depts_db);
474+ return unity::scopes::PreviewQueryBase::UPtr{preview};
475 }
476
477
478
479=== modified file 'scope/clickstore/store-query.h'
480--- scope/clickstore/store-query.h 2014-07-16 21:49:11 +0000
481+++ scope/clickstore/store-query.h 2014-08-13 14:49:17 +0000
482@@ -65,7 +65,6 @@
483 constexpr static const char* MAIN_SCREENSHOT{"main_screenshot"};
484 constexpr static const char* INSTALLED{"installed"};
485 constexpr static const char* PURCHASED{"purchased"};
486- constexpr static const char* DOWNLOAD_URL{"download_url"};
487 constexpr static const char* VERSION{"version"};
488 };
489
490
491=== modified file 'scope/clickstore/store-scope.cpp'
492--- scope/clickstore/store-scope.cpp 2014-08-01 15:04:19 +0000
493+++ scope/clickstore/store-scope.cpp 2014-08-13 14:49:17 +0000
494@@ -102,7 +102,9 @@
495 unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,
496 const unity::scopes::ActionMetadata& metadata) {
497 qDebug() << "Scope::preview() called.";
498- return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam, depts_db)};
499+ auto preview = new click::Preview(result, metadata);
500+ preview->choose_strategy(client, nam, depts_db);
501+ return unity::scopes::PreviewQueryBase::UPtr{preview};
502 }
503
504 unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata,
505@@ -119,6 +121,8 @@
506 std::string download_url = metadata.scope_data().get_dict()["download_url"].get_string();
507 qDebug() << "the download url is: " << QString::fromStdString(download_url);
508 activation->setHint("download_url", unity::scopes::Variant(download_url));
509+ std::string download_sha512 = metadata.scope_data().get_dict()["download_sha512"].get_string();
510+ activation->setHint("download_sha512", unity::scopes::Variant(download_sha512));
511 activation->setHint("action_id", unity::scopes::Variant(click::Preview::Actions::INSTALL_CLICK));
512 qDebug() << "returning ShowPreview";
513 activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview);
514@@ -130,6 +134,8 @@
515 std::string download_url = metadata.scope_data().get_dict()["download_url"].get_string();
516 qDebug() << "the download url is: " << QString::fromStdString(download_url);
517 activation->setHint("download_url", unity::scopes::Variant(download_url));
518+ std::string download_sha512 = metadata.scope_data().get_dict()["download_sha512"].get_string();
519+ activation->setHint("download_sha512", unity::scopes::Variant(download_sha512));
520 activation->setHint("action_id", unity::scopes::Variant(action_id));
521 qDebug() << "returning ShowPreview";
522 activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview);
523
524=== modified file 'scope/tests/CMakeLists.txt'
525--- scope/tests/CMakeLists.txt 2014-07-22 17:15:14 +0000
526+++ scope/tests/CMakeLists.txt 2014-08-13 14:49:17 +0000
527@@ -20,6 +20,7 @@
528 add_executable (${CLICKSCOPE_TESTS_TARGET}
529 test_pay.cpp
530 test_query.cpp
531+ test_store_scope.cpp
532 )
533
534 add_executable (${APPS_SCOPE_TESTS_TARGET}
535
536=== modified file 'scope/tests/download_manager_tool/download_manager_tool.cpp'
537--- scope/tests/download_manager_tool/download_manager_tool.cpp 2014-02-19 22:35:42 +0000
538+++ scope/tests/download_manager_tool/download_manager_tool.cpp 2014-08-13 14:49:17 +0000
539@@ -54,22 +54,22 @@
540 emit finished();
541 }
542
543-void DownloadManagerTool::fetchClickToken(QString url)
544+void DownloadManagerTool::fetchClickToken(QString url, QString sha512)
545 {
546 QObject::connect(_dm, &click::DownloadManager::clickTokenFetched,
547 this, &DownloadManagerTool::handleResponse);
548 QObject::connect(_dm, &click::DownloadManager::clickTokenFetchError,
549 this, &DownloadManagerTool::handleResponse);
550- _dm->fetchClickToken(url);
551+ _dm->fetchClickToken(url, sha512);
552 }
553
554-void DownloadManagerTool::startDownload(QString url, QString appId)
555+void DownloadManagerTool::startDownload(QString url, QString sha512, QString appId)
556 {
557 QObject::connect(_dm, &click::DownloadManager::downloadStarted,
558 this, &DownloadManagerTool::handleResponse);
559 QObject::connect(_dm, &click::DownloadManager::downloadError,
560 this, &DownloadManagerTool::handleResponse);
561- _dm->startDownload(url, appId);
562+ _dm->startDownload(url, sha512, appId);
563 }
564
565 int main(int argc, char *argv[])
566@@ -83,16 +83,16 @@
567
568 QObject::connect(&tool, SIGNAL(finished()), &a, SLOT(quit()));
569
570- if (argc == 2) {
571+ if (argc == 3) {
572
573 QObject::connect(&timer, &QTimer::timeout, [&]() {
574- tool.fetchClickToken(QString(argv[1]));
575+ tool.fetchClickToken(QString(argv[1]), QString(argv[2]));
576 } );
577
578- } else if (argc == 3) {
579+ } else if (argc == 4) {
580
581 QObject::connect(&timer, &QTimer::timeout, [&]() {
582- downloader.startDownload(std::string(argv[1]), std::string(argv[2]),
583+ downloader.startDownload(std::string(argv[1]), std::string(argv[2]), std::string(argv[3]),
584 [&a] (std::pair<std::string, click::InstallError> arg){
585 auto error = arg.second;
586 if (error == click::InstallError::NoError) {
587@@ -107,9 +107,9 @@
588
589 } else {
590 QTextStream(stderr) << "Usages:\n"
591- << "download_manager_tool https://public.apps.ubuntu.com/download/<<rest of click package dl url>>\n"
592+ << "download_manager_tool https://public.apps.ubuntu.com/download/<<rest of click package dl url>> sha512\n"
593 << "\t - when run with a valid U1 credential in the system, should print the click token to stdout.\n"
594- << "download_manager_tool url app_id\n"
595+ << "download_manager_tool url sha512 app_id\n"
596 << "\t - with a valid credential, should begin a download.\n";
597
598 return 1;
599
600=== modified file 'scope/tests/download_manager_tool/download_manager_tool.h'
601--- scope/tests/download_manager_tool/download_manager_tool.h 2014-02-11 09:47:54 +0000
602+++ scope/tests/download_manager_tool/download_manager_tool.h 2014-08-13 14:49:17 +0000
603@@ -40,8 +40,8 @@
604 explicit DownloadManagerTool(QObject *parent=0);
605
606 public slots:
607- void fetchClickToken(QString url);
608- void startDownload(QString url, QString appId);
609+ void fetchClickToken(QString url, QString sha512);
610+ void startDownload(QString url, QString sha512, QString appId);
611
612 private slots:
613 void handleResponse(QString response);
614
615=== added file 'scope/tests/test_store_scope.cpp'
616--- scope/tests/test_store_scope.cpp 1970-01-01 00:00:00 +0000
617+++ scope/tests/test_store_scope.cpp 2014-08-13 14:49:17 +0000
618@@ -0,0 +1,68 @@
619+/*
620+ * Copyright (C) 2014 Canonical Ltd.
621+ *
622+ * This program is free software: you can redistribute it and/or modify it
623+ * under the terms of the GNU General Public License version 3, as published
624+ * by the Free Software Foundation.
625+ *
626+ * This program is distributed in the hope that it will be useful, but
627+ * WITHOUT ANY WARRANTY; without even the implied warranties of
628+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
629+ * PURPOSE. See the GNU General Public License for more details.
630+ *
631+ * You should have received a copy of the GNU General Public License along
632+ * with this program. If not, see <http://www.gnu.org/licenses/>.
633+ *
634+ * In addition, as a special exception, the copyright holders give
635+ * permission to link the code of portions of this program with the
636+ * OpenSSL library under certain conditions as described in each
637+ * individual source file, and distribute linked combinations
638+ * including the two.
639+ * You must obey the GNU General Public License in all respects
640+ * for all of the code used other than OpenSSL. If you modify
641+ * file(s) with this exception, you may extend this exception to your
642+ * version of the file(s), but you are not obligated to do so. If you
643+ * do not wish to do so, delete this exception statement from your
644+ * version. If you delete this exception statement from all source
645+ * files in the program, then also delete it here.
646+ */
647+
648+#include <gtest/gtest.h>
649+#include <gmock/gmock.h>
650+
651+#include <unity/scopes/testing/Result.h>
652+
653+#include <click/preview.h>
654+#include <clickstore/store-scope.h>
655+
656+using namespace ::testing;
657+
658+class StoreScopeTest : public Test {
659+protected:
660+ const std::string FAKE_SHA512 = "FAKE_SHA512";
661+ click::Scope scope;
662+ unity::scopes::testing::Result result;
663+ unity::scopes::ActionMetadata metadata;
664+ unity::scopes::VariantMap metadict;
665+
666+public:
667+ StoreScopeTest() : metadata("en_EN", "phone") {
668+ metadict["download_url"] = "fake_download_url";
669+ metadict["download_sha512"] = FAKE_SHA512;
670+ metadata.set_scope_data(unity::scopes::Variant(metadict));
671+ }
672+};
673+
674+TEST_F(StoreScopeTest, testPurchaseCompletedPassesHash)
675+{
676+ auto activation = scope.perform_action(result, metadata, "widget_id", "purchaseCompleted");
677+ auto response = activation->activate();
678+ EXPECT_EQ(FAKE_SHA512, response.scope_data().get_dict()["download_sha512"].get_string());
679+}
680+
681+TEST_F(StoreScopeTest, testInstallClickPassesHash)
682+{
683+ auto activation = scope.perform_action(result, metadata, "widget_id", click::Preview::Actions::INSTALL_CLICK);
684+ auto response = activation->activate();
685+ EXPECT_EQ(FAKE_SHA512, response.scope_data().get_dict()["download_sha512"].get_string());
686+}

Subscribers

People subscribed via source and target branches

to all changes: