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