Merge lp:~dobey/unity-scope-click/no-more-click into lp:unity-scope-click
- no-more-click
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | dobey |
Approved revision: | 509 |
Merged at revision: | 510 |
Proposed branch: | lp:~dobey/unity-scope-click/no-more-click |
Merge into: | lp:unity-scope-click |
Diff against target: |
3453 lines (+11/-2854) 28 files modified
CMakeLists.txt (+0/-7) bin/CMakeLists.txt (+0/-1) bin/install-helper (+0/-77) debian/control (+0/-9) debian/unity-scope-click.install (+0/-1) libclickscope/click/CMakeLists.txt (+0/-9) libclickscope/click/download-manager.cpp (+0/-177) libclickscope/click/download-manager.h (+0/-87) libclickscope/click/index.cpp (+0/-43) libclickscope/click/interface.cpp (+0/-90) libclickscope/click/interface.h (+0/-4) libclickscope/click/preview.cpp (+8/-610) libclickscope/click/preview.h (+0/-122) libclickscope/click/reviews.cpp (+0/-245) libclickscope/click/reviews.h (+0/-95) libclickscope/click/scope_activation.cpp (+0/-40) libclickscope/click/scope_activation.h (+0/-7) libclickscope/tests/CMakeLists.txt (+0/-5) libclickscope/tests/mock_ubuntu_download_manager.h (+0/-140) libclickscope/tests/test_bootstrap.cpp (+0/-1) libclickscope/tests/test_download_manager.cpp (+0/-220) libclickscope/tests/test_index.cpp (+0/-12) libclickscope/tests/test_interface.cpp (+0/-74) libclickscope/tests/test_preview.cpp (+0/-181) libclickscope/tests/test_reviews.cpp (+0/-487) scope/clickapps/apps-scope.cpp (+3/-42) scope/clickapps/apps-scope.h (+0/-2) scope/tests/test_apps_scope.cpp (+0/-66) |
To merge this branch: | bzr merge lp:~dobey/unity-scope-click/no-more-click |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Charles Kerr (community) | Approve | ||
unity-api-1-bot | continuous-integration | Approve | |
Review via email: mp+312754@code.launchpad.net |
Commit message
Remove deps on ubuntu-
Remove download-manager, installing, uninstalling, and reviews code.
Description of the change
unity-api-1-bot (unity-api-1-bot) wrote : | # |
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:505
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:506
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:506
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
PASSED: Continuous integration, rev:507
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:507
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
PASSED: Continuous integration, rev:508
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Charles Kerr (charlesk) : | # |
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2016-12-02 18:37:59 +0000 | |||
3 | +++ CMakeLists.txt 2017-01-10 16:06:37 +0000 | |||
4 | @@ -26,9 +26,6 @@ | |||
5 | 26 | pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2>=0.9 gobject-2.0) | 26 | pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2>=0.9 gobject-2.0) |
6 | 27 | add_definitions(${UAL_CFLAGS} ${UAL_CFLAGS_OTHER}) | 27 | add_definitions(${UAL_CFLAGS} ${UAL_CFLAGS_OTHER}) |
7 | 28 | 28 | ||
8 | 29 | pkg_check_modules(CLICK REQUIRED click-0.4) | ||
9 | 30 | add_definitions(${CLICK_CFLAGS} ${CLICK_CFLAGS_OTHER}) | ||
10 | 31 | |||
11 | 32 | pkg_check_modules(UNITY_SCOPES REQUIRED libunity-scopes>=0.6.7 libunity-api>=0.1.3) | 29 | pkg_check_modules(UNITY_SCOPES REQUIRED libunity-scopes>=0.6.7 libunity-api>=0.1.3) |
12 | 33 | add_definitions(${UNITY_SCOPES_CFLAGS} ${UNITY_SCOPES_CFLAGS_OTHER}) | 30 | add_definitions(${UNITY_SCOPES_CFLAGS} ${UNITY_SCOPES_CFLAGS_OTHER}) |
13 | 34 | 31 | ||
14 | @@ -38,9 +35,6 @@ | |||
15 | 38 | pkg_check_modules(UBUNTUONE REQUIRED ubuntuoneauth-2.0>=15.10) | 35 | pkg_check_modules(UBUNTUONE REQUIRED ubuntuoneauth-2.0>=15.10) |
16 | 39 | add_definitions(${UBUNTUONE_CFLAGS} ${UBUNTUONE_CFLAGS_OTHER}) | 36 | add_definitions(${UBUNTUONE_CFLAGS} ${UBUNTUONE_CFLAGS_OTHER}) |
17 | 40 | 37 | ||
18 | 41 | pkg_check_modules(UBUNTU_DOWNLOAD_MANAGER_CLIENT REQUIRED ubuntu-download-manager-client) | ||
19 | 42 | pkg_check_modules(UBUNTU_DOWNLOAD_MANAGER_COMMON REQUIRED ubuntu-download-manager-common) | ||
20 | 43 | |||
21 | 44 | SET (SCOPE_LIB_VERSION 0.2.0) | 38 | SET (SCOPE_LIB_VERSION 0.2.0) |
22 | 45 | SET (SCOPE_LIB_SOVERSION 0) | 39 | SET (SCOPE_LIB_SOVERSION 0) |
23 | 46 | SET (SCOPE_LIB_API_VERSION 2.0) | 40 | SET (SCOPE_LIB_API_VERSION 2.0) |
24 | @@ -50,7 +44,6 @@ | |||
25 | 50 | 44 | ||
26 | 51 | # Add our own subdirectories. | 45 | # Add our own subdirectories. |
27 | 52 | add_subdirectory(tests) | 46 | add_subdirectory(tests) |
28 | 53 | add_subdirectory(bin) | ||
29 | 54 | add_subdirectory(libclickscope) | 47 | add_subdirectory(libclickscope) |
30 | 55 | add_subdirectory(scope) | 48 | add_subdirectory(scope) |
31 | 56 | add_subdirectory(data) | 49 | add_subdirectory(data) |
32 | 57 | 50 | ||
33 | === removed directory 'bin' | |||
34 | === removed file 'bin/CMakeLists.txt' | |||
35 | --- bin/CMakeLists.txt 2016-10-25 13:12:57 +0000 | |||
36 | +++ bin/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
37 | @@ -1,1 +0,0 @@ | |||
38 | 1 | install(PROGRAMS install-helper DESTINATION lib/unity-scope-click/) | ||
39 | 2 | 0 | ||
40 | === removed file 'bin/install-helper' | |||
41 | --- bin/install-helper 2014-06-20 05:09:01 +0000 | |||
42 | +++ bin/install-helper 1970-01-01 00:00:00 +0000 | |||
43 | @@ -1,77 +0,0 @@ | |||
44 | 1 | #!/bin/bash | ||
45 | 2 | # | ||
46 | 3 | # Copyright (C) 2014 Canonical Ltd. | ||
47 | 4 | # | ||
48 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
49 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
50 | 7 | # by the Free Software Foundation. | ||
51 | 8 | # | ||
52 | 9 | # This program is distributed in the hope that it will be useful, but | ||
53 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
54 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
55 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
56 | 13 | # | ||
57 | 14 | # You should have received a copy of the GNU General Public License along | ||
58 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
59 | 16 | # | ||
60 | 17 | # In addition, as a special exception, the copyright holders give | ||
61 | 18 | # permission to link the code of portions of this program with the | ||
62 | 19 | # OpenSSL library under certain conditions as described in each | ||
63 | 20 | # individual source file, and distribute linked combinations | ||
64 | 21 | # including the two. | ||
65 | 22 | # You must obey the GNU General Public License in all respects | ||
66 | 23 | # for all of the code used other than OpenSSL. If you modify | ||
67 | 24 | # file(s) with this exception, you may extend this exception to your | ||
68 | 25 | # version of the file(s), but you are not obligated to do so. If you | ||
69 | 26 | # do not wish to do so, delete this exception statement from your | ||
70 | 27 | # version. If you delete this exception statement from all source | ||
71 | 28 | # files in the program, then also delete it here. | ||
72 | 29 | # | ||
73 | 30 | |||
74 | 31 | FILE_NAME="$1" | ||
75 | 32 | PACKAGE_NAME="$2" | ||
76 | 33 | |||
77 | 34 | SCOPES_OBJECTPATH=/com/canonical/unity/scopes | ||
78 | 35 | SCOPES_INTERFACE=com.canonical.unity.scopes | ||
79 | 36 | SCOPES_METHOD=InvalidateResults | ||
80 | 37 | |||
81 | 38 | LAUNCHER_BUS=com.ubuntu.unity.launcher | ||
82 | 39 | LAUNCHER_OBJECTPATH=/com/ubuntu/unity/launcher/installations | ||
83 | 40 | LAUNCHER_INTERFACE=com.ubuntu.unity.launcher.Installations | ||
84 | 41 | LAUNCHER_METHOD=completeInstallation | ||
85 | 42 | |||
86 | 43 | function invalidate-scope { | ||
87 | 44 | SCOPE_ID=$1 | ||
88 | 45 | dbus-send $SCOPES_OBJECTPATH $SCOPES_INTERFACE.$SCOPES_METHOD string:$SCOPE_ID | ||
89 | 46 | } | ||
90 | 47 | |||
91 | 48 | function install-package { | ||
92 | 49 | FILE_NAME="$1" | ||
93 | 50 | pkcon -p install-local "$FILE_NAME" | ||
94 | 51 | } | ||
95 | 52 | |||
96 | 53 | function app_id-from-package_name { | ||
97 | 54 | PACKAGE_NAME=$1 | ||
98 | 55 | IFS=_ | ||
99 | 56 | TRIPLET=($(ubuntu-app-triplet $PACKAGE_NAME)) | ||
100 | 57 | unset IFS | ||
101 | 58 | echo ${TRIPLET[0]}_${TRIPLET[1]}_current-user-version | ||
102 | 59 | } | ||
103 | 60 | |||
104 | 61 | function complete-installation { | ||
105 | 62 | PACKAGE_NAME=$1 | ||
106 | 63 | APP_ID=$2 | ||
107 | 64 | dbus-send --dest=$LAUNCHER_BUS --type=method_call $LAUNCHER_OBJECTPATH $LAUNCHER_INTERFACE.$LAUNCHER_METHOD string:$PACKAGE_NAME string:$APP_ID | ||
108 | 65 | } | ||
109 | 66 | |||
110 | 67 | if install-package "$FILE_NAME" ; then | ||
111 | 68 | invalidate-scope clickscope | ||
112 | 69 | invalidate-scope com.canonical.scopes.clickstore | ||
113 | 70 | APP_ID=$(app_id-from-package_name $PACKAGE_NAME) | ||
114 | 71 | complete-installation $PACKAGE_NAME $APP_ID | ||
115 | 72 | else | ||
116 | 73 | PKCON_STATUS=$? | ||
117 | 74 | NO_APP_ID="" | ||
118 | 75 | complete-installation $PACKAGE_NAME $NO_APP_ID | ||
119 | 76 | exit $PKCON_STATUS | ||
120 | 77 | fi | ||
121 | 78 | 0 | ||
122 | === modified file 'debian/control' | |||
123 | --- debian/control 2016-12-21 15:27:35 +0000 | |||
124 | +++ debian/control 2017-01-10 16:06:37 +0000 | |||
125 | @@ -12,24 +12,19 @@ | |||
126 | 12 | intltool, | 12 | intltool, |
127 | 13 | lcov, | 13 | lcov, |
128 | 14 | libboost-locale-dev, | 14 | libboost-locale-dev, |
129 | 15 | libclick-0.4-dev, | ||
130 | 16 | libglib2.0-dev (>= 2.32), | 15 | libglib2.0-dev (>= 2.32), |
131 | 17 | libjsoncpp-dev, | 16 | libjsoncpp-dev, |
132 | 18 | libubuntu-app-launch2-dev (>= 0.9), | 17 | libubuntu-app-launch2-dev (>= 0.9), |
133 | 19 | libubuntu-download-manager-client-dev (>= 0.3+14.10.20140430-0ubuntu1), | ||
134 | 20 | libubuntu-download-manager-common-dev (>= 0.3+14.10.20140430-0ubuntu1), | ||
135 | 21 | libubuntuoneauth-2.0-dev (>= 15.10), | 18 | libubuntuoneauth-2.0-dev (>= 15.10), |
136 | 22 | libunity-api-dev (>= 7.80.7), | 19 | libunity-api-dev (>= 7.80.7), |
137 | 23 | libunity-scopes-dev (>= 0.6.7~), | 20 | libunity-scopes-dev (>= 0.6.7~), |
138 | 24 | libgsettings-qt-dev, | 21 | libgsettings-qt-dev, |
139 | 25 | ubuntu-sdk-libs, | ||
140 | 26 | pkg-config, | 22 | pkg-config, |
141 | 27 | python3-all:native, | 23 | python3-all:native, |
142 | 28 | python3-fixtures, | 24 | python3-fixtures, |
143 | 29 | python3-scope-harness (>= 0.5.8), | 25 | python3-scope-harness (>= 0.5.8), |
144 | 30 | python3-testtools, | 26 | python3-testtools, |
145 | 31 | xvfb, | 27 | xvfb, |
146 | 32 | ubuntu-download-manager, | ||
147 | 33 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> | 28 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
148 | 34 | Standards-Version: 3.9.5 | 29 | Standards-Version: 3.9.5 |
149 | 35 | Homepage: https://launchpad.net/unity-scope-click | 30 | Homepage: https://launchpad.net/unity-scope-click |
150 | @@ -42,10 +37,6 @@ | |||
151 | 42 | Depends: account-plugin-ubuntuone, | 37 | Depends: account-plugin-ubuntuone, |
152 | 43 | libglib2.0-bin, | 38 | libglib2.0-bin, |
153 | 44 | libsqlite3-0 (>= 3.8.5), | 39 | libsqlite3-0 (>= 3.8.5), |
154 | 45 | packagekit, | ||
155 | 46 | packagekit-tools, | ||
156 | 47 | ubuntu-app-launch-tools, | ||
157 | 48 | ubuntu-download-manager, | ||
158 | 49 | ${misc:Depends}, | 40 | ${misc:Depends}, |
159 | 50 | ${shlibs:Depends}, | 41 | ${shlibs:Depends}, |
160 | 51 | Breaks: unity (<< 7.0), | 42 | Breaks: unity (<< 7.0), |
161 | 52 | 43 | ||
162 | === modified file 'debian/unity-scope-click.install' | |||
163 | --- debian/unity-scope-click.install 2016-11-04 20:17:19 +0000 | |||
164 | +++ debian/unity-scope-click.install 2017-01-10 16:06:37 +0000 | |||
165 | @@ -1,5 +1,4 @@ | |||
166 | 1 | usr/lib/*/unity-scopes/* | 1 | usr/lib/*/unity-scopes/* |
167 | 2 | usr/lib/unity-scope-click/* | ||
168 | 3 | usr/share/unity/scopes/clickapps/*.jpg | 2 | usr/share/unity/scopes/clickapps/*.jpg |
169 | 4 | usr/share/unity/scopes/clickapps/*.png | 3 | usr/share/unity/scopes/clickapps/*.png |
170 | 5 | usr/share/unity/scopes/clickapps/*.svg | 4 | usr/share/unity/scopes/clickapps/*.svg |
171 | 6 | 5 | ||
172 | === modified file 'libclickscope/click/CMakeLists.txt' | |||
173 | --- libclickscope/click/CMakeLists.txt 2016-10-24 21:26:23 +0000 | |||
174 | +++ libclickscope/click/CMakeLists.txt 2017-01-10 16:06:37 +0000 | |||
175 | @@ -8,13 +8,11 @@ | |||
176 | 8 | add_definitions( | 8 | add_definitions( |
177 | 9 | -DGETTEXT_PACKAGE=\"${PROJECT_NAME}\" | 9 | -DGETTEXT_PACKAGE=\"${PROJECT_NAME}\" |
178 | 10 | -DGETTEXT_LOCALEDIR=\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}\" | 10 | -DGETTEXT_LOCALEDIR=\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}\" |
179 | 11 | -DCLICK_INSTALL_HELPER=\"${CMAKE_INSTALL_PREFIX}/lib/unity-scope-click/install-helper\" | ||
180 | 12 | ${GSETTINGS_QT_CFLAGS} ${GSETTINGS_QT_OTHER} | 11 | ${GSETTINGS_QT_CFLAGS} ${GSETTINGS_QT_OTHER} |
181 | 13 | ) | 12 | ) |
182 | 14 | 13 | ||
183 | 15 | add_library(${SCOPE_LIB_NAME} STATIC | 14 | add_library(${SCOPE_LIB_NAME} STATIC |
184 | 16 | configuration.cpp | 15 | configuration.cpp |
185 | 17 | download-manager.cpp | ||
186 | 18 | department-lookup.cpp | 16 | department-lookup.cpp |
187 | 19 | departments.cpp | 17 | departments.cpp |
188 | 20 | departments-db.cpp | 18 | departments-db.cpp |
189 | @@ -25,7 +23,6 @@ | |||
190 | 25 | network_access_manager.cpp | 23 | network_access_manager.cpp |
191 | 26 | package.cpp | 24 | package.cpp |
192 | 27 | preview.cpp | 25 | preview.cpp |
193 | 28 | reviews.cpp | ||
194 | 29 | qtbridge.cpp | 26 | qtbridge.cpp |
195 | 30 | scope_activation.cpp | 27 | scope_activation.cpp |
196 | 31 | smartconnect.cpp | 28 | smartconnect.cpp |
197 | @@ -38,22 +35,16 @@ | |||
198 | 38 | 35 | ||
199 | 39 | include_directories( | 36 | include_directories( |
200 | 40 | ${JSON_CPP_INCLUDE_DIRS} | 37 | ${JSON_CPP_INCLUDE_DIRS} |
201 | 41 | ${LIBPAY_INCLUDE_DIRS} | ||
202 | 42 | ${GSETTINGS_QT_INCLUDE_DIRS} | 38 | ${GSETTINGS_QT_INCLUDE_DIRS} |
203 | 43 | ${UAL_INCLUDE_DIRS} | 39 | ${UAL_INCLUDE_DIRS} |
204 | 44 | ${CLICK_INCLUDE_DIRS} | ||
205 | 45 | ${CMAKE_SOURCE_DIR}/libclickscope | 40 | ${CMAKE_SOURCE_DIR}/libclickscope |
206 | 46 | ) | 41 | ) |
207 | 47 | 42 | ||
208 | 48 | target_link_libraries (${SCOPE_LIB_NAME} | 43 | target_link_libraries (${SCOPE_LIB_NAME} |
209 | 49 | ${JSON_CPP_LDFLAGS} | 44 | ${JSON_CPP_LDFLAGS} |
210 | 50 | ${LIBPAY_LDFLAGS} | ||
211 | 51 | ${UNITY_SCOPES_LDFLAGS} | 45 | ${UNITY_SCOPES_LDFLAGS} |
212 | 52 | ${UBUNTUONE_LDFLAGS} | 46 | ${UBUNTUONE_LDFLAGS} |
213 | 53 | ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS} | ||
214 | 54 | ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS} | ||
215 | 55 | ${GSETTINGS_QT_LIBRARIES} | 47 | ${GSETTINGS_QT_LIBRARIES} |
216 | 56 | ${UAL_LDFLAGS} | 48 | ${UAL_LDFLAGS} |
217 | 57 | ${CLICK_LDFLAGS} | ||
218 | 58 | -lboost_locale | 49 | -lboost_locale |
219 | 59 | ) | 50 | ) |
220 | 60 | 51 | ||
221 | === removed file 'libclickscope/click/download-manager.cpp' | |||
222 | --- libclickscope/click/download-manager.cpp 2016-05-10 13:42:12 +0000 | |||
223 | +++ libclickscope/click/download-manager.cpp 1970-01-01 00:00:00 +0000 | |||
224 | @@ -1,177 +0,0 @@ | |||
225 | 1 | /* | ||
226 | 2 | * Copyright (C) 2014-2016 Canonical Ltd. | ||
227 | 3 | * | ||
228 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
229 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
230 | 6 | * by the Free Software Foundation. | ||
231 | 7 | * | ||
232 | 8 | * This program is distributed in the hope that it will be useful, but | ||
233 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
234 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
235 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
236 | 12 | * | ||
237 | 13 | * You should have received a copy of the GNU General Public License along | ||
238 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
239 | 15 | * | ||
240 | 16 | * In addition, as a special exception, the copyright holders give | ||
241 | 17 | * permission to link the code of portions of this program with the | ||
242 | 18 | * OpenSSL library under certain conditions as described in each | ||
243 | 19 | * individual source file, and distribute linked combinations | ||
244 | 20 | * including the two. | ||
245 | 21 | * You must obey the GNU General Public License in all respects | ||
246 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
247 | 23 | * file(s) with this exception, you may extend this exception to your | ||
248 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
249 | 25 | * do not wish to do so, delete this exception statement from your | ||
250 | 26 | * version. If you delete this exception statement from all source | ||
251 | 27 | * files in the program, then also delete it here. | ||
252 | 28 | */ | ||
253 | 29 | |||
254 | 30 | #include "download-manager.h" | ||
255 | 31 | |||
256 | 32 | #include <QDebug> | ||
257 | 33 | #include <QObject> | ||
258 | 34 | #include <QString> | ||
259 | 35 | #include <QStringBuilder> | ||
260 | 36 | #include <QTimer> | ||
261 | 37 | |||
262 | 38 | #include <click/qtbridge.h> | ||
263 | 39 | |||
264 | 40 | namespace u1 = UbuntuOne; | ||
265 | 41 | #include <click/ubuntuone_credentials.h> | ||
266 | 42 | #include <token.h> | ||
267 | 43 | |||
268 | 44 | namespace udm = Ubuntu::DownloadManager; | ||
269 | 45 | #include <ubuntu/download_manager/download_struct.h> | ||
270 | 46 | #include <ubuntu/download_manager/downloads_list.h> | ||
271 | 47 | #include <ubuntu/download_manager/download.h> | ||
272 | 48 | #include <ubuntu/download_manager/error.h> | ||
273 | 49 | |||
274 | 50 | namespace click | ||
275 | 51 | { | ||
276 | 52 | |||
277 | 53 | static const QString DOWNLOAD_APP_ID_KEY = "app_id"; | ||
278 | 54 | static const QString DOWNLOAD_COMMAND_KEY = "post-download-command"; | ||
279 | 55 | |||
280 | 56 | static const QString DOWNLOAD_COMMAND = CLICK_INSTALL_HELPER; | ||
281 | 57 | |||
282 | 58 | static const QString DOWNLOAD_MANAGER_SHA512 = "sha512"; | ||
283 | 59 | |||
284 | 60 | const QByteArray& CLICK_TOKEN_HEADER() | ||
285 | 61 | { | ||
286 | 62 | static const QByteArray result("X-Click-Token"); | ||
287 | 63 | return result; | ||
288 | 64 | } | ||
289 | 65 | |||
290 | 66 | DownloadManager::DownloadManager(const QSharedPointer<click::web::Client>& client, | ||
291 | 67 | const QSharedPointer<udm::Manager>& manager) : | ||
292 | 68 | client(client), | ||
293 | 69 | dm(manager) | ||
294 | 70 | { | ||
295 | 71 | } | ||
296 | 72 | |||
297 | 73 | DownloadManager::~DownloadManager() | ||
298 | 74 | { | ||
299 | 75 | } | ||
300 | 76 | |||
301 | 77 | void DownloadManager::get_progress(const std::string& package_name, | ||
302 | 78 | const std::function<void (std::string)>& callback) | ||
303 | 79 | { | ||
304 | 80 | dm->getAllDownloadsWithMetadata(DOWNLOAD_APP_ID_KEY, | ||
305 | 81 | QString::fromStdString(package_name), | ||
306 | 82 | [callback, package_name](const QString& /*key*/, const QString& /*value*/, DownloadsList* downloads_list){ | ||
307 | 83 | // got downloads matching metadata | ||
308 | 84 | std::string object_path; | ||
309 | 85 | auto downloads = downloads_list->downloads(); | ||
310 | 86 | if (downloads.size() > 0) { | ||
311 | 87 | auto download = downloads.at(0); | ||
312 | 88 | object_path = download->id().toStdString(); | ||
313 | 89 | } | ||
314 | 90 | qDebug() << "Found object path" << QString::fromStdString(object_path) | ||
315 | 91 | << "for package" << QString::fromStdString(package_name); | ||
316 | 92 | if (downloads.size() > 1) { | ||
317 | 93 | qWarning() << "More than one download with the same object path"; | ||
318 | 94 | } | ||
319 | 95 | callback(object_path); | ||
320 | 96 | }, [callback, package_name](const QString& /*key*/, const QString& /*value*/, DownloadsList* /*downloads_list*/){ | ||
321 | 97 | // no downloads found | ||
322 | 98 | qDebug() << "No object path found for package" << QString::fromStdString(package_name); | ||
323 | 99 | callback(""); | ||
324 | 100 | }); | ||
325 | 101 | } | ||
326 | 102 | |||
327 | 103 | click::web::Cancellable DownloadManager::start(const std::string& url, | ||
328 | 104 | const std::string& download_sha512, | ||
329 | 105 | const std::string& package_name, | ||
330 | 106 | const std::function<void (std::string, Error)>& callback) | ||
331 | 107 | { | ||
332 | 108 | QSharedPointer<click::web::Response> response = client->call | ||
333 | 109 | (url, "HEAD", true); | ||
334 | 110 | |||
335 | 111 | QObject::connect(response.data(), &click::web::Response::finished, | ||
336 | 112 | [this, callback, url, download_sha512, package_name, | ||
337 | 113 | response](QString) { | ||
338 | 114 | auto status = response->get_status_code(); | ||
339 | 115 | if (status == 200) { | ||
340 | 116 | auto clickToken = response->get_header(CLICK_TOKEN_HEADER().data()); | ||
341 | 117 | qDebug() << "Received click token:" << clickToken.c_str(); | ||
342 | 118 | QVariantMap metadata; | ||
343 | 119 | |||
344 | 120 | QVariant commandline = QVariant(QStringList() << DOWNLOAD_COMMAND << "$file" << package_name.c_str()); | ||
345 | 121 | metadata[DOWNLOAD_COMMAND_KEY] = commandline; | ||
346 | 122 | metadata[DOWNLOAD_APP_ID_KEY] = package_name.c_str(); | ||
347 | 123 | metadata["package_name"] = package_name.c_str(); | ||
348 | 124 | |||
349 | 125 | QMap<QString, QString> headers; | ||
350 | 126 | headers[CLICK_TOKEN_HEADER()] = clickToken.c_str(); | ||
351 | 127 | |||
352 | 128 | udm::DownloadStruct downloadStruct(url.c_str(), | ||
353 | 129 | download_sha512.c_str(), | ||
354 | 130 | DOWNLOAD_MANAGER_SHA512, | ||
355 | 131 | metadata, | ||
356 | 132 | headers); | ||
357 | 133 | |||
358 | 134 | dm->createDownload(downloadStruct, | ||
359 | 135 | [callback](Download* download) { | ||
360 | 136 | if (download->isError()) { | ||
361 | 137 | auto error = download->error()->errorString().toUtf8().data(); | ||
362 | 138 | qDebug() << "Received error from ubuntu-download-manager:" << error; | ||
363 | 139 | callback(error, Error::DownloadInstallError); | ||
364 | 140 | } else { | ||
365 | 141 | download->start(); | ||
366 | 142 | callback(download->id().toUtf8().data(), Error::NoError); | ||
367 | 143 | } | ||
368 | 144 | }, | ||
369 | 145 | [callback](Download* download) { | ||
370 | 146 | callback(download->error()->errorString().toUtf8().data(), | ||
371 | 147 | Error::DownloadInstallError); | ||
372 | 148 | }); | ||
373 | 149 | } else { | ||
374 | 150 | std::string error{"Unhandled HTTP response code: "}; | ||
375 | 151 | error += status; | ||
376 | 152 | callback(error, Error::DownloadInstallError); | ||
377 | 153 | } | ||
378 | 154 | }); | ||
379 | 155 | QObject::connect(response.data(), &click::web::Response::error, | ||
380 | 156 | [this, callback, package_name](QString error, int error_code) { | ||
381 | 157 | qWarning() << QStringLiteral("Network error (%1) fetching click token for:").arg(error_code) << package_name.c_str(); | ||
382 | 158 | switch(error_code) { | ||
383 | 159 | case 401: | ||
384 | 160 | case 403: | ||
385 | 161 | client->invalidateCredentials(); | ||
386 | 162 | callback(error.toUtf8().data(), Error::CredentialsError); | ||
387 | 163 | break; | ||
388 | 164 | default: | ||
389 | 165 | callback(error.toUtf8().data(), Error::DownloadInstallError); | ||
390 | 166 | } | ||
391 | 167 | }); | ||
392 | 168 | |||
393 | 169 | return click::web::Cancellable(response); | ||
394 | 170 | } | ||
395 | 171 | |||
396 | 172 | void DownloadManager::setCredentialsService(const QSharedPointer<click::CredentialsService>& credentialsService) | ||
397 | 173 | { | ||
398 | 174 | sso = credentialsService; | ||
399 | 175 | } | ||
400 | 176 | |||
401 | 177 | } // namespace click | ||
402 | 178 | 0 | ||
403 | === removed file 'libclickscope/click/download-manager.h' | |||
404 | --- libclickscope/click/download-manager.h 2016-02-26 18:51:22 +0000 | |||
405 | +++ libclickscope/click/download-manager.h 1970-01-01 00:00:00 +0000 | |||
406 | @@ -1,87 +0,0 @@ | |||
407 | 1 | /* | ||
408 | 2 | * Copyright (C) 2014-2016 Canonical Ltd. | ||
409 | 3 | * | ||
410 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
411 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
412 | 6 | * by the Free Software Foundation. | ||
413 | 7 | * | ||
414 | 8 | * This program is distributed in the hope that it will be useful, but | ||
415 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
416 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
417 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
418 | 12 | * | ||
419 | 13 | * You should have received a copy of the GNU General Public License along | ||
420 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
421 | 15 | * | ||
422 | 16 | * In addition, as a special exception, the copyright holders give | ||
423 | 17 | * permission to link the code of portions of this program with the | ||
424 | 18 | * OpenSSL library under certain conditions as described in each | ||
425 | 19 | * individual source file, and distribute linked combinations | ||
426 | 20 | * including the two. | ||
427 | 21 | * You must obey the GNU General Public License in all respects | ||
428 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
429 | 23 | * file(s) with this exception, you may extend this exception to your | ||
430 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
431 | 25 | * do not wish to do so, delete this exception statement from your | ||
432 | 26 | * version. If you delete this exception statement from all source | ||
433 | 27 | * files in the program, then also delete it here. | ||
434 | 28 | */ | ||
435 | 29 | |||
436 | 30 | #ifndef CLICK_DOWNLOAD_MANAGER_H | ||
437 | 31 | #define CLICK_DOWNLOAD_MANAGER_H | ||
438 | 32 | |||
439 | 33 | #include <QDebug> | ||
440 | 34 | #include <QNetworkReply> | ||
441 | 35 | #include <QObject> | ||
442 | 36 | #include <QString> | ||
443 | 37 | |||
444 | 38 | #include <click/ubuntuone_credentials.h> | ||
445 | 39 | #include <click/webclient.h> | ||
446 | 40 | |||
447 | 41 | #include <ubuntu/download_manager/manager.h> | ||
448 | 42 | |||
449 | 43 | using Ubuntu::DownloadManager::Download; | ||
450 | 44 | |||
451 | 45 | namespace UbuntuOne | ||
452 | 46 | { | ||
453 | 47 | class Token; | ||
454 | 48 | } | ||
455 | 49 | |||
456 | 50 | namespace click | ||
457 | 51 | { | ||
458 | 52 | // The dbus-send command to refresh the search results in the dash. | ||
459 | 53 | static const QString REFRESH_SCOPE_COMMAND = QStringLiteral("dbus-send /com/canonical/unity/scopes com.canonical.unity.scopes.InvalidateResults string:%1"); | ||
460 | 54 | static const QString APPS_SCOPE_ID = QStringLiteral("clickscope"); | ||
461 | 55 | static const QString STORE_SCOPE_ID = QStringLiteral("com.canonical.scopes.clickstore"); | ||
462 | 56 | |||
463 | 57 | const QByteArray& CLICK_TOKEN_HEADER(); | ||
464 | 58 | |||
465 | 59 | |||
466 | 60 | class DownloadManager | ||
467 | 61 | { | ||
468 | 62 | public: | ||
469 | 63 | enum class Error {NoError, CredentialsError, DownloadInstallError}; | ||
470 | 64 | |||
471 | 65 | DownloadManager(const QSharedPointer<click::web::Client>& client, | ||
472 | 66 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager); | ||
473 | 67 | virtual ~DownloadManager(); | ||
474 | 68 | |||
475 | 69 | virtual void get_progress(const std::string& package_name, | ||
476 | 70 | const std::function<void (std::string)>& callback); | ||
477 | 71 | virtual click::web::Cancellable start(const std::string& url, | ||
478 | 72 | const std::string& download_sha512, | ||
479 | 73 | const std::string& package_name, | ||
480 | 74 | const std::function<void (std::string, | ||
481 | 75 | Error)>& callback); | ||
482 | 76 | |||
483 | 77 | virtual void setCredentialsService(const QSharedPointer<click::CredentialsService>& credentialsService); | ||
484 | 78 | |||
485 | 79 | protected: | ||
486 | 80 | QSharedPointer<click::web::Client> client; | ||
487 | 81 | QSharedPointer<Ubuntu::DownloadManager::Manager> dm; | ||
488 | 82 | QSharedPointer<click::CredentialsService> sso; | ||
489 | 83 | }; | ||
490 | 84 | |||
491 | 85 | } | ||
492 | 86 | |||
493 | 87 | #endif /* CLICK_DOWNLOAD_MANAGER_H */ | ||
494 | 88 | 0 | ||
495 | === modified file 'libclickscope/click/index.cpp' | |||
496 | --- libclickscope/click/index.cpp 2016-04-26 10:56:47 +0000 | |||
497 | +++ libclickscope/click/index.cpp 2017-01-10 16:06:37 +0000 | |||
498 | @@ -36,7 +36,6 @@ | |||
499 | 36 | 36 | ||
500 | 37 | #include <click/smartconnect.h> | 37 | #include <click/smartconnect.h> |
501 | 38 | 38 | ||
502 | 39 | #include <click/download-manager.h> | ||
503 | 40 | #include "index.h" | 39 | #include "index.h" |
504 | 41 | #include "interface.h" | 40 | #include "interface.h" |
505 | 42 | #include "application.h" | 41 | #include "application.h" |
506 | @@ -46,48 +45,6 @@ | |||
507 | 46 | namespace click | 45 | namespace click |
508 | 47 | { | 46 | { |
509 | 48 | 47 | ||
510 | 49 | void PackageManager::uninstall(const Package& package, | ||
511 | 50 | std::function<void(int, std::string)> callback) | ||
512 | 51 | { | ||
513 | 52 | std::string package_id = package.name + ";" + package.version + ";all;local:click"; | ||
514 | 53 | std::string command = "pkcon -p remove " + package_id; | ||
515 | 54 | execute_uninstall_command(command, callback); | ||
516 | 55 | } | ||
517 | 56 | |||
518 | 57 | void PackageManager::execute_uninstall_command(const std::string& command, | ||
519 | 58 | std::function<void(int, std::string)> callback) | ||
520 | 59 | { | ||
521 | 60 | QSharedPointer<QProcess> process(new QProcess()); | ||
522 | 61 | |||
523 | 62 | typedef void(QProcess::*QProcessFinished)(int, QProcess::ExitStatus); | ||
524 | 63 | typedef void(QProcess::*QProcessError)(QProcess::ProcessError); | ||
525 | 64 | QObject::connect(process.data(), | ||
526 | 65 | static_cast<QProcessFinished>(&QProcess::finished), | ||
527 | 66 | [process, callback](int code, QProcess::ExitStatus status) { | ||
528 | 67 | Q_UNUSED(status); | ||
529 | 68 | qDebug() << "command finished with exit code:" << code; | ||
530 | 69 | callback(code, process.data()->readAllStandardError().data()); | ||
531 | 70 | if (code == 0) { | ||
532 | 71 | invalidate_results(APPS_SCOPE_ID.toUtf8().data()); | ||
533 | 72 | invalidate_results(STORE_SCOPE_ID.toUtf8().data()); | ||
534 | 73 | } | ||
535 | 74 | } ); | ||
536 | 75 | QObject::connect(process.data(), | ||
537 | 76 | static_cast<QProcessError>(&QProcess::error), | ||
538 | 77 | [process, callback](QProcess::ProcessError error) { | ||
539 | 78 | qCritical() << "error running command:" << error; | ||
540 | 79 | callback(-255 + error, process.data()->readAllStandardError().data()); | ||
541 | 80 | } ); | ||
542 | 81 | qDebug() << "Running command:" << command.c_str(); | ||
543 | 82 | process.data()->start(command.c_str()); | ||
544 | 83 | } | ||
545 | 84 | |||
546 | 85 | void PackageManager::invalidate_results(const std::string& scope_id) | ||
547 | 86 | { | ||
548 | 87 | QProcess::execute(REFRESH_SCOPE_COMMAND.arg(scope_id.c_str())); | ||
549 | 88 | } | ||
550 | 89 | |||
551 | 90 | |||
552 | 91 | Index::Index(const QSharedPointer<click::web::Client>& client, | 48 | Index::Index(const QSharedPointer<click::web::Client>& client, |
553 | 92 | const QSharedPointer<Configuration> configuration) : | 49 | const QSharedPointer<Configuration> configuration) : |
554 | 93 | client(client), configuration(configuration) | 50 | client(client), configuration(configuration) |
555 | 94 | 51 | ||
556 | === modified file 'libclickscope/click/interface.cpp' | |||
557 | --- libclickscope/click/interface.cpp 2016-10-04 17:35:15 +0000 | |||
558 | +++ libclickscope/click/interface.cpp 2017-01-10 16:06:37 +0000 | |||
559 | @@ -27,8 +27,6 @@ | |||
560 | 27 | * files in the program, then also delete it here. | 27 | * files in the program, then also delete it here. |
561 | 28 | */ | 28 | */ |
562 | 29 | 29 | ||
563 | 30 | #include <click.h> | ||
564 | 31 | |||
565 | 32 | #include "interface.h" | 30 | #include "interface.h" |
566 | 33 | 31 | ||
567 | 34 | #include <QDebug> | 32 | #include <QDebug> |
568 | @@ -343,39 +341,6 @@ | |||
569 | 343 | return icon_id; | 341 | return icon_id; |
570 | 344 | } | 342 | } |
571 | 345 | 343 | ||
572 | 346 | Manifest manifest_from_json(const std::string& json) | ||
573 | 347 | { | ||
574 | 348 | using namespace boost::property_tree; | ||
575 | 349 | |||
576 | 350 | std::istringstream is(json); | ||
577 | 351 | |||
578 | 352 | ptree pt; | ||
579 | 353 | read_json(is, pt); | ||
580 | 354 | |||
581 | 355 | Manifest manifest; | ||
582 | 356 | |||
583 | 357 | manifest.name = pt.get<std::string>("name"); | ||
584 | 358 | manifest.version = pt.get<std::string>("version"); | ||
585 | 359 | manifest.removable = pt.get<bool>("_removable"); | ||
586 | 360 | |||
587 | 361 | BOOST_FOREACH(ptree::value_type &sv, pt.get_child("hooks")) | ||
588 | 362 | { | ||
589 | 363 | // FIXME: "primary app or scope" for a package is not defined, | ||
590 | 364 | // we just use the first one in the manifest: | ||
591 | 365 | auto app_name = sv.second.get("desktop", ""); | ||
592 | 366 | if (manifest.first_app_name.empty() && !app_name.empty()) { | ||
593 | 367 | manifest.first_app_name = sv.first; | ||
594 | 368 | } | ||
595 | 369 | auto scope_id = sv.second.get("scope", ""); | ||
596 | 370 | if (manifest.first_scope_id.empty() && !scope_id.empty()) { | ||
597 | 371 | manifest.first_scope_id = manifest.name + "_" + sv.first; | ||
598 | 372 | } | ||
599 | 373 | } | ||
600 | 374 | qDebug() << "adding manifest: " << manifest.name.c_str() << manifest.version.c_str() << manifest.first_app_name.c_str(); | ||
601 | 375 | |||
602 | 376 | return manifest; | ||
603 | 377 | } | ||
604 | 378 | |||
605 | 379 | void Interface::get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback) | 344 | void Interface::get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback) |
606 | 380 | { | 345 | { |
607 | 381 | PackageSet packages; | 346 | PackageSet packages; |
608 | @@ -391,59 +356,4 @@ | |||
609 | 391 | callback(packages, InterfaceError::NoError); | 356 | callback(packages, InterfaceError::NoError); |
610 | 392 | } | 357 | } |
611 | 393 | 358 | ||
612 | 394 | std::string Interface::get_manifest_json(const std::string &package) const | ||
613 | 395 | { | ||
614 | 396 | GError* error = nullptr; | ||
615 | 397 | |||
616 | 398 | std::shared_ptr<ClickDB> clickdb{click_db_new(), | ||
617 | 399 | [](ClickDB* db){g_clear_object(&db);}}; | ||
618 | 400 | click_db_read(clickdb.get(), nullptr, &error); | ||
619 | 401 | if (error != nullptr) { | ||
620 | 402 | qCritical() << "Error reading click DB:" << error->message; | ||
621 | 403 | g_error_free(error); | ||
622 | 404 | return ""; | ||
623 | 405 | } | ||
624 | 406 | |||
625 | 407 | std::shared_ptr<ClickUser> clickuser{click_user_new_for_user(clickdb.get(), | ||
626 | 408 | nullptr, | ||
627 | 409 | &error), | ||
628 | 410 | [](ClickUser* cu){g_clear_object(&cu);}}; | ||
629 | 411 | if (error != nullptr) { | ||
630 | 412 | qCritical() << "Error setting up click user:" << error->message; | ||
631 | 413 | g_error_free(error); | ||
632 | 414 | return ""; | ||
633 | 415 | } | ||
634 | 416 | |||
635 | 417 | auto result = click_user_get_manifest_as_string(clickuser.get(), | ||
636 | 418 | package.c_str(), | ||
637 | 419 | &error); | ||
638 | 420 | if (error != nullptr) { | ||
639 | 421 | qCritical() << "Error getting manifest:" << error->message; | ||
640 | 422 | g_error_free(error); | ||
641 | 423 | return ""; | ||
642 | 424 | } | ||
643 | 425 | |||
644 | 426 | std::string retval; | ||
645 | 427 | if (result != nullptr) { | ||
646 | 428 | retval = result; | ||
647 | 429 | g_free(result); | ||
648 | 430 | } | ||
649 | 431 | return retval; | ||
650 | 432 | } | ||
651 | 433 | |||
652 | 434 | void Interface::get_manifest_for_app(const std::string &app_id, | ||
653 | 435 | std::function<void(Manifest, InterfaceError)> callback) | ||
654 | 436 | { | ||
655 | 437 | Manifest manifest; | ||
656 | 438 | InterfaceError error; | ||
657 | 439 | try { | ||
658 | 440 | manifest = manifest_from_json(get_manifest_json(app_id)); | ||
659 | 441 | error = InterfaceError::NoError; | ||
660 | 442 | } catch (...) { | ||
661 | 443 | qWarning() << "Can't parse manifest for:" << QString::fromStdString(app_id); | ||
662 | 444 | error = InterfaceError::ParseError; | ||
663 | 445 | } | ||
664 | 446 | callback(manifest, error); | ||
665 | 447 | } | ||
666 | 448 | |||
667 | 449 | } // namespace click | 359 | } // namespace click |
668 | 450 | 360 | ||
669 | === modified file 'libclickscope/click/interface.h' | |||
670 | --- libclickscope/click/interface.h 2016-09-02 21:29:13 +0000 | |||
671 | +++ libclickscope/click/interface.h 2017-01-10 16:06:37 +0000 | |||
672 | @@ -77,8 +77,6 @@ | |||
673 | 77 | enum class InterfaceError {NoError, CallError, ParseError}; | 77 | enum class InterfaceError {NoError, CallError, ParseError}; |
674 | 78 | typedef std::list<Manifest> ManifestList; | 78 | typedef std::list<Manifest> ManifestList; |
675 | 79 | 79 | ||
676 | 80 | Manifest manifest_from_json(const std::string& json); | ||
677 | 81 | |||
678 | 82 | class Interface | 80 | class Interface |
679 | 83 | { | 81 | { |
680 | 84 | public: | 82 | public: |
681 | @@ -97,8 +95,6 @@ | |||
682 | 97 | static bool is_icon_identifier(const std::string &icon_id); | 95 | static bool is_icon_identifier(const std::string &icon_id); |
683 | 98 | static std::string add_theme_scheme(const std::string &filename); | 96 | static std::string add_theme_scheme(const std::string &filename); |
684 | 99 | virtual void get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback); | 97 | virtual void get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback); |
685 | 100 | virtual std::string get_manifest_json(const std::string &package) const; | ||
686 | 101 | virtual void get_manifest_for_app(const std::string &app_id, std::function<void(Manifest, InterfaceError)> callback); | ||
687 | 102 | }; | 98 | }; |
688 | 103 | 99 | ||
689 | 104 | } // namespace click | 100 | } // namespace click |
690 | 105 | 101 | ||
691 | === modified file 'libclickscope/click/preview.cpp' | |||
692 | --- libclickscope/click/preview.cpp 2016-10-24 21:26:23 +0000 | |||
693 | +++ libclickscope/click/preview.cpp 2017-01-10 16:06:37 +0000 | |||
694 | @@ -31,7 +31,6 @@ | |||
695 | 31 | #include <click/interface.h> | 31 | #include <click/interface.h> |
696 | 32 | #include "preview.h" | 32 | #include "preview.h" |
697 | 33 | #include <click/qtbridge.h> | 33 | #include <click/qtbridge.h> |
698 | 34 | #include <click/download-manager.h> | ||
699 | 35 | #include <click/launcher.h> | 34 | #include <click/launcher.h> |
700 | 36 | #include <click/dbus_constants.h> | 35 | #include <click/dbus_constants.h> |
701 | 37 | #include <click/departments-db.h> | 36 | #include <click/departments-db.h> |
702 | @@ -172,76 +171,20 @@ | |||
703 | 172 | } | 171 | } |
704 | 173 | 172 | ||
705 | 174 | void Preview::choose_strategy(const QSharedPointer<web::Client> &client, | 173 | void Preview::choose_strategy(const QSharedPointer<web::Client> &client, |
706 | 175 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager, | ||
707 | 176 | std::shared_ptr<click::DepartmentsDb> depts) | 174 | std::shared_ptr<click::DepartmentsDb> depts) |
708 | 177 | { | 175 | { |
722 | 178 | strategy.reset(build_strategy(result, metadata, client, manager, depts)); | 176 | strategy.reset(build_strategy(result, metadata, client, depts)); |
723 | 179 | } | 177 | } |
711 | 180 | |||
712 | 181 | PreviewStrategy* Preview::build_installing(const std::string& download_url, | ||
713 | 182 | const std::string& download_sha512, | ||
714 | 183 | const unity::scopes::Result& result, | ||
715 | 184 | const QSharedPointer<click::web::Client>& client, | ||
716 | 185 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager, | ||
717 | 186 | std::shared_ptr<click::DepartmentsDb> depts) | ||
718 | 187 | { | ||
719 | 188 | return new InstallingPreview(download_url, download_sha512, result, client, manager, depts); | ||
720 | 189 | } | ||
721 | 190 | |||
724 | 191 | 178 | ||
725 | 192 | PreviewStrategy* Preview::build_strategy(const unity::scopes::Result &result, | 179 | PreviewStrategy* Preview::build_strategy(const unity::scopes::Result &result, |
726 | 193 | const unity::scopes::ActionMetadata &metadata, | 180 | const unity::scopes::ActionMetadata &metadata, |
727 | 194 | const QSharedPointer<web::Client> &client, | 181 | const QSharedPointer<web::Client> &client, |
728 | 195 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager, | ||
729 | 196 | std::shared_ptr<click::DepartmentsDb> depts) | 182 | std::shared_ptr<click::DepartmentsDb> depts) |
730 | 197 | { | 183 | { |
767 | 198 | if (metadata.scope_data().which() != scopes::Variant::Type::Null) { | 184 | if (result.uri().find("scope://") == 0) { |
768 | 199 | auto metadict = metadata.scope_data().get_dict(); | 185 | return new InstalledScopePreview(result); |
733 | 200 | |||
734 | 201 | if (metadict.count(click::Preview::Actions::DOWNLOAD_FAILED) != 0) { | ||
735 | 202 | return new DownloadErrorPreview(result); | ||
736 | 203 | } else if (metadict.count(click::Preview::Actions::DOWNLOAD_COMPLETED) != 0 || | ||
737 | 204 | metadict.count(click::Preview::Actions::SHOW_INSTALLED) != 0) { | ||
738 | 205 | qDebug() << "in Scope::preview(), metadata has download_completed=" | ||
739 | 206 | << metadict.count(click::Preview::Actions::DOWNLOAD_COMPLETED) | ||
740 | 207 | << " and close_preview=" | ||
741 | 208 | << metadict.count(click::Preview::Actions::SHOW_INSTALLED); | ||
742 | 209 | |||
743 | 210 | return new InstalledPreview(result, metadata, client, depts); | ||
744 | 211 | } else if (metadict.count("action_id") != 0 && metadict.count("download_url") != 0) { | ||
745 | 212 | std::string action_id = metadict["action_id"].get_string(); | ||
746 | 213 | std::string download_url = metadict["download_url"].get_string(); | ||
747 | 214 | std::string download_sha512 = metadict["download_sha512"].get_string(); | ||
748 | 215 | if (action_id == click::Preview::Actions::INSTALL_CLICK) { | ||
749 | 216 | return build_installing(download_url, download_sha512, result, client, manager, depts); | ||
750 | 217 | } else { | ||
751 | 218 | qWarning() << "unexpected action id " << QString::fromStdString(action_id) | ||
752 | 219 | << " given with download_url" << QString::fromStdString(download_url); | ||
753 | 220 | return new UninstalledPreview(result, metadata, client, depts, manager); | ||
754 | 221 | } | ||
755 | 222 | } else if (metadict.count(click::Preview::Actions::UNINSTALL_CLICK) != 0) { | ||
756 | 223 | return new UninstallConfirmationPreview(result); | ||
757 | 224 | } else if (metadict.count(click::Preview::Actions::CONFIRM_UNINSTALL) != 0) { | ||
758 | 225 | return new UninstallingPreview(result, metadata, client, manager); | ||
759 | 226 | } else if (metadict.count(click::Preview::Actions::RATED) != 0) { | ||
760 | 227 | return new InstalledPreview(result, metadata, client, depts); | ||
761 | 228 | } else if (metadict.count(click::Preview::Actions::SHOW_UNINSTALLED) != 0) { | ||
762 | 229 | return new UninstalledPreview(result, metadata, client, depts, manager); | ||
763 | 230 | } else { | ||
764 | 231 | qWarning() << "preview() called with unexpected metadata. returning uninstalled preview"; | ||
765 | 232 | return new UninstalledPreview(result, metadata, client, depts, manager); | ||
766 | 233 | } | ||
769 | 234 | } else { | 186 | } else { |
780 | 235 | // metadata.scope_data() is Null, so we return an appropriate "default" preview: | 187 | return new InstalledPreview(result, metadata, client, depts); |
771 | 236 | if (result.uri().find("scope://") == 0) | ||
772 | 237 | { | ||
773 | 238 | return new InstalledScopePreview(result); | ||
774 | 239 | } | ||
775 | 240 | if (result["installed"].get_bool() == true) { | ||
776 | 241 | return new InstalledPreview(result, metadata, client, depts); | ||
777 | 242 | } else { | ||
778 | 243 | return new UninstalledPreview(result, metadata, client, depts, manager); | ||
779 | 244 | } | ||
781 | 245 | } | 188 | } |
782 | 246 | 189 | ||
783 | 247 | } | 190 | } |
784 | @@ -271,7 +214,6 @@ | |||
785 | 271 | result(result), | 214 | result(result), |
786 | 272 | client(client), | 215 | client(client), |
787 | 273 | index(new click::Index(client)), | 216 | index(new click::Index(client)), |
788 | 274 | reviews(new click::Reviews(client)), | ||
789 | 275 | oa_client("ubuntuone", "ubuntuone", "ubuntuone", | 217 | oa_client("ubuntuone", "ubuntuone", "ubuntuone", |
790 | 276 | scopes::OnlineAccountClient::MainLoopSelect::CreateInternalMainLoop) | 218 | scopes::OnlineAccountClient::MainLoopSelect::CreateInternalMainLoop) |
791 | 277 | { | 219 | { |
792 | @@ -327,9 +269,6 @@ | |||
793 | 327 | void PreviewStrategy::cancelled() | 269 | void PreviewStrategy::cancelled() |
794 | 328 | { | 270 | { |
795 | 329 | index_operation.cancel(); | 271 | index_operation.cancel(); |
796 | 330 | reviews_operation.cancel(); | ||
797 | 331 | submit_operation.cancel(); | ||
798 | 332 | purchase_operation.cancel(); | ||
799 | 333 | } | 272 | } |
800 | 334 | 273 | ||
801 | 335 | scopes::PreviewWidget PreviewStrategy::build_other_metadata(const PackageDetails &details) | 274 | scopes::PreviewWidget PreviewStrategy::build_other_metadata(const PackageDetails &details) |
802 | @@ -396,8 +335,7 @@ | |||
803 | 396 | // return them from populateDetails and check them in the calling code | 335 | // return them from populateDetails and check them in the calling code |
804 | 397 | // to decide whether to show error widgets. see bug LP: #1289541 | 336 | // to decide whether to show error widgets. see bug LP: #1289541 |
805 | 398 | void PreviewStrategy::populateDetails(std::function<void(const click::PackageDetails& details)> details_callback, | 337 | void PreviewStrategy::populateDetails(std::function<void(const click::PackageDetails& details)> details_callback, |
808 | 399 | std::function<void(const click::ReviewList&, | 338 | bool force_cache) |
807 | 400 | click::Reviews::Error)> reviews_callback, bool force_cache) | ||
809 | 401 | { | 339 | { |
810 | 402 | 340 | ||
811 | 403 | std::string app_name = get_string_maybe_null(result["name"]); | 341 | std::string app_name = get_string_maybe_null(result["name"]); |
812 | @@ -410,15 +348,14 @@ | |||
813 | 410 | details.description = get_string_maybe_null(result["description"]); | 348 | details.description = get_string_maybe_null(result["description"]); |
814 | 411 | details.main_screenshot_url = get_string_maybe_null(result["main_screenshot"]); | 349 | details.main_screenshot_url = get_string_maybe_null(result["main_screenshot"]); |
815 | 412 | details_callback(details); | 350 | details_callback(details); |
816 | 413 | reviews_callback(click::ReviewList(), click::Reviews::Error::NoError); | ||
817 | 414 | } else { | 351 | } else { |
818 | 415 | qDebug() << "in populateDetails(), app_name is:" << app_name.c_str(); | 352 | qDebug() << "in populateDetails(), app_name is:" << app_name.c_str(); |
819 | 416 | // I think this should not be required when we switch the click::Index over | 353 | // I think this should not be required when we switch the click::Index over |
820 | 417 | // to using the Qt bridge. With that, the qt dependency becomes an implementation detail | 354 | // to using the Qt bridge. With that, the qt dependency becomes an implementation detail |
821 | 418 | // and code using it does not need to worry about threading/event loop topics. | 355 | // and code using it does not need to worry about threading/event loop topics. |
823 | 419 | run_under_qt([this, details_callback, reviews_callback, app_name, force_cache]() | 356 | run_under_qt([this, details_callback, app_name, force_cache]() |
824 | 420 | { | 357 | { |
826 | 421 | index_operation = index->get_details(app_name, [this, app_name, details_callback, reviews_callback, force_cache](PackageDetails details, click::Index::Error error){ | 358 | index_operation = index->get_details(app_name, [this, app_name, details_callback, force_cache](PackageDetails details, click::Index::Error error){ |
827 | 422 | if(error == click::Index::Error::NoError) { | 359 | if(error == click::Index::Error::NoError) { |
828 | 423 | qDebug() << "Got details:" << app_name.c_str(); | 360 | qDebug() << "Got details:" << app_name.c_str(); |
829 | 424 | details_callback(details); | 361 | details_callback(details); |
830 | @@ -431,9 +368,6 @@ | |||
831 | 431 | details.main_screenshot_url = get_string_maybe_null(result["main_screenshot"]); | 368 | details.main_screenshot_url = get_string_maybe_null(result["main_screenshot"]); |
832 | 432 | details_callback(details); | 369 | details_callback(details); |
833 | 433 | } | 370 | } |
834 | 434 | reviews_operation = reviews->fetch_reviews(app_name, | ||
835 | 435 | reviews_callback, | ||
836 | 436 | force_cache); | ||
837 | 437 | }, force_cache); | 371 | }, force_cache); |
838 | 438 | }); | 372 | }); |
839 | 439 | } | 373 | } |
840 | @@ -551,65 +485,6 @@ | |||
841 | 551 | return widgets; | 485 | return widgets; |
842 | 552 | } | 486 | } |
843 | 553 | 487 | ||
844 | 554 | scopes::PreviewWidgetList PreviewStrategy::reviewsWidgets(const click::ReviewList& reviewlist) | ||
845 | 555 | { | ||
846 | 556 | scopes::PreviewWidgetList widgets; | ||
847 | 557 | |||
848 | 558 | scopes::PreviewWidget rating("reviews", "reviews"); | ||
849 | 559 | scopes::VariantBuilder builder; | ||
850 | 560 | |||
851 | 561 | if (reviewlist.size() > 0) { | ||
852 | 562 | scopes::PreviewWidget title("reviews_title", "text"); | ||
853 | 563 | title.add_attribute_value("title", scopes::Variant(_("Reviews"))); | ||
854 | 564 | widgets.push_back(title); | ||
855 | 565 | |||
856 | 566 | for (const auto& kv : reviewlist) { | ||
857 | 567 | builder.add_tuple({ | ||
858 | 568 | {"rating", scopes::Variant(kv.rating)}, | ||
859 | 569 | {"author", scopes::Variant(kv.reviewer_name)}, | ||
860 | 570 | {"review", scopes::Variant(kv.review_text)} | ||
861 | 571 | }); | ||
862 | 572 | } | ||
863 | 573 | rating.add_attribute_value("reviews", builder.end()); | ||
864 | 574 | widgets.push_back(rating); | ||
865 | 575 | } | ||
866 | 576 | |||
867 | 577 | return widgets; | ||
868 | 578 | } | ||
869 | 579 | |||
870 | 580 | scopes::PreviewWidgetList PreviewStrategy::downloadErrorWidgets() | ||
871 | 581 | { | ||
872 | 582 | return errorWidgets(scopes::Variant(_("Download Error")), | ||
873 | 583 | scopes::Variant(_("Download or install failed. Please try again.")), | ||
874 | 584 | scopes::Variant(click::Preview::Actions::SHOW_UNINSTALLED), | ||
875 | 585 | scopes::Variant(_("Close"))); | ||
876 | 586 | } | ||
877 | 587 | |||
878 | 588 | scopes::PreviewWidgetList PreviewStrategy::loginErrorWidgets(const std::string& download_url, const std::string& download_sha512) | ||
879 | 589 | { | ||
880 | 590 | auto widgets = errorWidgets(scopes::Variant(_("Login Error")), | ||
881 | 591 | scopes::Variant(_("Please log in to your Ubuntu One account.")), | ||
882 | 592 | scopes::Variant(click::Preview::Actions::INSTALL_CLICK), | ||
883 | 593 | scopes::Variant(_("Go to Accounts"))); | ||
884 | 594 | auto buttons = widgets.back(); | ||
885 | 595 | widgets.pop_back(); | ||
886 | 596 | |||
887 | 597 | scopes::VariantBuilder builder; | ||
888 | 598 | builder.add_tuple( | ||
889 | 599 | { | ||
890 | 600 | {"id", scopes::Variant(click::Preview::Actions::INSTALL_CLICK)}, | ||
891 | 601 | {"label", scopes::Variant(_("Go to Accounts"))}, | ||
892 | 602 | {"download_url", scopes::Variant(download_url)}, | ||
893 | 603 | {"download_sha512", scopes::Variant(download_sha512)}, | ||
894 | 604 | }); | ||
895 | 605 | buttons.add_attribute_value("actions", builder.end()); | ||
896 | 606 | oa_client.register_account_login_item(buttons, | ||
897 | 607 | scopes::OnlineAccountClient::PostLoginAction::ContinueActivation, | ||
898 | 608 | scopes::OnlineAccountClient::PostLoginAction::DoNothing); | ||
899 | 609 | widgets.push_back(buttons); | ||
900 | 610 | return widgets; | ||
901 | 611 | } | ||
902 | 612 | |||
903 | 613 | scopes::PreviewWidgetList PreviewStrategy::errorWidgets(const scopes::Variant& title, | 488 | scopes::PreviewWidgetList PreviewStrategy::errorWidgets(const scopes::Variant& title, |
904 | 614 | const scopes::Variant& summary, | 489 | const scopes::Variant& summary, |
905 | 615 | const scopes::Variant& action_id, | 490 | const scopes::Variant& action_id, |
906 | @@ -639,129 +514,6 @@ | |||
907 | 639 | return widgets; | 514 | return widgets; |
908 | 640 | } | 515 | } |
909 | 641 | 516 | ||
910 | 642 | void PreviewStrategy::invalidateScope(const std::string& scope_id) | ||
911 | 643 | { | ||
912 | 644 | run_under_qt([scope_id]() { | ||
913 | 645 | PackageManager::invalidate_results(scope_id); | ||
914 | 646 | }); | ||
915 | 647 | } | ||
916 | 648 | |||
917 | 649 | // class DownloadErrorPreview | ||
918 | 650 | |||
919 | 651 | DownloadErrorPreview::DownloadErrorPreview(const unity::scopes::Result &result) | ||
920 | 652 | : PreviewStrategy(result) | ||
921 | 653 | { | ||
922 | 654 | } | ||
923 | 655 | |||
924 | 656 | DownloadErrorPreview::~DownloadErrorPreview() | ||
925 | 657 | { | ||
926 | 658 | |||
927 | 659 | } | ||
928 | 660 | |||
929 | 661 | void DownloadErrorPreview::run(const unity::scopes::PreviewReplyProxy &reply) | ||
930 | 662 | { | ||
931 | 663 | // NOTE: no details used by downloadErrorWidgets(), so no need to | ||
932 | 664 | // call populateDetails() here. | ||
933 | 665 | reply->push(downloadErrorWidgets()); | ||
934 | 666 | } | ||
935 | 667 | |||
936 | 668 | // class InstallingPreview | ||
937 | 669 | |||
938 | 670 | InstallingPreview::InstallingPreview(const std::string &download_url, | ||
939 | 671 | const std::string &download_sha512, | ||
940 | 672 | const unity::scopes::Result &result, | ||
941 | 673 | const QSharedPointer<click::web::Client>& client, | ||
942 | 674 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager, | ||
943 | 675 | std::shared_ptr<click::DepartmentsDb> depts) : | ||
944 | 676 | PreviewStrategy(result, client), | ||
945 | 677 | DepartmentUpdater(depts), | ||
946 | 678 | download_url(download_url), | ||
947 | 679 | download_sha512(download_sha512), | ||
948 | 680 | dm(new DownloadManager(client, manager)), | ||
949 | 681 | depts_db(depts) | ||
950 | 682 | { | ||
951 | 683 | } | ||
952 | 684 | |||
953 | 685 | InstallingPreview::~InstallingPreview() | ||
954 | 686 | { | ||
955 | 687 | } | ||
956 | 688 | |||
957 | 689 | void InstallingPreview::startLauncherAnimation(const PackageDetails &details) | ||
958 | 690 | { | ||
959 | 691 | Launcher l(LAUNCHER_BUSNAME, LAUNCHER_OBJECT_PATH, QDBusConnection::sessionBus()); | ||
960 | 692 | l.startInstallation(QString::fromStdString(details.package.title), | ||
961 | 693 | QString::fromStdString(details.package.icon_url), | ||
962 | 694 | QString::fromStdString(details.package.name)); | ||
963 | 695 | |||
964 | 696 | } | ||
965 | 697 | |||
966 | 698 | void InstallingPreview::run(const unity::scopes::PreviewReplyProxy &reply) | ||
967 | 699 | { | ||
968 | 700 | qDebug() << "Starting installation" << QString(download_url.c_str()) << QString(download_sha512.c_str()); | ||
969 | 701 | std::promise<bool> promise; | ||
970 | 702 | auto future = promise.get_future(); | ||
971 | 703 | run_under_qt([this, reply, &promise]() { | ||
972 | 704 | dm->start(download_url, download_sha512, result["name"].get_string(), | ||
973 | 705 | [this, reply, &promise] (std::string msg, DownloadManager::Error dmerr){ | ||
974 | 706 | switch (dmerr) | ||
975 | 707 | { | ||
976 | 708 | case DownloadManager::Error::DownloadInstallError: | ||
977 | 709 | qWarning() << "Error received from UDM during startDownload:" << msg.c_str(); | ||
978 | 710 | reply->push(downloadErrorWidgets()); | ||
979 | 711 | promise.set_value(false); | ||
980 | 712 | break; | ||
981 | 713 | case DownloadManager::Error::CredentialsError: | ||
982 | 714 | qWarning() << "InstallingPreview got error in getting credentials during startDownload"; | ||
983 | 715 | reply->push(loginErrorWidgets(download_url, download_sha512)); | ||
984 | 716 | promise.set_value(false); | ||
985 | 717 | break; | ||
986 | 718 | case DownloadManager::Error::NoError: { | ||
987 | 719 | std::string object_path = msg; | ||
988 | 720 | qDebug() << "Successfully created UDM Download."; | ||
989 | 721 | populateDetails([this, reply, object_path](const PackageDetails &details) { | ||
990 | 722 | store_department(details); | ||
991 | 723 | pushPackagePreviewWidgets(cachedWidgets, details, progressBarWidget(object_path)); | ||
992 | 724 | startLauncherAnimation(details); | ||
993 | 725 | }, | ||
994 | 726 | [this, reply, &promise](const ReviewList& reviewlist, | ||
995 | 727 | click::Reviews::Error error) { | ||
996 | 728 | if (error == click::Reviews::Error::NoError) { | ||
997 | 729 | auto const revs = reviewsWidgets(reviewlist); | ||
998 | 730 | cachedWidgets.push(revs); | ||
999 | 731 | cachedWidgets.layout.appendToColumn(cachedWidgets.layout.singleColumn.column1, revs); | ||
1000 | 732 | cachedWidgets.layout.appendToColumn(cachedWidgets.layout.twoColumns.column1, revs); | ||
1001 | 733 | } else { | ||
1002 | 734 | qDebug() << "There was an error getting reviews for:" << result["name"].get_string().c_str(); | ||
1003 | 735 | } | ||
1004 | 736 | cachedWidgets.flush(reply); | ||
1005 | 737 | promise.set_value(true); | ||
1006 | 738 | }); | ||
1007 | 739 | break; | ||
1008 | 740 | } | ||
1009 | 741 | default: | ||
1010 | 742 | qCritical() << "Unknown error occurred downloading."; | ||
1011 | 743 | promise.set_value(false); | ||
1012 | 744 | break; | ||
1013 | 745 | } | ||
1014 | 746 | }); | ||
1015 | 747 | }); | ||
1016 | 748 | future.get(); | ||
1017 | 749 | reply->finished(); | ||
1018 | 750 | } | ||
1019 | 751 | |||
1020 | 752 | scopes::PreviewWidgetList PreviewStrategy::progressBarWidget(const std::string& object_path) | ||
1021 | 753 | { | ||
1022 | 754 | scopes::PreviewWidgetList widgets; | ||
1023 | 755 | scopes::PreviewWidget progress("download", "progress"); | ||
1024 | 756 | scopes::VariantMap tuple; | ||
1025 | 757 | tuple["dbus-name"] = "com.canonical.applications.Downloader"; | ||
1026 | 758 | tuple["dbus-object"] = object_path; | ||
1027 | 759 | progress.add_attribute_value("source", scopes::Variant(tuple)); | ||
1028 | 760 | widgets.push_back(progress); | ||
1029 | 761 | |||
1030 | 762 | return widgets; | ||
1031 | 763 | } | ||
1032 | 764 | |||
1033 | 765 | // class InstalledPreview | 517 | // class InstalledPreview |
1034 | 766 | 518 | ||
1035 | 767 | InstalledPreview::InstalledPreview(const unity::scopes::Result& result, | 519 | InstalledPreview::InstalledPreview(const unity::scopes::Result& result, |
1036 | @@ -778,163 +530,18 @@ | |||
1037 | 778 | { | 530 | { |
1038 | 779 | } | 531 | } |
1039 | 780 | 532 | ||
1040 | 781 | std::string InstalledPreview::get_consumer_key() | ||
1041 | 782 | { | ||
1042 | 783 | std::promise<std::string> promise; | ||
1043 | 784 | auto future = promise.get_future(); | ||
1044 | 785 | QSharedPointer<click::CredentialsService> sso; | ||
1045 | 786 | |||
1046 | 787 | qt::core::world::enter_with_task([this, &sso, &promise]() { | ||
1047 | 788 | sso.reset(new click::CredentialsService()); | ||
1048 | 789 | |||
1049 | 790 | QObject::connect(sso.data(), &click::CredentialsService::credentialsFound, | ||
1050 | 791 | [&promise, &sso](const UbuntuOne::Token& token) { | ||
1051 | 792 | qDebug() << "Credentials found"; | ||
1052 | 793 | sso.clear(); | ||
1053 | 794 | try { | ||
1054 | 795 | promise.set_value(token.consumerKey().toStdString()); | ||
1055 | 796 | } catch (const std::future_error&) { | ||
1056 | 797 | // Ignore promise_already_satisfied | ||
1057 | 798 | } | ||
1058 | 799 | }); | ||
1059 | 800 | QObject::connect(sso.data(), &click::CredentialsService::credentialsNotFound, | ||
1060 | 801 | [&promise, &sso]() { | ||
1061 | 802 | qDebug() << "No credentials found"; | ||
1062 | 803 | sso.clear(); | ||
1063 | 804 | try { | ||
1064 | 805 | promise.set_value(""); | ||
1065 | 806 | } catch (const std::future_error&) { | ||
1066 | 807 | // Ignore promise_already_satisfied | ||
1067 | 808 | } | ||
1068 | 809 | }); | ||
1069 | 810 | |||
1070 | 811 | sso->getCredentials(); | ||
1071 | 812 | qDebug() << "getCredentials finished"; | ||
1072 | 813 | }); | ||
1073 | 814 | return future.get(); | ||
1074 | 815 | } | ||
1075 | 816 | |||
1076 | 817 | scopes::PreviewWidget InstalledPreview::createRatingWidget(const click::Review& review) const | ||
1077 | 818 | { | ||
1078 | 819 | scopes::PreviewWidget rating("rating", "rating-input"); | ||
1079 | 820 | |||
1080 | 821 | if (review.id != 0) { | ||
1081 | 822 | qDebug() << "Review for current user already exists, review id:" << review.id; | ||
1082 | 823 | rating = scopes::PreviewWidget(std::to_string(review.id), "rating-edit"); // pass review id via widget id | ||
1083 | 824 | rating.add_attribute_value("review", scopes::Variant(review.review_text)); | ||
1084 | 825 | rating.add_attribute_value("rating", scopes::Variant(review.rating)); | ||
1085 | 826 | rating.add_attribute_value("author", scopes::Variant(review.reviewer_name)); | ||
1086 | 827 | } | ||
1087 | 828 | |||
1088 | 829 | return rating; | ||
1089 | 830 | } | ||
1090 | 831 | |||
1091 | 832 | void InstalledPreview::run(unity::scopes::PreviewReplyProxy const& reply) | 533 | void InstalledPreview::run(unity::scopes::PreviewReplyProxy const& reply) |
1092 | 833 | { | 534 | { |
1093 | 834 | const bool force_cache = (metadata.internet_connectivity() == scopes::QueryMetadata::ConnectivityStatus::Disconnected); | 535 | const bool force_cache = (metadata.internet_connectivity() == scopes::QueryMetadata::ConnectivityStatus::Disconnected); |
1094 | 835 | qDebug() << "preview, force_cache=" << force_cache << ", conn status=" << (int)metadata.internet_connectivity(); | 536 | qDebug() << "preview, force_cache=" << force_cache << ", conn status=" << (int)metadata.internet_connectivity(); |
1095 | 836 | 537 | ||
1096 | 837 | // Check if the user is submitting a rating, so we can submit it. | ||
1097 | 838 | Review review; | ||
1098 | 839 | review.rating = 0; | ||
1099 | 840 | std::string widget_id; | ||
1100 | 841 | // We use a try/catch here, as scope_data() can be a dict, but not have | ||
1101 | 842 | // the values we need, which will result in an exception thrown. | ||
1102 | 843 | try { | ||
1103 | 844 | auto metadict = metadata.scope_data().get_dict(); | ||
1104 | 845 | review.rating = metadict["rating"].get_int(); | ||
1105 | 846 | review.review_text = metadict["review"].get_string(); | ||
1106 | 847 | widget_id = metadict["widget_id"].get_string(); | ||
1107 | 848 | } catch(...) { | ||
1108 | 849 | // Do nothing as we are not submitting a review. | ||
1109 | 850 | } | ||
1110 | 851 | |||
1111 | 852 | auto userid = get_consumer_key(); | ||
1112 | 853 | |||
1113 | 854 | // | ||
1114 | 855 | // Get the click manifest. | 538 | // Get the click manifest. |
1115 | 856 | Manifest manifest; | 539 | Manifest manifest; |
1116 | 857 | std::promise<Manifest> manifest_promise; | ||
1117 | 858 | std::future<Manifest> manifest_future = manifest_promise.get_future(); | ||
1118 | 859 | std::string app_name = result["name"].get_string(); | 540 | std::string app_name = result["name"].get_string(); |
1119 | 860 | if (!app_name.empty() && !std::regex_match(app_name, desktop_match)) { | ||
1120 | 861 | qt::core::world::enter_with_task([&]() { | ||
1121 | 862 | click::Interface().get_manifest_for_app(app_name, | ||
1122 | 863 | [&](Manifest found_manifest, InterfaceError error) { | ||
1123 | 864 | qDebug() << "Got manifest for:" << app_name.c_str(); | ||
1124 | 865 | |||
1125 | 866 | // Fill in required data about the package being reviewed. | ||
1126 | 867 | review.package_name = found_manifest.name; | ||
1127 | 868 | review.package_version = found_manifest.version; | ||
1128 | 869 | |||
1129 | 870 | if (error != click::InterfaceError::NoError) { | ||
1130 | 871 | qDebug() << "There was an error getting the manifest for:" << app_name.c_str(); | ||
1131 | 872 | } | ||
1132 | 873 | manifest_promise.set_value(found_manifest); | ||
1133 | 874 | }); | ||
1134 | 875 | }); | ||
1135 | 876 | manifest = manifest_future.get(); | ||
1136 | 877 | if (review.rating > 0) { | ||
1137 | 878 | std::promise<bool> submit_promise; | ||
1138 | 879 | std::future<bool> submit_future = submit_promise.get_future(); | ||
1139 | 880 | qt::core::world::enter_with_task([this, review, &submit_promise, widget_id]() mutable { | ||
1140 | 881 | if (widget_id == "rating") { | ||
1141 | 882 | submit_operation = reviews->submit_review(review, | ||
1142 | 883 | [&submit_promise](click::Reviews::Error){ | ||
1143 | 884 | // TODO: Need to handle errors properly. | ||
1144 | 885 | submit_promise.set_value(true); | ||
1145 | 886 | }); | ||
1146 | 887 | |||
1147 | 888 | } else { | ||
1148 | 889 | try { | ||
1149 | 890 | review.id = std::stoul(widget_id); | ||
1150 | 891 | qDebug() << "Updating review" << review.id << "with '" << QString::fromStdString(review.review_text) << "'"; | ||
1151 | 892 | submit_operation = reviews->edit_review(review, | ||
1152 | 893 | [&submit_promise](click::Reviews::Error){ | ||
1153 | 894 | // TODO: Need to handle errors properly. | ||
1154 | 895 | submit_promise.set_value(true); | ||
1155 | 896 | }); | ||
1156 | 897 | } catch (const std::exception &e) { | ||
1157 | 898 | qWarning() << "Failed to update review:" << QString::fromStdString(e.what()) << " review widget:" << QString::fromStdString(widget_id); | ||
1158 | 899 | submit_promise.set_value(false); | ||
1159 | 900 | } | ||
1160 | 901 | } | ||
1161 | 902 | }); | ||
1162 | 903 | submit_future.get(); | ||
1163 | 904 | } | ||
1164 | 905 | } | ||
1165 | 906 | populateDetails([this, reply, manifest, app_name](const PackageDetails &details){ | 541 | populateDetails([this, reply, manifest, app_name](const PackageDetails &details){ |
1166 | 907 | cachedDetails = details; | 542 | cachedDetails = details; |
1167 | 908 | store_department(details); | 543 | store_department(details); |
1168 | 909 | pushPackagePreviewWidgets(cachedWidgets, details, createButtons(manifest)); | 544 | pushPackagePreviewWidgets(cachedWidgets, details, createButtons(manifest)); |
1169 | 910 | }, | ||
1170 | 911 | [this, reply, &review, manifest, userid](const ReviewList& reviewlist, | ||
1171 | 912 | click::Reviews::Error error) { | ||
1172 | 913 | auto reviews = bring_to_front(reviewlist, userid); | ||
1173 | 914 | if (manifest.removable && !cachedDetails.download_url.empty()) { | ||
1174 | 915 | scopes::PreviewWidgetList review_input; | ||
1175 | 916 | bool has_reviewed = reviews.size() > 0 && reviews.front().reviewer_username == userid; | ||
1176 | 917 | |||
1177 | 918 | Review existing_review; | ||
1178 | 919 | existing_review.id = 0; | ||
1179 | 920 | if (has_reviewed) { | ||
1180 | 921 | existing_review = reviews.front(); | ||
1181 | 922 | reviews.pop_front(); | ||
1182 | 923 | } | ||
1183 | 924 | review_input.push_back(createRatingWidget(existing_review)); | ||
1184 | 925 | cachedWidgets.push(review_input); | ||
1185 | 926 | cachedWidgets.layout.appendToColumn(cachedWidgets.layout.singleColumn.column1, review_input); | ||
1186 | 927 | cachedWidgets.layout.appendToColumn(cachedWidgets.layout.twoColumns.column1, review_input); | ||
1187 | 928 | } | ||
1188 | 929 | |||
1189 | 930 | if (error == click::Reviews::Error::NoError) { | ||
1190 | 931 | auto const revs = reviewsWidgets(reviews); | ||
1191 | 932 | cachedWidgets.push(revs); | ||
1192 | 933 | cachedWidgets.layout.appendToColumn(cachedWidgets.layout.singleColumn.column1, revs); | ||
1193 | 934 | cachedWidgets.layout.appendToColumn(cachedWidgets.layout.twoColumns.column1, revs); | ||
1194 | 935 | } else { | ||
1195 | 936 | qDebug() << "There was an error getting reviews for:" << result["name"].get_string().c_str(); | ||
1196 | 937 | } | ||
1197 | 938 | cachedWidgets.flush(reply); | 545 | cachedWidgets.flush(reply); |
1198 | 939 | reply->finished(); | 546 | reply->finished(); |
1199 | 940 | }, force_cache); | 547 | }, force_cache); |
1200 | @@ -965,16 +572,6 @@ | |||
1201 | 965 | qDebug() << "Adding button" << QString::fromStdString(open_label) << "-" | 572 | qDebug() << "Adding button" << QString::fromStdString(open_label) << "-" |
1202 | 966 | << QString::fromStdString(uri); | 573 | << QString::fromStdString(uri); |
1203 | 967 | } | 574 | } |
1204 | 968 | if (manifest.removable) | ||
1205 | 969 | { | ||
1206 | 970 | auto price = result.contains("price") ? result["price"].get_double() : 0.00f; | ||
1207 | 971 | if (price == 0.00f) { | ||
1208 | 972 | builder.add_tuple({ | ||
1209 | 973 | {"id", scopes::Variant(click::Preview::Actions::UNINSTALL_CLICK)}, | ||
1210 | 974 | {"label", scopes::Variant(_("Uninstall"))} | ||
1211 | 975 | }); | ||
1212 | 976 | } | ||
1213 | 977 | } | ||
1214 | 978 | if (!uri.empty() || manifest.removable) { | 575 | if (!uri.empty() || manifest.removable) { |
1215 | 979 | buttons.add_attribute_value("actions", builder.end()); | 576 | buttons.add_attribute_value("actions", builder.end()); |
1216 | 980 | widgets.push_back(buttons); | 577 | widgets.push_back(buttons); |
1217 | @@ -1032,203 +629,4 @@ | |||
1218 | 1032 | reply->push({actions}); | 629 | reply->push({actions}); |
1219 | 1033 | } | 630 | } |
1220 | 1034 | 631 | ||
1221 | 1035 | // class PurchasingPreview | ||
1222 | 1036 | |||
1223 | 1037 | PurchasingPreview::PurchasingPreview(const unity::scopes::Result& result, | ||
1224 | 1038 | const QSharedPointer<click::web::Client>& client) | ||
1225 | 1039 | : PreviewStrategy(result, client) | ||
1226 | 1040 | { | ||
1227 | 1041 | } | ||
1228 | 1042 | |||
1229 | 1043 | PurchasingPreview::~PurchasingPreview() | ||
1230 | 1044 | { | ||
1231 | 1045 | } | ||
1232 | 1046 | |||
1233 | 1047 | void PurchasingPreview::run(unity::scopes::PreviewReplyProxy const& reply) | ||
1234 | 1048 | { | ||
1235 | 1049 | populateDetails([this, reply](const PackageDetails &details){ | ||
1236 | 1050 | reply->push(purchasingWidgets(details)); | ||
1237 | 1051 | }, | ||
1238 | 1052 | [this, reply](const click::ReviewList&, click::Reviews::Error) { | ||
1239 | 1053 | reply->finished(); | ||
1240 | 1054 | }); | ||
1241 | 1055 | } | ||
1242 | 1056 | |||
1243 | 1057 | scopes::PreviewWidgetList PurchasingPreview::purchasingWidgets(const PackageDetails &/*details*/) | ||
1244 | 1058 | { | ||
1245 | 1059 | scopes::PreviewWidgetList widgets; | ||
1246 | 1060 | return widgets; | ||
1247 | 1061 | } | ||
1248 | 1062 | |||
1249 | 1063 | // class UninstallConfirmationPreview | ||
1250 | 1064 | |||
1251 | 1065 | UninstallConfirmationPreview::UninstallConfirmationPreview(const unity::scopes::Result& result) | ||
1252 | 1066 | : PreviewStrategy(result) | ||
1253 | 1067 | { | ||
1254 | 1068 | } | ||
1255 | 1069 | |||
1256 | 1070 | UninstallConfirmationPreview::~UninstallConfirmationPreview() | ||
1257 | 1071 | { | ||
1258 | 1072 | } | ||
1259 | 1073 | |||
1260 | 1074 | void UninstallConfirmationPreview::run(unity::scopes::PreviewReplyProxy const& reply) | ||
1261 | 1075 | { | ||
1262 | 1076 | // NOTE: no need to populateDetails() here. | ||
1263 | 1077 | scopes::PreviewWidgetList widgets; | ||
1264 | 1078 | |||
1265 | 1079 | scopes::PreviewWidget header("hdr", "header"); | ||
1266 | 1080 | header.add_attribute_value("title", scopes::Variant(_("Confirmation"))); | ||
1267 | 1081 | std::string title = result["title"].get_string(); | ||
1268 | 1082 | // TRANSLATORS: Do NOT translate ${title} here. | ||
1269 | 1083 | std::string message = _("Uninstall ${title}?"); | ||
1270 | 1084 | boost::replace_first(message, "${title}", title); | ||
1271 | 1085 | header.add_attribute_value("subtitle", scopes::Variant(message)); | ||
1272 | 1086 | widgets.push_back(header); | ||
1273 | 1087 | |||
1274 | 1088 | scopes::PreviewWidget buttons("buttons", "actions"); | ||
1275 | 1089 | scopes::VariantBuilder builder; | ||
1276 | 1090 | builder.add_tuple({ | ||
1277 | 1091 | {"id", scopes::Variant(click::Preview::Actions::SHOW_INSTALLED)}, | ||
1278 | 1092 | {"label", scopes::Variant(_("Cancel"))} | ||
1279 | 1093 | }); | ||
1280 | 1094 | builder.add_tuple({ | ||
1281 | 1095 | {"id", scopes::Variant(click::Preview::Actions::CONFIRM_UNINSTALL)}, | ||
1282 | 1096 | {"label", scopes::Variant(_("Confirm"))} | ||
1283 | 1097 | }); | ||
1284 | 1098 | buttons.add_attribute_value("actions", builder.end()); | ||
1285 | 1099 | widgets.push_back(buttons); | ||
1286 | 1100 | |||
1287 | 1101 | reply->push(widgets); | ||
1288 | 1102 | } | ||
1289 | 1103 | |||
1290 | 1104 | // class UninstalledPreview | ||
1291 | 1105 | |||
1292 | 1106 | UninstalledPreview::UninstalledPreview(const unity::scopes::Result& result, | ||
1293 | 1107 | const unity::scopes::ActionMetadata& metadata, | ||
1294 | 1108 | const QSharedPointer<click::web::Client>& client, | ||
1295 | 1109 | const std::shared_ptr<click::DepartmentsDb>& depts, | ||
1296 | 1110 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager) | ||
1297 | 1111 | : PreviewStrategy(result, client), | ||
1298 | 1112 | DepartmentUpdater(depts), | ||
1299 | 1113 | metadata(metadata), | ||
1300 | 1114 | dm(new DownloadManager(client, manager)) | ||
1301 | 1115 | { | ||
1302 | 1116 | qDebug() << "Creating new UninstalledPreview for result" << QString::fromStdString(result["name"].get_string()); | ||
1303 | 1117 | } | ||
1304 | 1118 | |||
1305 | 1119 | UninstalledPreview::~UninstalledPreview() | ||
1306 | 1120 | { | ||
1307 | 1121 | } | ||
1308 | 1122 | |||
1309 | 1123 | void UninstalledPreview::run(unity::scopes::PreviewReplyProxy const& reply) | ||
1310 | 1124 | { | ||
1311 | 1125 | const bool force_cache = (metadata.internet_connectivity() == scopes::QueryMetadata::ConnectivityStatus::Disconnected); | ||
1312 | 1126 | qDebug() << "preview, force_cache=" << force_cache << ", conn status=" << (int)metadata.internet_connectivity(); | ||
1313 | 1127 | |||
1314 | 1128 | qDebug() << "in UninstalledPreview::run, about to populate details"; | ||
1315 | 1129 | populateDetails([this, reply](const PackageDetails &details){ | ||
1316 | 1130 | store_department(details); | ||
1317 | 1131 | found_details = details; | ||
1318 | 1132 | }, | ||
1319 | 1133 | [this, reply](const ReviewList& reviewlist, | ||
1320 | 1134 | click::Reviews::Error reviewserror) { | ||
1321 | 1135 | std::string app_name = result["name"].get_string(); | ||
1322 | 1136 | dm->get_progress(app_name, | ||
1323 | 1137 | [this, reply, reviewlist, reviewserror](std::string object_path){ | ||
1324 | 1138 | found_object_path = object_path; | ||
1325 | 1139 | scopes::PreviewWidgetList button_widgets; | ||
1326 | 1140 | if(found_object_path.empty()) { | ||
1327 | 1141 | button_widgets = uninstalledActionButtonWidgets(found_details); | ||
1328 | 1142 | } else { | ||
1329 | 1143 | button_widgets = progressBarWidget(found_object_path); | ||
1330 | 1144 | } | ||
1331 | 1145 | qDebug() << "Pushed button action widgets."; | ||
1332 | 1146 | pushPackagePreviewWidgets(cachedWidgets, found_details, button_widgets); | ||
1333 | 1147 | qDebug() << "Pushed package details widgets."; | ||
1334 | 1148 | if (reviewserror == click::Reviews::Error::NoError) { | ||
1335 | 1149 | qDebug() << "Pushing reviews widgets."; | ||
1336 | 1150 | auto const revs = reviewsWidgets(reviewlist); | ||
1337 | 1151 | cachedWidgets.push(revs); | ||
1338 | 1152 | cachedWidgets.layout.appendToColumn(cachedWidgets.layout.singleColumn.column1, revs); | ||
1339 | 1153 | cachedWidgets.layout.appendToColumn(cachedWidgets.layout.twoColumns.column1, revs); | ||
1340 | 1154 | } else { | ||
1341 | 1155 | qDebug() << "There was an error getting reviews for:" << result["name"].get_string().c_str(); | ||
1342 | 1156 | } | ||
1343 | 1157 | cachedWidgets.flush(reply); | ||
1344 | 1158 | reply->finished(); | ||
1345 | 1159 | qDebug() << "---------- Finished reply for:" << result["name"].get_string().c_str(); | ||
1346 | 1160 | }); | ||
1347 | 1161 | }, force_cache); | ||
1348 | 1162 | } | ||
1349 | 1163 | |||
1350 | 1164 | scopes::PreviewWidgetList UninstalledPreview::uninstalledActionButtonWidgets(const PackageDetails &details) | ||
1351 | 1165 | { | ||
1352 | 1166 | scopes::PreviewWidgetList widgets; | ||
1353 | 1167 | auto price = result["price"].get_double(); | ||
1354 | 1168 | |||
1355 | 1169 | if (price == double(0.00) | ||
1356 | 1170 | || result["purchased"].get_bool() == false) { | ||
1357 | 1171 | scopes::PreviewWidget buttons("buttons", "actions"); | ||
1358 | 1172 | scopes::VariantBuilder builder; | ||
1359 | 1173 | builder.add_tuple( | ||
1360 | 1174 | { | ||
1361 | 1175 | {"id", scopes::Variant(click::Preview::Actions::INSTALL_CLICK)}, | ||
1362 | 1176 | {"label", scopes::Variant(_("Install"))}, | ||
1363 | 1177 | {"download_url", scopes::Variant(details.download_url)}, | ||
1364 | 1178 | {"download_sha512", scopes::Variant(details.download_sha512)}, | ||
1365 | 1179 | }); | ||
1366 | 1180 | buttons.add_attribute_value("actions", builder.end()); | ||
1367 | 1181 | oa_client.register_account_login_item(buttons, | ||
1368 | 1182 | scopes::OnlineAccountClient::PostLoginAction::ContinueActivation, | ||
1369 | 1183 | scopes::OnlineAccountClient::PostLoginAction::DoNothing); | ||
1370 | 1184 | widgets.push_back(buttons); | ||
1371 | 1185 | } | ||
1372 | 1186 | |||
1373 | 1187 | return widgets; | ||
1374 | 1188 | } | ||
1375 | 1189 | |||
1376 | 1190 | // class UninstallingPreview : public UninstalledPreview | ||
1377 | 1191 | |||
1378 | 1192 | // TODO: this class should be removed once uninstall() is handled elsewhere. | ||
1379 | 1193 | UninstallingPreview::UninstallingPreview(const unity::scopes::Result& result, | ||
1380 | 1194 | const unity::scopes::ActionMetadata& metadata, | ||
1381 | 1195 | const QSharedPointer<click::web::Client>& client, | ||
1382 | 1196 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager) | ||
1383 | 1197 | : UninstalledPreview(result, metadata, client, nullptr, manager) | ||
1384 | 1198 | { | ||
1385 | 1199 | } | ||
1386 | 1200 | |||
1387 | 1201 | UninstallingPreview::~UninstallingPreview() | ||
1388 | 1202 | { | ||
1389 | 1203 | } | ||
1390 | 1204 | |||
1391 | 1205 | void UninstallingPreview::run(unity::scopes::PreviewReplyProxy const& reply) | ||
1392 | 1206 | { | ||
1393 | 1207 | qDebug() << "in UninstallingPreview::run, calling uninstall"; | ||
1394 | 1208 | uninstall(); | ||
1395 | 1209 | qDebug() << "in UninstallingPreview::run, calling UninstalledPreview::run()"; | ||
1396 | 1210 | UninstalledPreview::run(reply); | ||
1397 | 1211 | } | ||
1398 | 1212 | |||
1399 | 1213 | void UninstallingPreview::uninstall() | ||
1400 | 1214 | { | ||
1401 | 1215 | click::Package package; | ||
1402 | 1216 | package.title = result.title(); | ||
1403 | 1217 | package.name = result["name"].get_string(); | ||
1404 | 1218 | package.version = result["version"].get_string(); | ||
1405 | 1219 | qt::core::world::enter_with_task([this, package] () | ||
1406 | 1220 | { | ||
1407 | 1221 | click::PackageManager manager; | ||
1408 | 1222 | manager.uninstall(package, [&](int code, std::string stderr_content) { | ||
1409 | 1223 | if (code != 0) { | ||
1410 | 1224 | qDebug() << "Error removing package:" << stderr_content.c_str(); | ||
1411 | 1225 | } else { | ||
1412 | 1226 | qDebug() << "successfully removed package"; | ||
1413 | 1227 | |||
1414 | 1228 | } | ||
1415 | 1229 | } ); | ||
1416 | 1230 | }); | ||
1417 | 1231 | } | ||
1418 | 1232 | |||
1419 | 1233 | |||
1420 | 1234 | } // namespace click | 632 | } // namespace click |
1421 | 1235 | 633 | ||
1422 | === modified file 'libclickscope/click/preview.h' | |||
1423 | --- libclickscope/click/preview.h 2016-10-24 21:26:23 +0000 | |||
1424 | +++ libclickscope/click/preview.h 2017-01-10 16:06:37 +0000 | |||
1425 | @@ -31,9 +31,7 @@ | |||
1426 | 31 | #define CLICKPREVIEW_H | 31 | #define CLICKPREVIEW_H |
1427 | 32 | 32 | ||
1428 | 33 | #include <click/index.h> | 33 | #include <click/index.h> |
1429 | 34 | #include <click/download-manager.h> | ||
1430 | 35 | #include <click/qtbridge.h> | 34 | #include <click/qtbridge.h> |
1431 | 36 | #include "reviews.h" | ||
1432 | 37 | 35 | ||
1433 | 38 | #include <click/network_access_manager.h> | 36 | #include <click/network_access_manager.h> |
1434 | 39 | 37 | ||
1435 | @@ -105,14 +103,7 @@ | |||
1436 | 105 | PreviewStrategy* build_strategy(const unity::scopes::Result& result, | 103 | PreviewStrategy* build_strategy(const unity::scopes::Result& result, |
1437 | 106 | const unity::scopes::ActionMetadata& metadata, | 104 | const unity::scopes::ActionMetadata& metadata, |
1438 | 107 | const QSharedPointer<web::Client> &client, | 105 | const QSharedPointer<web::Client> &client, |
1439 | 108 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager, | ||
1440 | 109 | std::shared_ptr<click::DepartmentsDb> depts); | 106 | std::shared_ptr<click::DepartmentsDb> depts); |
1441 | 110 | virtual PreviewStrategy* build_installing(const std::string& download_url, | ||
1442 | 111 | const std::string& download_sha512, | ||
1443 | 112 | const unity::scopes::Result& result, | ||
1444 | 113 | const QSharedPointer<click::web::Client>& client, | ||
1445 | 114 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager, | ||
1446 | 115 | std::shared_ptr<click::DepartmentsDb> depts); | ||
1447 | 116 | public: | 107 | public: |
1448 | 117 | UNITY_DEFINES_PTRS(Preview); | 108 | UNITY_DEFINES_PTRS(Preview); |
1449 | 118 | struct Actions | 109 | struct Actions |
1450 | @@ -145,7 +136,6 @@ | |||
1451 | 145 | std::shared_future<void> const& qt_ready = std::future<void>()); | 136 | std::shared_future<void> const& qt_ready = std::future<void>()); |
1452 | 146 | virtual ~Preview(); | 137 | virtual ~Preview(); |
1453 | 147 | void choose_strategy(const QSharedPointer<web::Client> &client, | 138 | void choose_strategy(const QSharedPointer<web::Client> &client, |
1454 | 148 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager, | ||
1455 | 149 | std::shared_ptr<click::DepartmentsDb> depts); | 139 | std::shared_ptr<click::DepartmentsDb> depts); |
1456 | 150 | // From unity::scopes::PreviewQuery | 140 | // From unity::scopes::PreviewQuery |
1457 | 151 | void cancelled() override; | 141 | void cancelled() override; |
1458 | @@ -168,20 +158,13 @@ | |||
1459 | 168 | const scopes::PreviewWidgetList& button_area_widgets); | 158 | const scopes::PreviewWidgetList& button_area_widgets); |
1460 | 169 | 159 | ||
1461 | 170 | virtual void run_under_qt(const std::function<void ()> &task); | 160 | virtual void run_under_qt(const std::function<void ()> &task); |
1462 | 171 | virtual void invalidateScope(const std::string& scope_id); | ||
1463 | 172 | 161 | ||
1464 | 173 | protected: | 162 | protected: |
1465 | 174 | virtual void populateDetails(std::function<void(const PackageDetails &)> details_callback, | 163 | virtual void populateDetails(std::function<void(const PackageDetails &)> details_callback, |
1466 | 175 | std::function<void(const click::ReviewList&, | ||
1467 | 176 | click::Reviews::Error)> reviews_callback, | ||
1468 | 177 | bool force_cache = false); | 164 | bool force_cache = false); |
1469 | 178 | virtual scopes::PreviewWidgetList headerWidgets(const PackageDetails &details); | 165 | virtual scopes::PreviewWidgetList headerWidgets(const PackageDetails &details); |
1470 | 179 | virtual scopes::PreviewWidgetList screenshotsWidgets(const PackageDetails &details); | 166 | virtual scopes::PreviewWidgetList screenshotsWidgets(const PackageDetails &details); |
1471 | 180 | virtual scopes::PreviewWidgetList descriptionWidgets(const PackageDetails &details); | 167 | virtual scopes::PreviewWidgetList descriptionWidgets(const PackageDetails &details); |
1472 | 181 | virtual scopes::PreviewWidgetList progressBarWidget(const std::string& object_path); | ||
1473 | 182 | virtual scopes::PreviewWidgetList reviewsWidgets(const click::ReviewList &reviewlist); | ||
1474 | 183 | virtual scopes::PreviewWidgetList downloadErrorWidgets(); | ||
1475 | 184 | virtual scopes::PreviewWidgetList loginErrorWidgets(const std::string& download_url, const std::string& download_sha512); | ||
1476 | 185 | virtual scopes::PreviewWidgetList errorWidgets(const scopes::Variant& title, | 168 | virtual scopes::PreviewWidgetList errorWidgets(const scopes::Variant& title, |
1477 | 186 | const scopes::Variant& summary, | 169 | const scopes::Variant& summary, |
1478 | 187 | const scopes::Variant& action_id, | 170 | const scopes::Variant& action_id, |
1479 | @@ -199,45 +182,7 @@ | |||
1480 | 199 | QSharedPointer<click::web::Client> client; | 182 | QSharedPointer<click::web::Client> client; |
1481 | 200 | QSharedPointer<click::Index> index; | 183 | QSharedPointer<click::Index> index; |
1482 | 201 | click::web::Cancellable index_operation; | 184 | click::web::Cancellable index_operation; |
1483 | 202 | QSharedPointer<click::Reviews> reviews; | ||
1484 | 203 | click::web::Cancellable reviews_operation; | ||
1485 | 204 | click::web::Cancellable submit_operation; | ||
1486 | 205 | scopes::OnlineAccountClient oa_client; | 185 | scopes::OnlineAccountClient oa_client; |
1487 | 206 | click::web::Cancellable purchase_operation; | ||
1488 | 207 | }; | ||
1489 | 208 | |||
1490 | 209 | class DownloadErrorPreview : public PreviewStrategy | ||
1491 | 210 | { | ||
1492 | 211 | public: | ||
1493 | 212 | DownloadErrorPreview(const unity::scopes::Result& result); | ||
1494 | 213 | |||
1495 | 214 | virtual ~DownloadErrorPreview(); | ||
1496 | 215 | |||
1497 | 216 | void run(unity::scopes::PreviewReplyProxy const& reply) override; | ||
1498 | 217 | }; | ||
1499 | 218 | |||
1500 | 219 | class InstallingPreview : public PreviewStrategy, public DepartmentUpdater | ||
1501 | 220 | { | ||
1502 | 221 | public: | ||
1503 | 222 | InstallingPreview(const unity::scopes::Result& result) : PreviewStrategy(result) {} | ||
1504 | 223 | InstallingPreview(const std::string& download_url, | ||
1505 | 224 | const std::string& download_sha512, | ||
1506 | 225 | const unity::scopes::Result& result, | ||
1507 | 226 | const QSharedPointer<click::web::Client>& client, | ||
1508 | 227 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager, | ||
1509 | 228 | std::shared_ptr<click::DepartmentsDb> depts); | ||
1510 | 229 | |||
1511 | 230 | virtual ~InstallingPreview(); | ||
1512 | 231 | |||
1513 | 232 | void run(unity::scopes::PreviewReplyProxy const& reply) override; | ||
1514 | 233 | |||
1515 | 234 | protected: | ||
1516 | 235 | std::string download_url; | ||
1517 | 236 | std::string download_sha512; | ||
1518 | 237 | QSharedPointer<click::DownloadManager> dm; | ||
1519 | 238 | std::shared_ptr<click::DepartmentsDb> depts_db; | ||
1520 | 239 | CachedPreviewWidgets cachedWidgets; | ||
1521 | 240 | void startLauncherAnimation(const PackageDetails& details); | ||
1522 | 241 | }; | 186 | }; |
1523 | 242 | 187 | ||
1524 | 243 | class InstalledPreview : public PreviewStrategy, public DepartmentUpdater | 188 | class InstalledPreview : public PreviewStrategy, public DepartmentUpdater |
1525 | @@ -253,9 +198,7 @@ | |||
1526 | 253 | void run(unity::scopes::PreviewReplyProxy const& reply) override; | 198 | void run(unity::scopes::PreviewReplyProxy const& reply) override; |
1527 | 254 | 199 | ||
1528 | 255 | std::string getApplicationUri(const Manifest& manifest); | 200 | std::string getApplicationUri(const Manifest& manifest); |
1529 | 256 | std::string get_consumer_key(); | ||
1530 | 257 | scopes::PreviewWidgetList createButtons(const click::Manifest& manifest); | 201 | scopes::PreviewWidgetList createButtons(const click::Manifest& manifest); |
1531 | 258 | scopes::PreviewWidget createRatingWidget(const click::Review& review) const; | ||
1532 | 259 | 202 | ||
1533 | 260 | private: | 203 | private: |
1534 | 261 | scopes::ActionMetadata metadata; | 204 | scopes::ActionMetadata metadata; |
1535 | @@ -270,71 +213,6 @@ | |||
1536 | 270 | void run(unity::scopes::PreviewReplyProxy const& reply) override; | 213 | void run(unity::scopes::PreviewReplyProxy const& reply) override; |
1537 | 271 | }; | 214 | }; |
1538 | 272 | 215 | ||
1539 | 273 | class PurchasingPreview : public PreviewStrategy | ||
1540 | 274 | { | ||
1541 | 275 | public: | ||
1542 | 276 | PurchasingPreview(const unity::scopes::Result& result, | ||
1543 | 277 | const QSharedPointer<click::web::Client>& client); | ||
1544 | 278 | virtual ~PurchasingPreview(); | ||
1545 | 279 | |||
1546 | 280 | void run(unity::scopes::PreviewReplyProxy const& reply) override; | ||
1547 | 281 | |||
1548 | 282 | protected: | ||
1549 | 283 | virtual scopes::PreviewWidgetList purchasingWidgets(const PackageDetails &); | ||
1550 | 284 | }; | ||
1551 | 285 | |||
1552 | 286 | class UninstallConfirmationPreview : public PreviewStrategy | ||
1553 | 287 | { | ||
1554 | 288 | public: | ||
1555 | 289 | UninstallConfirmationPreview(const unity::scopes::Result& result); | ||
1556 | 290 | |||
1557 | 291 | virtual ~UninstallConfirmationPreview(); | ||
1558 | 292 | |||
1559 | 293 | void run(unity::scopes::PreviewReplyProxy const& reply) override; | ||
1560 | 294 | }; | ||
1561 | 295 | |||
1562 | 296 | class UninstalledPreview : public PreviewStrategy, public DepartmentUpdater | ||
1563 | 297 | { | ||
1564 | 298 | public: | ||
1565 | 299 | UninstalledPreview(const unity::scopes::Result& result, | ||
1566 | 300 | const unity::scopes::ActionMetadata& metadata, | ||
1567 | 301 | const QSharedPointer<click::web::Client>& client, | ||
1568 | 302 | const std::shared_ptr<click::DepartmentsDb>& depts, | ||
1569 | 303 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager); | ||
1570 | 304 | |||
1571 | 305 | virtual ~UninstalledPreview(); | ||
1572 | 306 | |||
1573 | 307 | void run(unity::scopes::PreviewReplyProxy const& reply) override; | ||
1574 | 308 | virtual scopes::PreviewWidgetList uninstalledActionButtonWidgets(const PackageDetails &details); | ||
1575 | 309 | |||
1576 | 310 | protected: | ||
1577 | 311 | scopes::ActionMetadata metadata; | ||
1578 | 312 | PackageDetails found_details; | ||
1579 | 313 | CachedPreviewWidgets cachedWidgets; | ||
1580 | 314 | std::string found_object_path; | ||
1581 | 315 | |||
1582 | 316 | QSharedPointer<click::DownloadManager> dm; | ||
1583 | 317 | }; | ||
1584 | 318 | |||
1585 | 319 | // TODO: this is only necessary to perform uninstall. | ||
1586 | 320 | // That should be moved to a separate action, and this class removed. | ||
1587 | 321 | class UninstallingPreview : public UninstalledPreview | ||
1588 | 322 | { | ||
1589 | 323 | public: | ||
1590 | 324 | UninstallingPreview(const unity::scopes::Result& result, | ||
1591 | 325 | const unity::scopes::ActionMetadata& metadata, | ||
1592 | 326 | const QSharedPointer<click::web::Client>& client, | ||
1593 | 327 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager); | ||
1594 | 328 | |||
1595 | 329 | virtual ~UninstallingPreview(); | ||
1596 | 330 | |||
1597 | 331 | void run(unity::scopes::PreviewReplyProxy const& reply) override; | ||
1598 | 332 | |||
1599 | 333 | protected: | ||
1600 | 334 | void uninstall(); | ||
1601 | 335 | |||
1602 | 336 | }; | ||
1603 | 337 | |||
1604 | 338 | } // namespace click | 216 | } // namespace click |
1605 | 339 | 217 | ||
1606 | 340 | #endif | 218 | #endif |
1607 | 341 | 219 | ||
1608 | === removed file 'libclickscope/click/reviews.cpp' | |||
1609 | --- libclickscope/click/reviews.cpp 2016-05-25 16:19:51 +0000 | |||
1610 | +++ libclickscope/click/reviews.cpp 1970-01-01 00:00:00 +0000 | |||
1611 | @@ -1,245 +0,0 @@ | |||
1612 | 1 | /* | ||
1613 | 2 | * Copyright (C) 2014 Canonical Ltd. | ||
1614 | 3 | * | ||
1615 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
1616 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
1617 | 6 | * by the Free Software Foundation. | ||
1618 | 7 | * | ||
1619 | 8 | * This program is distributed in the hope that it will be useful, but | ||
1620 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1621 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1622 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
1623 | 12 | * | ||
1624 | 13 | * You should have received a copy of the GNU General Public License along | ||
1625 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1626 | 15 | * | ||
1627 | 16 | * In addition, as a special exception, the copyright holders give | ||
1628 | 17 | * permission to link the code of portions of this program with the | ||
1629 | 18 | * OpenSSL library under certain conditions as described in each | ||
1630 | 19 | * individual source file, and distribute linked combinations | ||
1631 | 20 | * including the two. | ||
1632 | 21 | * You must obey the GNU General Public License in all respects | ||
1633 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
1634 | 23 | * file(s) with this exception, you may extend this exception to your | ||
1635 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
1636 | 25 | * do not wish to do so, delete this exception statement from your | ||
1637 | 26 | * version. If you delete this exception statement from all source | ||
1638 | 27 | * files in the program, then also delete it here. | ||
1639 | 28 | */ | ||
1640 | 29 | |||
1641 | 30 | #include <cstdlib> | ||
1642 | 31 | #include <algorithm> | ||
1643 | 32 | |||
1644 | 33 | #include <boost/property_tree/ptree.hpp> | ||
1645 | 34 | #include <boost/property_tree/json_parser.hpp> | ||
1646 | 35 | #include <boost/foreach.hpp> | ||
1647 | 36 | |||
1648 | 37 | #include <click/configuration.h> | ||
1649 | 38 | |||
1650 | 39 | #include <json/value.h> | ||
1651 | 40 | #include <json/writer.h> | ||
1652 | 41 | |||
1653 | 42 | #include "reviews.h" | ||
1654 | 43 | |||
1655 | 44 | namespace click | ||
1656 | 45 | { | ||
1657 | 46 | |||
1658 | 47 | bool operator== (const Review& lhs, const Review &rhs) | ||
1659 | 48 | { | ||
1660 | 49 | return lhs.id == rhs.id && | ||
1661 | 50 | lhs.rating == rhs.rating && | ||
1662 | 51 | lhs.usefulness_favorable == rhs.usefulness_favorable && | ||
1663 | 52 | lhs.usefulness_total == rhs.usefulness_total && | ||
1664 | 53 | lhs.hide == rhs.hide && | ||
1665 | 54 | lhs.date_created == rhs.date_created && | ||
1666 | 55 | lhs.date_deleted == rhs.date_deleted && | ||
1667 | 56 | lhs.package_name == rhs.package_name && | ||
1668 | 57 | lhs.package_version == rhs.package_version && | ||
1669 | 58 | lhs.language == rhs.language && | ||
1670 | 59 | lhs.summary == rhs.summary && | ||
1671 | 60 | lhs.review_text == rhs.review_text && | ||
1672 | 61 | lhs.reviewer_name == rhs.reviewer_name && | ||
1673 | 62 | lhs.reviewer_username == rhs.reviewer_username; | ||
1674 | 63 | } | ||
1675 | 64 | |||
1676 | 65 | ReviewList review_list_from_json (const std::string& json) | ||
1677 | 66 | { | ||
1678 | 67 | std::istringstream stream(json); | ||
1679 | 68 | |||
1680 | 69 | boost::property_tree::ptree tree; | ||
1681 | 70 | boost::property_tree::read_json(stream, tree); | ||
1682 | 71 | |||
1683 | 72 | ReviewList reviews; | ||
1684 | 73 | |||
1685 | 74 | BOOST_FOREACH(boost::property_tree::ptree::value_type &value, tree) | ||
1686 | 75 | { | ||
1687 | 76 | assert(value.first.empty()); // array elements have no names | ||
1688 | 77 | auto node = value.second; | ||
1689 | 78 | Review review; | ||
1690 | 79 | |||
1691 | 80 | review.id = node.get<uint32_t>("id"); | ||
1692 | 81 | review.rating = node.get<int>("rating"); | ||
1693 | 82 | review.usefulness_favorable = node.get<uint32_t>("usefulness_favorable"); | ||
1694 | 83 | review.usefulness_total = node.get<uint32_t>("usefulness_total"); | ||
1695 | 84 | review.hide = node.get<bool>("hide"); | ||
1696 | 85 | review.date_created = node.get<std::string>("date_created"); | ||
1697 | 86 | review.date_deleted = node.get<std::string>("date_deleted"); | ||
1698 | 87 | review.package_name = node.get<std::string>("package_name"); | ||
1699 | 88 | review.package_version = node.get<std::string>("version"); | ||
1700 | 89 | review.language = node.get<std::string>("language"); | ||
1701 | 90 | review.summary = node.get<std::string>("summary"); | ||
1702 | 91 | review.review_text = node.get<std::string>("review_text"); | ||
1703 | 92 | review.reviewer_username = node.get<std::string>("reviewer_username"); | ||
1704 | 93 | review.reviewer_name = node.get<std::string>("reviewer_displayname", review.reviewer_username); | ||
1705 | 94 | |||
1706 | 95 | reviews.push_back(review); | ||
1707 | 96 | } | ||
1708 | 97 | return reviews; | ||
1709 | 98 | } | ||
1710 | 99 | |||
1711 | 100 | ReviewList bring_to_front (const ReviewList& reviews, const std::string& userid) | ||
1712 | 101 | { | ||
1713 | 102 | if (userid.size() == 0) | ||
1714 | 103 | { | ||
1715 | 104 | return reviews; | ||
1716 | 105 | } | ||
1717 | 106 | auto new_reviews = reviews; | ||
1718 | 107 | auto it = std::find_if(new_reviews.begin(), new_reviews.end(), [userid](const Review& review) { | ||
1719 | 108 | return review.reviewer_username == userid; | ||
1720 | 109 | }); | ||
1721 | 110 | if (it != new_reviews.end() && it != new_reviews.begin()) { | ||
1722 | 111 | // move own review to the front | ||
1723 | 112 | auto const review = *it; | ||
1724 | 113 | new_reviews.erase(it); | ||
1725 | 114 | new_reviews.push_front(review); | ||
1726 | 115 | } | ||
1727 | 116 | return new_reviews; | ||
1728 | 117 | } | ||
1729 | 118 | |||
1730 | 119 | Reviews::Reviews (const QSharedPointer<click::web::Client>& client) | ||
1731 | 120 | : client(client) | ||
1732 | 121 | { | ||
1733 | 122 | } | ||
1734 | 123 | |||
1735 | 124 | Reviews::~Reviews () | ||
1736 | 125 | { | ||
1737 | 126 | } | ||
1738 | 127 | |||
1739 | 128 | click::web::Cancellable Reviews::fetch_reviews (const std::string& package_name, | ||
1740 | 129 | std::function<void(ReviewList, Error)> callback, | ||
1741 | 130 | bool force_cache) | ||
1742 | 131 | { | ||
1743 | 132 | click::web::CallParams params; | ||
1744 | 133 | params.add(click::REVIEWS_QUERY_ARGNAME, package_name.c_str()); | ||
1745 | 134 | QSharedPointer<click::web::Response> response = client->call | ||
1746 | 135 | (get_base_url() + click::REVIEWS_API_PATH, "GET", false, | ||
1747 | 136 | std::map<std::string, std::string>{}, "", params, force_cache); | ||
1748 | 137 | |||
1749 | 138 | QObject::connect(response.data(), &click::web::Response::finished, | ||
1750 | 139 | [=](QString reply) { | ||
1751 | 140 | auto status = response->get_status_code(); | ||
1752 | 141 | click::ReviewList reviews; | ||
1753 | 142 | if (status == 200) { | ||
1754 | 143 | reviews = review_list_from_json(reply.toUtf8().constData()); | ||
1755 | 144 | callback(reviews, click::Reviews::Error::NoError); | ||
1756 | 145 | } else { | ||
1757 | 146 | callback(reviews, click::Reviews::Error::NetworkError); | ||
1758 | 147 | } | ||
1759 | 148 | }); | ||
1760 | 149 | QObject::connect(response.data(), &click::web::Response::error, | ||
1761 | 150 | [=](QString) { | ||
1762 | 151 | qDebug() << "Network error attempting to fetch reviews for:" << package_name.c_str(); | ||
1763 | 152 | callback(ReviewList(), click::Reviews::Error::NetworkError); | ||
1764 | 153 | }); | ||
1765 | 154 | |||
1766 | 155 | return click::web::Cancellable(response); | ||
1767 | 156 | } | ||
1768 | 157 | |||
1769 | 158 | click::web::Cancellable Reviews::submit_review (const Review& review, | ||
1770 | 159 | std::function<void(Error)> callback) | ||
1771 | 160 | { | ||
1772 | 161 | std::map<std::string, std::string> headers({ | ||
1773 | 162 | {click::web::CONTENT_TYPE_HEADER, click::web::CONTENT_TYPE_JSON}, | ||
1774 | 163 | }); | ||
1775 | 164 | Json::Value root(Json::ValueType::objectValue); | ||
1776 | 165 | root["package_name"] = review.package_name; | ||
1777 | 166 | root["version"] = review.package_version; | ||
1778 | 167 | root["rating"] = review.rating; | ||
1779 | 168 | root["review_text"] = review.review_text; | ||
1780 | 169 | |||
1781 | 170 | root["arch_tag"] = click::Configuration().get_architecture(); | ||
1782 | 171 | /* NOTE: We only use the base language code for reviews, except for | ||
1783 | 172 | * codes in the click::Configuration::FULL_LANG_CODES vector. | ||
1784 | 173 | */ | ||
1785 | 174 | auto language = click::Configuration().get_language(); | ||
1786 | 175 | if (click::Configuration::is_full_lang_code(language)) { | ||
1787 | 176 | root["language"] = language; | ||
1788 | 177 | } else { | ||
1789 | 178 | root["language"] = click::Configuration().get_language_base(); | ||
1790 | 179 | } | ||
1791 | 180 | |||
1792 | 181 | // NOTE: "summary" is a required field, but we don't have one. Use "". | ||
1793 | 182 | root["summary"] = "Review"; | ||
1794 | 183 | |||
1795 | 184 | qDebug() << "Rating" << review.package_name.c_str() << review.rating; | ||
1796 | 185 | |||
1797 | 186 | QSharedPointer<click::web::Response> response = client->call | ||
1798 | 187 | (get_base_url() + click::REVIEWS_API_PATH, "POST", true, | ||
1799 | 188 | headers, Json::FastWriter().write(root), click::web::CallParams()); | ||
1800 | 189 | |||
1801 | 190 | QObject::connect(response.data(), &click::web::Response::finished, | ||
1802 | 191 | [=](QString) { | ||
1803 | 192 | qDebug() << "Review submitted for:" << review.package_name.c_str(); | ||
1804 | 193 | callback(Error::NoError); | ||
1805 | 194 | }); | ||
1806 | 195 | QObject::connect(response.data(), &click::web::Response::error, | ||
1807 | 196 | [=](QString) { | ||
1808 | 197 | qCritical() << "Network error submitting a reviews for:" << review.package_name.c_str(); | ||
1809 | 198 | callback(Error::NetworkError); | ||
1810 | 199 | }); | ||
1811 | 200 | |||
1812 | 201 | return click::web::Cancellable(response); | ||
1813 | 202 | } | ||
1814 | 203 | |||
1815 | 204 | click::web::Cancellable Reviews::edit_review (const Review& review, | ||
1816 | 205 | std::function<void(Error)> callback) | ||
1817 | 206 | { | ||
1818 | 207 | std::map<std::string, std::string> headers({ | ||
1819 | 208 | {click::web::CONTENT_TYPE_HEADER, click::web::CONTENT_TYPE_JSON}, | ||
1820 | 209 | }); | ||
1821 | 210 | Json::Value root(Json::ValueType::objectValue); | ||
1822 | 211 | root["rating"] = review.rating; | ||
1823 | 212 | root["review_text"] = review.review_text; | ||
1824 | 213 | // NOTE: "summary" is a required field, but we don't have one. Use "". | ||
1825 | 214 | root["summary"] = "Review"; | ||
1826 | 215 | |||
1827 | 216 | qDebug() << "Rating" << review.package_name.c_str() << review.rating; | ||
1828 | 217 | |||
1829 | 218 | QSharedPointer<click::web::Response> response = client->call | ||
1830 | 219 | (get_base_url() + click::REVIEWS_API_PATH + std::to_string(review.id) + "/", "PUT", true, | ||
1831 | 220 | headers, Json::FastWriter().write(root), click::web::CallParams()); | ||
1832 | 221 | |||
1833 | 222 | QObject::connect(response.data(), &click::web::Response::finished, | ||
1834 | 223 | [=](QString) { | ||
1835 | 224 | qDebug() << "Review updated for:" << review.package_name.c_str(); | ||
1836 | 225 | callback(Error::NoError); | ||
1837 | 226 | }); | ||
1838 | 227 | QObject::connect(response.data(), &click::web::Response::error, | ||
1839 | 228 | [=](QString) { | ||
1840 | 229 | qCritical() << "Network error updating a review for:" << review.package_name.c_str(); | ||
1841 | 230 | callback(Error::NetworkError); | ||
1842 | 231 | }); | ||
1843 | 232 | |||
1844 | 233 | return click::web::Cancellable(response); | ||
1845 | 234 | } | ||
1846 | 235 | |||
1847 | 236 | std::string Reviews::get_base_url () | ||
1848 | 237 | { | ||
1849 | 238 | const char *env_url = getenv(REVIEWS_BASE_URL_ENVVAR.c_str()); | ||
1850 | 239 | if (env_url != NULL) { | ||
1851 | 240 | return env_url; | ||
1852 | 241 | } | ||
1853 | 242 | return click::REVIEWS_BASE_URL; | ||
1854 | 243 | } | ||
1855 | 244 | |||
1856 | 245 | } //namespace click | ||
1857 | 246 | 0 | ||
1858 | === removed file 'libclickscope/click/reviews.h' | |||
1859 | --- libclickscope/click/reviews.h 2016-04-27 14:06:29 +0000 | |||
1860 | +++ libclickscope/click/reviews.h 1970-01-01 00:00:00 +0000 | |||
1861 | @@ -1,95 +0,0 @@ | |||
1862 | 1 | /* | ||
1863 | 2 | * Copyright (C) 2014 Canonical Ltd. | ||
1864 | 3 | * | ||
1865 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
1866 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
1867 | 6 | * by the Free Software Foundation. | ||
1868 | 7 | * | ||
1869 | 8 | * This program is distributed in the hope that it will be useful, but | ||
1870 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1871 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1872 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
1873 | 12 | * | ||
1874 | 13 | * You should have received a copy of the GNU General Public License along | ||
1875 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1876 | 15 | * | ||
1877 | 16 | * In addition, as a special exception, the copyright holders give | ||
1878 | 17 | * permission to link the code of portions of this program with the | ||
1879 | 18 | * OpenSSL library under certain conditions as described in each | ||
1880 | 19 | * individual source file, and distribute linked combinations | ||
1881 | 20 | * including the two. | ||
1882 | 21 | * You must obey the GNU General Public License in all respects | ||
1883 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
1884 | 23 | * file(s) with this exception, you may extend this exception to your | ||
1885 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
1886 | 25 | * do not wish to do so, delete this exception statement from your | ||
1887 | 26 | * version. If you delete this exception statement from all source | ||
1888 | 27 | * files in the program, then also delete it here. | ||
1889 | 28 | */ | ||
1890 | 29 | |||
1891 | 30 | #ifndef CLICK_REVIEWS_H | ||
1892 | 31 | #define CLICK_REVIEWS_H | ||
1893 | 32 | |||
1894 | 33 | #include <functional> | ||
1895 | 34 | #include <string> | ||
1896 | 35 | #include <list> | ||
1897 | 36 | |||
1898 | 37 | #include <click/webclient.h> | ||
1899 | 38 | |||
1900 | 39 | namespace click | ||
1901 | 40 | { | ||
1902 | 41 | |||
1903 | 42 | const std::string REVIEWS_BASE_URL_ENVVAR = "U1_REVIEWS_BASE_URL"; | ||
1904 | 43 | const std::string REVIEWS_BASE_URL = "https://reviews.ubuntu.com"; | ||
1905 | 44 | const std::string REVIEWS_API_PATH = "/click/api/1.0/reviews/"; | ||
1906 | 45 | const std::string REVIEWS_QUERY_ARGNAME = "package_name"; | ||
1907 | 46 | |||
1908 | 47 | struct Review | ||
1909 | 48 | { | ||
1910 | 49 | uint32_t id; | ||
1911 | 50 | int rating; | ||
1912 | 51 | uint32_t usefulness_favorable; | ||
1913 | 52 | uint32_t usefulness_total; | ||
1914 | 53 | bool hide; | ||
1915 | 54 | std::string date_created; | ||
1916 | 55 | std::string date_deleted; | ||
1917 | 56 | std::string package_name; | ||
1918 | 57 | std::string package_version; | ||
1919 | 58 | std::string language; | ||
1920 | 59 | std::string summary; | ||
1921 | 60 | std::string review_text; | ||
1922 | 61 | std::string reviewer_name; | ||
1923 | 62 | std::string reviewer_username; | ||
1924 | 63 | }; | ||
1925 | 64 | |||
1926 | 65 | typedef std::list<Review> ReviewList; | ||
1927 | 66 | |||
1928 | 67 | ReviewList review_list_from_json (const std::string& json); | ||
1929 | 68 | ReviewList bring_to_front (const ReviewList& reviews, const std::string& userid); | ||
1930 | 69 | |||
1931 | 70 | class Reviews | ||
1932 | 71 | { | ||
1933 | 72 | protected: | ||
1934 | 73 | QSharedPointer<web::Client> client; | ||
1935 | 74 | public: | ||
1936 | 75 | enum class Error {NoError, CredentialsError, NetworkError}; | ||
1937 | 76 | Reviews() {} | ||
1938 | 77 | Reviews(const QSharedPointer<click::web::Client>& client); | ||
1939 | 78 | virtual ~Reviews(); | ||
1940 | 79 | |||
1941 | 80 | virtual click::web::Cancellable fetch_reviews (const std::string& package_name, | ||
1942 | 81 | std::function<void(ReviewList, Error)> callback, | ||
1943 | 82 | bool force_cache = false); | ||
1944 | 83 | click::web::Cancellable submit_review (const Review& review, | ||
1945 | 84 | std::function<void(Error)> callback); | ||
1946 | 85 | click::web::Cancellable edit_review (const Review& review, | ||
1947 | 86 | std::function<void(Error)> callback); | ||
1948 | 87 | |||
1949 | 88 | static std::string get_base_url (); | ||
1950 | 89 | }; | ||
1951 | 90 | |||
1952 | 91 | bool operator==(const Review& lhs, const Review& rhs); | ||
1953 | 92 | |||
1954 | 93 | } // namespace click | ||
1955 | 94 | |||
1956 | 95 | #endif // CLICK_REVIEWS_H | ||
1957 | 96 | 0 | ||
1958 | === modified file 'libclickscope/click/scope_activation.cpp' | |||
1959 | --- libclickscope/click/scope_activation.cpp 2016-05-19 18:05:56 +0000 | |||
1960 | +++ libclickscope/click/scope_activation.cpp 2017-01-10 16:06:37 +0000 | |||
1961 | @@ -28,7 +28,6 @@ | |||
1962 | 28 | */ | 28 | */ |
1963 | 29 | 29 | ||
1964 | 30 | #include "scope_activation.h" | 30 | #include "scope_activation.h" |
1965 | 31 | #include <click/download-manager.h> | ||
1966 | 32 | #include <click/package.h> | 31 | #include <click/package.h> |
1967 | 33 | #include <click/interface.h> | 32 | #include <click/interface.h> |
1968 | 34 | #include <click/qtbridge.h> | 33 | #include <click/qtbridge.h> |
1969 | @@ -55,42 +54,3 @@ | |||
1970 | 55 | { | 54 | { |
1971 | 56 | hints_[key] = value; | 55 | hints_[key] = value; |
1972 | 57 | } | 56 | } |
1973 | 58 | |||
1974 | 59 | click::PerformUninstallAction::PerformUninstallAction(const unity::scopes::Result& result, const unity::scopes::ActionMetadata& metadata) | ||
1975 | 60 | : unity::scopes::ActivationQueryBase(result, metadata) | ||
1976 | 61 | { | ||
1977 | 62 | } | ||
1978 | 63 | |||
1979 | 64 | unity::scopes::ActivationResponse click::PerformUninstallAction::activate() | ||
1980 | 65 | { | ||
1981 | 66 | std::promise<bool> uninstall_success_p; | ||
1982 | 67 | std::future<bool> uninstall_success_f = uninstall_success_p.get_future(); | ||
1983 | 68 | |||
1984 | 69 | auto const res = result(); | ||
1985 | 70 | click::Package package; | ||
1986 | 71 | package.title = res.title(); | ||
1987 | 72 | package.name = res["name"].get_string(); | ||
1988 | 73 | package.version = res["version"].get_string(); | ||
1989 | 74 | qt::core::world::enter_with_task([this, package, &uninstall_success_p] () | ||
1990 | 75 | { | ||
1991 | 76 | click::PackageManager manager; | ||
1992 | 77 | manager.uninstall(package, [&](int code, std::string stderr_content) { | ||
1993 | 78 | if (code != 0) { | ||
1994 | 79 | qDebug() << "Error removing package:" << stderr_content.c_str(); | ||
1995 | 80 | uninstall_success_p.set_value(false); | ||
1996 | 81 | } else { | ||
1997 | 82 | qDebug() << "successfully removed package"; | ||
1998 | 83 | uninstall_success_p.set_value(true); | ||
1999 | 84 | } | ||
2000 | 85 | } ); | ||
2001 | 86 | }); | ||
2002 | 87 | |||
2003 | 88 | if (uninstall_success_f.get()) | ||
2004 | 89 | { | ||
2005 | 90 | if (res.contains("lonely_result") && res.value("lonely_result").get_bool()) | ||
2006 | 91 | { | ||
2007 | 92 | return unity::scopes::ActivationResponse(unity::scopes::CannedQuery(APPS_SCOPE_ID.toUtf8().data())); | ||
2008 | 93 | } | ||
2009 | 94 | } | ||
2010 | 95 | return unity::scopes::ActivationResponse(unity::scopes::ActivationResponse::ShowDash); | ||
2011 | 96 | } | ||
2012 | 97 | 57 | ||
2013 | === modified file 'libclickscope/click/scope_activation.h' | |||
2014 | --- libclickscope/click/scope_activation.h 2016-05-18 12:38:46 +0000 | |||
2015 | +++ libclickscope/click/scope_activation.h 2017-01-10 16:06:37 +0000 | |||
2016 | @@ -37,13 +37,6 @@ | |||
2017 | 37 | namespace click | 37 | namespace click |
2018 | 38 | { | 38 | { |
2019 | 39 | 39 | ||
2020 | 40 | class PerformUninstallAction: public unity::scopes::ActivationQueryBase | ||
2021 | 41 | { | ||
2022 | 42 | public: | ||
2023 | 43 | PerformUninstallAction(const unity::scopes::Result& result, const unity::scopes::ActionMetadata& metadata); | ||
2024 | 44 | unity::scopes::ActivationResponse activate() override; | ||
2025 | 45 | }; | ||
2026 | 46 | |||
2027 | 47 | class ScopeActivation : public unity::scopes::ActivationQueryBase | 40 | class ScopeActivation : public unity::scopes::ActivationQueryBase |
2028 | 48 | { | 41 | { |
2029 | 49 | unity::scopes::ActivationResponse activate() override; | 42 | unity::scopes::ActivationResponse activate() override; |
2030 | 50 | 43 | ||
2031 | === modified file 'libclickscope/tests/CMakeLists.txt' | |||
2032 | --- libclickscope/tests/CMakeLists.txt 2016-10-24 21:26:23 +0000 | |||
2033 | +++ libclickscope/tests/CMakeLists.txt 2017-01-10 16:06:37 +0000 | |||
2034 | @@ -20,7 +20,6 @@ | |||
2035 | 20 | add_executable (${LIBCLICKSCOPE_TESTS_TARGET} | 20 | add_executable (${LIBCLICKSCOPE_TESTS_TARGET} |
2036 | 21 | mock_network_access_manager.h | 21 | mock_network_access_manager.h |
2037 | 22 | mock_ual.h | 22 | mock_ual.h |
2038 | 23 | mock_ubuntu_download_manager.h | ||
2039 | 24 | mock_ubuntuone_credentials.h | 23 | mock_ubuntuone_credentials.h |
2040 | 25 | mock_webclient.h | 24 | mock_webclient.h |
2041 | 26 | fake_json.cpp | 25 | fake_json.cpp |
2042 | @@ -28,12 +27,10 @@ | |||
2043 | 28 | test_configuration.cpp | 27 | test_configuration.cpp |
2044 | 29 | test_departments.cpp | 28 | test_departments.cpp |
2045 | 30 | test_departments-db.cpp | 29 | test_departments-db.cpp |
2046 | 31 | test_download_manager.cpp | ||
2047 | 32 | test_index.cpp | 30 | test_index.cpp |
2048 | 33 | test_interface.cpp | 31 | test_interface.cpp |
2049 | 34 | test_package.cpp | 32 | test_package.cpp |
2050 | 35 | test_preview.cpp | 33 | test_preview.cpp |
2051 | 36 | test_reviews.cpp | ||
2052 | 37 | test_smartconnect.cpp | 34 | test_smartconnect.cpp |
2053 | 38 | test_utils.cpp | 35 | test_utils.cpp |
2054 | 39 | test_webclient.cpp | 36 | test_webclient.cpp |
2055 | @@ -46,8 +43,6 @@ | |||
2056 | 46 | 43 | ||
2057 | 47 | ${UNITY_SCOPES_LDFLAGS} | 44 | ${UNITY_SCOPES_LDFLAGS} |
2058 | 48 | ${UBUNTUONE_LDFLAGS} | 45 | ${UBUNTUONE_LDFLAGS} |
2059 | 49 | ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS} | ||
2060 | 50 | ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS} | ||
2061 | 51 | ${JSON_CPP_LDFLAGS} | 46 | ${JSON_CPP_LDFLAGS} |
2062 | 52 | 47 | ||
2063 | 53 | gmock | 48 | gmock |
2064 | 54 | 49 | ||
2065 | === removed file 'libclickscope/tests/mock_ubuntu_download_manager.h' | |||
2066 | --- libclickscope/tests/mock_ubuntu_download_manager.h 2016-02-24 17:48:56 +0000 | |||
2067 | +++ libclickscope/tests/mock_ubuntu_download_manager.h 1970-01-01 00:00:00 +0000 | |||
2068 | @@ -1,140 +0,0 @@ | |||
2069 | 1 | /* | ||
2070 | 2 | * Copyright (C) 2014-2016 Canonical Ltd. | ||
2071 | 3 | * | ||
2072 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2073 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
2074 | 6 | * by the Free Software Foundation. | ||
2075 | 7 | * | ||
2076 | 8 | * This program is distributed in the hope that it will be useful, but | ||
2077 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2078 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2079 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
2080 | 12 | * | ||
2081 | 13 | * You should have received a copy of the GNU General Public License along | ||
2082 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2083 | 15 | * | ||
2084 | 16 | * In addition, as a special exception, the copyright holders give | ||
2085 | 17 | * permission to link the code of portions of this program with the | ||
2086 | 18 | * OpenSSL library under certain conditions as described in each | ||
2087 | 19 | * individual source file, and distribute linked combinations | ||
2088 | 20 | * including the two. | ||
2089 | 21 | * You must obey the GNU General Public License in all respects | ||
2090 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
2091 | 23 | * file(s) with this exception, you may extend this exception to your | ||
2092 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
2093 | 25 | * do not wish to do so, delete this exception statement from your | ||
2094 | 26 | * version. If you delete this exception statement from all source | ||
2095 | 27 | * files in the program, then also delete it here. | ||
2096 | 28 | */ | ||
2097 | 29 | |||
2098 | 30 | #ifndef _MOCK_UBUNTU_DOWNLOAD_MANAGER_H_ | ||
2099 | 31 | #define _MOCK_UBUNTU_DOWNLOAD_MANAGER_H_ | ||
2100 | 32 | |||
2101 | 33 | #include <QDBusConnection> | ||
2102 | 34 | #include <QDBusObjectPath> | ||
2103 | 35 | |||
2104 | 36 | #include <ubuntu/download_manager/download.h> | ||
2105 | 37 | #include <ubuntu/download_manager/downloads_list.h> | ||
2106 | 38 | #include <ubuntu/download_manager/error.h> | ||
2107 | 39 | #include <ubuntu/download_manager/manager.h> | ||
2108 | 40 | |||
2109 | 41 | #include <gmock/gmock.h> | ||
2110 | 42 | |||
2111 | 43 | class MockDownload : public Ubuntu::DownloadManager::Download | ||
2112 | 44 | { | ||
2113 | 45 | public: | ||
2114 | 46 | MockDownload() : Ubuntu::DownloadManager::Download(){}; | ||
2115 | 47 | MockDownload(Ubuntu::DownloadManager::Error *err) : Ubuntu::DownloadManager::Download(err) {}; | ||
2116 | 48 | // mock ALL methods so that we do not have an abstract class | ||
2117 | 49 | |||
2118 | 50 | MOCK_METHOD0(start, void()); | ||
2119 | 51 | MOCK_METHOD0(pause, void()); | ||
2120 | 52 | MOCK_METHOD0(resume, void()); | ||
2121 | 53 | MOCK_METHOD0(cancel, void()); | ||
2122 | 54 | |||
2123 | 55 | MOCK_METHOD1(allowMobileDownload, void(bool)); | ||
2124 | 56 | MOCK_METHOD0(isMobileDownloadAllowed, bool()); | ||
2125 | 57 | |||
2126 | 58 | MOCK_METHOD1(setThrottle, void(qulonglong)); | ||
2127 | 59 | MOCK_METHOD0(throttle, qulonglong()); | ||
2128 | 60 | |||
2129 | 61 | MOCK_CONST_METHOD0(id, QString()); | ||
2130 | 62 | |||
2131 | 63 | MOCK_METHOD1(setDestinationDir, void(const QString& path)); | ||
2132 | 64 | MOCK_METHOD0(metadata, QVariantMap()); | ||
2133 | 65 | MOCK_METHOD1(setMetadata, void(QVariantMap)); | ||
2134 | 66 | MOCK_METHOD0(progress, qulonglong()); | ||
2135 | 67 | MOCK_METHOD0(totalSize, qulonglong()); | ||
2136 | 68 | |||
2137 | 69 | MOCK_CONST_METHOD0(clickPackage, QString()); | ||
2138 | 70 | MOCK_CONST_METHOD0(title, QString()); | ||
2139 | 71 | MOCK_CONST_METHOD0(showInIndicator, bool()); | ||
2140 | 72 | |||
2141 | 73 | MOCK_CONST_METHOD0(isError, bool()); | ||
2142 | 74 | MOCK_CONST_METHOD0(error, Error*()); | ||
2143 | 75 | MOCK_METHOD0(headers, QMap<QString, QString>()); | ||
2144 | 76 | MOCK_METHOD1(setHeaders, void(QMap<QString, QString>)); | ||
2145 | 77 | MOCK_CONST_METHOD0(destinationApp, QString()); | ||
2146 | 78 | |||
2147 | 79 | MOCK_METHOD0(collected, void()); | ||
2148 | 80 | MOCK_METHOD0(filePath, QString()); | ||
2149 | 81 | MOCK_METHOD0(state, Download::State()); | ||
2150 | 82 | }; | ||
2151 | 83 | |||
2152 | 84 | class MockError : public Ubuntu::DownloadManager::Error | ||
2153 | 85 | { | ||
2154 | 86 | public: | ||
2155 | 87 | |||
2156 | 88 | MockError() : Ubuntu::DownloadManager::Error(Ubuntu::DownloadManager::Error::Type::Process, 0) {}; | ||
2157 | 89 | MOCK_METHOD0(errorString, QString()); | ||
2158 | 90 | }; | ||
2159 | 91 | |||
2160 | 92 | class MockDownloadsList : public Ubuntu::DownloadManager::DownloadsList | ||
2161 | 93 | { | ||
2162 | 94 | public: | ||
2163 | 95 | |||
2164 | 96 | MockDownloadsList() : Ubuntu::DownloadManager::DownloadsList() {}; | ||
2165 | 97 | |||
2166 | 98 | MOCK_CONST_METHOD0(downloads, QList<QSharedPointer<Ubuntu::DownloadManager::Download>>()); | ||
2167 | 99 | MOCK_CONST_METHOD0(isError, bool()); | ||
2168 | 100 | MOCK_CONST_METHOD0(error, Ubuntu::DownloadManager::Error*()); | ||
2169 | 101 | }; | ||
2170 | 102 | |||
2171 | 103 | class MockSystemDownloadManager : public Ubuntu::DownloadManager::Manager | ||
2172 | 104 | { | ||
2173 | 105 | public: | ||
2174 | 106 | |||
2175 | 107 | MockSystemDownloadManager() : Ubuntu::DownloadManager::Manager() {}; | ||
2176 | 108 | |||
2177 | 109 | MOCK_METHOD1(getDownloadForId, Download*(const QString&)); | ||
2178 | 110 | MOCK_METHOD1(createDownload, | ||
2179 | 111 | void(DownloadStruct downStruct)); | ||
2180 | 112 | MOCK_METHOD3(createDownload, | ||
2181 | 113 | void(DownloadStruct downStruct, DownloadCb cb, DownloadCb errCb)); | ||
2182 | 114 | MOCK_METHOD5(createDownload, | ||
2183 | 115 | void(StructList downs, const QString &algorithm, bool allowed3G, const QVariantMap &metadata, StringMap headers)); | ||
2184 | 116 | MOCK_METHOD7(createDownload, | ||
2185 | 117 | void(StructList downs, const QString &algorithm, bool allowed3G, const QVariantMap &metadata, StringMap headers, GroupCb cb, GroupCb errCb)); | ||
2186 | 118 | |||
2187 | 119 | MOCK_METHOD2(getAllDownloads, void(const QString &appId, bool uncompleted)); | ||
2188 | 120 | MOCK_METHOD4(getAllDownloads, void(const QString &appId, | ||
2189 | 121 | bool uncompleted, | ||
2190 | 122 | DownloadsListCb cb, | ||
2191 | 123 | DownloadsListCb errCb)); | ||
2192 | 124 | MOCK_METHOD2(getAllDownloadsWithMetadata, void(const QString &name, | ||
2193 | 125 | const QString &value)); | ||
2194 | 126 | |||
2195 | 127 | MOCK_METHOD4(getAllDownloadsWithMetadata, void(const QString &name, | ||
2196 | 128 | const QString &value, MetadataDownloadsListCb cb, | ||
2197 | 129 | MetadataDownloadsListCb errCb)); | ||
2198 | 130 | |||
2199 | 131 | MOCK_CONST_METHOD0(isError, bool()); | ||
2200 | 132 | MOCK_CONST_METHOD0(lastError, Error*()); | ||
2201 | 133 | MOCK_METHOD1(allowMobileDataDownload, void(bool)); | ||
2202 | 134 | MOCK_METHOD0(isMobileDataDownload, bool()); | ||
2203 | 135 | MOCK_METHOD0(defaultThrottle, qulonglong()); | ||
2204 | 136 | MOCK_METHOD1(setDefaultThrottle, void(qulonglong)); | ||
2205 | 137 | MOCK_METHOD0(exit, void()); | ||
2206 | 138 | }; | ||
2207 | 139 | |||
2208 | 140 | #endif /* _MOCK_UBUNTU_DOWNLOAD_MANAGER_H_ */ | ||
2209 | 141 | 0 | ||
2210 | === modified file 'libclickscope/tests/test_bootstrap.cpp' | |||
2211 | --- libclickscope/tests/test_bootstrap.cpp 2016-06-30 20:42:56 +0000 | |||
2212 | +++ libclickscope/tests/test_bootstrap.cpp 2017-01-10 16:06:37 +0000 | |||
2213 | @@ -27,7 +27,6 @@ | |||
2214 | 27 | * files in the program, then also delete it here. | 27 | * files in the program, then also delete it here. |
2215 | 28 | */ | 28 | */ |
2216 | 29 | #include <click/configuration.h> | 29 | #include <click/configuration.h> |
2217 | 30 | #include <click/reviews.h> | ||
2218 | 31 | #include <click/webclient.h> | 30 | #include <click/webclient.h> |
2219 | 32 | #include <click/index.h> | 31 | #include <click/index.h> |
2220 | 33 | 32 | ||
2221 | 34 | 33 | ||
2222 | === removed file 'libclickscope/tests/test_download_manager.cpp' | |||
2223 | --- libclickscope/tests/test_download_manager.cpp 2016-05-10 13:42:12 +0000 | |||
2224 | +++ libclickscope/tests/test_download_manager.cpp 1970-01-01 00:00:00 +0000 | |||
2225 | @@ -1,220 +0,0 @@ | |||
2226 | 1 | /* | ||
2227 | 2 | * Copyright (C) 2014-2016 Canonical Ltd. | ||
2228 | 3 | * | ||
2229 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2230 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
2231 | 6 | * by the Free Software Foundation. | ||
2232 | 7 | * | ||
2233 | 8 | * This program is distributed in the hope that it will be useful, but | ||
2234 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2235 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2236 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
2237 | 12 | * | ||
2238 | 13 | * You should have received a copy of the GNU General Public License along | ||
2239 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2240 | 15 | * | ||
2241 | 16 | * In addition, as a special exception, the copyright holders give | ||
2242 | 17 | * permission to link the code of portions of this program with the | ||
2243 | 18 | * OpenSSL library under certain conditions as described in each | ||
2244 | 19 | * individual source file, and distribute linked combinations | ||
2245 | 20 | * including the two. | ||
2246 | 21 | * You must obey the GNU General Public License in all respects | ||
2247 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
2248 | 23 | * file(s) with this exception, you may extend this exception to your | ||
2249 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
2250 | 25 | * do not wish to do so, delete this exception statement from your | ||
2251 | 26 | * version. If you delete this exception statement from all source | ||
2252 | 27 | * files in the program, then also delete it here. | ||
2253 | 28 | */ | ||
2254 | 29 | |||
2255 | 30 | #include <click/download-manager.h> | ||
2256 | 31 | #include <tests/mock_network_access_manager.h> | ||
2257 | 32 | #include <tests/mock_webclient.h> | ||
2258 | 33 | #include <tests/mock_ubuntu_download_manager.h> | ||
2259 | 34 | #include <tests/mock_ubuntuone_credentials.h> | ||
2260 | 35 | |||
2261 | 36 | #include <gtest/gtest.h> | ||
2262 | 37 | #include <memory> | ||
2263 | 38 | |||
2264 | 39 | using namespace ::testing; | ||
2265 | 40 | |||
2266 | 41 | namespace udm = Ubuntu::DownloadManager; | ||
2267 | 42 | #include <ubuntu/download_manager/download_struct.h> | ||
2268 | 43 | |||
2269 | 44 | namespace | ||
2270 | 45 | { | ||
2271 | 46 | const QString TEST_URL("http://test.local/"); | ||
2272 | 47 | const QString TEST_SHA512("fake_hash"); | ||
2273 | 48 | const QString TEST_HEADER_VALUE("test header value"); | ||
2274 | 49 | const QString TEST_APP_ID("test_app_id"); | ||
2275 | 50 | const QString TEST_CLICK_TOKEN_VALUE("test token value"); | ||
2276 | 51 | const QString TEST_DOWNLOAD_ID("/com/ubuntu/download_manager/test"); | ||
2277 | 52 | const QString TEST_DOWNLOADERROR_STRING("test downloadError string"); | ||
2278 | 53 | |||
2279 | 54 | |||
2280 | 55 | class DownloadManagerTest : public ::testing::Test | ||
2281 | 56 | { | ||
2282 | 57 | protected: | ||
2283 | 58 | QSharedPointer<MockClient> clientPtr; | ||
2284 | 59 | QSharedPointer<MockNetworkAccessManager> namPtr; | ||
2285 | 60 | QSharedPointer<MockSystemDownloadManager> sdmPtr; | ||
2286 | 61 | QSharedPointer<MockCredentialsService> ssoPtr; | ||
2287 | 62 | std::shared_ptr<click::DownloadManager> dmPtr; | ||
2288 | 63 | |||
2289 | 64 | virtual void SetUp() | ||
2290 | 65 | { | ||
2291 | 66 | ssoPtr.reset(new MockCredentialsService()); | ||
2292 | 67 | namPtr.reset(new MockNetworkAccessManager()); | ||
2293 | 68 | clientPtr.reset(new NiceMock<MockClient>(namPtr)); | ||
2294 | 69 | clientPtr->setCredentialsService(ssoPtr); | ||
2295 | 70 | dmPtr.reset(new click::DownloadManager(clientPtr, sdmPtr)); | ||
2296 | 71 | } | ||
2297 | 72 | |||
2298 | 73 | MOCK_METHOD2(start_callback, void(std::string, click::DownloadManager::Error)); | ||
2299 | 74 | MOCK_METHOD1(progress_callback, void(std::string)); | ||
2300 | 75 | }; | ||
2301 | 76 | |||
2302 | 77 | } | ||
2303 | 78 | |||
2304 | 79 | TEST_F(DownloadManagerTest, testStartCallsWebservice) | ||
2305 | 80 | { | ||
2306 | 81 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2307 | 82 | auto response = responseForReply(reply.asSharedPtr()); | ||
2308 | 83 | |||
2309 | 84 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
2310 | 85 | .Times(1) | ||
2311 | 86 | .WillOnce(Return(response)); | ||
2312 | 87 | |||
2313 | 88 | dmPtr->start("", "", "", | ||
2314 | 89 | [](std::string, click::DownloadManager::Error) {}); | ||
2315 | 90 | } | ||
2316 | 91 | |||
2317 | 92 | TEST_F(DownloadManagerTest, testStartCallbackCalled) | ||
2318 | 93 | { | ||
2319 | 94 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2320 | 95 | auto response = responseForReply(reply.asSharedPtr()); | ||
2321 | 96 | |||
2322 | 97 | EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(0))); | ||
2323 | 98 | EXPECT_CALL(reply.instance, readAll()) | ||
2324 | 99 | .Times(1) | ||
2325 | 100 | .WillOnce(Return("")); | ||
2326 | 101 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
2327 | 102 | .Times(1) | ||
2328 | 103 | .WillOnce(Return(response)); | ||
2329 | 104 | EXPECT_CALL(*this, start_callback(_, _)).Times(1); | ||
2330 | 105 | |||
2331 | 106 | dmPtr->start("", "", "", | ||
2332 | 107 | [this](std::string msg, click::DownloadManager::Error err) { | ||
2333 | 108 | start_callback(msg, err); | ||
2334 | 109 | }); | ||
2335 | 110 | response->replyFinished(); | ||
2336 | 111 | } | ||
2337 | 112 | |||
2338 | 113 | TEST_F(DownloadManagerTest, testStartHTTPForbidden) | ||
2339 | 114 | { | ||
2340 | 115 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2341 | 116 | auto response = responseForReply(reply.asSharedPtr()); | ||
2342 | 117 | |||
2343 | 118 | EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(403))); | ||
2344 | 119 | EXPECT_CALL(reply.instance, readAll()) | ||
2345 | 120 | .Times(1) | ||
2346 | 121 | .WillOnce(Return("")); | ||
2347 | 122 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
2348 | 123 | .Times(1) | ||
2349 | 124 | .WillOnce(Return(response)); | ||
2350 | 125 | EXPECT_CALL(*this, start_callback(StartsWith("Unhandled HTTP response code:"), | ||
2351 | 126 | click::DownloadManager::Error::DownloadInstallError)).Times(1); | ||
2352 | 127 | |||
2353 | 128 | dmPtr->start("", "", "", | ||
2354 | 129 | [this](std::string msg, click::DownloadManager::Error err) { | ||
2355 | 130 | start_callback(msg, err); | ||
2356 | 131 | }); | ||
2357 | 132 | response->replyFinished(); | ||
2358 | 133 | } | ||
2359 | 134 | |||
2360 | 135 | TEST_F(DownloadManagerTest, testStartHTTPError) | ||
2361 | 136 | { | ||
2362 | 137 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2363 | 138 | auto response = responseForReply(reply.asSharedPtr()); | ||
2364 | 139 | |||
2365 | 140 | EXPECT_CALL(reply.instance, errorString()) | ||
2366 | 141 | .WillOnce(Return(QString("ERROR"))); | ||
2367 | 142 | EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(404))); | ||
2368 | 143 | EXPECT_CALL(reply.instance, readAll()) | ||
2369 | 144 | .Times(1) | ||
2370 | 145 | .WillOnce(Return("")); | ||
2371 | 146 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
2372 | 147 | .Times(1) | ||
2373 | 148 | .WillOnce(Return(response)); | ||
2374 | 149 | EXPECT_CALL(*this, start_callback("ERROR (203)", | ||
2375 | 150 | click::DownloadManager::Error::DownloadInstallError)).Times(1); | ||
2376 | 151 | |||
2377 | 152 | dmPtr->start("", "", "", | ||
2378 | 153 | [this](std::string msg, click::DownloadManager::Error err) { | ||
2379 | 154 | start_callback(msg, err); | ||
2380 | 155 | }); | ||
2381 | 156 | response->errorHandler(QNetworkReply::ContentNotFoundError); | ||
2382 | 157 | } | ||
2383 | 158 | |||
2384 | 159 | TEST_F(DownloadManagerTest, testStartCredentialsError) | ||
2385 | 160 | { | ||
2386 | 161 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2387 | 162 | auto response = responseForReply(reply.asSharedPtr()); | ||
2388 | 163 | |||
2389 | 164 | EXPECT_CALL(reply.instance, errorString()) | ||
2390 | 165 | .WillOnce(Return(QString("ERROR"))); | ||
2391 | 166 | EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(401))); | ||
2392 | 167 | EXPECT_CALL(reply.instance, readAll()) | ||
2393 | 168 | .Times(1) | ||
2394 | 169 | .WillOnce(Return("")); | ||
2395 | 170 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
2396 | 171 | .Times(1) | ||
2397 | 172 | .WillOnce(Return(response)); | ||
2398 | 173 | EXPECT_CALL(*ssoPtr, invalidateCredentials()); | ||
2399 | 174 | EXPECT_CALL(*this, start_callback("ERROR (201)", | ||
2400 | 175 | click::DownloadManager::Error::CredentialsError)).Times(1); | ||
2401 | 176 | |||
2402 | 177 | dmPtr->start("", "", "test.package", | ||
2403 | 178 | [this](std::string msg, click::DownloadManager::Error err) { | ||
2404 | 179 | start_callback(msg, err); | ||
2405 | 180 | }); | ||
2406 | 181 | response->errorHandler(QNetworkReply::ContentAccessDenied); | ||
2407 | 182 | } | ||
2408 | 183 | |||
2409 | 184 | // FIXME: createDownload() SEGV under tests | ||
2410 | 185 | TEST_F(DownloadManagerTest, DISABLED_testStartDownloadCreated) | ||
2411 | 186 | { | ||
2412 | 187 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2413 | 188 | auto response = responseForReply(reply.asSharedPtr()); | ||
2414 | 189 | |||
2415 | 190 | EXPECT_CALL(reply.instance, rawHeader(QByteArray("X-Click-Token"))) | ||
2416 | 191 | .Times(1) | ||
2417 | 192 | .WillOnce(Return(QString("clicktoken"))); | ||
2418 | 193 | EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200))); | ||
2419 | 194 | EXPECT_CALL(reply.instance, readAll()) | ||
2420 | 195 | .Times(1) | ||
2421 | 196 | .WillOnce(Return("")); | ||
2422 | 197 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
2423 | 198 | .Times(1) | ||
2424 | 199 | .WillOnce(Return(response)); | ||
2425 | 200 | |||
2426 | 201 | EXPECT_CALL(*sdmPtr, createDownload(_, _, _)); | ||
2427 | 202 | dmPtr->start("", "", "test.package", | ||
2428 | 203 | [this](std::string msg, click::DownloadManager::Error err) { | ||
2429 | 204 | start_callback(msg, err); | ||
2430 | 205 | }); | ||
2431 | 206 | response->replyFinished(); | ||
2432 | 207 | } | ||
2433 | 208 | |||
2434 | 209 | // FIXME: getAllDownloadsWithMetadata() SEGV under tests | ||
2435 | 210 | TEST_F(DownloadManagerTest, DISABLED_testGetProgressNoDownloads) | ||
2436 | 211 | { | ||
2437 | 212 | EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _)) | ||
2438 | 213 | .Times(1) | ||
2439 | 214 | .WillOnce(InvokeArgument<3>(QStringLiteral(""), QStringLiteral(""), | ||
2440 | 215 | nullptr)); | ||
2441 | 216 | dmPtr->get_progress("com.example.test", | ||
2442 | 217 | [this](std::string object_path) { | ||
2443 | 218 | progress_callback(object_path); | ||
2444 | 219 | }); | ||
2445 | 220 | } | ||
2446 | 221 | 0 | ||
2447 | === modified file 'libclickscope/tests/test_index.cpp' | |||
2448 | --- libclickscope/tests/test_index.cpp 2016-12-02 18:37:59 +0000 | |||
2449 | +++ libclickscope/tests/test_index.cpp 2017-01-10 16:06:37 +0000 | |||
2450 | @@ -613,18 +613,6 @@ | |||
2451 | 613 | EXPECT_EQ(1u, lists.second.size()); | 613 | EXPECT_EQ(1u, lists.second.size()); |
2452 | 614 | } | 614 | } |
2453 | 615 | 615 | ||
2454 | 616 | TEST_F(MockPackageManager, testUninstallCommandCorrect) | ||
2455 | 617 | { | ||
2456 | 618 | click::Package package = { | ||
2457 | 619 | "org.example.testapp", "Test App", 0.00, | ||
2458 | 620 | "/tmp/foo.png", | ||
2459 | 621 | "uri", "0.1.5", "app" | ||
2460 | 622 | }; | ||
2461 | 623 | std::string expected = "pkcon -p remove org.example.testapp;0.1.5;all;local:click"; | ||
2462 | 624 | EXPECT_CALL(*this, execute_uninstall_command(expected, _)).Times(1); | ||
2463 | 625 | uninstall(package, [](int, std::string) {}); | ||
2464 | 626 | } | ||
2465 | 627 | |||
2466 | 628 | class ExhibitionistIndex : public click::Index { | 616 | class ExhibitionistIndex : public click::Index { |
2467 | 629 | public: | 617 | public: |
2468 | 630 | using click::Index::build_index_query; | 618 | using click::Index::build_index_query; |
2469 | 631 | 619 | ||
2470 | === modified file 'libclickscope/tests/test_interface.cpp' | |||
2471 | --- libclickscope/tests/test_interface.cpp 2016-12-02 18:37:59 +0000 | |||
2472 | +++ libclickscope/tests/test_interface.cpp 2017-01-10 16:06:37 +0000 | |||
2473 | @@ -114,7 +114,6 @@ | |||
2474 | 114 | public: | 114 | public: |
2475 | 115 | FakeClickInterface() {} | 115 | FakeClickInterface() {} |
2476 | 116 | 116 | ||
2477 | 117 | MOCK_CONST_METHOD1(get_manifest_json, std::string(const std::string&)); | ||
2478 | 118 | MOCK_CONST_METHOD0(installed_apps, std::list<std::shared_ptr<ual::Application>>()); | 117 | MOCK_CONST_METHOD0(installed_apps, std::list<std::shared_ptr<ual::Application>>()); |
2479 | 119 | }; | 118 | }; |
2480 | 120 | 119 | ||
2481 | @@ -485,79 +484,6 @@ | |||
2482 | 485 | Interface::add_theme_scheme("/usr/share/unity8/graphics/applicationIcons/contacts-app@18.png")); | 484 | Interface::add_theme_scheme("/usr/share/unity8/graphics/applicationIcons/contacts-app@18.png")); |
2483 | 486 | } | 485 | } |
2484 | 487 | 486 | ||
2485 | 488 | TEST(ClickInterface, testManifestFromJsonOneApp) | ||
2486 | 489 | { | ||
2487 | 490 | Manifest m = manifest_from_json(FAKE_JSON_MANIFEST_ONE_APP); | ||
2488 | 491 | ASSERT_EQ(m.first_app_name, "fake-app"); | ||
2489 | 492 | ASSERT_TRUE(m.has_any_apps()); | ||
2490 | 493 | ASSERT_FALSE(m.has_any_scopes()); | ||
2491 | 494 | } | ||
2492 | 495 | |||
2493 | 496 | TEST(ClickInterface, testManifestFromJsonOneScope) | ||
2494 | 497 | { | ||
2495 | 498 | Manifest m = manifest_from_json(FAKE_JSON_MANIFEST_ONE_SCOPE); | ||
2496 | 499 | ASSERT_EQ(m.first_scope_id, "com.example.fake-scope_fake-scope-hook"); | ||
2497 | 500 | ASSERT_FALSE(m.has_any_apps()); | ||
2498 | 501 | ASSERT_TRUE(m.has_any_scopes()); | ||
2499 | 502 | } | ||
2500 | 503 | |||
2501 | 504 | TEST(ClickInterface, testManifestFromJsonOneAppOneScope) | ||
2502 | 505 | { | ||
2503 | 506 | Manifest m = manifest_from_json(FAKE_JSON_MANIFEST_ONE_APP_ONE_SCOPE); | ||
2504 | 507 | ASSERT_EQ(m.first_app_name, "fake-app"); | ||
2505 | 508 | ASSERT_EQ(m.first_scope_id, "com.example.fake-1app-1scope_fake-scope-hook"); | ||
2506 | 509 | ASSERT_TRUE(m.has_any_apps()); | ||
2507 | 510 | ASSERT_TRUE(m.has_any_scopes()); | ||
2508 | 511 | } | ||
2509 | 512 | |||
2510 | 513 | TEST(ClickInterface, testManifestFromJsonTwoAppsTwoScopes) | ||
2511 | 514 | { | ||
2512 | 515 | Manifest m = manifest_from_json(FAKE_JSON_MANIFEST_TWO_APPS_TWO_SCOPES); | ||
2513 | 516 | ASSERT_EQ(m.first_app_name, "fake-app1"); | ||
2514 | 517 | ASSERT_EQ(m.first_scope_id, "com.example.fake-2apps-2scopes_fake-scope-hook1"); | ||
2515 | 518 | ASSERT_TRUE(m.has_any_apps()); | ||
2516 | 519 | ASSERT_TRUE(m.has_any_scopes()); | ||
2517 | 520 | } | ||
2518 | 521 | |||
2519 | 522 | TEST_F(ClickInterfaceTest, testGetManifestForAppParseError) | ||
2520 | 523 | { | ||
2521 | 524 | FakeClickInterface iface; | ||
2522 | 525 | EXPECT_CALL(iface, get_manifest_json(_)). | ||
2523 | 526 | Times(1). | ||
2524 | 527 | WillOnce(Return("INVALID JSON")); | ||
2525 | 528 | EXPECT_CALL(*this, manifest_callback(_, InterfaceError::ParseError)); | ||
2526 | 529 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest, | ||
2527 | 530 | InterfaceError error){ | ||
2528 | 531 | manifest_callback(manifest, error); | ||
2529 | 532 | }); | ||
2530 | 533 | } | ||
2531 | 534 | |||
2532 | 535 | TEST_F(ClickInterfaceTest, testGetManifestForAppIsRemovable) | ||
2533 | 536 | { | ||
2534 | 537 | FakeClickInterface iface; | ||
2535 | 538 | EXPECT_CALL(iface, get_manifest_json(_)). | ||
2536 | 539 | Times(1). | ||
2537 | 540 | WillOnce(Return(FAKE_JSON_MANIFEST_REMOVABLE)); | ||
2538 | 541 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest, | ||
2539 | 542 | InterfaceError error){ | ||
2540 | 543 | ASSERT_TRUE(error == InterfaceError::NoError); | ||
2541 | 544 | ASSERT_TRUE(manifest.removable); | ||
2542 | 545 | }); | ||
2543 | 546 | } | ||
2544 | 547 | |||
2545 | 548 | TEST_F(ClickInterfaceTest, testGetManifestForAppIsNotRemovable) | ||
2546 | 549 | { | ||
2547 | 550 | FakeClickInterface iface; | ||
2548 | 551 | EXPECT_CALL(iface, get_manifest_json(_)). | ||
2549 | 552 | Times(1). | ||
2550 | 553 | WillOnce(Return(FAKE_JSON_MANIFEST_NONREMOVABLE)); | ||
2551 | 554 | iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest, | ||
2552 | 555 | InterfaceError error){ | ||
2553 | 556 | ASSERT_TRUE(error == InterfaceError::NoError); | ||
2554 | 557 | ASSERT_FALSE(manifest.removable); | ||
2555 | 558 | }); | ||
2556 | 559 | } | ||
2557 | 560 | |||
2558 | 561 | TEST_F(ClickInterfaceTest, testGetInstalledPackagesParsed) | 487 | TEST_F(ClickInterfaceTest, testGetInstalledPackagesParsed) |
2559 | 562 | { | 488 | { |
2560 | 563 | FakeClickInterface iface; | 489 | FakeClickInterface iface; |
2561 | 564 | 490 | ||
2562 | === modified file 'libclickscope/tests/test_preview.cpp' | |||
2563 | --- libclickscope/tests/test_preview.cpp 2016-12-02 18:37:59 +0000 | |||
2564 | +++ libclickscope/tests/test_preview.cpp 2017-01-10 16:06:37 +0000 | |||
2565 | @@ -31,9 +31,7 @@ | |||
2566 | 31 | 31 | ||
2567 | 32 | #include <click/index.h> | 32 | #include <click/index.h> |
2568 | 33 | #include <click/interface.h> | 33 | #include <click/interface.h> |
2569 | 34 | #include <click/reviews.h> | ||
2570 | 35 | #include <fake_json.h> | 34 | #include <fake_json.h> |
2571 | 36 | #include <mock_ubuntu_download_manager.h> | ||
2572 | 37 | 35 | ||
2573 | 38 | #include <QCoreApplication> | 36 | #include <QCoreApplication> |
2574 | 39 | #include <QTimer> | 37 | #include <QTimer> |
2575 | @@ -70,26 +68,12 @@ | |||
2576 | 70 | 68 | ||
2577 | 71 | }; | 69 | }; |
2578 | 72 | 70 | ||
2579 | 73 | class FakeReviews : public click::Reviews | ||
2580 | 74 | { | ||
2581 | 75 | public: | ||
2582 | 76 | FakeReviews() { | ||
2583 | 77 | |||
2584 | 78 | } | ||
2585 | 79 | |||
2586 | 80 | click::web::Cancellable fetch_reviews(const std::string &/*package_name*/, std::function<void (click::ReviewList, Error)> callback, bool) override { | ||
2587 | 81 | callback(click::ReviewList(), Error::NoError); | ||
2588 | 82 | return click::web::Cancellable(); | ||
2589 | 83 | } | ||
2590 | 84 | }; | ||
2591 | 85 | |||
2592 | 86 | class FakePreview : public click::PreviewStrategy | 71 | class FakePreview : public click::PreviewStrategy |
2593 | 87 | { | 72 | { |
2594 | 88 | public: | 73 | public: |
2595 | 89 | FakePreview(Result& result) : click::PreviewStrategy::PreviewStrategy(result) | 74 | FakePreview(Result& result) : click::PreviewStrategy::PreviewStrategy(result) |
2596 | 90 | { | 75 | { |
2597 | 91 | index.reset(new FakeIndex()); | 76 | index.reset(new FakeIndex()); |
2598 | 92 | reviews.reset(new FakeReviews()); | ||
2599 | 93 | } | 77 | } |
2600 | 94 | 78 | ||
2601 | 95 | void run(const PreviewReplyProxy &/*reply*/) | 79 | void run(const PreviewReplyProxy &/*reply*/) |
2602 | @@ -155,8 +139,6 @@ | |||
2603 | 155 | FakePreview preview{result}; | 139 | FakePreview preview{result}; |
2604 | 156 | preview.populateDetails( | 140 | preview.populateDetails( |
2605 | 157 | [](const click::PackageDetails &){ | 141 | [](const click::PackageDetails &){ |
2606 | 158 | }, | ||
2607 | 159 | [](const click::ReviewList&, click::Reviews::Error){ | ||
2608 | 160 | }); | 142 | }); |
2609 | 161 | 143 | ||
2610 | 162 | } | 144 | } |
2611 | @@ -342,150 +324,6 @@ | |||
2612 | 342 | ASSERT_EQ(expected_order, preview.call_order); | 324 | ASSERT_EQ(expected_order, preview.call_order); |
2613 | 343 | } | 325 | } |
2614 | 344 | 326 | ||
2615 | 345 | class StrategyChooserTest : public Test { | ||
2616 | 346 | protected: | ||
2617 | 347 | unity::scopes::testing::Result result; | ||
2618 | 348 | unity::scopes::ActionMetadata metadata; | ||
2619 | 349 | unity::scopes::VariantMap metadict; | ||
2620 | 350 | QSharedPointer<click::web::Client> client; | ||
2621 | 351 | QSharedPointer<MockSystemDownloadManager> dm; | ||
2622 | 352 | std::shared_ptr<click::DepartmentsDb> depts; | ||
2623 | 353 | const std::string FAKE_SHA512 = "FAKE_SHA512"; | ||
2624 | 354 | |||
2625 | 355 | public: | ||
2626 | 356 | StrategyChooserTest() : metadata("en_EN", "phone") { | ||
2627 | 357 | } | ||
2628 | 358 | }; | ||
2629 | 359 | |||
2630 | 360 | class MockablePreview : public click::Preview { | ||
2631 | 361 | public: | ||
2632 | 362 | MockablePreview(const unity::scopes::Result& result, const unity::scopes::ActionMetadata& metadata) : | ||
2633 | 363 | click::Preview(result, metadata) | ||
2634 | 364 | { | ||
2635 | 365 | |||
2636 | 366 | } | ||
2637 | 367 | |||
2638 | 368 | MOCK_METHOD6(build_installing, | ||
2639 | 369 | click::PreviewStrategy*(const std::string&, | ||
2640 | 370 | const std::string&, | ||
2641 | 371 | const unity::scopes::Result&, | ||
2642 | 372 | const QSharedPointer<click::web::Client>&, | ||
2643 | 373 | const QSharedPointer<Ubuntu::DownloadManager::Manager>&, | ||
2644 | 374 | std::shared_ptr<click::DepartmentsDb>)); | ||
2645 | 375 | }; | ||
2646 | 376 | |||
2647 | 377 | TEST_F(StrategyChooserTest, testSha512IsUsed) { | ||
2648 | 378 | metadict["action_id"] = click::Preview::Actions::INSTALL_CLICK; | ||
2649 | 379 | metadict["download_url"] = "fake_download_url"; | ||
2650 | 380 | metadict["download_sha512"] = FAKE_SHA512; | ||
2651 | 381 | metadata.set_scope_data(unity::scopes::Variant(metadict)); | ||
2652 | 382 | MockablePreview preview(result, metadata); | ||
2653 | 383 | EXPECT_CALL(preview, build_installing(_, FAKE_SHA512, _, _, _, _)); | ||
2654 | 384 | preview.choose_strategy(client, dm, depts); | ||
2655 | 385 | } | ||
2656 | 386 | |||
2657 | 387 | |||
2658 | 388 | class UninstalledPreviewTest : public PreviewsBaseTest { | ||
2659 | 389 | public: | ||
2660 | 390 | FakeResult result{vm}; | ||
2661 | 391 | click::PackageDetails details; | ||
2662 | 392 | unity::scopes::PreviewWidgetList widgets; | ||
2663 | 393 | QSharedPointer<click::web::Client> client; | ||
2664 | 394 | QSharedPointer<MockSystemDownloadManager> sdm; | ||
2665 | 395 | std::shared_ptr<click::DepartmentsDb> depts; | ||
2666 | 396 | unity::scopes::testing::MockPreviewReply reply; | ||
2667 | 397 | std::shared_ptr<unity::scopes::testing::MockPreviewReply> replyptr{&reply, [](unity::scopes::testing::MockPreviewReply*){}}; | ||
2668 | 398 | }; | ||
2669 | 399 | |||
2670 | 400 | class FakeBaseUninstalledPreview : public click::UninstalledPreview { | ||
2671 | 401 | std::string object_path; | ||
2672 | 402 | public: | ||
2673 | 403 | FakeBaseUninstalledPreview(const std::string& object_path, | ||
2674 | 404 | const unity::scopes::Result& result, | ||
2675 | 405 | const unity::scopes::ActionMetadata& metadata, | ||
2676 | 406 | const QSharedPointer<click::web::Client>& client, | ||
2677 | 407 | const std::shared_ptr<click::DepartmentsDb>& depts, | ||
2678 | 408 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager) | ||
2679 | 409 | : click::UninstalledPreview(result, metadata, client, depts, manager), | ||
2680 | 410 | object_path(object_path) | ||
2681 | 411 | { | ||
2682 | 412 | } | ||
2683 | 413 | |||
2684 | 414 | void populateDetails(std::function<void (const click::PackageDetails &)> details_callback, | ||
2685 | 415 | std::function<void (const click::ReviewList &, click::Reviews::Error)> reviews_callback) { | ||
2686 | 416 | click::PackageDetails details; | ||
2687 | 417 | details_callback(details); | ||
2688 | 418 | reviews_callback({}, click::Reviews::Error::NoError); | ||
2689 | 419 | } | ||
2690 | 420 | }; | ||
2691 | 421 | |||
2692 | 422 | class FakeUninstalledPreview : public FakeBaseUninstalledPreview { | ||
2693 | 423 | public: | ||
2694 | 424 | MOCK_METHOD1(uninstalledActionButtonWidgets, scopes::PreviewWidgetList (const click::PackageDetails &details)); | ||
2695 | 425 | MOCK_METHOD1(progressBarWidget, scopes::PreviewWidgetList(const std::string& object_path)); | ||
2696 | 426 | FakeUninstalledPreview(const std::string& object_path, | ||
2697 | 427 | const unity::scopes::Result& result, | ||
2698 | 428 | const unity::scopes::ActionMetadata& metadata, | ||
2699 | 429 | const QSharedPointer<click::web::Client>& client, | ||
2700 | 430 | const std::shared_ptr<click::DepartmentsDb>& depts, | ||
2701 | 431 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager) | ||
2702 | 432 | : FakeBaseUninstalledPreview(object_path, result, metadata, client, depts, manager) { | ||
2703 | 433 | } | ||
2704 | 434 | }; | ||
2705 | 435 | |||
2706 | 436 | |||
2707 | 437 | // FIXME: Needs Qt main loop | ||
2708 | 438 | TEST_F(UninstalledPreviewTest, DISABLED_testDownloadInProgress) { | ||
2709 | 439 | std::string fake_object_path = "/fake/object/path"; | ||
2710 | 440 | |||
2711 | 441 | result["name"] = "fake_app_name"; | ||
2712 | 442 | scopes::PreviewWidgetList response; | ||
2713 | 443 | unity::scopes::ActionMetadata metadata("en_EN", "desktop"); | ||
2714 | 444 | FakeUninstalledPreview preview(fake_object_path, result, metadata, client, depts, sdm); | ||
2715 | 445 | EXPECT_CALL(preview, progressBarWidget(_)) | ||
2716 | 446 | .Times(1) | ||
2717 | 447 | .WillOnce(Return(response)); | ||
2718 | 448 | EXPECT_CALL(*replyptr, register_layout(_)); | ||
2719 | 449 | preview.run(replyptr); | ||
2720 | 450 | } | ||
2721 | 451 | |||
2722 | 452 | // FIXME: Needs Qt main loop | ||
2723 | 453 | TEST_F(UninstalledPreviewTest, DISABLED_testNoDownloadProgress) { | ||
2724 | 454 | std::string fake_object_path = ""; | ||
2725 | 455 | |||
2726 | 456 | result["name"] = "fake_app_name"; | ||
2727 | 457 | scopes::PreviewWidgetList response; | ||
2728 | 458 | unity::scopes::ActionMetadata metadata("en_EN", "desktop"); | ||
2729 | 459 | FakeUninstalledPreview preview(fake_object_path, result, metadata, client, depts, sdm); | ||
2730 | 460 | EXPECT_CALL(preview, uninstalledActionButtonWidgets(_)) | ||
2731 | 461 | .Times(1) | ||
2732 | 462 | .WillOnce(Return(response)); | ||
2733 | 463 | preview.run(replyptr); | ||
2734 | 464 | } | ||
2735 | 465 | |||
2736 | 466 | class FakeUninstalledRefundablePreview : FakeBaseUninstalledPreview { | ||
2737 | 467 | public: | ||
2738 | 468 | FakeUninstalledRefundablePreview(const unity::scopes::Result& result, | ||
2739 | 469 | const unity::scopes::ActionMetadata& metadata, | ||
2740 | 470 | const QSharedPointer<click::web::Client>& client, | ||
2741 | 471 | const std::shared_ptr<click::DepartmentsDb>& depts, | ||
2742 | 472 | const QSharedPointer<Ubuntu::DownloadManager::Manager>& manager) | ||
2743 | 473 | : FakeBaseUninstalledPreview(std::string{""}, result, metadata, client, depts, manager){ | ||
2744 | 474 | } | ||
2745 | 475 | using click::UninstalledPreview::uninstalledActionButtonWidgets; | ||
2746 | 476 | }; | ||
2747 | 477 | |||
2748 | 478 | unity::scopes::VariantArray get_actions_from_widgets(const unity::scopes::PreviewWidgetList& widgets, int widget_number) { | ||
2749 | 479 | auto widget = *std::next(widgets.begin(), widget_number); | ||
2750 | 480 | return widget.attribute_values()["actions"].get_array(); | ||
2751 | 481 | } | ||
2752 | 482 | |||
2753 | 483 | std::string get_action_from_widgets(const unity::scopes::PreviewWidgetList& widgets, int widget_number, int action_number) { | ||
2754 | 484 | auto actions = get_actions_from_widgets(widgets, widget_number); | ||
2755 | 485 | auto selected_action = actions.at(action_number).get_dict(); | ||
2756 | 486 | return selected_action["id"].get_string(); | ||
2757 | 487 | } | ||
2758 | 488 | |||
2759 | 489 | class InstalledPreviewTest : public Test { | 327 | class InstalledPreviewTest : public Test { |
2760 | 490 | protected: | 328 | protected: |
2761 | 491 | unity::scopes::testing::Result result; | 329 | unity::scopes::testing::Result result; |
2762 | @@ -499,25 +337,6 @@ | |||
2763 | 499 | } | 337 | } |
2764 | 500 | }; | 338 | }; |
2765 | 501 | 339 | ||
2766 | 502 | TEST_F(InstalledPreviewTest, testReviewWidgetIsNew) { | ||
2767 | 503 | click::InstalledPreview preview(result, metadata, client, depts); | ||
2768 | 504 | click::Review existing_review; | ||
2769 | 505 | existing_review.id = 0; | ||
2770 | 506 | auto widget = preview.createRatingWidget(existing_review); | ||
2771 | 507 | ASSERT_EQ(widget.widget_type(), "rating-input"); | ||
2772 | 508 | } | ||
2773 | 509 | |||
2774 | 510 | TEST_F(InstalledPreviewTest, testReviewWidgetIsEdit) { | ||
2775 | 511 | click::InstalledPreview preview(result, metadata, client, depts); | ||
2776 | 512 | click::Review existing_review; | ||
2777 | 513 | existing_review.id = 123456789; | ||
2778 | 514 | existing_review.rating = 2.625f; | ||
2779 | 515 | existing_review.review_text = "Mediocre at best."; | ||
2780 | 516 | existing_review.reviewer_name = "reviewbot"; | ||
2781 | 517 | auto widget = preview.createRatingWidget(existing_review); | ||
2782 | 518 | ASSERT_EQ(widget.widget_type(), "rating-edit"); | ||
2783 | 519 | } | ||
2784 | 520 | |||
2785 | 521 | TEST_F(InstalledPreviewTest, testGetApplicationURIClick) { | 340 | TEST_F(InstalledPreviewTest, testGetApplicationURIClick) { |
2786 | 522 | click::InstalledPreview preview(result, metadata, client, depts); | 341 | click::InstalledPreview preview(result, metadata, client, depts); |
2787 | 523 | click::Manifest manifest; | 342 | click::Manifest manifest; |
2788 | 524 | 343 | ||
2789 | === removed file 'libclickscope/tests/test_reviews.cpp' | |||
2790 | --- libclickscope/tests/test_reviews.cpp 2016-12-02 18:37:59 +0000 | |||
2791 | +++ libclickscope/tests/test_reviews.cpp 1970-01-01 00:00:00 +0000 | |||
2792 | @@ -1,487 +0,0 @@ | |||
2793 | 1 | /* | ||
2794 | 2 | * Copyright (C) 2014 Canonical Ltd. | ||
2795 | 3 | * | ||
2796 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
2797 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
2798 | 6 | * by the Free Software Foundation. | ||
2799 | 7 | * | ||
2800 | 8 | * This program is distributed in the hope that it will be useful, but | ||
2801 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
2802 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
2803 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
2804 | 12 | * | ||
2805 | 13 | * You should have received a copy of the GNU General Public License along | ||
2806 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
2807 | 15 | * | ||
2808 | 16 | * In addition, as a special exception, the copyright holders give | ||
2809 | 17 | * permission to link the code of portions of this program with the | ||
2810 | 18 | * OpenSSL library under certain conditions as described in each | ||
2811 | 19 | * individual source file, and distribute linked combinations | ||
2812 | 20 | * including the two. | ||
2813 | 21 | * You must obey the GNU General Public License in all respects | ||
2814 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
2815 | 23 | * file(s) with this exception, you may extend this exception to your | ||
2816 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
2817 | 25 | * do not wish to do so, delete this exception statement from your | ||
2818 | 26 | * version. If you delete this exception statement from all source | ||
2819 | 27 | * files in the program, then also delete it here. | ||
2820 | 28 | */ | ||
2821 | 29 | |||
2822 | 30 | #include <click/configuration.h> | ||
2823 | 31 | #include <click/reviews.h> | ||
2824 | 32 | #include <click/webclient.h> | ||
2825 | 33 | |||
2826 | 34 | #include <tests/mock_network_access_manager.h> | ||
2827 | 35 | #include <tests/mock_ubuntuone_credentials.h> | ||
2828 | 36 | #include <tests/mock_webclient.h> | ||
2829 | 37 | |||
2830 | 38 | #include "fake_json.h" | ||
2831 | 39 | |||
2832 | 40 | #include <gtest/gtest.h> | ||
2833 | 41 | #include <memory> | ||
2834 | 42 | #include <stdlib.h> | ||
2835 | 43 | |||
2836 | 44 | using namespace ::testing; | ||
2837 | 45 | |||
2838 | 46 | namespace | ||
2839 | 47 | { | ||
2840 | 48 | |||
2841 | 49 | class ReviewsTest : public ::testing::Test { | ||
2842 | 50 | protected: | ||
2843 | 51 | QSharedPointer<MockClient> clientPtr; | ||
2844 | 52 | QSharedPointer<MockNetworkAccessManager> namPtr; | ||
2845 | 53 | std::shared_ptr<click::Reviews> reviewsPtr; | ||
2846 | 54 | |||
2847 | 55 | virtual void SetUp() { | ||
2848 | 56 | namPtr.reset(new MockNetworkAccessManager()); | ||
2849 | 57 | clientPtr.reset(new NiceMock<MockClient>(namPtr)); | ||
2850 | 58 | reviewsPtr.reset(new click::Reviews(clientPtr)); | ||
2851 | 59 | } | ||
2852 | 60 | |||
2853 | 61 | public: | ||
2854 | 62 | MOCK_METHOD2(reviews_callback, void(click::ReviewList, click::Reviews::Error)); | ||
2855 | 63 | }; | ||
2856 | 64 | } | ||
2857 | 65 | |||
2858 | 66 | TEST_F(ReviewsTest, bringToFrontUserMatches) | ||
2859 | 67 | { | ||
2860 | 68 | click::Review r1; | ||
2861 | 69 | r1.id = 1; | ||
2862 | 70 | r1.reviewer_username = "user1"; | ||
2863 | 71 | |||
2864 | 72 | click::Review r2; | ||
2865 | 73 | r2.id = 2; | ||
2866 | 74 | r2.reviewer_username = "user2"; | ||
2867 | 75 | |||
2868 | 76 | click::Review r3; | ||
2869 | 77 | r3.id = 3; | ||
2870 | 78 | r3.reviewer_username = "user3"; | ||
2871 | 79 | |||
2872 | 80 | click::ReviewList reviews {r1, r2, r3}; | ||
2873 | 81 | |||
2874 | 82 | auto newReviews = bring_to_front(reviews, "user2"); | ||
2875 | 83 | EXPECT_EQ(3u, newReviews.size()); | ||
2876 | 84 | auto it = newReviews.begin(); | ||
2877 | 85 | EXPECT_EQ(2u, (*it).id); | ||
2878 | 86 | ++it; | ||
2879 | 87 | EXPECT_EQ(1u, (*it).id); | ||
2880 | 88 | ++it; | ||
2881 | 89 | EXPECT_EQ(3u, (*it).id); | ||
2882 | 90 | } | ||
2883 | 91 | |||
2884 | 92 | TEST_F(ReviewsTest, bringToFrontUserMatchesFirstElement) | ||
2885 | 93 | { | ||
2886 | 94 | click::Review r1; | ||
2887 | 95 | r1.id = 1; | ||
2888 | 96 | r1.reviewer_username = "user1"; | ||
2889 | 97 | |||
2890 | 98 | click::Review r2; | ||
2891 | 99 | r2.id = 2; | ||
2892 | 100 | r2.reviewer_username = "user2"; | ||
2893 | 101 | |||
2894 | 102 | click::ReviewList reviews {r1, r2}; | ||
2895 | 103 | |||
2896 | 104 | auto newReviews = bring_to_front(reviews, "user1"); | ||
2897 | 105 | EXPECT_EQ(2u, newReviews.size()); | ||
2898 | 106 | auto it = newReviews.begin(); | ||
2899 | 107 | EXPECT_EQ(1u, (*it).id); | ||
2900 | 108 | ++it; | ||
2901 | 109 | EXPECT_EQ(2u, (*it).id); | ||
2902 | 110 | } | ||
2903 | 111 | |||
2904 | 112 | TEST_F(ReviewsTest, bringToFrontEmptyList) | ||
2905 | 113 | { | ||
2906 | 114 | click::ReviewList reviews; | ||
2907 | 115 | |||
2908 | 116 | auto newReviews = bring_to_front(reviews, "user1"); | ||
2909 | 117 | EXPECT_EQ(0u, newReviews.size()); | ||
2910 | 118 | } | ||
2911 | 119 | |||
2912 | 120 | TEST_F(ReviewsTest, bringToFrontUserDoesntMatch) | ||
2913 | 121 | { | ||
2914 | 122 | click::Review r1; | ||
2915 | 123 | r1.id = 1; | ||
2916 | 124 | r1.reviewer_username = "user1"; | ||
2917 | 125 | |||
2918 | 126 | click::Review r2; | ||
2919 | 127 | r2.id = 2; | ||
2920 | 128 | r2.reviewer_username = "user2"; | ||
2921 | 129 | |||
2922 | 130 | click::ReviewList reviews {r1, r2}; | ||
2923 | 131 | |||
2924 | 132 | auto newReviews = bring_to_front(reviews, "user0"); | ||
2925 | 133 | EXPECT_EQ(2u, newReviews.size()); | ||
2926 | 134 | auto it = newReviews.begin(); | ||
2927 | 135 | EXPECT_EQ(1u, (*it).id); | ||
2928 | 136 | ++it; | ||
2929 | 137 | EXPECT_EQ(2u, (*it).id); | ||
2930 | 138 | } | ||
2931 | 139 | |||
2932 | 140 | TEST_F(ReviewsTest, testFetchReviewsCallsWebservice) | ||
2933 | 141 | { | ||
2934 | 142 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2935 | 143 | auto response = responseForReply(reply.asSharedPtr()); | ||
2936 | 144 | |||
2937 | 145 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
2938 | 146 | .Times(1) | ||
2939 | 147 | .WillOnce(Return(response)); | ||
2940 | 148 | |||
2941 | 149 | reviewsPtr->fetch_reviews("", [](click::ReviewList, | ||
2942 | 150 | click::Reviews::Error) {}); | ||
2943 | 151 | } | ||
2944 | 152 | |||
2945 | 153 | TEST_F(ReviewsTest, testFetchReviewsDoesNotSignCall) | ||
2946 | 154 | { | ||
2947 | 155 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2948 | 156 | auto response = responseForReply(reply.asSharedPtr()); | ||
2949 | 157 | |||
2950 | 158 | EXPECT_CALL(*clientPtr, callImpl(_, _, false, _, _, _)) | ||
2951 | 159 | .Times(1) | ||
2952 | 160 | .WillOnce(Return(response)); | ||
2953 | 161 | |||
2954 | 162 | reviewsPtr->fetch_reviews("", [](click::ReviewList, | ||
2955 | 163 | click::Reviews::Error) {}); | ||
2956 | 164 | } | ||
2957 | 165 | |||
2958 | 166 | TEST_F(ReviewsTest, testFetchReviewsSendsQueryAsParam) | ||
2959 | 167 | { | ||
2960 | 168 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2961 | 169 | auto response = responseForReply(reply.asSharedPtr()); | ||
2962 | 170 | |||
2963 | 171 | click::web::CallParams params; | ||
2964 | 172 | params.add(click::REVIEWS_QUERY_ARGNAME, FAKE_PACKAGENAME); | ||
2965 | 173 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, params)) | ||
2966 | 174 | .Times(1) | ||
2967 | 175 | .WillOnce(Return(response)); | ||
2968 | 176 | |||
2969 | 177 | reviewsPtr->fetch_reviews(FAKE_PACKAGENAME, [](click::ReviewList, | ||
2970 | 178 | click::Reviews::Error) {}); | ||
2971 | 179 | } | ||
2972 | 180 | |||
2973 | 181 | TEST_F(ReviewsTest, testFetchReviewsSendsCorrectPath) | ||
2974 | 182 | { | ||
2975 | 183 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2976 | 184 | auto response = responseForReply(reply.asSharedPtr()); | ||
2977 | 185 | |||
2978 | 186 | EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::REVIEWS_API_PATH), | ||
2979 | 187 | _, _, _, _, _)) | ||
2980 | 188 | .Times(1) | ||
2981 | 189 | .WillOnce(Return(response)); | ||
2982 | 190 | |||
2983 | 191 | reviewsPtr->fetch_reviews(FAKE_PACKAGENAME, [](click::ReviewList, | ||
2984 | 192 | click::Reviews::Error) {}); | ||
2985 | 193 | } | ||
2986 | 194 | |||
2987 | 195 | TEST_F(ReviewsTest, testFetchReviewsCallbackCalled) | ||
2988 | 196 | { | ||
2989 | 197 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
2990 | 198 | auto response = responseForReply(reply.asSharedPtr()); | ||
2991 | 199 | |||
2992 | 200 | QByteArray fake_json("[]"); | ||
2993 | 201 | EXPECT_CALL(reply.instance, readAll()) | ||
2994 | 202 | .Times(1) | ||
2995 | 203 | .WillOnce(Return(fake_json)); | ||
2996 | 204 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
2997 | 205 | .Times(1) | ||
2998 | 206 | .WillOnce(Return(response)); | ||
2999 | 207 | EXPECT_CALL(*this, reviews_callback(_, _)).Times(1); | ||
3000 | 208 | |||
3001 | 209 | reviewsPtr->fetch_reviews("", [this](click::ReviewList reviews, | ||
3002 | 210 | click::Reviews::Error error){ | ||
3003 | 211 | reviews_callback(reviews, error); | ||
3004 | 212 | }); | ||
3005 | 213 | response->replyFinished(); | ||
3006 | 214 | } | ||
3007 | 215 | |||
3008 | 216 | TEST_F(ReviewsTest, testFetchReviewsNot200) | ||
3009 | 217 | { | ||
3010 | 218 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3011 | 219 | auto response = responseForReply(reply.asSharedPtr()); | ||
3012 | 220 | |||
3013 | 221 | EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(301))); | ||
3014 | 222 | EXPECT_CALL(reply.instance, readAll()) | ||
3015 | 223 | .Times(1) | ||
3016 | 224 | .WillOnce(Return(FAKE_JSON_REVIEWS_RESULT_ONE.c_str())); | ||
3017 | 225 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
3018 | 226 | .Times(1) | ||
3019 | 227 | .WillOnce(Return(response)); | ||
3020 | 228 | click::ReviewList empty_reviews_list; | ||
3021 | 229 | EXPECT_CALL(*this, reviews_callback(empty_reviews_list, _)).Times(1); | ||
3022 | 230 | |||
3023 | 231 | reviewsPtr->fetch_reviews("", [this](click::ReviewList reviews, | ||
3024 | 232 | click::Reviews::Error error){ | ||
3025 | 233 | reviews_callback(reviews, error); | ||
3026 | 234 | }); | ||
3027 | 235 | response->replyFinished(); | ||
3028 | 236 | } | ||
3029 | 237 | |||
3030 | 238 | TEST_F(ReviewsTest, testFetchReviewsEmptyJsonIsParsed) | ||
3031 | 239 | { | ||
3032 | 240 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3033 | 241 | auto response = responseForReply(reply.asSharedPtr()); | ||
3034 | 242 | |||
3035 | 243 | QByteArray fake_json("[]"); | ||
3036 | 244 | EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200))); | ||
3037 | 245 | EXPECT_CALL(reply.instance, readAll()) | ||
3038 | 246 | .Times(1) | ||
3039 | 247 | .WillOnce(Return(fake_json)); | ||
3040 | 248 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
3041 | 249 | .Times(1) | ||
3042 | 250 | .WillOnce(Return(response)); | ||
3043 | 251 | click::ReviewList empty_reviews_list; | ||
3044 | 252 | EXPECT_CALL(*this, reviews_callback(empty_reviews_list, _)).Times(1); | ||
3045 | 253 | |||
3046 | 254 | reviewsPtr->fetch_reviews("", [this](click::ReviewList reviews, | ||
3047 | 255 | click::Reviews::Error error){ | ||
3048 | 256 | reviews_callback(reviews, error); | ||
3049 | 257 | }); | ||
3050 | 258 | response->replyFinished(); | ||
3051 | 259 | } | ||
3052 | 260 | |||
3053 | 261 | TEST_F(ReviewsTest, testFetchReviewsSingleJsonIsParsed) | ||
3054 | 262 | { | ||
3055 | 263 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3056 | 264 | auto response = responseForReply(reply.asSharedPtr()); | ||
3057 | 265 | |||
3058 | 266 | QByteArray fake_json(FAKE_JSON_REVIEWS_RESULT_ONE.c_str()); | ||
3059 | 267 | EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200))); | ||
3060 | 268 | EXPECT_CALL(reply.instance, readAll()) | ||
3061 | 269 | .Times(1) | ||
3062 | 270 | .WillOnce(Return(fake_json)); | ||
3063 | 271 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
3064 | 272 | .Times(1) | ||
3065 | 273 | .WillOnce(Return(response)); | ||
3066 | 274 | click::ReviewList single_review_list = | ||
3067 | 275 | { | ||
3068 | 276 | click::Review | ||
3069 | 277 | { | ||
3070 | 278 | 1, 4, 0, 0, false, | ||
3071 | 279 | "2014-01-28T09:09:47.218Z", "null", | ||
3072 | 280 | FAKE_PACKAGENAME, "0.2", | ||
3073 | 281 | "en", | ||
3074 | 282 | "Review Summary", "It is ok.", | ||
3075 | 283 | "Reviewer", "reviewer" | ||
3076 | 284 | } | ||
3077 | 285 | }; | ||
3078 | 286 | EXPECT_CALL(*this, reviews_callback(single_review_list, _)).Times(1); | ||
3079 | 287 | |||
3080 | 288 | reviewsPtr->fetch_reviews("", [this](click::ReviewList reviews, | ||
3081 | 289 | click::Reviews::Error error){ | ||
3082 | 290 | reviews_callback(reviews, error); | ||
3083 | 291 | }); | ||
3084 | 292 | response->replyFinished(); | ||
3085 | 293 | } | ||
3086 | 294 | |||
3087 | 295 | TEST_F(ReviewsTest, testFetchReviewsNetworkErrorReported) | ||
3088 | 296 | { | ||
3089 | 297 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3090 | 298 | auto response = responseForReply(reply.asSharedPtr()); | ||
3091 | 299 | |||
3092 | 300 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
3093 | 301 | .Times(1) | ||
3094 | 302 | .WillOnce(Return(response)); | ||
3095 | 303 | EXPECT_CALL(reply.instance, errorString()) | ||
3096 | 304 | .Times(1) | ||
3097 | 305 | .WillOnce(Return("fake error")); | ||
3098 | 306 | reviewsPtr->fetch_reviews("", [this](click::ReviewList reviews, | ||
3099 | 307 | click::Reviews::Error error){ | ||
3100 | 308 | reviews_callback(reviews, error); | ||
3101 | 309 | }); | ||
3102 | 310 | click::ReviewList empty_reviews_list; | ||
3103 | 311 | EXPECT_CALL(*this, reviews_callback(empty_reviews_list, | ||
3104 | 312 | click::Reviews::Error::NetworkError)) | ||
3105 | 313 | .Times(1); | ||
3106 | 314 | |||
3107 | 315 | emit reply.instance.error(QNetworkReply::UnknownNetworkError); | ||
3108 | 316 | } | ||
3109 | 317 | |||
3110 | 318 | TEST_F(ReviewsTest, testFetchReviewsIsCancellable) | ||
3111 | 319 | { | ||
3112 | 320 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3113 | 321 | auto response = responseForReply(reply.asSharedPtr()); | ||
3114 | 322 | |||
3115 | 323 | EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _)) | ||
3116 | 324 | .Times(1) | ||
3117 | 325 | .WillOnce(Return(response)); | ||
3118 | 326 | |||
3119 | 327 | auto fetch_reviews_op = reviewsPtr->fetch_reviews("", [](click::ReviewList, | ||
3120 | 328 | click::Reviews::Error) {}); | ||
3121 | 329 | EXPECT_CALL(reply.instance, abort()).Times(1); | ||
3122 | 330 | fetch_reviews_op.cancel(); | ||
3123 | 331 | } | ||
3124 | 332 | |||
3125 | 333 | TEST_F(ReviewsTest, testSubmitReviewIsCancellable) | ||
3126 | 334 | { | ||
3127 | 335 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3128 | 336 | auto response = responseForReply(reply.asSharedPtr()); | ||
3129 | 337 | |||
3130 | 338 | click::Review review; | ||
3131 | 339 | review.rating = 3; | ||
3132 | 340 | review.review_text = "A review"; | ||
3133 | 341 | review.package_name = "com.example.test"; | ||
3134 | 342 | review.package_version = "0.1"; | ||
3135 | 343 | |||
3136 | 344 | EXPECT_CALL(*clientPtr, callImpl(_, "POST", true, _, _, _)) | ||
3137 | 345 | .Times(1) | ||
3138 | 346 | .WillOnce(Return(response)); | ||
3139 | 347 | |||
3140 | 348 | auto submit_op = reviewsPtr->submit_review(review, | ||
3141 | 349 | [](click::Reviews::Error){}); | ||
3142 | 350 | EXPECT_CALL(reply.instance, abort()).Times(1); | ||
3143 | 351 | submit_op.cancel(); | ||
3144 | 352 | } | ||
3145 | 353 | |||
3146 | 354 | TEST_F(ReviewsTest, testSubmitReviewUtf8) | ||
3147 | 355 | { | ||
3148 | 356 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3149 | 357 | auto response = responseForReply(reply.asSharedPtr()); | ||
3150 | 358 | |||
3151 | 359 | click::Review review; | ||
3152 | 360 | review.rating = 3; | ||
3153 | 361 | review.review_text = "'\"小海嚴選"; | ||
3154 | 362 | review.package_name = "com.example.test"; | ||
3155 | 363 | review.package_version = "0.1"; | ||
3156 | 364 | |||
3157 | 365 | // NOTE: gmock replaces the \" above as \\\" for HasSubstr(), so we have | ||
3158 | 366 | // to manually copy the string into the expected result. | ||
3159 | 367 | std::string expected_review_text = "\"review_text\":\"'\\\"小海嚴選\""; | ||
3160 | 368 | |||
3161 | 369 | EXPECT_CALL(*clientPtr, callImpl(_, "POST", true, _, | ||
3162 | 370 | HasSubstr(expected_review_text), _)) | ||
3163 | 371 | .Times(1) | ||
3164 | 372 | .WillOnce(Return(response)); | ||
3165 | 373 | |||
3166 | 374 | auto submit_op = reviewsPtr->submit_review(review, | ||
3167 | 375 | [](click::Reviews::Error){}); | ||
3168 | 376 | } | ||
3169 | 377 | |||
3170 | 378 | TEST_F(ReviewsTest, testSubmitReviewLanguageCorrect) | ||
3171 | 379 | { | ||
3172 | 380 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3173 | 381 | auto response = responseForReply(reply.asSharedPtr()); | ||
3174 | 382 | |||
3175 | 383 | click::Review review; | ||
3176 | 384 | review.rating = 3; | ||
3177 | 385 | review.review_text = "A review."; | ||
3178 | 386 | review.package_name = "com.example.test"; | ||
3179 | 387 | review.package_version = "0.1"; | ||
3180 | 388 | |||
3181 | 389 | ASSERT_EQ(setenv(click::Configuration::LANGUAGE_ENVVAR, | ||
3182 | 390 | "es_AR.UTF-8", 1), 0); | ||
3183 | 391 | std::string expected_language = "\"language\":\"es\""; | ||
3184 | 392 | EXPECT_CALL(*clientPtr, callImpl(_, "POST", true, _, | ||
3185 | 393 | HasSubstr(expected_language), _)) | ||
3186 | 394 | .Times(1) | ||
3187 | 395 | .WillOnce(Return(response)); | ||
3188 | 396 | |||
3189 | 397 | auto submit_op = reviewsPtr->submit_review(review, | ||
3190 | 398 | [](click::Reviews::Error){}); | ||
3191 | 399 | ASSERT_EQ(unsetenv(click::Configuration::LANGUAGE_ENVVAR), 0); | ||
3192 | 400 | } | ||
3193 | 401 | |||
3194 | 402 | TEST_F(ReviewsTest, testSubmitReviewLanguageCorrectForFullLangCodes) | ||
3195 | 403 | { | ||
3196 | 404 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3197 | 405 | auto response = responseForReply(reply.asSharedPtr()); | ||
3198 | 406 | |||
3199 | 407 | click::Review review; | ||
3200 | 408 | review.rating = 3; | ||
3201 | 409 | review.review_text = "A review."; | ||
3202 | 410 | review.package_name = "com.example.test"; | ||
3203 | 411 | review.package_version = "0.1"; | ||
3204 | 412 | |||
3205 | 413 | for (std::string lang: click::Configuration::FULL_LANG_CODES) { | ||
3206 | 414 | ASSERT_EQ(setenv(click::Configuration::LANGUAGE_ENVVAR, | ||
3207 | 415 | lang.c_str(), 1), 0); | ||
3208 | 416 | std::string expected_language = "\"language\":\"" + lang + "\""; | ||
3209 | 417 | EXPECT_CALL(*clientPtr, callImpl(_, "POST", true, _, | ||
3210 | 418 | HasSubstr(expected_language), _)) | ||
3211 | 419 | .Times(1) | ||
3212 | 420 | .WillOnce(Return(response)); | ||
3213 | 421 | |||
3214 | 422 | auto submit_op = reviewsPtr->submit_review(review, | ||
3215 | 423 | [](click::Reviews::Error){}); | ||
3216 | 424 | ASSERT_EQ(unsetenv(click::Configuration::LANGUAGE_ENVVAR), 0); | ||
3217 | 425 | } | ||
3218 | 426 | } | ||
3219 | 427 | |||
3220 | 428 | TEST_F(ReviewsTest, testEditReviewUrlHasReviewId) | ||
3221 | 429 | { | ||
3222 | 430 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3223 | 431 | auto response = responseForReply(reply.asSharedPtr()); | ||
3224 | 432 | |||
3225 | 433 | click::Review review; | ||
3226 | 434 | review.id = 1234; | ||
3227 | 435 | review.rating = 4; | ||
3228 | 436 | review.review_text = "A review"; | ||
3229 | 437 | review.package_name = "com.example.test"; | ||
3230 | 438 | review.package_version = "0.1"; | ||
3231 | 439 | |||
3232 | 440 | EXPECT_CALL(*clientPtr, callImpl(HasSubstr("/1234/"), "PUT", true, _, _, _)) | ||
3233 | 441 | .Times(1) | ||
3234 | 442 | .WillOnce(Return(response)); | ||
3235 | 443 | |||
3236 | 444 | auto submit_op = reviewsPtr->edit_review(review, | ||
3237 | 445 | [](click::Reviews::Error){}); | ||
3238 | 446 | } | ||
3239 | 447 | |||
3240 | 448 | TEST_F(ReviewsTest, testEditReviewIsCancellable) | ||
3241 | 449 | { | ||
3242 | 450 | LifetimeHelper<click::network::Reply, MockNetworkReply> reply; | ||
3243 | 451 | auto response = responseForReply(reply.asSharedPtr()); | ||
3244 | 452 | |||
3245 | 453 | click::Review review; | ||
3246 | 454 | review.id = 1234; | ||
3247 | 455 | review.rating = 4; | ||
3248 | 456 | review.review_text = "A review"; | ||
3249 | 457 | review.package_name = "com.example.test"; | ||
3250 | 458 | review.package_version = "0.1"; | ||
3251 | 459 | |||
3252 | 460 | EXPECT_CALL(*clientPtr, callImpl(_, "PUT", true, _, _, _)) | ||
3253 | 461 | .Times(1) | ||
3254 | 462 | .WillOnce(Return(response)); | ||
3255 | 463 | |||
3256 | 464 | auto submit_op = reviewsPtr->edit_review(review, | ||
3257 | 465 | [](click::Reviews::Error){}); | ||
3258 | 466 | EXPECT_CALL(reply.instance, abort()).Times(1); | ||
3259 | 467 | submit_op.cancel(); | ||
3260 | 468 | } | ||
3261 | 469 | |||
3262 | 470 | |||
3263 | 471 | TEST_F(ReviewsTest, testGetBaseUrl) | ||
3264 | 472 | { | ||
3265 | 473 | const char *value = getenv(click::REVIEWS_BASE_URL_ENVVAR.c_str()); | ||
3266 | 474 | if (value != NULL) { | ||
3267 | 475 | ASSERT_TRUE(unsetenv(click::REVIEWS_BASE_URL_ENVVAR.c_str()) == 0); | ||
3268 | 476 | } | ||
3269 | 477 | ASSERT_TRUE(click::Reviews::get_base_url() == click::REVIEWS_BASE_URL); | ||
3270 | 478 | |||
3271 | 479 | } | ||
3272 | 480 | |||
3273 | 481 | TEST_F(ReviewsTest, testGetBaseUrlFromEnv) | ||
3274 | 482 | { | ||
3275 | 483 | ASSERT_TRUE(setenv(click::REVIEWS_BASE_URL_ENVVAR.c_str(), | ||
3276 | 484 | FAKE_SERVER.c_str(), 1) == 0); | ||
3277 | 485 | ASSERT_TRUE(click::Reviews::get_base_url() == FAKE_SERVER); | ||
3278 | 486 | ASSERT_TRUE(unsetenv(click::REVIEWS_BASE_URL_ENVVAR.c_str()) == 0); | ||
3279 | 487 | } | ||
3280 | 488 | 0 | ||
3281 | === modified file 'scope/clickapps/apps-scope.cpp' | |||
3282 | --- scope/clickapps/apps-scope.cpp 2016-11-08 13:42:04 +0000 | |||
3283 | +++ scope/clickapps/apps-scope.cpp 2017-01-10 16:06:37 +0000 | |||
3284 | @@ -81,7 +81,6 @@ | |||
3285 | 81 | static const int zero = 0; | 81 | static const int zero = 0; |
3286 | 82 | auto emptyCb = [this]() | 82 | auto emptyCb = [this]() |
3287 | 83 | { | 83 | { |
3288 | 84 | dm.reset(Ubuntu::DownloadManager::Manager::createSessionManager()); | ||
3289 | 85 | qt_ready_for_search_p.set_value(); | 84 | qt_ready_for_search_p.set_value(); |
3290 | 86 | 85 | ||
3291 | 87 | sso.reset(new click::CredentialsService()); | 86 | sso.reset(new click::CredentialsService()); |
3292 | @@ -107,57 +106,19 @@ | |||
3293 | 107 | const unity::scopes::ActionMetadata& metadata) { | 106 | const unity::scopes::ActionMetadata& metadata) { |
3294 | 108 | qDebug() << "Scope::preview() called."; | 107 | qDebug() << "Scope::preview() called."; |
3295 | 109 | auto preview = new click::Preview(result, metadata, qt_ready_for_preview_f.share()); | 108 | auto preview = new click::Preview(result, metadata, qt_ready_for_preview_f.share()); |
3297 | 110 | preview->choose_strategy(client, dm, depts_db); | 109 | preview->choose_strategy(client, depts_db); |
3298 | 111 | return unity::scopes::PreviewQueryBase::UPtr{preview}; | 110 | return unity::scopes::PreviewQueryBase::UPtr{preview}; |
3299 | 112 | } | 111 | } |
3300 | 113 | 112 | ||
3301 | 114 | 113 | ||
3302 | 115 | unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata, | 114 | unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata, |
3304 | 116 | std::string const& widget_id, std::string const& action_id) | 115 | std::string const&, std::string const& action_id) |
3305 | 117 | { | 116 | { |
3306 | 118 | if (action_id == click::Preview::Actions::CONFIRM_UNINSTALL) { | ||
3307 | 119 | return scopes::ActivationQueryBase::UPtr(new PerformUninstallAction(result, metadata)); | ||
3308 | 120 | } | ||
3309 | 121 | |||
3310 | 122 | auto activation = new ScopeActivation(result, metadata); | 117 | auto activation = new ScopeActivation(result, metadata); |
3311 | 123 | qDebug() << "perform_action called with action_id" << QString().fromStdString(action_id); | 118 | qDebug() << "perform_action called with action_id" << QString().fromStdString(action_id); |
3312 | 124 | 119 | ||
3323 | 125 | if (action_id == click::Preview::Actions::UNINSTALL_CLICK) { | 120 | if (action_id == click::Preview::Actions::SHOW_INSTALLED) { |
3314 | 126 | activation->setHint(click::Preview::Actions::UNINSTALL_CLICK, unity::scopes::Variant(true)); | ||
3315 | 127 | activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview); | ||
3316 | 128 | } else if (action_id == click::Preview::Actions::CANCEL_PURCHASE_INSTALLED) { | ||
3317 | 129 | activation->setHint(click::Preview::Actions::CANCEL_PURCHASE_INSTALLED, unity::scopes::Variant(true)); | ||
3318 | 130 | activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview); | ||
3319 | 131 | } else if (action_id == click::Preview::Actions::CANCEL_PURCHASE_UNINSTALLED) { | ||
3320 | 132 | activation->setHint(click::Preview::Actions::CANCEL_PURCHASE_UNINSTALLED, unity::scopes::Variant(true)); | ||
3321 | 133 | activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview); | ||
3322 | 134 | } else if (action_id == click::Preview::Actions::SHOW_INSTALLED) { | ||
3324 | 135 | activation->setHint(click::Preview::Actions::SHOW_INSTALLED, unity::scopes::Variant(true)); | 121 | activation->setHint(click::Preview::Actions::SHOW_INSTALLED, unity::scopes::Variant(true)); |
3325 | 136 | activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview); | ||
3326 | 137 | } else if (action_id == click::Preview::Actions::SHOW_UNINSTALLED) { | ||
3327 | 138 | activation->setHint(click::Preview::Actions::SHOW_UNINSTALLED, unity::scopes::Variant(true)); | ||
3328 | 139 | activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview); | ||
3329 | 140 | } else if (action_id == click::Preview::Actions::CONFIRM_CANCEL_PURCHASE_UNINSTALLED) { | ||
3330 | 141 | activation->setHint(click::Preview::Actions::CONFIRM_CANCEL_PURCHASE_UNINSTALLED, unity::scopes::Variant(true)); | ||
3331 | 142 | activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview); | ||
3332 | 143 | } else if (action_id == click::Preview::Actions::CONFIRM_CANCEL_PURCHASE_INSTALLED) { | ||
3333 | 144 | activation->setHint(click::Preview::Actions::CONFIRM_CANCEL_PURCHASE_INSTALLED, unity::scopes::Variant(true)); | ||
3334 | 145 | activation->setStatus(unity::scopes::ActivationResponse::Status::ShowPreview); | ||
3335 | 146 | } else if (action_id == click::Preview::Actions::RATED) { | ||
3336 | 147 | scopes::VariantMap rating_info = metadata.scope_data().get_dict(); | ||
3337 | 148 | // Cast to int because widget gives us double, which is wrong. | ||
3338 | 149 | int rating = ((int)rating_info["rating"].get_double()); | ||
3339 | 150 | std::string review_text = rating_info["review"].get_string(); | ||
3340 | 151 | |||
3341 | 152 | // We have to get the values and then set them as hints here, to be | ||
3342 | 153 | // able to pass them on to the Preview, which actually makes the | ||
3343 | 154 | // call to submit. | ||
3344 | 155 | activation->setHint("rating", scopes::Variant(rating)); | ||
3345 | 156 | activation->setHint("review", scopes::Variant(review_text)); | ||
3346 | 157 | activation->setHint(click::Preview::Actions::RATED, | ||
3347 | 158 | scopes::Variant(true)); | ||
3348 | 159 | activation->setHint("widget_id", scopes::Variant(widget_id)); | ||
3349 | 160 | activation->setStatus(scopes::ActivationResponse::Status::ShowPreview); | ||
3350 | 161 | } | 122 | } |
3351 | 162 | return scopes::ActivationQueryBase::UPtr(activation); | 123 | return scopes::ActivationQueryBase::UPtr(activation); |
3352 | 163 | } | 124 | } |
3353 | 164 | 125 | ||
3354 | === modified file 'scope/clickapps/apps-scope.h' | |||
3355 | --- scope/clickapps/apps-scope.h 2016-10-24 21:26:23 +0000 | |||
3356 | +++ scope/clickapps/apps-scope.h 2017-01-10 16:06:37 +0000 | |||
3357 | @@ -34,7 +34,6 @@ | |||
3358 | 34 | #include <click/network_access_manager.h> | 34 | #include <click/network_access_manager.h> |
3359 | 35 | #include <click/webclient.h> | 35 | #include <click/webclient.h> |
3360 | 36 | 36 | ||
3361 | 37 | #include <ubuntu/download_manager/manager.h> | ||
3362 | 38 | #include <unity/scopes/ScopeBase.h> | 37 | #include <unity/scopes/ScopeBase.h> |
3363 | 39 | #include <unity/scopes/QueryBase.h> | 38 | #include <unity/scopes/QueryBase.h> |
3364 | 40 | #include <unity/scopes/ActivationQueryBase.h> | 39 | #include <unity/scopes/ActivationQueryBase.h> |
3365 | @@ -73,7 +72,6 @@ | |||
3366 | 73 | QSharedPointer<click::network::AccessManager> nam; | 72 | QSharedPointer<click::network::AccessManager> nam; |
3367 | 74 | QSharedPointer<click::web::Client> client; | 73 | QSharedPointer<click::web::Client> client; |
3368 | 75 | QSharedPointer<click::Index> index; | 74 | QSharedPointer<click::Index> index; |
3369 | 76 | QSharedPointer<Ubuntu::DownloadManager::Manager> dm; | ||
3370 | 77 | QSharedPointer<click::CredentialsService> sso; | 75 | QSharedPointer<click::CredentialsService> sso; |
3371 | 78 | std::shared_ptr<click::DepartmentsDb> depts_db; | 76 | std::shared_ptr<click::DepartmentsDb> depts_db; |
3372 | 79 | 77 | ||
3373 | 80 | 78 | ||
3374 | === modified file 'scope/tests/test_apps_scope.cpp' | |||
3375 | --- scope/tests/test_apps_scope.cpp 2015-11-24 18:23:23 +0000 | |||
3376 | +++ scope/tests/test_apps_scope.cpp 2017-01-10 16:06:37 +0000 | |||
3377 | @@ -53,32 +53,6 @@ | |||
3378 | 53 | } | 53 | } |
3379 | 54 | }; | 54 | }; |
3380 | 55 | 55 | ||
3381 | 56 | TEST_F(AppsScopeTest, DISABLED_testConfirmUninstall) | ||
3382 | 57 | { | ||
3383 | 58 | result.set_title("foo"); | ||
3384 | 59 | result[click::apps::Query::ResultKeys::NAME] = "foo.name"; | ||
3385 | 60 | result[click::apps::Query::ResultKeys::VERSION] = "0.1"; | ||
3386 | 61 | auto activation = scope.perform_action(result, metadata, "widget", | ||
3387 | 62 | click::Preview::Actions::CONFIRM_UNINSTALL); | ||
3388 | 63 | auto response = activation->activate(); | ||
3389 | 64 | } | ||
3390 | 65 | |||
3391 | 66 | TEST_F(AppsScopeTest, testCancelPurchaseInstalled) | ||
3392 | 67 | { | ||
3393 | 68 | auto activation = scope.perform_action(result, metadata, "button", | ||
3394 | 69 | click::Preview::Actions::CANCEL_PURCHASE_INSTALLED); | ||
3395 | 70 | auto response = activation->activate(); | ||
3396 | 71 | EXPECT_TRUE(response.scope_data().get_dict()[click::Preview::Actions::CANCEL_PURCHASE_INSTALLED].get_bool()); | ||
3397 | 72 | } | ||
3398 | 73 | |||
3399 | 74 | TEST_F(AppsScopeTest, testCancelPurchaseUninstalled) | ||
3400 | 75 | { | ||
3401 | 76 | auto activation = scope.perform_action(result, metadata, "button", | ||
3402 | 77 | click::Preview::Actions::CANCEL_PURCHASE_UNINSTALLED); | ||
3403 | 78 | auto response = activation->activate(); | ||
3404 | 79 | EXPECT_TRUE(response.scope_data().get_dict()[click::Preview::Actions::CANCEL_PURCHASE_UNINSTALLED].get_bool()); | ||
3405 | 80 | } | ||
3406 | 81 | |||
3407 | 82 | TEST_F(AppsScopeTest, testShowInstalled) | 56 | TEST_F(AppsScopeTest, testShowInstalled) |
3408 | 83 | { | 57 | { |
3409 | 84 | auto activation = scope.perform_action(result, metadata, "button", | 58 | auto activation = scope.perform_action(result, metadata, "button", |
3410 | @@ -86,43 +60,3 @@ | |||
3411 | 86 | auto response = activation->activate(); | 60 | auto response = activation->activate(); |
3412 | 87 | EXPECT_TRUE(response.scope_data().get_dict()[click::Preview::Actions::SHOW_INSTALLED].get_bool()); | 61 | EXPECT_TRUE(response.scope_data().get_dict()[click::Preview::Actions::SHOW_INSTALLED].get_bool()); |
3413 | 88 | } | 62 | } |
3414 | 89 | |||
3415 | 90 | TEST_F(AppsScopeTest, testShowUninstalled) | ||
3416 | 91 | { | ||
3417 | 92 | auto activation = scope.perform_action(result, metadata, "button", | ||
3418 | 93 | click::Preview::Actions::SHOW_UNINSTALLED); | ||
3419 | 94 | auto response = activation->activate(); | ||
3420 | 95 | EXPECT_TRUE(response.scope_data().get_dict()[click::Preview::Actions::SHOW_UNINSTALLED].get_bool()); | ||
3421 | 96 | } | ||
3422 | 97 | |||
3423 | 98 | TEST_F(AppsScopeTest, testConfirmCancelPurchaseUninstalled) | ||
3424 | 99 | { | ||
3425 | 100 | auto activation = scope.perform_action(result, metadata, "widget_id", | ||
3426 | 101 | click::Preview::Actions::CONFIRM_CANCEL_PURCHASE_UNINSTALLED); | ||
3427 | 102 | auto response = activation->activate(); | ||
3428 | 103 | EXPECT_TRUE(response.scope_data().get_dict()[click::Preview::Actions::CONFIRM_CANCEL_PURCHASE_UNINSTALLED].get_bool()); | ||
3429 | 104 | } | ||
3430 | 105 | |||
3431 | 106 | TEST_F(AppsScopeTest, testConfirmCancelPurcahseInstalled) | ||
3432 | 107 | { | ||
3433 | 108 | auto activation = scope.perform_action(result, metadata, "widget_id", | ||
3434 | 109 | click::Preview::Actions::CONFIRM_CANCEL_PURCHASE_INSTALLED); | ||
3435 | 110 | auto response = activation->activate(); | ||
3436 | 111 | EXPECT_TRUE(response.scope_data().get_dict()[click::Preview::Actions::CONFIRM_CANCEL_PURCHASE_INSTALLED].get_bool()); | ||
3437 | 112 | } | ||
3438 | 113 | |||
3439 | 114 | TEST_F(AppsScopeTest, testRatingNew) | ||
3440 | 115 | { | ||
3441 | 116 | auto activation = scope.perform_action(result, metadata, "rating", | ||
3442 | 117 | click::Preview::Actions::RATED); | ||
3443 | 118 | auto response = activation->activate(); | ||
3444 | 119 | EXPECT_EQ("rating", response.scope_data().get_dict()["widget_id"].get_string()); | ||
3445 | 120 | } | ||
3446 | 121 | |||
3447 | 122 | TEST_F(AppsScopeTest, testRatingEdit) | ||
3448 | 123 | { | ||
3449 | 124 | auto activation = scope.perform_action(result, metadata, "93345", | ||
3450 | 125 | click::Preview::Actions::RATED); | ||
3451 | 126 | auto response = activation->activate(); | ||
3452 | 127 | EXPECT_EQ("93345", response.scope_data().get_dict()["widget_id"].get_string()); | ||
3453 | 128 | } |
FAILED: Continuous integration, rev:504 /jenkins. canonical. com/unity- api-1/job/ lp-unity- scope-click- ci/130/ /jenkins. canonical. com/unity- api-1/job/ build/1248/ console /jenkins. canonical. com/unity- api-1/job/ build-0- fetch/1255 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1038/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= zesty/1038/ console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1038/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= zesty/1038/ console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1038/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= zesty/1038/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/unity- api-1/job/ lp-unity- scope-click- ci/130/ rebuild
https:/