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
=== modified file 'libclickscope/click/download-manager.cpp'
--- libclickscope/click/download-manager.cpp 2014-06-20 03:23:40 +0000
+++ libclickscope/click/download-manager.cpp 2014-08-13 14:49:17 +0000
@@ -54,8 +54,7 @@
5454
55static const QString DOWNLOAD_COMMAND = CLICK_INSTALL_HELPER;55static const QString DOWNLOAD_COMMAND = CLICK_INSTALL_HELPER;
5656
57static const QString DOWNLOAD_MANAGER_DO_NOT_HASH = "";57static const QString DOWNLOAD_MANAGER_SHA512 = "sha512";
58static const QString DOWNLOAD_MANAGER_IGNORE_HASH_ALGORITHM = "";
59}58}
6059
61struct click::DownloadManager::Private60struct click::DownloadManager::Private
@@ -78,6 +77,7 @@
78 QSharedPointer<udm::Manager> systemDownloadManager;77 QSharedPointer<udm::Manager> systemDownloadManager;
79 QSharedPointer<click::network::Reply> reply;78 QSharedPointer<click::network::Reply> reply;
80 QString downloadUrl;79 QString downloadUrl;
80 QString download_sha512;
81 QString package_name;81 QString package_name;
82};82};
8383
@@ -121,7 +121,7 @@
121click::DownloadManager::~DownloadManager(){121click::DownloadManager::~DownloadManager(){
122}122}
123123
124void click::DownloadManager::startDownload(const QString& downloadUrl, const QString& package_name)124void click::DownloadManager::startDownload(const QString& downloadUrl, const QString& download_sha512, const QString& package_name)
125{125{
126 impl->package_name = package_name;126 impl->package_name = package_name;
127127
@@ -133,7 +133,7 @@
133 QObject::connect(this, SIGNAL(clickTokenFetchError(QString)),133 QObject::connect(this, SIGNAL(clickTokenFetchError(QString)),
134 this, SLOT(handleClickTokenFetchError(QString)),134 this, SLOT(handleClickTokenFetchError(QString)),
135 Qt::UniqueConnection);135 Qt::UniqueConnection);
136 fetchClickToken(downloadUrl);136 fetchClickToken(downloadUrl, download_sha512);
137}137}
138138
139void click::DownloadManager::handleClickTokenFetched(const QString& clickToken)139void click::DownloadManager::handleClickTokenFetched(const QString& clickToken)
@@ -149,8 +149,8 @@
149 headers[CLICK_TOKEN_HEADER()] = clickToken;149 headers[CLICK_TOKEN_HEADER()] = clickToken;
150150
151 udm::DownloadStruct downloadStruct(impl->downloadUrl,151 udm::DownloadStruct downloadStruct(impl->downloadUrl,
152 DOWNLOAD_MANAGER_DO_NOT_HASH,152 impl->download_sha512,
153 DOWNLOAD_MANAGER_IGNORE_HASH_ALGORITHM,153 DOWNLOAD_MANAGER_SHA512,
154 metadata,154 metadata,
155 headers);155 headers);
156156
@@ -175,9 +175,10 @@
175 }175 }
176}176}
177177
178void click::DownloadManager::fetchClickToken(const QString& downloadUrl)178void click::DownloadManager::fetchClickToken(const QString& downloadUrl, const QString& download_sha512)
179{179{
180 impl->downloadUrl = downloadUrl;180 impl->downloadUrl = downloadUrl;
181 impl->download_sha512 = download_sha512;
181 impl->updateCredentialsFromService();182 impl->updateCredentialsFromService();
182}183}
183184
@@ -323,10 +324,10 @@
323};324};
324}325}
325326
326void click::Downloader::startDownload(std::string url, std::string package_name,327void click::Downloader::startDownload(const std::string& url, const std::string& download_sha512, const std::string& package_name,
327 const std::function<void (std::pair<std::string, click::InstallError >)>& callback)328 const std::function<void (std::pair<std::string, click::InstallError >)>& callback)
328{329{
329 qt::core::world::enter_with_task([this, callback, url, package_name] ()330 qt::core::world::enter_with_task([this, callback, url, download_sha512, package_name] ()
330 {331 {
331 auto& dm = downloadManagerInstance(networkAccessManager);332 auto& dm = downloadManagerInstance(networkAccessManager);
332333
@@ -342,7 +343,7 @@
342 QObject::connect(&dm, &click::DownloadManager::downloadError,343 QObject::connect(&dm, &click::DownloadManager::downloadError,
343 cb, &Callback::onDownloadError);344 cb, &Callback::onDownloadError);
344345
345 dm.startDownload(QString::fromStdString(url),346 dm.startDownload(QString::fromStdString(url), QString::fromStdString(download_sha512),
346 QString::fromStdString(package_name));347 QString::fromStdString(package_name));
347 });348 });
348}349}
349350
=== modified file 'libclickscope/click/download-manager.h'
--- libclickscope/click/download-manager.h 2014-06-19 21:22:53 +0000
+++ libclickscope/click/download-manager.h 2014-08-13 14:49:17 +0000
@@ -66,8 +66,8 @@
66 virtual ~DownloadManager();66 virtual ~DownloadManager();
6767
68public slots:68public slots:
69 virtual void startDownload(const QString& downloadUrl, const QString& package_name);69 virtual void startDownload(const QString& downloadUrl, const QString& download_sha512, const QString& package_name);
70 virtual void fetchClickToken(const QString& downloadUrl);70 virtual void fetchClickToken(const QString& downloadUrl, const QString& download_sha512);
7171
72signals:72signals:
7373
@@ -98,7 +98,7 @@
98public:98public:
99 Downloader(const QSharedPointer<click::network::AccessManager>& networkAccessManager);99 Downloader(const QSharedPointer<click::network::AccessManager>& networkAccessManager);
100 void get_download_progress(std::string package_name, const std::function<void (std::string)>& callback);100 void get_download_progress(std::string package_name, const std::function<void (std::string)>& callback);
101 void startDownload(std::string url, std::string package_name,101 void startDownload(const std::string& url, const std::string& download_sha512, const std::string& package_name,
102 const std::function<void (std::pair<std::string, InstallError>)>& callback);102 const std::function<void (std::pair<std::string, InstallError>)>& callback);
103private:103private:
104 QSharedPointer<click::network::AccessManager> networkAccessManager;104 QSharedPointer<click::network::AccessManager> networkAccessManager;
105105
=== modified file 'libclickscope/click/package.cpp'
--- libclickscope/click/package.cpp 2014-08-05 19:00:03 +0000
+++ libclickscope/click/package.cpp 2014-08-13 14:49:17 +0000
@@ -52,6 +52,7 @@
52 return lhs.package == rhs.package &&52 return lhs.package == rhs.package &&
53 lhs.description == rhs.description &&53 lhs.description == rhs.description &&
54 lhs.download_url == rhs.download_url &&54 lhs.download_url == rhs.download_url &&
55 lhs.download_sha512 == rhs.download_sha512 &&
55 lhs.rating == rhs.rating &&56 lhs.rating == rhs.rating &&
56 // TODO: keywords should be a list of strings57 // TODO: keywords should be a list of strings
57 lhs.keywords == rhs.keywords &&58 lhs.keywords == rhs.keywords &&
@@ -144,6 +145,9 @@
144 }145 }
145146
146 // Optional details go here.147 // Optional details go here.
148 if (root[JsonKeys::download_sha512].isString())
149 details.download_sha512 = root[JsonKeys::download_sha512].asString();
150
147 if (root[JsonKeys::version].isString())151 if (root[JsonKeys::version].isString())
148 details.version = root[JsonKeys::version].asString();152 details.version = root[JsonKeys::version].asString();
149153
@@ -245,6 +249,7 @@
245 << print_string_if_not_empty(details.package.icon_url) << ", "249 << print_string_if_not_empty(details.package.icon_url) << ", "
246 << print_string_if_not_empty(details.description) << ", "250 << print_string_if_not_empty(details.description) << ", "
247 << print_string_if_not_empty(details.download_url) << ", "251 << print_string_if_not_empty(details.download_url) << ", "
252 << print_string_if_not_empty(details.download_sha512) << ", "
248 << details.rating << ", "253 << details.rating << ", "
249 << print_string_if_not_empty(details.keywords) << ", "254 << print_string_if_not_empty(details.keywords) << ", "
250 << print_string_if_not_empty(details.terms_of_service) << ", "255 << print_string_if_not_empty(details.terms_of_service) << ", "
251256
=== modified file 'libclickscope/click/package.h'
--- libclickscope/click/package.h 2014-08-05 22:30:30 +0000
+++ libclickscope/click/package.h 2014-08-13 14:49:17 +0000
@@ -126,6 +126,7 @@
126 constexpr static const char* icon_url{"icon_url"};126 constexpr static const char* icon_url{"icon_url"};
127 constexpr static const char* description{"description"};127 constexpr static const char* description{"description"};
128 constexpr static const char* download_url{"download_url"};128 constexpr static const char* download_url{"download_url"};
129 constexpr static const char* download_sha512{"download_sha512"};
129 constexpr static const char* rating{"rating"};130 constexpr static const char* rating{"rating"};
130 constexpr static const char* keywords{"keywords"};131 constexpr static const char* keywords{"keywords"};
131132
@@ -155,6 +156,7 @@
155156
156 std::string description;157 std::string description;
157 std::string download_url;158 std::string download_url;
159 std::string download_sha512;
158 double rating;160 double rating;
159 std::string keywords;161 std::string keywords;
160162
161163
=== modified file 'libclickscope/click/preview.cpp'
--- libclickscope/click/preview.cpp 2014-07-25 20:25:49 +0000
+++ libclickscope/click/preview.cpp 2014-08-13 14:49:17 +0000
@@ -95,16 +95,34 @@
95// Preview base class95// Preview base class
9696
97Preview::Preview(const unity::scopes::Result& result,97Preview::Preview(const unity::scopes::Result& result,
98 const unity::scopes::ActionMetadata& metadata,98 const unity::scopes::ActionMetadata& metadata)
99 const QSharedPointer<click::web::Client>& client,99 : PreviewQueryBase(result, metadata), result(result), metadata(metadata)
100 const QSharedPointer<click::network::AccessManager>& nam,100{
101 std::shared_ptr<click::DepartmentsDb> depts)101}
102 : PreviewQueryBase(result, metadata)102
103{103Preview::~Preview()
104 strategy.reset(choose_strategy(result, metadata, client, nam, depts));104{
105}105}
106106
107PreviewStrategy* Preview::choose_strategy(const unity::scopes::Result &result,107void Preview::choose_strategy(const QSharedPointer<web::Client> &client,
108 const QSharedPointer<click::network::AccessManager>& nam,
109 std::shared_ptr<click::DepartmentsDb> depts)
110{
111 strategy.reset(build_strategy(result, metadata, client, nam, depts));
112}
113
114PreviewStrategy* Preview::build_installing(const std::string& download_url,
115 const std::string& download_sha512,
116 const unity::scopes::Result& result,
117 const QSharedPointer<click::web::Client>& client,
118 const QSharedPointer<click::network::AccessManager>& nam,
119 std::shared_ptr<click::DepartmentsDb> depts)
120{
121 return new InstallingPreview(download_url, download_sha512, result, client, nam, depts);
122}
123
124
125PreviewStrategy* Preview::build_strategy(const unity::scopes::Result &result,
108 const unity::scopes::ActionMetadata &metadata,126 const unity::scopes::ActionMetadata &metadata,
109 const QSharedPointer<web::Client> &client,127 const QSharedPointer<web::Client> &client,
110 const QSharedPointer<click::network::AccessManager>& nam,128 const QSharedPointer<click::network::AccessManager>& nam,
@@ -126,8 +144,9 @@
126 } else if (metadict.count("action_id") != 0 && metadict.count("download_url") != 0) {144 } else if (metadict.count("action_id") != 0 && metadict.count("download_url") != 0) {
127 std::string action_id = metadict["action_id"].get_string();145 std::string action_id = metadict["action_id"].get_string();
128 std::string download_url = metadict["download_url"].get_string();146 std::string download_url = metadict["download_url"].get_string();
147 std::string download_sha512 = metadict["download_sha512"].get_string();
129 if (action_id == click::Preview::Actions::INSTALL_CLICK) {148 if (action_id == click::Preview::Actions::INSTALL_CLICK) {
130 return new InstallingPreview(download_url, result, client, nam, depts);149 return build_installing(download_url, download_sha512, result, client, nam, depts);
131 } else {150 } else {
132 qWarning() << "unexpected action id " << QString::fromStdString(action_id)151 qWarning() << "unexpected action id " << QString::fromStdString(action_id)
133 << " given with download_url" << QString::fromStdString(download_url);152 << " given with download_url" << QString::fromStdString(download_url);
@@ -447,12 +466,14 @@
447// class InstallingPreview466// class InstallingPreview
448467
449InstallingPreview::InstallingPreview(const std::string &download_url,468InstallingPreview::InstallingPreview(const std::string &download_url,
469 const std::string &download_sha512,
450 const unity::scopes::Result &result,470 const unity::scopes::Result &result,
451 const QSharedPointer<click::web::Client>& client,471 const QSharedPointer<click::web::Client>& client,
452 const QSharedPointer<click::network::AccessManager> &nam,472 const QSharedPointer<click::network::AccessManager> &nam,
453 std::shared_ptr<click::DepartmentsDb> depts)473 std::shared_ptr<click::DepartmentsDb> depts)
454 : PreviewStrategy(result, client), DepartmentUpdater(depts),474 : PreviewStrategy(result, client), DepartmentUpdater(depts),
455 download_url(download_url),475 download_url(download_url),
476 download_sha512(download_sha512),
456 downloader(new click::Downloader(nam)),477 downloader(new click::Downloader(nam)),
457 depts_db(depts)478 depts_db(depts)
458{479{
@@ -473,7 +494,8 @@
473494
474void InstallingPreview::run(const unity::scopes::PreviewReplyProxy &reply)495void InstallingPreview::run(const unity::scopes::PreviewReplyProxy &reply)
475{496{
476 downloader->startDownload(download_url, result["name"].get_string(),497 qDebug() << "Starting installation" << QString(download_url.c_str()) << QString(download_sha512.c_str());
498 downloader->startDownload(download_url, download_sha512, result["name"].get_string(),
477 [this, reply] (std::pair<std::string, click::InstallError> rc){499 [this, reply] (std::pair<std::string, click::InstallError> rc){
478 // NOTE: details not needed by fooErrorWidgets, so no need to populateDetails():500 // NOTE: details not needed by fooErrorWidgets, so no need to populateDetails():
479 switch (rc.second)501 switch (rc.second)
@@ -832,6 +854,7 @@
832 tuple["price"] = scopes::Variant(details.package.price);854 tuple["price"] = scopes::Variant(details.package.price);
833 tuple["store_item_id"] = details.package.name;855 tuple["store_item_id"] = details.package.name;
834 tuple["download_url"] = details.download_url;856 tuple["download_url"] = details.download_url;
857 tuple["download_sha512"] = details.download_sha512;
835 payments.add_attribute_value("source", scopes::Variant(tuple));858 payments.add_attribute_value("source", scopes::Variant(tuple));
836 widgets.push_back(payments);859 widgets.push_back(payments);
837 } else {860 } else {
@@ -841,7 +864,8 @@
841 {864 {
842 {"id", scopes::Variant(click::Preview::Actions::INSTALL_CLICK)},865 {"id", scopes::Variant(click::Preview::Actions::INSTALL_CLICK)},
843 {"label", scopes::Variant(_("Install"))},866 {"label", scopes::Variant(_("Install"))},
844 {"download_url", scopes::Variant(details.download_url)}867 {"download_url", scopes::Variant(details.download_url)},
868 {"download_sha512", scopes::Variant(details.download_sha512)},
845 });869 });
846 buttons.add_attribute_value("actions", builder.end());870 buttons.add_attribute_value("actions", builder.end());
847 widgets.push_back(buttons);871 widgets.push_back(buttons);
848872
=== modified file 'libclickscope/click/preview.h'
--- libclickscope/click/preview.h 2014-07-24 04:25:22 +0000
+++ libclickscope/click/preview.h 2014-08-13 14:49:17 +0000
@@ -42,6 +42,7 @@
42#include <unity/scopes/PreviewWidget.h>42#include <unity/scopes/PreviewWidget.h>
43#include <unity/scopes/Result.h>43#include <unity/scopes/Result.h>
44#include <unity/scopes/ScopeBase.h>44#include <unity/scopes/ScopeBase.h>
45#include <unity/util/DefinesPtrs.h>
4546
46namespace scopes = unity::scopes;47namespace scopes = unity::scopes;
4748
@@ -67,12 +68,21 @@
67{68{
68protected:69protected:
69 std::unique_ptr<PreviewStrategy> strategy;70 std::unique_ptr<PreviewStrategy> strategy;
70 PreviewStrategy* choose_strategy(const unity::scopes::Result& result,71 const unity::scopes::Result& result;
71 const unity::scopes::ActionMetadata& metadata,72 const unity::scopes::ActionMetadata& metadata;
72 const QSharedPointer<web::Client> &client,73 PreviewStrategy* build_strategy(const unity::scopes::Result& result,
73 const QSharedPointer<click::network::AccessManager>& nam,74 const unity::scopes::ActionMetadata& metadata,
74 std::shared_ptr<click::DepartmentsDb> depts);75 const QSharedPointer<web::Client> &client,
76 const QSharedPointer<click::network::AccessManager>& nam,
77 std::shared_ptr<click::DepartmentsDb> depts);
78 virtual PreviewStrategy* build_installing(const std::string& download_url,
79 const std::string& download_sha512,
80 const unity::scopes::Result& result,
81 const QSharedPointer<click::web::Client>& client,
82 const QSharedPointer<click::network::AccessManager>& nam,
83 std::shared_ptr<click::DepartmentsDb> depts);
75public:84public:
85 UNITY_DEFINES_PTRS(Preview);
76 struct Actions86 struct Actions
77 {87 {
78 Actions() = delete;88 Actions() = delete;
@@ -94,10 +104,11 @@
94104
95 Preview(const unity::scopes::Result& result);105 Preview(const unity::scopes::Result& result);
96 Preview(const unity::scopes::Result& result,106 Preview(const unity::scopes::Result& result,
97 const unity::scopes::ActionMetadata& metadata,107 const unity::scopes::ActionMetadata& metadata);
98 const QSharedPointer<click::web::Client>& client,108 virtual ~Preview();
99 const QSharedPointer<click::network::AccessManager>& nam,109 void choose_strategy(const QSharedPointer<web::Client> &client,
100 std::shared_ptr<click::DepartmentsDb> depts);110 const QSharedPointer<click::network::AccessManager>& nam,
111 std::shared_ptr<click::DepartmentsDb> depts);
101 // From unity::scopes::PreviewQuery112 // From unity::scopes::PreviewQuery
102 void cancelled() override;113 void cancelled() override;
103 virtual void run(unity::scopes::PreviewReplyProxy const& reply) override;114 virtual void run(unity::scopes::PreviewReplyProxy const& reply) override;
@@ -163,7 +174,8 @@
163{174{
164public:175public:
165 InstallingPreview(const unity::scopes::Result& result) : PreviewStrategy(result) {}176 InstallingPreview(const unity::scopes::Result& result) : PreviewStrategy(result) {}
166 InstallingPreview(std::string const& download_url,177 InstallingPreview(const std::string& download_url,
178 const std::string& download_sha512,
167 const unity::scopes::Result& result,179 const unity::scopes::Result& result,
168 const QSharedPointer<click::web::Client>& client,180 const QSharedPointer<click::web::Client>& client,
169 const QSharedPointer<click::network::AccessManager>& nam,181 const QSharedPointer<click::network::AccessManager>& nam,
@@ -176,6 +188,7 @@
176protected:188protected:
177 virtual scopes::PreviewWidgetList progressBarWidget(const std::string& object_path);189 virtual scopes::PreviewWidgetList progressBarWidget(const std::string& object_path);
178 std::string download_url;190 std::string download_url;
191 std::string download_sha512;
179 QSharedPointer<click::Downloader> downloader;192 QSharedPointer<click::Downloader> downloader;
180 std::shared_ptr<click::DepartmentsDb> depts_db;193 std::shared_ptr<click::DepartmentsDb> depts_db;
181 void startLauncherAnimation(const PackageDetails& details);194 void startLauncherAnimation(const PackageDetails& details);
182195
=== modified file 'libclickscope/tests/fake_json.cpp'
--- libclickscope/tests/fake_json.cpp 2014-08-05 19:00:03 +0000
+++ libclickscope/tests/fake_json.cpp 2014-08-13 14:49:17 +0000
@@ -194,6 +194,7 @@
194 "title": "\u1F4A9 Weather",194 "title": "\u1F4A9 Weather",
195 "description": "\u1F4A9 Weather\nA weather application.",195 "description": "\u1F4A9 Weather\nA weather application.",
196 "download_url": "https://public.apps.staging.ubuntu.com/download/ar.com.beuno/wheather-touch/ar.com.beuno.wheather-touch-0.2",196 "download_url": "https://public.apps.staging.ubuntu.com/download/ar.com.beuno/wheather-touch/ar.com.beuno.wheather-touch-0.2",
197 "download_sha512": "fake_sha512",
197 "rating": 3.5,198 "rating": 3.5,
198 "keywords": "these, are, key, words",199 "keywords": "these, are, key, words",
199200
200201
=== modified file 'libclickscope/tests/test_download_manager.cpp'
--- libclickscope/tests/test_download_manager.cpp 2014-06-19 21:22:53 +0000
+++ libclickscope/tests/test_download_manager.cpp 2014-08-13 14:49:17 +0000
@@ -58,6 +58,7 @@
58namespace58namespace
59{59{
60const QString TEST_URL("http://test.local/");60const QString TEST_URL("http://test.local/");
61const QString TEST_SHA512("fake_hash");
61const QString TEST_HEADER_VALUE("test header value");62const QString TEST_HEADER_VALUE("test header value");
62const QString TEST_APP_ID("test_app_id");63const QString TEST_APP_ID("test_app_id");
63const QString TEST_CLICK_TOKEN_VALUE("test token value");64const QString TEST_CLICK_TOKEN_VALUE("test token value");
@@ -326,7 +327,7 @@
326 QTimer timer;327 QTimer timer;
327 timer.setSingleShot(true);328 timer.setSingleShot(true);
328 QObject::connect(&timer, &QTimer::timeout, [&dm]() {329 QObject::connect(&timer, &QTimer::timeout, [&dm]() {
329 dm.fetchClickToken(TEST_URL);330 dm.fetchClickToken(TEST_URL, TEST_SHA512);
330 } );331 } );
331 timer.start(0);332 timer.start(0);
332333
@@ -466,7 +467,7 @@
466 QTimer timer;467 QTimer timer;
467 timer.setSingleShot(true);468 timer.setSingleShot(true);
468 QObject::connect(&timer, &QTimer::timeout, [&dm]() {469 QObject::connect(&timer, &QTimer::timeout, [&dm]() {
469 dm.startDownload(TEST_URL, TEST_APP_ID);470 dm.startDownload(TEST_URL, TEST_SHA512, TEST_APP_ID);
470 } );471 } );
471 timer.start(0);472 timer.start(0);
472473
473474
=== modified file 'libclickscope/tests/test_index.cpp'
--- libclickscope/tests/test_index.cpp 2014-08-05 19:00:03 +0000
+++ libclickscope/tests/test_index.cpp 2014-08-13 14:49:17 +0000
@@ -342,6 +342,7 @@
342 },342 },
343 "\u1F4A9 Weather\nA weather application.",343 "\u1F4A9 Weather\nA weather application.",
344 "https://public.apps.staging.ubuntu.com/download/ar.com.beuno/wheather-touch/ar.com.beuno.wheather-touch-0.2",344 "https://public.apps.staging.ubuntu.com/download/ar.com.beuno/wheather-touch/ar.com.beuno.wheather-touch-0.2",
345 "fake_sha512",
345 3.5,346 3.5,
346 "these, are, key, words",347 "these, are, key, words",
347348
@@ -407,6 +408,7 @@
407 },408 },
408 (std::string("\u1F4A9 ") + std::string(appname_utf8.constData()) + "\nA weather application.").c_str(),409 (std::string("\u1F4A9 ") + std::string(appname_utf8.constData()) + "\nA weather application.").c_str(),
409 "https://public.apps.staging.ubuntu.com/download/ar.com.beuno/wheather-touch/ar.com.beuno.wheather-touch-0.2",410 "https://public.apps.staging.ubuntu.com/download/ar.com.beuno/wheather-touch/ar.com.beuno.wheather-touch-0.2",
411 "fake_sha512",
410 3.5,412 3.5,
411 "these, are, key, words",413 "these, are, key, words",
412414
413415
=== modified file 'libclickscope/tests/test_preview.cpp'
--- libclickscope/tests/test_preview.cpp 2014-07-24 04:25:22 +0000
+++ libclickscope/tests/test_preview.cpp 2014-08-13 14:49:17 +0000
@@ -28,6 +28,7 @@
28 */28 */
2929
30#include <unity/scopes/testing/MockPreviewReply.h>30#include <unity/scopes/testing/MockPreviewReply.h>
31#include <unity/scopes/testing/Result.h>
3132
32#include <gtest/gtest.h>33#include <gtest/gtest.h>
33#include <click/preview.h>34#include <click/preview.h>
@@ -171,3 +172,41 @@
171 std::vector<std::string> expected_order {"header", "screenshots"};172 std::vector<std::string> expected_order {"header", "screenshots"};
172 ASSERT_EQ(expected_order, preview.call_order);173 ASSERT_EQ(expected_order, preview.call_order);
173}174}
175
176class StrategyChooserTest : public Test {
177protected:
178 unity::scopes::testing::Result result;
179 unity::scopes::ActionMetadata metadata;
180 unity::scopes::VariantMap metadict;
181 QSharedPointer<click::web::Client> client;
182 QSharedPointer<click::network::AccessManager> nam;
183 std::shared_ptr<click::DepartmentsDb> depts;
184 const std::string FAKE_SHA512 = "FAKE_SHA512";
185
186public:
187 StrategyChooserTest() : metadata("en_EN", "phone") {
188 }
189};
190
191class MockablePreview : public click::Preview {
192public:
193 MockablePreview(const unity::scopes::Result& result, const unity::scopes::ActionMetadata& metadata) :
194 click::Preview(result, metadata)
195 {
196
197 }
198
199 MOCK_METHOD6(build_installing, click::PreviewStrategy*(const std::string&, const std::string&,
200 const unity::scopes::Result&, const QSharedPointer<click::web::Client>&,
201 const QSharedPointer<click::network::AccessManager>&, std::shared_ptr<click::DepartmentsDb>));
202};
203
204TEST_F(StrategyChooserTest, testSha512IsUsed) {
205 metadict["action_id"] = click::Preview::Actions::INSTALL_CLICK;
206 metadict["download_url"] = "fake_download_url";
207 metadict["download_sha512"] = FAKE_SHA512;
208 metadata.set_scope_data(unity::scopes::Variant(metadict));
209 MockablePreview preview(result, metadata);
210 EXPECT_CALL(preview, build_installing(_, FAKE_SHA512, _, _, _, _));
211 preview.choose_strategy(client, nam, depts);
212}
174213
=== modified file 'scope/clickapps/apps-query.h'
--- scope/clickapps/apps-query.h 2014-07-22 13:17:28 +0000
+++ scope/clickapps/apps-query.h 2014-08-13 14:49:17 +0000
@@ -61,7 +61,6 @@
61 constexpr static const char* DESCRIPTION{"description"};61 constexpr static const char* DESCRIPTION{"description"};
62 constexpr static const char* MAIN_SCREENSHOT{"main_screenshot"};62 constexpr static const char* MAIN_SCREENSHOT{"main_screenshot"};
63 constexpr static const char* INSTALLED{"installed"};63 constexpr static const char* INSTALLED{"installed"};
64 constexpr static const char* DOWNLOAD_URL{"download_url"};
65 constexpr static const char* VERSION{"version"};64 constexpr static const char* VERSION{"version"};
66 };65 };
6766
6867
=== modified file 'scope/clickapps/apps-scope.cpp'
--- scope/clickapps/apps-scope.cpp 2014-08-06 21:48:26 +0000
+++ scope/clickapps/apps-scope.cpp 2014-08-13 14:49:17 +0000
@@ -98,7 +98,9 @@
98unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,98unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,
99 const unity::scopes::ActionMetadata& metadata) {99 const unity::scopes::ActionMetadata& metadata) {
100 qDebug() << "Scope::preview() called.";100 qDebug() << "Scope::preview() called.";
101 return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam, depts_db)};101 auto preview = new click::Preview(result, metadata);
102 preview->choose_strategy(client, nam, depts_db);
103 return unity::scopes::PreviewQueryBase::UPtr{preview};
102}104}
103105
104106
105107
=== modified file 'scope/clickstore/store-query.h'
--- scope/clickstore/store-query.h 2014-07-16 21:49:11 +0000
+++ scope/clickstore/store-query.h 2014-08-13 14:49:17 +0000
@@ -65,7 +65,6 @@
65 constexpr static const char* MAIN_SCREENSHOT{"main_screenshot"};65 constexpr static const char* MAIN_SCREENSHOT{"main_screenshot"};
66 constexpr static const char* INSTALLED{"installed"};66 constexpr static const char* INSTALLED{"installed"};
67 constexpr static const char* PURCHASED{"purchased"};67 constexpr static const char* PURCHASED{"purchased"};
68 constexpr static const char* DOWNLOAD_URL{"download_url"};
69 constexpr static const char* VERSION{"version"};68 constexpr static const char* VERSION{"version"};
70 };69 };
7170
7271
=== modified file 'scope/clickstore/store-scope.cpp'
--- scope/clickstore/store-scope.cpp 2014-08-01 15:04:19 +0000
+++ scope/clickstore/store-scope.cpp 2014-08-13 14:49:17 +0000
@@ -102,7 +102,9 @@
102unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,102unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,
103 const unity::scopes::ActionMetadata& metadata) {103 const unity::scopes::ActionMetadata& metadata) {
104 qDebug() << "Scope::preview() called.";104 qDebug() << "Scope::preview() called.";
105 return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam, depts_db)};105 auto preview = new click::Preview(result, metadata);
106 preview->choose_strategy(client, nam, depts_db);
107 return unity::scopes::PreviewQueryBase::UPtr{preview};
106}108}
107109
108unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata,110unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata,
@@ -119,6 +121,8 @@
119 std::string download_url = metadata.scope_data().get_dict()["download_url"].get_string();121 std::string download_url = metadata.scope_data().get_dict()["download_url"].get_string();
120 qDebug() << "the download url is: " << QString::fromStdString(download_url);122 qDebug() << "the download url is: " << QString::fromStdString(download_url);
121 activation->setHint("download_url", unity::scopes::Variant(download_url));123 activation->setHint("download_url", unity::scopes::Variant(download_url));
124 std::string download_sha512 = metadata.scope_data().get_dict()["download_sha512"].get_string();
125 activation->setHint("download_sha512", unity::scopes::Variant(download_sha512));
122 activation->setHint("action_id", unity::scopes::Variant(click::Preview::Actions::INSTALL_CLICK));126 activation->setHint("action_id", unity::scopes::Variant(click::Preview::Actions::INSTALL_CLICK));
123 qDebug() << "returning ShowPreview";127 qDebug() << "returning ShowPreview";
124 activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview);128 activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview);
@@ -130,6 +134,8 @@
130 std::string download_url = metadata.scope_data().get_dict()["download_url"].get_string();134 std::string download_url = metadata.scope_data().get_dict()["download_url"].get_string();
131 qDebug() << "the download url is: " << QString::fromStdString(download_url);135 qDebug() << "the download url is: " << QString::fromStdString(download_url);
132 activation->setHint("download_url", unity::scopes::Variant(download_url));136 activation->setHint("download_url", unity::scopes::Variant(download_url));
137 std::string download_sha512 = metadata.scope_data().get_dict()["download_sha512"].get_string();
138 activation->setHint("download_sha512", unity::scopes::Variant(download_sha512));
133 activation->setHint("action_id", unity::scopes::Variant(action_id));139 activation->setHint("action_id", unity::scopes::Variant(action_id));
134 qDebug() << "returning ShowPreview";140 qDebug() << "returning ShowPreview";
135 activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview);141 activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview);
136142
=== modified file 'scope/tests/CMakeLists.txt'
--- scope/tests/CMakeLists.txt 2014-07-22 17:15:14 +0000
+++ scope/tests/CMakeLists.txt 2014-08-13 14:49:17 +0000
@@ -20,6 +20,7 @@
20add_executable (${CLICKSCOPE_TESTS_TARGET}20add_executable (${CLICKSCOPE_TESTS_TARGET}
21 test_pay.cpp21 test_pay.cpp
22 test_query.cpp22 test_query.cpp
23 test_store_scope.cpp
23)24)
2425
25add_executable (${APPS_SCOPE_TESTS_TARGET}26add_executable (${APPS_SCOPE_TESTS_TARGET}
2627
=== modified file 'scope/tests/download_manager_tool/download_manager_tool.cpp'
--- scope/tests/download_manager_tool/download_manager_tool.cpp 2014-02-19 22:35:42 +0000
+++ scope/tests/download_manager_tool/download_manager_tool.cpp 2014-08-13 14:49:17 +0000
@@ -54,22 +54,22 @@
54 emit finished();54 emit finished();
55}55}
5656
57void DownloadManagerTool::fetchClickToken(QString url)57void DownloadManagerTool::fetchClickToken(QString url, QString sha512)
58{58{
59 QObject::connect(_dm, &click::DownloadManager::clickTokenFetched,59 QObject::connect(_dm, &click::DownloadManager::clickTokenFetched,
60 this, &DownloadManagerTool::handleResponse);60 this, &DownloadManagerTool::handleResponse);
61 QObject::connect(_dm, &click::DownloadManager::clickTokenFetchError,61 QObject::connect(_dm, &click::DownloadManager::clickTokenFetchError,
62 this, &DownloadManagerTool::handleResponse);62 this, &DownloadManagerTool::handleResponse);
63 _dm->fetchClickToken(url);63 _dm->fetchClickToken(url, sha512);
64}64}
6565
66void DownloadManagerTool::startDownload(QString url, QString appId)66void DownloadManagerTool::startDownload(QString url, QString sha512, QString appId)
67{67{
68 QObject::connect(_dm, &click::DownloadManager::downloadStarted,68 QObject::connect(_dm, &click::DownloadManager::downloadStarted,
69 this, &DownloadManagerTool::handleResponse);69 this, &DownloadManagerTool::handleResponse);
70 QObject::connect(_dm, &click::DownloadManager::downloadError,70 QObject::connect(_dm, &click::DownloadManager::downloadError,
71 this, &DownloadManagerTool::handleResponse);71 this, &DownloadManagerTool::handleResponse);
72 _dm->startDownload(url, appId);72 _dm->startDownload(url, sha512, appId);
73}73}
7474
75int main(int argc, char *argv[])75int main(int argc, char *argv[])
@@ -83,16 +83,16 @@
8383
84 QObject::connect(&tool, SIGNAL(finished()), &a, SLOT(quit()));84 QObject::connect(&tool, SIGNAL(finished()), &a, SLOT(quit()));
8585
86 if (argc == 2) {86 if (argc == 3) {
8787
88 QObject::connect(&timer, &QTimer::timeout, [&]() {88 QObject::connect(&timer, &QTimer::timeout, [&]() {
89 tool.fetchClickToken(QString(argv[1]));89 tool.fetchClickToken(QString(argv[1]), QString(argv[2]));
90 } );90 } );
9191
92 } else if (argc == 3) {92 } else if (argc == 4) {
9393
94 QObject::connect(&timer, &QTimer::timeout, [&]() {94 QObject::connect(&timer, &QTimer::timeout, [&]() {
95 downloader.startDownload(std::string(argv[1]), std::string(argv[2]),95 downloader.startDownload(std::string(argv[1]), std::string(argv[2]), std::string(argv[3]),
96 [&a] (std::pair<std::string, click::InstallError> arg){96 [&a] (std::pair<std::string, click::InstallError> arg){
97 auto error = arg.second;97 auto error = arg.second;
98 if (error == click::InstallError::NoError) {98 if (error == click::InstallError::NoError) {
@@ -107,9 +107,9 @@
107 107
108 } else {108 } else {
109 QTextStream(stderr) << "Usages:\n"109 QTextStream(stderr) << "Usages:\n"
110 << "download_manager_tool https://public.apps.ubuntu.com/download/<<rest of click package dl url>>\n" 110 << "download_manager_tool https://public.apps.ubuntu.com/download/<<rest of click package dl url>> sha512\n"
111 << "\t - when run with a valid U1 credential in the system, should print the click token to stdout.\n"111 << "\t - when run with a valid U1 credential in the system, should print the click token to stdout.\n"
112 << "download_manager_tool url app_id\n"112 << "download_manager_tool url sha512 app_id\n"
113 << "\t - with a valid credential, should begin a download.\n";113 << "\t - with a valid credential, should begin a download.\n";
114 114
115 return 1;115 return 1;
116116
=== modified file 'scope/tests/download_manager_tool/download_manager_tool.h'
--- scope/tests/download_manager_tool/download_manager_tool.h 2014-02-11 09:47:54 +0000
+++ scope/tests/download_manager_tool/download_manager_tool.h 2014-08-13 14:49:17 +0000
@@ -40,8 +40,8 @@
40 explicit DownloadManagerTool(QObject *parent=0);40 explicit DownloadManagerTool(QObject *parent=0);
41 41
42public slots:42public slots:
43 void fetchClickToken(QString url);43 void fetchClickToken(QString url, QString sha512);
44 void startDownload(QString url, QString appId);44 void startDownload(QString url, QString sha512, QString appId);
4545
46private slots:46private slots:
47 void handleResponse(QString response);47 void handleResponse(QString response);
4848
=== added file 'scope/tests/test_store_scope.cpp'
--- scope/tests/test_store_scope.cpp 1970-01-01 00:00:00 +0000
+++ scope/tests/test_store_scope.cpp 2014-08-13 14:49:17 +0000
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * In addition, as a special exception, the copyright holders give
17 * permission to link the code of portions of this program with the
18 * OpenSSL library under certain conditions as described in each
19 * individual source file, and distribute linked combinations
20 * including the two.
21 * You must obey the GNU General Public License in all respects
22 * for all of the code used other than OpenSSL. If you modify
23 * file(s) with this exception, you may extend this exception to your
24 * version of the file(s), but you are not obligated to do so. If you
25 * do not wish to do so, delete this exception statement from your
26 * version. If you delete this exception statement from all source
27 * files in the program, then also delete it here.
28 */
29
30#include <gtest/gtest.h>
31#include <gmock/gmock.h>
32
33#include <unity/scopes/testing/Result.h>
34
35#include <click/preview.h>
36#include <clickstore/store-scope.h>
37
38using namespace ::testing;
39
40class StoreScopeTest : public Test {
41protected:
42 const std::string FAKE_SHA512 = "FAKE_SHA512";
43 click::Scope scope;
44 unity::scopes::testing::Result result;
45 unity::scopes::ActionMetadata metadata;
46 unity::scopes::VariantMap metadict;
47
48public:
49 StoreScopeTest() : metadata("en_EN", "phone") {
50 metadict["download_url"] = "fake_download_url";
51 metadict["download_sha512"] = FAKE_SHA512;
52 metadata.set_scope_data(unity::scopes::Variant(metadict));
53 }
54};
55
56TEST_F(StoreScopeTest, testPurchaseCompletedPassesHash)
57{
58 auto activation = scope.perform_action(result, metadata, "widget_id", "purchaseCompleted");
59 auto response = activation->activate();
60 EXPECT_EQ(FAKE_SHA512, response.scope_data().get_dict()["download_sha512"].get_string());
61}
62
63TEST_F(StoreScopeTest, testInstallClickPassesHash)
64{
65 auto activation = scope.perform_action(result, metadata, "widget_id", click::Preview::Actions::INSTALL_CLICK);
66 auto response = activation->activate();
67 EXPECT_EQ(FAKE_SHA512, response.scope_data().get_dict()["download_sha512"].get_string());
68}

Subscribers

People subscribed via source and target branches

to all changes: