Merge lp:~dobey/unity-scope-click/clicksnap into lp:unity-scope-click

Proposed by dobey
Status: Superseded
Proposed branch: lp:~dobey/unity-scope-click/clicksnap
Merge into: lp:unity-scope-click
Diff against target: 4429 lines (+1203/-1758)
66 files modified
CMakeLists.txt (+7/-1)
bin/install-helper (+7/-2)
debian/control (+3/-2)
libclickscope/click/CMakeLists.txt (+4/-1)
libclickscope/click/configuration.cpp (+17/-3)
libclickscope/click/configuration.h (+5/-4)
libclickscope/click/download-manager.cpp (+43/-83)
libclickscope/click/download-manager.h (+4/-8)
libclickscope/click/index.cpp (+52/-2)
libclickscope/click/index.h (+11/-2)
libclickscope/click/interface.cpp (+167/-370)
libclickscope/click/interface.h (+15/-29)
libclickscope/click/key_file_locator.cpp (+0/-94)
libclickscope/click/key_file_locator.h (+0/-70)
libclickscope/click/package.cpp (+4/-0)
libclickscope/click/package.h (+4/-0)
libclickscope/click/preview.cpp (+23/-8)
libclickscope/click/webclient.cpp (+26/-17)
libclickscope/click/webclient.h (+2/-0)
libclickscope/tests/CMakeLists.txt (+3/-3)
libclickscope/tests/applications/system/address-book-app.desktop (+0/-15)
libclickscope/tests/applications/system/messaging-app.desktop (+0/-14)
libclickscope/tests/applications/system/translated.desktop (+0/-9)
libclickscope/tests/applications/user/badd-appid.desktop (+0/-10)
libclickscope/tests/applications/user/com.ubuntu.accented_accented_0.5.29.desktop (+0/-13)
libclickscope/tests/applications/user/com.ubuntu.calculator_calculator_0.1.3.206.desktop (+0/-14)
libclickscope/tests/applications/user/com.ubuntu.calendar_calendar_0.4.182.desktop (+0/-14)
libclickscope/tests/applications/user/com.ubuntu.clock_clock_1.0.300.desktop (+0/-14)
libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6.desktop (+0/-10)
libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8.desktop (+0/-11)
libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5.desktop (+0/-12)
libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8.desktop (+0/-11)
libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5.desktop (+0/-12)
libclickscope/tests/applications/user/com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43.desktop (+0/-13)
libclickscope/tests/applications/user/com.ubuntu.filemanager_filemanager_0.1.1.97.desktop (+0/-13)
libclickscope/tests/applications/user/com.ubuntu.music_music_1.1.329.desktop (+0/-15)
libclickscope/tests/applications/user/com.ubuntu.notes_notes_1.4.242.desktop (+0/-14)
libclickscope/tests/applications/user/com.ubuntu.shorts_shorts_0.2.162.desktop (+0/-14)
libclickscope/tests/applications/user/com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop (+0/-16)
libclickscope/tests/applications/user/com.ubuntu.sudoku_sudoku_1.0.142.desktop (+0/-15)
libclickscope/tests/applications/user/com.ubuntu.terminal_terminal_0.5.29.desktop (+0/-13)
libclickscope/tests/applications/user/com.ubuntu.weather_weather_1.0.168.desktop (+0/-15)
libclickscope/tests/applications/user/non-click-app-nodisplay.desktop (+0/-9)
libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome-unity.desktop (+0/-10)
libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome.desktop (+0/-10)
libclickscope/tests/applications/user/non-click-app-onlyshowin-unity.desktop (+0/-10)
libclickscope/tests/applications/user/non-click-app-without-exception.desktop (+0/-9)
libclickscope/tests/applications/user/pre-translated.desktop (+0/-14)
libclickscope/tests/applications/user/semi-broken.desktop (+0/-1)
libclickscope/tests/mock_ual.h (+156/-0)
libclickscope/tests/mock_webclient.h (+9/-7)
libclickscope/tests/test_bootstrap.cpp (+2/-2)
libclickscope/tests/test_data.cpp.in (+0/-43)
libclickscope/tests/test_data.h (+0/-3)
libclickscope/tests/test_download_manager.cpp (+155/-127)
libclickscope/tests/test_index.cpp (+225/-20)
libclickscope/tests/test_interface.cpp (+162/-446)
libclickscope/tests/test_pay.cpp (+13/-13)
libclickscope/tests/test_preview.cpp (+2/-2)
libclickscope/tests/test_reviews.cpp (+16/-16)
scope/clickapps/apps-query.cpp (+8/-8)
scope/clickapps/apps-scope.cpp (+0/-1)
scope/clickstore/store-query.cpp (+47/-10)
scope/clickstore/store-scope.cpp (+0/-1)
scope/tests/test_apps_query.cpp (+6/-6)
tools/init-departments/init-departments.cpp (+5/-4)
To merge this branch: bzr merge lp:~dobey/unity-scope-click/clicksnap
Reviewer Review Type Date Requested Status
unity-api-1-bot continuous-integration Approve
Unity API Team Pending
Review via email: mp+303849@code.launchpad.net

This proposal has been superseded by a proposal from 2016-08-25.

Commit message

Support for snaps.

To post a comment you must log in.
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:496
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/86/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/470
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/476
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/381
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/381
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/381
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/311/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/86/rebuild

review: Approve (continuous-integration)
497. By dobey

Merge up with ual-apps again.

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:497
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/88/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/474
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/480
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/385
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/385
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/385
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/315/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/88/rebuild

review: Approve (continuous-integration)
498. By dobey

Update dependencies to allow either snaps or clicks to be supported.

499. By dobey

Merge up chagnes from ual-apps.

500. By dobey

Collapse snapd.socket check to simplify function.

501. By dobey

Remove the extra check for downloads.size > 1, as it shouldn't happen.

502. By dobey

Some cleanup in download-manager.cpp per code review.

503. By dobey

Fixes to index.cpp per code review.

504. By dobey

Break up mock responseForReply per code review.

505. By dobey

Refactor index tests perh code review.

506. By dobey

Use const auto in for loops.

507. By dobey

Want const references for the for loops here.

508. By dobey

New script to download snap assertions and perform install

509. By dobey

Fix the snap script to do the right thing.
Add necessary dependencies for the script.

510. By dobey

Check that filename argument is non-empty before continuing.

511. By dobey

Check if name is alias instead of using snap_id to determine if snap.

512. By dobey

If frameworks list is empty send "none" instead of empty header.

513. By dobey

Use a bash function instead of variable for wget, to avoid weird escaping.

Unmerged revisions

513. By dobey

Use a bash function instead of variable for wget, to avoid weird escaping.

512. By dobey

If frameworks list is empty send "none" instead of empty header.

511. By dobey

Check if name is alias instead of using snap_id to determine if snap.

510. By dobey

Check that filename argument is non-empty before continuing.

509. By dobey

Fix the snap script to do the right thing.
Add necessary dependencies for the script.

508. By dobey

New script to download snap assertions and perform install

507. By dobey

Want const references for the for loops here.

506. By dobey

Use const auto in for loops.

505. By dobey

Refactor index tests perh code review.

504. By dobey

Break up mock responseForReply per code review.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-07-14 18:37:27 +0000
3+++ CMakeLists.txt 2016-08-24 21:39:08 +0000
4@@ -8,7 +8,7 @@
5
6 # Some default CFLAGS
7 SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -Wall -Wextra -Werror -fPIC")
8-SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -g -Wextra -Wall -Werror -Werror=conversion-null -fPIC")
9+SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -g -Wextra -Wall -Werror -Werror=conversion-null -Wno-ignored-qualifiers -fPIC")
10
11 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
12
13@@ -24,6 +24,12 @@
14 include(UseGSettings)
15 find_package (PkgConfig REQUIRED)
16
17+pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2>=0.9)
18+add_definitions(${UAL_CFLAGS} ${UAL_CFLAGS_OTHER})
19+
20+pkg_check_modules(CLICK REQUIRED click-0.4)
21+add_definitions(${CLICK_CFLAGS} ${CLICK_CFLAGS_OTHER})
22+
23 pkg_check_modules(UNITY_SCOPES REQUIRED libunity-scopes>=0.6.7 libunity-api>=0.1.3)
24 add_definitions(${UNITY_SCOPES_CFLAGS} ${UNITY_SCOPES_CFLAGS_OTHER})
25
26
27=== modified file 'bin/install-helper'
28--- bin/install-helper 2014-06-20 05:09:01 +0000
29+++ bin/install-helper 2016-08-24 21:39:08 +0000
30@@ -1,6 +1,6 @@
31 #!/bin/bash
32 #
33-# Copyright (C) 2014 Canonical Ltd.
34+# Copyright (C) 2014-2016 Canonical Ltd.
35 #
36 # This program is free software: you can redistribute it and/or modify it
37 # under the terms of the GNU General Public License version 3, as published
38@@ -47,7 +47,12 @@
39
40 function install-package {
41 FILE_NAME="$1"
42- pkcon -p install-local "$FILE_NAME"
43+ FILE_TYPE="${FILE_NAME##*.}"
44+ if [ ${FILE_TYPE} = "click" ]; then
45+ pkcon -p install-local "${FILE_NAME}"
46+ else
47+ pkexec snap install "${FILE_NAME}"
48+ fi
49 }
50
51 function app_id-from-package_name {
52
53=== modified file 'debian/control'
54--- debian/control 2016-05-25 16:17:00 +0000
55+++ debian/control 2016-08-24 21:39:08 +0000
56@@ -1,8 +1,7 @@
57 Source: unity-scope-click
58 Section: x11
59 Priority: optional
60-Build-Depends: click,
61- cmake (>= 2.8.10),
62+Build-Depends: cmake (>= 2.8.10),
63 cmake-extras,
64 dbus-x11,
65 debhelper (>= 9),
66@@ -12,9 +11,11 @@
67 intltool,
68 lcov,
69 libboost-locale-dev,
70+ libclick-0.4-dev,
71 libglib2.0-dev (>= 2.32),
72 libjsoncpp-dev,
73 libpay2-dev (>= 2.0.0+15.04.20150701),
74+ libubuntu-app-launch2-dev (>= 0.9),
75 libubuntu-download-manager-client-dev (>= 0.3+14.10.20140430-0ubuntu1),
76 libubuntu-download-manager-common-dev (>= 0.3+14.10.20140430-0ubuntu1),
77 libubuntuoneauth-2.0-dev (>= 15.10),
78
79=== modified file 'libclickscope/click/CMakeLists.txt'
80--- libclickscope/click/CMakeLists.txt 2015-04-14 21:19:21 +0000
81+++ libclickscope/click/CMakeLists.txt 2016-08-24 21:39:08 +0000
82@@ -22,7 +22,6 @@
83 highlights.cpp
84 index.cpp
85 interface.cpp
86- key_file_locator.cpp
87 launcher.cpp
88 network_access_manager.cpp
89 package.cpp
90@@ -43,6 +42,8 @@
91 ${JSON_CPP_INCLUDE_DIRS}
92 ${LIBPAY_INCLUDE_DIRS}
93 ${GSETTINGS_QT_INCLUDE_DIRS}
94+ ${UAL_INCLUDE_DIRS}
95+ ${CLICK_INCLUDE_DIRS}
96 ${CMAKE_SOURCE_DIR}/libclickscope
97 )
98
99@@ -54,5 +55,7 @@
100 ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS}
101 ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS}
102 ${GSETTINGS_QT_LIBRARIES}
103+ ${UAL_LDFLAGS}
104+ ${CLICK_LDFLAGS}
105 -lboost_locale
106 )
107
108=== modified file 'libclickscope/click/configuration.cpp'
109--- libclickscope/click/configuration.cpp 2016-02-19 03:35:43 +0000
110+++ libclickscope/click/configuration.cpp 2016-08-24 21:39:08 +0000
111@@ -1,5 +1,5 @@
112 /*
113- * Copyright (C) 2014-2015 Canonical Ltd.
114+ * Copyright (C) 2014-2016 Canonical Ltd.
115 *
116 * This program is free software: you can redistribute it and/or modify it
117 * under the terms of the GNU General Public License version 3, as published
118@@ -27,6 +27,8 @@
119 * files in the program, then also delete it here.
120 */
121
122+#include "configuration.h"
123+
124 #include <string>
125 #include <vector>
126
127@@ -43,8 +45,9 @@
128
129 #include <boost/algorithm/string.hpp>
130 #include <boost/algorithm/string/replace.hpp>
131-
132-#include "configuration.h"
133+#include <sys/stat.h>
134+#include <sys/types.h>
135+#include <unistd.h>
136
137 namespace click {
138
139@@ -121,6 +124,17 @@
140 return arch;
141 }
142
143+bool Configuration::is_snapd_running() const
144+{
145+ struct stat sb;
146+ int retval = stat("/run/snapd.socket", &sb);
147+ if (retval == 0 && (sb.st_mode & S_IFMT) == S_IFSOCK) {
148+ return true;
149+ }
150+
151+ return false;
152+}
153+
154 bool Configuration::get_purchases_enabled()
155 {
156 const char* env_value = std::getenv(PURCHASES_ENVVAR);
157
158=== modified file 'libclickscope/click/configuration.h'
159--- libclickscope/click/configuration.h 2016-02-19 03:35:43 +0000
160+++ libclickscope/click/configuration.h 2016-08-24 21:39:08 +0000
161@@ -54,6 +54,7 @@
162
163 virtual std::vector<std::string> get_available_frameworks();
164 virtual std::string get_architecture();
165+ virtual bool is_snapd_running() const;
166 static bool get_purchases_enabled();
167 static std::string get_currency(const std::string& fallback = CURRENCY_DEFAULT);
168
169@@ -78,11 +79,11 @@
170 virtual const std::vector<std::string> get_dconf_strings(const std::string& schema, const std::string& key) const;
171 static const std::vector<std::string>& get_default_core_apps() {
172 static std::vector<std::string> default_apps {
173- "dialer-app",
174- "messaging-app",
175- "address-book-app",
176+ "dialer-app.desktop",
177+ "messaging-app.desktop",
178+ "address-book-app.desktop",
179 "com.ubuntu.camera_camera",
180- "webbrowser-app",
181+ "webbrowser-app.desktop",
182 "com.ubuntu.clock_clock"
183 };
184 return default_apps;
185
186=== modified file 'libclickscope/click/download-manager.cpp'
187--- libclickscope/click/download-manager.cpp 2016-05-10 13:42:12 +0000
188+++ libclickscope/click/download-manager.cpp 2016-08-24 21:39:08 +0000
189@@ -57,12 +57,6 @@
190
191 static const QString DOWNLOAD_MANAGER_SHA512 = "sha512";
192
193-const QByteArray& CLICK_TOKEN_HEADER()
194-{
195- static const QByteArray result("X-Click-Token");
196- return result;
197-}
198-
199 DownloadManager::DownloadManager(const QSharedPointer<click::web::Client>& client,
200 const QSharedPointer<udm::Manager>& manager) :
201 client(client),
202@@ -86,11 +80,11 @@
203 if (downloads.size() > 0) {
204 auto download = downloads.at(0);
205 object_path = download->id().toStdString();
206- }
207- qDebug() << "Found object path" << QString::fromStdString(object_path)
208- << "for package" << QString::fromStdString(package_name);
209- if (downloads.size() > 1) {
210- qWarning() << "More than one download with the same object path";
211+ qDebug() << "Found object path" << QString::fromStdString(object_path)
212+ << "for package" << QString::fromStdString(package_name);
213+ if (downloads.size() > 1) {
214+ qWarning() << "More than one download with the same object path";
215+ }
216 }
217 callback(object_path);
218 }, [callback, package_name](const QString& /*key*/, const QString& /*value*/, DownloadsList* /*downloads_list*/){
219@@ -100,78 +94,44 @@
220 });
221 }
222
223-click::web::Cancellable DownloadManager::start(const std::string& url,
224- const std::string& download_sha512,
225- const std::string& package_name,
226- const std::function<void (std::string, Error)>& callback)
227-{
228- QSharedPointer<click::web::Response> response = client->call
229- (url, "HEAD", true);
230-
231- QObject::connect(response.data(), &click::web::Response::finished,
232- [this, callback, url, download_sha512, package_name,
233- response](QString) {
234- auto status = response->get_status_code();
235- if (status == 200) {
236- auto clickToken = response->get_header(CLICK_TOKEN_HEADER().data());
237- qDebug() << "Received click token:" << clickToken.c_str();
238- QVariantMap metadata;
239-
240- QVariant commandline = QVariant(QStringList() << DOWNLOAD_COMMAND << "$file" << package_name.c_str());
241- metadata[DOWNLOAD_COMMAND_KEY] = commandline;
242- metadata[DOWNLOAD_APP_ID_KEY] = package_name.c_str();
243- metadata["package_name"] = package_name.c_str();
244-
245- QMap<QString, QString> headers;
246- headers[CLICK_TOKEN_HEADER()] = clickToken.c_str();
247-
248- udm::DownloadStruct downloadStruct(url.c_str(),
249- download_sha512.c_str(),
250- DOWNLOAD_MANAGER_SHA512,
251- metadata,
252- headers);
253-
254- dm->createDownload(downloadStruct,
255- [callback](Download* download) {
256- if (download->isError()) {
257- auto error = download->error()->errorString().toUtf8().data();
258- qDebug() << "Received error from ubuntu-download-manager:" << error;
259- callback(error, Error::DownloadInstallError);
260- } else {
261- download->start();
262- callback(download->id().toUtf8().data(), Error::NoError);
263- }
264- },
265- [callback](Download* download) {
266- callback(download->error()->errorString().toUtf8().data(),
267- Error::DownloadInstallError);
268- });
269- } else {
270- std::string error{"Unhandled HTTP response code: "};
271- error += status;
272- callback(error, Error::DownloadInstallError);
273- }
274- });
275- QObject::connect(response.data(), &click::web::Response::error,
276- [this, callback, package_name](QString error, int error_code) {
277- qWarning() << QStringLiteral("Network error (%1) fetching click token for:").arg(error_code) << package_name.c_str();
278- switch(error_code) {
279- case 401:
280- case 403:
281- client->invalidateCredentials();
282- callback(error.toUtf8().data(), Error::CredentialsError);
283- break;
284- default:
285- callback(error.toUtf8().data(), Error::DownloadInstallError);
286- }
287- });
288-
289- return click::web::Cancellable(response);
290-}
291-
292-void DownloadManager::setCredentialsService(const QSharedPointer<click::CredentialsService>& credentialsService)
293-{
294- sso = credentialsService;
295+void DownloadManager::start(const std::string& url,
296+ const std::string& download_sha512,
297+ const std::string& package_name,
298+ const std::function<void (std::string, Error)>& callback)
299+{
300+ auto signature = client->signUrl(url, "GET");
301+
302+ QVariantMap metadata;
303+
304+ QVariant commandline = QVariant(QStringList() << DOWNLOAD_COMMAND << "$file" << package_name.c_str());
305+ metadata[DOWNLOAD_COMMAND_KEY] = commandline;
306+ metadata[DOWNLOAD_APP_ID_KEY] = package_name.c_str();
307+ metadata["package_name"] = package_name.c_str();
308+
309+ QMap<QString, QString> headers;
310+ headers[click::web::AUTHORIZATION_HEADER.c_str()] = signature.c_str();
311+
312+ udm::DownloadStruct downloadStruct(url.c_str(),
313+ download_sha512.c_str(),
314+ DOWNLOAD_MANAGER_SHA512,
315+ metadata,
316+ headers);
317+
318+ dm->createDownload(downloadStruct,
319+ [callback](Download* download) {
320+ if (download->isError()) {
321+ auto error = download->error()->errorString().toUtf8().data();
322+ qDebug() << "Received error from ubuntu-download-manager:" << error;
323+ callback(error, Error::DownloadInstallError);
324+ } else {
325+ download->start();
326+ callback(download->id().toUtf8().data(), Error::NoError);
327+ }
328+ },
329+ [callback](Download* download) {
330+ callback(download->error()->errorString().toUtf8().data(),
331+ Error::DownloadInstallError);
332+ });
333 }
334
335 } // namespace click
336
337=== modified file 'libclickscope/click/download-manager.h'
338--- libclickscope/click/download-manager.h 2016-02-26 18:51:22 +0000
339+++ libclickscope/click/download-manager.h 2016-08-24 21:39:08 +0000
340@@ -68,18 +68,14 @@
341
342 virtual void get_progress(const std::string& package_name,
343 const std::function<void (std::string)>& callback);
344- virtual click::web::Cancellable start(const std::string& url,
345- const std::string& download_sha512,
346- const std::string& package_name,
347- const std::function<void (std::string,
348- Error)>& callback);
349-
350- virtual void setCredentialsService(const QSharedPointer<click::CredentialsService>& credentialsService);
351+ virtual void start(const std::string& url,
352+ const std::string& download_sha512,
353+ const std::string& package_name,
354+ const std::function<void (std::string, Error)>& callback);
355
356 protected:
357 QSharedPointer<click::web::Client> client;
358 QSharedPointer<Ubuntu::DownloadManager::Manager> dm;
359- QSharedPointer<click::CredentialsService> sso;
360 };
361
362 }
363
364=== modified file 'libclickscope/click/index.cpp'
365--- libclickscope/click/index.cpp 2016-04-26 10:56:47 +0000
366+++ libclickscope/click/index.cpp 2016-08-24 21:39:08 +0000
367@@ -123,6 +123,15 @@
368 };
369 }
370
371+std::map<std::string, std::string> Index::add_snap_headers(const std::map<std::string, std::string>& headers) const
372+{
373+ std::map<std::string, std::string> new_headers{headers};
374+ new_headers["X-Ubuntu-Series"] = "16"; // Need to get from snapd
375+ new_headers["X-Ubuntu-Slots"] = "unity8"; // Only want unity8-using snaps
376+
377+ return new_headers;
378+}
379+
380 std::pair<Packages, Packages> Index::package_lists_from_json(const std::string& json)
381 {
382 Json::Reader reader;
383@@ -147,6 +156,36 @@
384 return std::pair<Packages, Packages>(pl, recommends);
385 }
386
387+click::web::Cancellable Index::search_snaps(const std::string& query,
388+ std::function<void(click::Packages search_results, click::Packages recommendations)> callback,
389+ bool force_cache)
390+{
391+ click::web::CallParams params;
392+ auto built_query = build_index_query(query, "" /* No dept for snaps */);
393+ params.add(click::QUERY_ARGNAME, built_query.c_str());
394+
395+ auto headers = add_snap_headers(build_headers());
396+
397+ QSharedPointer<click::web::Response> response
398+ (client->call(get_base_url() + click::SNAP_SEARCH_PATH,
399+ "GET", true, headers, "", params, force_cache));
400+
401+ QObject::connect(response.data(), &click::web::Response::finished, [=](QString reply) {
402+ std::pair<Packages, Packages> package_lists;
403+ package_lists = package_lists_from_json(reply.toUtf8().constData());
404+ callback(package_lists.first, package_lists.second);
405+ });
406+ QObject::connect(response.data(), &click::web::Response::error, [=](QString /*description*/) {
407+ qDebug() << "No packages found due to network error";
408+ click::Packages pl;
409+ click::Packages recommends;
410+ qDebug() << "calling callback";
411+ callback(pl, recommends);
412+ qDebug() << " ...Done!";
413+ });
414+ return click::web::Cancellable(response);
415+}
416+
417 click::web::Cancellable Index::search (const std::string& query, const std::string& department,
418 std::function<void(click::Packages search_results, click::Packages recommendations)> callback,
419 bool force_cache)
420@@ -215,10 +254,21 @@
421 return click::web::Cancellable(response);
422 }
423
424-click::web::Cancellable Index::get_details (const std::string& package_name, std::function<void(PackageDetails, click::Index::Error)> callback, bool force_cache)
425+click::web::Cancellable Index::get_details (const std::string& package_name,
426+ std::function<void(PackageDetails,
427+ click::Index::Error)> callback,
428+ bool is_snap,
429+ bool force_cache)
430 {
431+ std::string details_path{click::DETAILS_PATH};
432+ auto headers = build_headers();
433+ if (is_snap) {
434+ details_path = click::SNAP_DETAILS_PATH;
435+ headers = add_snap_headers(headers);
436+ }
437 QSharedPointer<click::web::Response> response = client->call
438- (get_base_url() + click::DETAILS_PATH + package_name,
439+ (get_base_url() + details_path + package_name,
440+ "GET", true, headers, "",
441 click::web::CallParams(),
442 force_cache);
443 qDebug() << "getting details for" << package_name.c_str();
444
445=== modified file 'libclickscope/click/index.h'
446--- libclickscope/click/index.h 2016-04-26 10:56:47 +0000
447+++ libclickscope/click/index.h 2016-08-24 21:39:08 +0000
448@@ -1,5 +1,5 @@
449 /*
450- * Copyright (C) 2014 Canonical Ltd.
451+ * Copyright (C) 2014-2016 Canonical Ltd.
452 *
453 * This program is free software: you can redistribute it and/or modify it
454 * under the terms of the GNU General Public License version 3, as published
455@@ -49,11 +49,13 @@
456 const std::string SEARCH_BASE_URL_ENVVAR = "U1_SEARCH_BASE_URL";
457 const std::string SEARCH_BASE_URL = "https://search.apps.ubuntu.com/";
458 const std::string SEARCH_PATH = "api/v1/search";
459+const std::string SNAP_SEARCH_PATH = "api/v1/snaps/search";
460 const std::string BOOTSTRAP_PATH = "api/v1";
461 const std::string SUPPORTED_FRAMEWORKS = "framework:ubuntu-sdk-13.10";
462 const std::string QUERY_ARGNAME = "q";
463 const std::string ARCHITECTURE = "architecture:";
464 const std::string DETAILS_PATH = "api/v1/package/";
465+const std::string SNAP_DETAILS_PATH = "api/v1/snaps/details/";
466 const std::string CURRENCY_HEADER = "X-Suggested-Currency";
467
468 class PackageManager
469@@ -72,6 +74,7 @@
470 std::string m_suggested_currency;
471 virtual std::string build_index_query(const std::string& query, const std::string& department);
472 virtual std::map<std::string, std::string> build_headers();
473+ virtual std::map<std::string, std::string> add_snap_headers(const std::map<std::string, std::string>& headers) const;
474
475 public:
476 enum class Error {NoError, CredentialsError, NetworkError};
477@@ -79,9 +82,15 @@
478 Index(const QSharedPointer<click::web::Client>& client,
479 const QSharedPointer<Configuration> configuration=QSharedPointer<Configuration>(new Configuration()));
480 virtual std::pair<Packages, Packages> package_lists_from_json(const std::string& json);
481+ virtual click::web::Cancellable search_snaps(const std::string& query,
482+ std::function<void(click::Packages search_results, click::Packages recommendations)> callback,
483+ bool force_cache = false);
484 virtual click::web::Cancellable search (const std::string& query, const std::string& department, std::function<void(Packages, Packages)> callback, bool
485 force_cache = false);
486- virtual click::web::Cancellable get_details(const std::string& package_name, std::function<void(PackageDetails, Error)> callback, bool force_cache = false);
487+ virtual click::web::Cancellable get_details(const std::string& package_name,
488+ std::function<void(PackageDetails, Error)> callback,
489+ bool is_snap = false,
490+ bool force_cache = false);
491 virtual click::web::Cancellable bootstrap(std::function<void(const DepartmentList&, const HighlightList&, Error, int)> callback, bool force_cache = false);
492 virtual click::web::Cancellable departments(const std::string& department_href, std::function<void(const DepartmentList&, const HighlightList&, Error, int)>
493 callback, bool force_cache = false);
494
495=== modified file 'libclickscope/click/interface.cpp'
496--- libclickscope/click/interface.cpp 2016-07-14 18:37:27 +0000
497+++ libclickscope/click/interface.cpp 2016-08-24 21:39:08 +0000
498@@ -1,5 +1,5 @@
499 /*
500- * Copyright (C) 2014 Canonical Ltd.
501+ * Copyright (C) 2014-2016 Canonical Ltd.
502 *
503 * This program is free software: you can redistribute it and/or modify it
504 * under the terms of the GNU General Public License version 3, as published
505@@ -27,6 +27,10 @@
506 * files in the program, then also delete it here.
507 */
508
509+#include <click.h>
510+
511+#include "interface.h"
512+
513 #include <QDebug>
514 #include <QDir>
515 #include <QProcess>
516@@ -51,12 +55,15 @@
517 #include <unity/UnityExceptions.h>
518 #include <unity/util/IniParser.h>
519
520-#include "interface.h"
521-#include <click/key_file_locator.h>
522 #include <click/departments-db.h>
523
524+#include <ubuntu-app-launch/registry.h>
525+
526 #include <click/click-i18n.h>
527
528+using namespace ubuntu::app_launch;
529+namespace ual = ubuntu::app_launch;
530+
531 namespace {
532
533 /* Thanks to
534@@ -122,114 +129,6 @@
535 static const std::string DESKTOP_FILE_ONLYSHOWIN("OnlyShowIn");
536 static const std::string ONLYSHOWIN_UNITY("Unity");
537
538-Interface::Interface(const QSharedPointer<click::KeyFileLocator>& keyFileLocator)
539- : keyFileLocator(keyFileLocator)
540-{
541-}
542-
543-Interface::~Interface()
544-{
545-}
546-
547-bool Interface::show_desktop_apps()
548-{
549- return getenv(ENV_SHOW_DESKTOP_APPS) != nullptr;
550-}
551-
552-bool Interface::is_visible_app(const unity::util::IniParser &keyFile)
553-{
554- if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_NODISPLAY)) {
555- auto val = keyFile.get_string(DESKTOP_FILE_GROUP, DESKTOP_FILE_NODISPLAY);
556- if (val == std::string("true")) {
557- return false;
558- }
559- }
560-
561- if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_ONLYSHOWIN)) {
562- auto value = keyFile.get_string(DESKTOP_FILE_GROUP, DESKTOP_FILE_ONLYSHOWIN);
563- std::stringstream ss(value);
564- std::string item;
565-
566- while (std::getline(ss, item, ';')) {
567- if (item == ONLYSHOWIN_UNITY) {
568- return true;
569- }
570- }
571- return false;
572- }
573-
574- return true;
575-}
576-
577-std::string Interface::get_translated_string(const unity::util::IniParser& keyFile,
578- const std::string& group,
579- const std::string& key,
580- const std::string& domain)
581-{
582- std::string language = Configuration().get_language();
583- if (!domain.empty()) {
584- return dgettext(domain.c_str(),
585- keyFile.get_string(group, key).c_str());
586- } else {
587- return keyFile.get_locale_string(group, key, language);
588- }
589-}
590-
591-click::Application Interface::load_app_from_desktop(const unity::util::IniParser& keyFile,
592- const std::string& filename)
593-{
594- Application app;
595- std::string domain;
596- if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_DOMAIN)) {
597- domain = keyFile.get_string(DESKTOP_FILE_GROUP,
598- DESKTOP_FILE_KEY_DOMAIN);
599- }
600- app.title = get_translated_string(keyFile,
601- DESKTOP_FILE_GROUP,
602- DESKTOP_FILE_KEY_NAME,
603- domain);
604-
605- app.url = "application:///" + filename;
606- if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_ICON)) {
607- app.icon_url = add_theme_scheme(keyFile.get_string(DESKTOP_FILE_GROUP,
608- DESKTOP_FILE_KEY_ICON));
609- }
610-
611- if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_KEYWORDS)) {
612- app.keywords = keyFile.get_string_array(DESKTOP_FILE_GROUP,
613- DESKTOP_FILE_KEY_KEYWORDS);
614- }
615-
616- if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_UBUNTU_DEFAULT_DEPARTMENT)) {
617- app.default_department = keyFile.get_string(DESKTOP_FILE_GROUP, DESKTOP_FILE_UBUNTU_DEFAULT_DEPARTMENT);
618- }
619-
620- if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_APP_ID)) {
621- QString app_id = QString::fromStdString(keyFile.get_string(
622- DESKTOP_FILE_GROUP,
623- DESKTOP_FILE_KEY_APP_ID));
624- QStringList id = app_id.split("_", QString::SkipEmptyParts);
625- if (id.length() == 3) {
626- app.name = id[0].toUtf8().data();
627- app.version = id[2].toUtf8().data();
628- app.url = "appid://" + id[0].toStdString() + "/" + id[1].toStdString() + "/current-user-version";
629- } else {
630- app.name = "unknown";
631- app.version = "unknown";
632- }
633- }
634- if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_COMMENT)) {
635- app.description = get_translated_string(keyFile,
636- DESKTOP_FILE_GROUP,
637- DESKTOP_FILE_COMMENT,
638- domain);
639- }
640- if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_SCREENSHOT)) {
641- app.main_screenshot = keyFile.get_string(DESKTOP_FILE_GROUP,
642- DESKTOP_FILE_SCREENSHOT);
643- }
644- return app;
645-}
646
647 std::vector<click::Application> Interface::sort_apps(const std::vector<click::Application>& apps)
648 {
649@@ -264,11 +163,16 @@
650 return result;
651 }
652
653-/* find_installed_apps()
654+std::list<std::shared_ptr<ual::Application>> Interface::installed_apps()
655+{
656+ return ual::Registry::installedApps();
657+}
658+
659+/* search()
660 *
661- * Find all of the installed apps matching @search_query in a timeout.
662+ * Find all of the installed apps matching @query in a timeout.
663 */
664-std::vector<click::Application> Interface::find_installed_apps(const std::string& search_query,
665+std::vector<click::Application> Interface::search(const std::string& query,
666 const std::vector<std::string>& ignored_apps,
667 const std::string& current_department,
668 const std::shared_ptr<click::DepartmentsDb>& depts_db)
669@@ -292,118 +196,109 @@
670 }
671 }
672
673- std::vector<Application> result;
674-
675- bool include_desktop_results = show_desktop_apps();
676- auto enumerator = [&result, this, search_query, ignored_apps, current_department, packages_in_department, apply_department_filter, include_desktop_results, depts_db]
677- (const unity::util::IniParser& keyFile, const std::string& filename)
678- {
679- if (keyFile.has_group(DESKTOP_FILE_GROUP) == false) {
680- qWarning() << "Broken desktop file:" << QString::fromStdString(filename);
681- return;
682- }
683- if (is_visible_app(keyFile) == false) {
684- return; // from the enumerator lambda
685- }
686-
687- if (include_desktop_results || keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_UBUNTU_TOUCH)
688- || keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_APP_ID)
689- || Interface::is_non_click_app(QString::fromStdString(filename))) {
690- auto app = load_app_from_desktop(keyFile, filename);
691- auto app_id = app.name.empty() ? filename : app.name;
692- if (!ignored_apps.empty() &&
693- std::find(ignored_apps.begin(), ignored_apps.end(),
694- app_id) != ignored_apps.end())
695- {
696- // The app is ignored. Get out of here.
697- return;
698- }
699-
700- // app from click package has non-empty name; for non-click apps use desktop filename
701- const std::string department_key = app.name.empty() ? filename : app.name;
702-
703- // check if apps is present in current department
704- if (apply_department_filter)
705- {
706- if (packages_in_department.find(department_key) == packages_in_department.end())
707- {
708- if (app.default_department.empty())
709- {
710- // default department not present in the keyfile, skip this app
711- return;
712- }
713- else
714- {
715- // default department not empty: check if this app is in a different
716- // department in the db (i.e. got moved from the default department);
717- if (depts_db->has_package(department_key))
718- {
719- // app is now in a different department
720- return;
721- }
722-
723- if (app.default_department != current_department)
724- {
725- return;
726- }
727- // else - this package is in current department
728- }
729- }
730- }
731-
732- //
733- // the packages_in_department set contains packages from
734- // all its subdepartments; we need to find actual department now
735- // to update app.real_department.
736- if (depts_db)
737- {
738- if (depts_db->has_package(department_key))
739- {
740- try
741- {
742- app.real_department = depts_db->get_department_for_package(department_key);
743- }
744- catch (const std::exception &e)
745- {
746- qWarning() << "Failed to get department of package:" << QString::fromStdString(department_key);
747- }
748- }
749- else
750- {
751- app.real_department = app.default_department;
752- if (app.real_department.empty())
753- {
754- qWarning() << "No default department set in the .desktop file and no entry in the database for" << QString::fromStdString(department_key);
755- }
756- }
757- }
758-
759- if (search_query.empty()) {
760+ std::vector<click::Application> result;
761+
762+ for (auto ualapp: installed_apps()) {
763+ click::Application app;
764+
765+ // Get the package name and APP_ID info.
766+ app.name = ualapp->appId().package.value();
767+ if (app.name.empty()) {
768+ app.name = std::string{ualapp->appId().appname.value()} + ".desktop";
769+ app.url = "application:///" + app.name;
770+ if (!is_non_click_app(app.name)) {
771+ qDebug() << "Skipping legacy app:" << QString::fromStdString(app.name);
772+ continue;
773+ }
774+ } else {
775+ app.url = "appid://" + app.name + "/" + ualapp->appId().appname.value() + "/current-user-version";
776+ }
777+
778+ if (!ignored_apps.empty() &&
779+ std::find(ignored_apps.begin(), ignored_apps.end(),
780+ app.name) != ignored_apps.end()) {
781+ // The app is ignored. Get out of here.
782+ qDebug() << "App is ignored, skipping:" << QString::fromStdString(app.name);
783+ continue;
784+ }
785+
786+ // Get the .desktop file info from UAL, since we're not ignoring
787+ auto appinfo = ualapp->info();
788+ app.title = appinfo->name();
789+ app.description = appinfo->description();
790+ app.icon_url = appinfo->iconPath();
791+ app.default_department = appinfo->defaultDepartment();
792+ app.main_screenshot = appinfo->screenshotPath();
793+ app.keywords = appinfo->keywords();
794+
795+ // app from click package has non-empty name; for non-click apps use desktop filename
796+ auto department_key = app.name;
797+ qDebug() << "Using department key:" << QString::fromStdString(department_key);
798+
799+ // check if apps is present in current department
800+ if (apply_department_filter) {
801+ if (packages_in_department.find(department_key) ==
802+ packages_in_department.end()) {
803+ if (app.default_department.empty()) {
804+ // default department not present in the keyfile, skip this app
805+ continue;
806+ } else {
807+ // default department not empty: check if this app is in a different
808+ // department in the db (i.e. got moved from the default department);
809+ if (depts_db->has_package(department_key)) {
810+ // app is now in a different department
811+ continue;
812+ }
813+
814+ if (app.default_department != current_department) {
815+ continue;
816+ }
817+ // else - this package is in current department
818+ }
819+ }
820+ }
821+
822+ // the packages_in_department set contains packages from
823+ // all its subdepartments; we need to find actual department now
824+ // to update app.real_department.
825+ if (depts_db) {
826+ if (depts_db->has_package(department_key)) {
827+ try {
828+ app.real_department = depts_db->get_department_for_package(department_key);
829+ } catch (const std::exception &e) {
830+ qWarning() << "Failed to get department of package:" << QString::fromStdString(department_key);
831+ }
832+ } else {
833+ app.real_department = app.default_department;
834+ if (app.real_department.empty()) {
835+ qWarning() << "No default department set in the .desktop file and no entry in the database for" << QString::fromStdString(department_key);
836+ }
837+ }
838+ }
839+
840+ if (query.empty()) {
841+ result.push_back(app);
842+ } else {
843+ QString lquery = ::unaccent(QString::fromStdString(query));
844+
845+ // Check keywords for the search query as well.
846+ for (auto kwd: app.keywords) {
847+ QString keyword = ::unaccent(QString::fromStdString(kwd));
848+ if (!keyword.isEmpty()
849+ && keyword.contains(lquery, Qt::CaseInsensitive)) {
850+ result.push_back(app);
851+ }
852+ }
853+
854+ QString search_title = ::unaccent(QString::fromStdString(app.title));
855+ // check the app title for the search query.
856+ if (!search_title.isEmpty()
857+ && search_title.contains(lquery, Qt::CaseInsensitive)) {
858 result.push_back(app);
859- } else {
860- QString lquery = ::unaccent(QString::fromStdString(search_query));
861-
862- // Check keywords for the search query as well.
863- for (auto kwd: app.keywords) {
864- QString keyword = ::unaccent(QString::fromStdString(kwd));
865- if (!keyword.isEmpty()
866- && keyword.contains(lquery, Qt::CaseInsensitive)) {
867- result.push_back(app);
868- return;
869- }
870- }
871-
872- QString search_title = ::unaccent(QString::fromStdString(app.title));
873- // check the app title for the search query.
874- if (!search_title.isEmpty()
875- && search_title.contains(lquery, Qt::CaseInsensitive)) {
876- result.push_back(app);
877- }
878 }
879 }
880- };
881+ }
882
883- keyFileLocator->enumerateKeyFilesForInstalledApplications(enumerator);
884 return sort_apps(result);
885 }
886
887@@ -412,9 +307,9 @@
888 * Tests that @filename is one of the special-cased filenames for apps
889 * which are not packaged as clicks, but required on Ubuntu Touch.
890 */
891-bool Interface::is_non_click_app(const QString& filename)
892+bool Interface::is_non_click_app(const std::string& app_id)
893 {
894- return click::nonClickDesktopFiles().count(filename.toUtf8().data()) > 0;
895+ return click::nonClickDesktopFiles().count(app_id) > 0;
896 }
897
898 /*
899@@ -440,42 +335,6 @@
900 return icon_id;
901 }
902
903-ManifestList manifest_list_from_json(const std::string& json)
904-{
905- using namespace boost::property_tree;
906-
907- std::istringstream is(json);
908-
909- ptree pt;
910- read_json(is, pt);
911-
912- ManifestList manifests;
913-
914- BOOST_FOREACH(ptree::value_type &v, pt)
915- {
916- assert(v.first.empty()); // array elements have no names
917- auto node = v.second;
918- Manifest manifest;
919-
920- manifest.name = node.get<std::string>("name");
921- manifest.version = node.get<std::string>("version");
922- manifest.removable = node.get<bool>("_removable");
923-
924- BOOST_FOREACH(ptree::value_type &sv, node.get_child("hooks"))
925- {
926- // FIXME: "primary app" for a package is not defined, we just
927- // use first one here:
928- manifest.first_app_name = sv.first;
929- break;
930- }
931- qDebug() << "adding manifest: " << manifest.name.c_str() << manifest.version.c_str() << manifest.first_app_name.c_str();
932-
933- manifests.push_back(manifest);
934- }
935-
936- return manifests;
937-}
938-
939 Manifest manifest_from_json(const std::string& json)
940 {
941 using namespace boost::property_tree;
942@@ -509,124 +368,62 @@
943 return manifest;
944 }
945
946-void Interface::get_manifests(std::function<void(ManifestList, InterfaceError)> callback)
947-{
948- std::string command = "click list --manifest";
949- qDebug() << "Running command:" << command.c_str();
950- run_process(command, [callback](int code, const std::string& stdout_data, const std::string& stderr_data) {
951- if (code == 0) {
952- try {
953- ManifestList manifests = manifest_list_from_json(stdout_data);
954- callback(manifests, InterfaceError::NoError);
955- } catch (...) {
956- qWarning() << "Can't parse 'click list --manifest' output: " << QString::fromStdString(stdout_data);
957- callback(ManifestList(), InterfaceError::ParseError);
958- }
959- } else {
960- qWarning() << "Error" << code << "running 'click list --manifest': " << QString::fromStdString(stderr_data);
961- callback(ManifestList(), InterfaceError::CallError);
962- }
963- });
964-}
965-
966-PackageSet package_names_from_stdout(const std::string& stdout_data)
967-{
968- const char TAB='\t', NEWLINE='\n';
969- std::istringstream iss(stdout_data);
970- PackageSet installed_packages;
971-
972- while (iss.peek() != EOF) {
973- std::string line;
974- std::getline(iss, line, NEWLINE);
975-
976- if (!line.empty()) {
977- // Must initialize linestream after line is filled.
978- std::istringstream linestream(line);
979-
980- Package p;
981- std::getline(linestream, p.name, TAB);
982- std::getline(linestream, p.version);
983- if (iss.eof() || p.name.empty() || p.version.empty()) {
984- qWarning() << "Error encountered parsing 'click list' output:" << QString::fromStdString(line);
985- } else {
986- installed_packages.insert(p);
987- }
988- }
989- }
990-
991- return installed_packages;
992-}
993-
994 void Interface::get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback)
995 {
996- std::string command = "click list";
997- qDebug() << "Running command:" << command.c_str();
998- run_process(command, [callback](int code, const std::string& stdout_data, const std::string& stderr_data) {
999- if (code == 0) {
1000- try {
1001- PackageSet package_names = package_names_from_stdout(stdout_data);
1002- callback(package_names, InterfaceError::NoError);
1003- } catch (...) {
1004- qWarning() << "Can't parse 'click list' output: " << QString::fromStdString(stdout_data);
1005- callback(PackageSet(), InterfaceError::ParseError);
1006- }
1007- } else {
1008- qWarning() << "Error" << code << "running 'click list': " << QString::fromStdString(stderr_data);
1009- callback(PackageSet(), InterfaceError::CallError);
1010+ PackageSet packages;
1011+ for (auto app: installed_apps()) {
1012+ Package p;
1013+ p.name = app->appId().package.value();
1014+ p.version = app->appId().version.value();
1015+ if (!p.name.empty() && !p.version.empty()) {
1016+ packages.insert(p);
1017 }
1018- });
1019+ }
1020+ callback(packages, InterfaceError::NoError);
1021+}
1022+
1023+std::string Interface::get_manifest_json(const std::string &package)
1024+{
1025+ GError* error = NULL;
1026+
1027+ auto clickdb = click_db_new();
1028+ click_db_read(clickdb, NULL, &error);
1029+ if (error != NULL) {
1030+ qCritical() << "Error reading click DB:" << error->message;
1031+ g_error_free(error);
1032+ return "";
1033+ }
1034+
1035+ auto clickuser = click_user_new_for_user(clickdb, NULL, &error);
1036+ if (error != NULL) {
1037+ qCritical() << "Error setting up click user:" << error->message;
1038+ g_error_free(error);
1039+ return "";
1040+ }
1041+
1042+ auto result = click_user_get_manifest_as_string(clickuser, package.c_str(),
1043+ &error);
1044+ if (error != NULL) {
1045+ qCritical() << "Error getting manifest:" << error->message;
1046+ g_error_free(error);
1047+ return "";
1048+ }
1049+
1050+ std::string retval{result};
1051+ g_free(result);
1052+ return retval;
1053 }
1054
1055 void Interface::get_manifest_for_app(const std::string &app_id,
1056 std::function<void(Manifest, InterfaceError)> callback)
1057 {
1058- std::string command = "click info " + app_id;
1059- qDebug() << "Running command:" << command.c_str();
1060- run_process(command, [callback, app_id](int code, const std::string& stdout_data, const std::string& stderr_data) {
1061- if (code == 0) {
1062- try {
1063- Manifest manifest = manifest_from_json(stdout_data);
1064- callback(manifest, InterfaceError::NoError);
1065- } catch (...) {
1066- qWarning() << "Can't parse 'click info" << QString::fromStdString(app_id)
1067- << "' output: " << QString::fromStdString(stdout_data);
1068- callback(Manifest(), InterfaceError::ParseError);
1069- }
1070- } else {
1071- qWarning() << "Error" << code << "running 'click info" << QString::fromStdString(app_id)
1072- << "': " << QString::fromStdString(stderr_data);
1073- callback(Manifest(), InterfaceError::CallError);
1074- }
1075- });
1076-}
1077-
1078-void Interface::run_process(const std::string& command,
1079- std::function<void(int code,
1080- const std::string& stdout_data,
1081- const std::string& stderr_data)> callback)
1082-{
1083- QSharedPointer<QProcess> process(new QProcess());
1084- typedef void(QProcess::*QProcessFinished)(int, QProcess::ExitStatus);
1085- typedef void(QProcess::*QProcessError)(QProcess::ProcessError);
1086- QObject::connect(process.data(),
1087- static_cast<QProcessFinished>(&QProcess::finished),
1088- [callback, process](int code, QProcess::ExitStatus /*status*/) {
1089- qDebug() << "command finished with exit code:" << code;
1090- std::string data{process->readAllStandardOutput().data()};
1091- std::string errors{process->readAllStandardError().data()};
1092- callback(code, data, errors);
1093- } );
1094-
1095- QObject::connect(process.data(),
1096- static_cast<QProcessError>(&QProcess::error),
1097- [callback, process](QProcess::ProcessError error) {
1098- qCritical() << "error running command:" << error;
1099- std::string data{process->readAllStandardOutput().data()};
1100- std::string errors{process->readAllStandardError().data()};
1101- callback(process->exitCode(), data, errors);
1102- } );
1103-
1104- process->start(command.c_str());
1105+ try {
1106+ Manifest manifest = manifest_from_json(get_manifest_json(app_id));
1107+ callback(manifest, InterfaceError::NoError);
1108+ } catch (...) {
1109+ qWarning() << "Can't parse manifest for:" << QString::fromStdString(app_id);
1110+ callback(Manifest(), InterfaceError::ParseError);
1111+ }
1112 }
1113
1114 } // namespace click
1115
1116=== modified file 'libclickscope/click/interface.h'
1117--- libclickscope/click/interface.h 2016-07-14 18:37:27 +0000
1118+++ libclickscope/click/interface.h 2016-08-24 21:39:08 +0000
1119@@ -1,5 +1,5 @@
1120 /*
1121- * Copyright (C) 2014 Canonical Ltd.
1122+ * Copyright (C) 2014-2016 Canonical Ltd.
1123 *
1124 * This program is free software: you can redistribute it and/or modify it
1125 * under the terms of the GNU General Public License version 3, as published
1126@@ -30,15 +30,19 @@
1127 #ifndef CLICK_INTERFACE_H
1128 #define CLICK_INTERFACE_H
1129
1130-#include <QObject>
1131-#include <QStringList>
1132+#include "application.h"
1133+#include "package.h"
1134+
1135+#include <ubuntu-app-launch/application.h>
1136+
1137 #include <unity/util/IniParser.h>
1138
1139+#include <memory>
1140+#include <unordered_set>
1141 #include <vector>
1142-#include <unordered_set>
1143
1144-#include "application.h"
1145-#include "package.h"
1146+using namespace ubuntu::app_launch;
1147+namespace ual = ubuntu::app_launch;
1148
1149 namespace click
1150 {
1151@@ -74,46 +78,28 @@
1152 enum class InterfaceError {NoError, CallError, ParseError};
1153 typedef std::list<Manifest> ManifestList;
1154
1155-ManifestList manifest_list_from_json(const std::string& json);
1156 Manifest manifest_from_json(const std::string& json);
1157-PackageSet package_names_from_stdout(const std::string& stdout_data);
1158
1159 class Interface
1160 {
1161 public:
1162- Interface(const QSharedPointer<KeyFileLocator>& keyFileLocator);
1163 Interface() = default;
1164- virtual ~Interface();
1165+ virtual ~Interface() = default;
1166
1167- virtual std::string get_translated_string(const unity::util::IniParser& keyFile,
1168- const std::string& group,
1169- const std::string& key,
1170- const std::string& domain);
1171- virtual Application load_app_from_desktop(const unity::util::IniParser& keyFile,
1172- const std::string& filename);
1173 static std::vector<Application> sort_apps(const std::vector<Application>& apps);
1174- virtual std::vector<Application> find_installed_apps(const std::string& search_query,
1175+ virtual std::list<std::shared_ptr<ual::Application>> installed_apps();
1176+ virtual std::vector<Application> search(const std::string& query,
1177 const std::vector<std::string>& ignored_apps = std::vector<std::string>{},
1178 const std::string& current_department = "",
1179 const std::shared_ptr<click::DepartmentsDb>& depts_db = nullptr);
1180
1181- static bool is_non_click_app(const QString& filename);
1182+ static bool is_non_click_app(const std::string& app_id);
1183
1184 static bool is_icon_identifier(const std::string &icon_id);
1185 static std::string add_theme_scheme(const std::string &filename);
1186- virtual void get_manifests(std::function<void(ManifestList, InterfaceError)> callback);
1187 virtual void get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback);
1188+ virtual std::string get_manifest_json(const std::string &package);
1189 virtual void get_manifest_for_app(const std::string &app_id, std::function<void(Manifest, InterfaceError)> callback);
1190- constexpr static const char* ENV_SHOW_DESKTOP_APPS {"CLICK_SCOPE_SHOW_DESKTOP_APPS"};
1191- virtual bool is_visible_app(const unity::util::IniParser& keyFile);
1192- virtual bool show_desktop_apps();
1193-
1194- virtual void run_process(const std::string& command,
1195- std::function<void(int code,
1196- const std::string& stdout_data,
1197- const std::string& stderr_data)> callback);
1198-private:
1199- QSharedPointer<KeyFileLocator> keyFileLocator;
1200 };
1201
1202 } // namespace click
1203
1204=== removed file 'libclickscope/click/key_file_locator.cpp'
1205--- libclickscope/click/key_file_locator.cpp 2015-11-24 18:23:23 +0000
1206+++ libclickscope/click/key_file_locator.cpp 1970-01-01 00:00:00 +0000
1207@@ -1,94 +0,0 @@
1208-/*
1209- * Copyright (C) 2014 Canonical Ltd.
1210- *
1211- * This program is free software: you can redistribute it and/or modify it
1212- * under the terms of the GNU General Public License version 3, as published
1213- * by the Free Software Foundation.
1214- *
1215- * This program is distributed in the hope that it will be useful, but
1216- * WITHOUT ANY WARRANTY; without even the implied warranties of
1217- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1218- * PURPOSE. See the GNU General Public License for more details.
1219- *
1220- * You should have received a copy of the GNU General Public License along
1221- * with this program. If not, see <http://www.gnu.org/licenses/>.
1222- *
1223- * In addition, as a special exception, the copyright holders give
1224- * permission to link the code of portions of this program with the
1225- * OpenSSL library under certain conditions as described in each
1226- * individual source file, and distribute linked combinations
1227- * including the two.
1228- * You must obey the GNU General Public License in all respects
1229- * for all of the code used other than OpenSSL. If you modify
1230- * file(s) with this exception, you may extend this exception to your
1231- * version of the file(s), but you are not obligated to do so. If you
1232- * do not wish to do so, delete this exception statement from your
1233- * version. If you delete this exception statement from all source
1234- * files in the program, then also delete it here.
1235- */
1236-
1237-#include "key_file_locator.h"
1238-
1239-#include <unity/Exception.h>
1240-#include <unity/UnityExceptions.h>
1241-#include <unity/util/IniParser.h>
1242-
1243-#include <QDebug>
1244-#include <QDir>
1245-#include <QStandardPaths>
1246-#include <QString>
1247-
1248-namespace
1249-{
1250-static const QString NON_CLICK_PATH("/usr/share/applications");
1251-
1252-void find_apps_in_dir(const QString& dir_path,
1253- const click::KeyFileLocator::Enumerator& enumerator)
1254-{
1255- QDir dir(dir_path, "*.desktop",
1256- QDir::Unsorted, QDir::Readable | QDir::Files);
1257- QStringList entries = dir.entryList();
1258- for (int i = 0; i < entries.size(); ++i) {
1259- QString filename = entries.at(i);
1260- QString full_path = dir.absoluteFilePath(filename);
1261- try {
1262- enumerator(unity::util::IniParser(full_path.toUtf8().data()),
1263- filename.toUtf8().data());
1264- } catch (const unity::FileException& file_exp) {
1265- qWarning() << "Error reading file:" << file_exp.to_string().c_str();
1266- } catch (const unity::LogicException& logic_exp) {
1267- qCritical() << "Error reading file:" << logic_exp.to_string().c_str();
1268- }
1269- }
1270-}
1271-}
1272-
1273-const std::string& click::KeyFileLocator::systemApplicationsDirectory()
1274-{
1275- static const std::string s{"/usr/share/applications"};
1276- return s;
1277-}
1278-
1279-const std::string& click::KeyFileLocator::userApplicationsDirectory()
1280-{
1281- static const std::string s
1282- {
1283- qPrintable(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/applications")
1284- };
1285- return s;
1286-}
1287-
1288-click::KeyFileLocator::KeyFileLocator(
1289- const std::string& systemApplicationsDir,
1290- const std::string& userApplicationsDir)
1291- : systemApplicationsDir(systemApplicationsDir),
1292- userApplicationsDir(userApplicationsDir)
1293-{
1294-}
1295-
1296-void click::KeyFileLocator::enumerateKeyFilesForInstalledApplications(
1297- const click::KeyFileLocator::Enumerator& enumerator)
1298-{
1299- find_apps_in_dir(QString::fromStdString(systemApplicationsDir), enumerator);
1300- find_apps_in_dir(QString::fromStdString(userApplicationsDir), enumerator);
1301-}
1302
1303=== removed file 'libclickscope/click/key_file_locator.h'
1304--- libclickscope/click/key_file_locator.h 2014-05-13 19:32:29 +0000
1305+++ libclickscope/click/key_file_locator.h 1970-01-01 00:00:00 +0000
1306@@ -1,70 +0,0 @@
1307-/*
1308- * Copyright (C) 2014 Canonical Ltd.
1309- *
1310- * This program is free software: you can redistribute it and/or modify it
1311- * under the terms of the GNU General Public License version 3, as published
1312- * by the Free Software Foundation.
1313- *
1314- * This program is distributed in the hope that it will be useful, but
1315- * WITHOUT ANY WARRANTY; without even the implied warranties of
1316- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1317- * PURPOSE. See the GNU General Public License for more details.
1318- *
1319- * You should have received a copy of the GNU General Public License along
1320- * with this program. If not, see <http://www.gnu.org/licenses/>.
1321- *
1322- * In addition, as a special exception, the copyright holders give
1323- * permission to link the code of portions of this program with the
1324- * OpenSSL library under certain conditions as described in each
1325- * individual source file, and distribute linked combinations
1326- * including the two.
1327- * You must obey the GNU General Public License in all respects
1328- * for all of the code used other than OpenSSL. If you modify
1329- * file(s) with this exception, you may extend this exception to your
1330- * version of the file(s), but you are not obligated to do so. If you
1331- * do not wish to do so, delete this exception statement from your
1332- * version. If you delete this exception statement from all source
1333- * files in the program, then also delete it here.
1334- */
1335-
1336-#ifndef CLICK_KEY_FILE_LOCATOR_H
1337-#define CLICK_KEY_FILE_LOCATOR_H
1338-
1339-#include <functional>
1340-#include <string>
1341-
1342-namespace unity
1343-{
1344-namespace util
1345-{
1346-class IniParser;
1347-}
1348-}
1349-
1350-namespace click
1351-{
1352-class KeyFileLocator
1353-{
1354-public:
1355- static const std::string& systemApplicationsDirectory();
1356- static const std::string& userApplicationsDirectory();
1357-
1358- typedef std::function<void(const unity::util::IniParser&, const std::string&)> Enumerator;
1359-
1360- KeyFileLocator(const std::string& systemApplicationsDir = systemApplicationsDirectory(),
1361- const std::string& userApplicationsDir = userApplicationsDirectory());
1362- KeyFileLocator(const KeyFileLocator&) = delete;
1363- virtual ~KeyFileLocator() = default;
1364-
1365- KeyFileLocator& operator=(const KeyFileLocator&) = delete;
1366- bool operator==(const KeyFileLocator&) const = delete;
1367-
1368- virtual void enumerateKeyFilesForInstalledApplications(const Enumerator& enumerator);
1369-
1370-private:
1371- std::string systemApplicationsDir;
1372- std::string userApplicationsDir;
1373-};
1374-}
1375-
1376-#endif // CLICK_KEY_FILE_LOCATOR_H
1377
1378=== modified file 'libclickscope/click/package.cpp'
1379--- libclickscope/click/package.cpp 2015-11-24 18:23:23 +0000
1380+++ libclickscope/click/package.cpp 2016-08-24 21:39:08 +0000
1381@@ -95,6 +95,10 @@
1382 p.publisher = item[Package::JsonKeys::publisher].asString();
1383 p.rating = item[Package::JsonKeys::rating].asDouble();
1384 p.version = item[Package::JsonKeys::version].asString();
1385+
1386+ p.snap_id = item[Package::JsonKeys::snap_id].asString();
1387+ p.alias = item[Package::JsonKeys::alias].asString();
1388+
1389 return p;
1390 }
1391
1392
1393=== modified file 'libclickscope/click/package.h'
1394--- libclickscope/click/package.h 2015-11-24 18:23:23 +0000
1395+++ libclickscope/click/package.h 2016-08-24 21:39:08 +0000
1396@@ -64,6 +64,8 @@
1397 constexpr static const char* publisher{"publisher"};
1398 constexpr static const char* rating{"ratings_average"};
1399 constexpr static const char* version{"version"};
1400+ constexpr static const char* snap_id{"snap_id"};
1401+ constexpr static const char* alias{"alias"};
1402
1403 // NOTE: The "price" field is deprecated in favor of "prices"
1404 constexpr static const char* prices{"prices"};
1405@@ -107,6 +109,8 @@
1406 void matches (std::string query, std::function<bool> callback);
1407 std::string content;
1408 std::map<std::string, double> prices;
1409+ std::string snap_id;
1410+ std::string alias;
1411
1412 struct hash_name {
1413 public :
1414
1415=== modified file 'libclickscope/click/preview.cpp'
1416--- libclickscope/click/preview.cpp 2016-07-18 15:38:22 +0000
1417+++ libclickscope/click/preview.cpp 2016-08-24 21:39:08 +0000
1418@@ -413,6 +413,9 @@
1419 }
1420 }
1421
1422+// Need to use this in a couple places, so it's a static const.
1423+static const std::regex desktop_match("^(.*)\\.desktop$");
1424+
1425 // TODO: error handling - once get_details provides errors, we can
1426 // return them from populateDetails and check them in the calling code
1427 // to decide whether to show error widgets. see bug LP: #1289541
1428@@ -422,8 +425,9 @@
1429 {
1430
1431 std::string app_name = get_string_maybe_null(result["name"]);
1432+ std::string snap_id = get_string_maybe_null(result["snap_id"]);
1433
1434- if (app_name.empty()) {
1435+ if (app_name.empty() || std::regex_match(app_name, desktop_match)) {
1436 click::PackageDetails details;
1437 qDebug() << "in populateDetails(), app_name is empty";
1438 details.package.title = result.title();
1439@@ -437,9 +441,13 @@
1440 // I think this should not be required when we switch the click::Index over
1441 // to using the Qt bridge. With that, the qt dependency becomes an implementation detail
1442 // and code using it does not need to worry about threading/event loop topics.
1443- run_under_qt([this, details_callback, reviews_callback, app_name, force_cache]()
1444+ run_under_qt([this, details_callback, reviews_callback, app_name, snap_id, force_cache]()
1445 {
1446- index_operation = index->get_details(app_name, [this, app_name, details_callback, reviews_callback, force_cache](PackageDetails details, click::Index::Error error){
1447+ index_operation = index->get_details(app_name,
1448+ [this, app_name, snap_id,
1449+ details_callback,
1450+ reviews_callback,
1451+ force_cache](PackageDetails details, click::Index::Error error){
1452 if(error == click::Index::Error::NoError) {
1453 qDebug() << "Got details:" << app_name.c_str();
1454 details_callback(details);
1455@@ -452,10 +460,17 @@
1456 details.main_screenshot_url = get_string_maybe_null(result["main_screenshot"]);
1457 details_callback(details);
1458 }
1459- reviews_operation = reviews->fetch_reviews(app_name,
1460- reviews_callback,
1461- force_cache);
1462- }, force_cache);
1463+ // FIXME: No RNR support for v2 snaps yet, so avoid the
1464+ // network hit if we're showing a snap preview
1465+ if (snap_id.empty()) {
1466+ reviews_operation = reviews->fetch_reviews(app_name,
1467+ reviews_callback,
1468+ force_cache);
1469+ } else {
1470+ reviews_callback(click::ReviewList{},
1471+ click::Reviews::Error::NoError);
1472+ }
1473+ }, !snap_id.empty(), force_cache);
1474 });
1475 }
1476 }
1477@@ -900,7 +915,7 @@
1478 std::promise<Manifest> manifest_promise;
1479 std::future<Manifest> manifest_future = manifest_promise.get_future();
1480 std::string app_name = result["name"].get_string();
1481- if (!app_name.empty()) {
1482+ if (!app_name.empty() && !std::regex_match(app_name, desktop_match)) {
1483 qt::core::world::enter_with_task([&]() {
1484 click::Interface().get_manifest_for_app(app_name,
1485 [&](Manifest found_manifest, InterfaceError error) {
1486
1487=== modified file 'libclickscope/click/webclient.cpp'
1488--- libclickscope/click/webclient.cpp 2016-05-25 16:19:51 +0000
1489+++ libclickscope/click/webclient.cpp 2016-08-24 21:39:08 +0000
1490@@ -78,6 +78,26 @@
1491 {
1492 }
1493
1494+std::string click::web::Client::signUrl(const std::string& url,
1495+ const std::string& method)
1496+{
1497+ QString signature;
1498+
1499+ if (impl->sso.isNull()) {
1500+ qCritical() << "Unable to sign request without SSO object.";
1501+ } else {
1502+ auto token = impl->sso->getToken();
1503+ if (token.isValid()) {
1504+ signature = token.signUrl(QString::fromStdString(url),
1505+ QString::fromStdString(method));
1506+ qDebug() << "Signed URL:" << QString::fromStdString(url);
1507+ } else {
1508+ qWarning() << "Signing requested but returned token is invalid.";
1509+ }
1510+ }
1511+ return signature.toStdString();
1512+}
1513+
1514 QSharedPointer<click::web::Response> click::web::Client::call(
1515 const std::string& iri,
1516 const click::web::CallParams& params,
1517@@ -137,25 +157,14 @@
1518 auto deviceId = Configuration().get_device_id();
1519 request->setRawHeader(DEVICE_ID_HEADER.c_str(), deviceId.data());
1520
1521- if (sign && !impl->sso.isNull()) {
1522- auto token = impl->sso->getToken();
1523- if (token.isValid()) {
1524- QString auth_header = token.signUrl(url.toString(),
1525- method.c_str());
1526- qDebug() << "Signed URL:" << request->url().toString();
1527- request->setRawHeader(AUTHORIZATION_HEADER.c_str(), auth_header.toUtf8());
1528- } else {
1529- qWarning() << "Signing reuested but returned token is invalid.";
1530- }
1531-
1532- doConnect();
1533- } else {
1534- if (sign && impl->sso.isNull()) {
1535- qCritical() << "Unable to sign request without SSO object.";
1536- }
1537- doConnect();
1538+ if (sign) {
1539+ auto auth_header = signUrl(url.toString().toStdString(), method);
1540+ if (!auth_header.empty())
1541+ request->setRawHeader(AUTHORIZATION_HEADER.c_str(),
1542+ auth_header.c_str());
1543 }
1544
1545+ doConnect();
1546
1547 return responsePtr;
1548 }
1549
1550=== modified file 'libclickscope/click/webclient.h'
1551--- libclickscope/click/webclient.h 2016-05-25 16:19:51 +0000
1552+++ libclickscope/click/webclient.h 2016-08-24 21:39:08 +0000
1553@@ -115,6 +115,8 @@
1554 Client(const QSharedPointer<click::network::AccessManager>& networkAccessManager);
1555 virtual ~Client();
1556
1557+ virtual std::string signUrl(const std::string& url,
1558+ const std::string& method);
1559 virtual QSharedPointer<Response> call(
1560 const std::string& iri,
1561 const CallParams& params = CallParams(), bool force_cache = false);
1562
1563=== modified file 'libclickscope/tests/CMakeLists.txt'
1564--- libclickscope/tests/CMakeLists.txt 2015-07-02 21:56:45 +0000
1565+++ libclickscope/tests/CMakeLists.txt 2016-08-24 21:39:08 +0000
1566@@ -15,11 +15,13 @@
1567 ${GMOCK_INCLUDE_DIR}
1568 )
1569
1570-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test_data.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp)
1571 add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}")
1572
1573 add_executable (${LIBCLICKSCOPE_TESTS_TARGET}
1574 mock_network_access_manager.h
1575+ mock_pay.h
1576+ mock_ual.h
1577+ mock_ubuntu_download_manager.h
1578 mock_ubuntuone_credentials.h
1579 mock_webclient.h
1580 fake_json.cpp
1581@@ -37,8 +39,6 @@
1582 test_smartconnect.cpp
1583 test_utils.cpp
1584 test_webclient.cpp
1585-
1586- ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp
1587 )
1588
1589 qt5_use_modules(${LIBCLICKSCOPE_TESTS_TARGET} Core Sql)
1590
1591=== removed directory 'libclickscope/tests/applications'
1592=== removed directory 'libclickscope/tests/applications/system'
1593=== removed file 'libclickscope/tests/applications/system/address-book-app.desktop'
1594--- libclickscope/tests/applications/system/address-book-app.desktop 2014-07-21 12:41:31 +0000
1595+++ libclickscope/tests/applications/system/address-book-app.desktop 1970-01-01 00:00:00 +0000
1596@@ -1,15 +0,0 @@
1597-[Desktop Entry]
1598-Encoding=UTF-8
1599-Version=1.0
1600-Terminal=false
1601-Type=Application
1602-Name=Contacts
1603-GenericName=Contacts
1604-Exec=/usr/bin/address-book-app %u
1605-Icon=contacts-app
1606-X-Ubuntu-Touch=true
1607-X-Ubuntu-StageHint=SideStage
1608-X-Ubuntu-Gettext-Domain=address-book-app
1609-X-Ubuntu-Single-Instance=true
1610-X-Ubuntu-Default-Department-ID=accessories
1611-# this one has no screenshot nor comment, to test how it breaks
1612
1613=== removed file 'libclickscope/tests/applications/system/messaging-app.desktop'
1614--- libclickscope/tests/applications/system/messaging-app.desktop 2014-04-02 11:56:49 +0000
1615+++ libclickscope/tests/applications/system/messaging-app.desktop 1970-01-01 00:00:00 +0000
1616@@ -1,14 +0,0 @@
1617-[Desktop Entry]
1618-Type=Application
1619-Name=Messaging
1620-GenericName=Messaging
1621-Comment=Messaging application
1622-Exec=messaging-app %u
1623-Terminal=false
1624-Icon=messages-app
1625-MimeType=x-scheme-handler/contact;x-scheme-handler/call
1626-X-Ubuntu-Touch=true
1627-X-Ubuntu-StageHint=SideStage
1628-X-Ubuntu-Gettext-Domain=messaging-app
1629-X-Ubuntu-Single-Instance=true
1630-X-Screenshot=/usr/share/messaging-app/assets/messaging-app-screenshot.png
1631
1632=== removed file 'libclickscope/tests/applications/system/translated.desktop'
1633--- libclickscope/tests/applications/system/translated.desktop 2014-05-05 20:21:53 +0000
1634+++ libclickscope/tests/applications/system/translated.desktop 1970-01-01 00:00:00 +0000
1635@@ -1,9 +0,0 @@
1636-[Desktop Entry]
1637-Type=Application
1638-Name=Translated App
1639-Name[en]=Translated App
1640-Name[es]=Translated App in Spanish
1641-Comment=Translated application
1642-Comment[en]=Translated application
1643-Comment[es]=Translated application in Spanish
1644-X-Ubuntu-Touch=true
1645
1646=== removed directory 'libclickscope/tests/applications/user'
1647=== removed file 'libclickscope/tests/applications/user/badd-appid.desktop'
1648--- libclickscope/tests/applications/user/badd-appid.desktop 2016-01-04 20:50:16 +0000
1649+++ libclickscope/tests/applications/user/badd-appid.desktop 1970-01-01 00:00:00 +0000
1650@@ -1,10 +0,0 @@
1651-[Desktop Entry]
1652-Version=1.0
1653-Type=Application
1654-Terminal=false
1655-Exec=processTest
1656-Icon=/home/phablet/animatedDemos/football-ball.png
1657-Path=/home/phablet/processTest
1658-Name=Football
1659-X-Ubuntu-Touch=true
1660-X-Ubuntu-Application-ID=football
1661
1662=== removed file 'libclickscope/tests/applications/user/broken.desktop'
1663Binary files libclickscope/tests/applications/user/broken.desktop 2014-04-28 22:10:15 +0000 and libclickscope/tests/applications/user/broken.desktop 1970-01-01 00:00:00 +0000 differ
1664=== removed file 'libclickscope/tests/applications/user/com.ubuntu.accented_accented_0.5.29.desktop'
1665--- libclickscope/tests/applications/user/com.ubuntu.accented_accented_0.5.29.desktop 2016-03-03 14:19:50 +0000
1666+++ libclickscope/tests/applications/user/com.ubuntu.accented_accented_0.5.29.desktop 1970-01-01 00:00:00 +0000
1667@@ -1,13 +0,0 @@
1668-[Desktop Entry]
1669-Version=1.0
1670-Type=Application
1671-Terminal=false
1672-Exec=aa-exec-click -p com.ubuntu.accented_accented_0.5.29 -- qmlscene ./ubuntu-accented-app.qml -I ./plugins
1673-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.accented/./accented64.png
1674-Name=Cámara
1675-X-Ubuntu-Touch=true
1676-X-Ubuntu-StageHint=SideStage
1677-
1678-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.accented
1679-X-Ubuntu-Old-Icon=./accented64.png
1680-X-Ubuntu-Application-ID=com.ubuntu.accented_accented_0.5.29
1681
1682=== removed file 'libclickscope/tests/applications/user/com.ubuntu.calculator_calculator_0.1.3.206.desktop'
1683--- libclickscope/tests/applications/user/com.ubuntu.calculator_calculator_0.1.3.206.desktop 2014-02-10 12:23:35 +0000
1684+++ libclickscope/tests/applications/user/com.ubuntu.calculator_calculator_0.1.3.206.desktop 1970-01-01 00:00:00 +0000
1685@@ -1,14 +0,0 @@
1686-[Desktop Entry]
1687-Version=1.0
1688-Type=Application
1689-Terminal=false
1690-Exec=aa-exec-click -p com.ubuntu.calculator_calculator_0.1.3.206 -- qmlscene ./ubuntu-calculator-app.qml
1691-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/./calculator64.png
1692-Name=Calculator
1693-X-Ubuntu-Touch=true
1694-X-Ubuntu-StageHint=SideStage
1695-X-Ubuntu-Gettext-Domain=com.ubuntu.calculator
1696-
1697-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator
1698-X-Ubuntu-Old-Icon=./calculator64.png
1699-X-Ubuntu-Application-ID=com.ubuntu.calculator_calculator_0.1.3.206
1700
1701=== removed file 'libclickscope/tests/applications/user/com.ubuntu.calendar_calendar_0.4.182.desktop'
1702--- libclickscope/tests/applications/user/com.ubuntu.calendar_calendar_0.4.182.desktop 2014-02-10 12:23:35 +0000
1703+++ libclickscope/tests/applications/user/com.ubuntu.calendar_calendar_0.4.182.desktop 1970-01-01 00:00:00 +0000
1704@@ -1,14 +0,0 @@
1705-[Desktop Entry]
1706-Version=1.0
1707-Type=Application
1708-Terminal=false
1709-Exec=aa-exec-click -p com.ubuntu.calendar_calendar_0.4.182 -- qmlscene %u ./calendar.qml
1710-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calendar/./calendar64.png
1711-Name=Calendar
1712-X-Ubuntu-Touch=true
1713-X-Ubuntu-StageHint=SideStage
1714-X-Ubuntu-Gettext-Domain=com.ubuntu.calendar
1715-
1716-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calendar
1717-X-Ubuntu-Old-Icon=./calendar64.png
1718-X-Ubuntu-Application-ID=com.ubuntu.calendar_calendar_0.4.182
1719
1720=== removed file 'libclickscope/tests/applications/user/com.ubuntu.clock_clock_1.0.300.desktop'
1721--- libclickscope/tests/applications/user/com.ubuntu.clock_clock_1.0.300.desktop 2014-02-10 12:23:35 +0000
1722+++ libclickscope/tests/applications/user/com.ubuntu.clock_clock_1.0.300.desktop 1970-01-01 00:00:00 +0000
1723@@ -1,14 +0,0 @@
1724-[Desktop Entry]
1725-Version=1.0
1726-Type=Application
1727-Terminal=false
1728-Exec=aa-exec-click -p com.ubuntu.clock_clock_1.0.300 -- qmlscene ./ubuntu-clock-app.qml
1729-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock/./clock64.png
1730-Name=Clock
1731-X-Ubuntu-Touch=true
1732-X-Ubuntu-StageHint=SideStage
1733-X-Ubuntu-Gettext-Domain=com.ubuntu.clock
1734-
1735-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock
1736-X-Ubuntu-Old-Icon=./clock64.png
1737-X-Ubuntu-Application-ID=com.ubuntu.clock_clock_1.0.300
1738
1739=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6.desktop'
1740--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6.desktop 2014-02-10 12:23:35 +0000
1741+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6.desktop 1970-01-01 00:00:00 +0000
1742@@ -1,10 +0,0 @@
1743-[Desktop Entry]
1744-Type=Application
1745-Terminal=false
1746-Exec=aa-exec-click -p com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6 -- webbrowser-app --enable-back-forward --webapp --webappUrlPatterns=https?://www.amazon.com/*,https?://s.amazon-adsystem.com/* http://www.amazon.com/gp/aw
1747-Name=Amazon
1748-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-amazon/./amazon.png
1749-X-Ubuntu-Touch=true
1750-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-amazon
1751-X-Ubuntu-Old-Icon=./amazon.png
1752-X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6
1753
1754=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8.desktop'
1755--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8.desktop 2014-02-10 12:23:35 +0000
1756+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8.desktop 1970-01-01 00:00:00 +0000
1757@@ -1,11 +0,0 @@
1758-[Desktop Entry]
1759-Type=Application
1760-Terminal=false
1761-Exec=aa-exec-click -p com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8 -- webbrowser-app --enable-back-forward --webappUrlPatterns=https?://*.ebay.com/* --webapp http://m.ebay.com/
1762-Name=eBay
1763-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-ebay/./ebay.png
1764-X-Ubuntu-Touch=true
1765-X-Ubuntu-Single-Instance=true
1766-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-ebay
1767-X-Ubuntu-Old-Icon=./ebay.png
1768-X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8
1769
1770=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5.desktop'
1771--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5.desktop 2014-02-10 12:23:35 +0000
1772+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5.desktop 1970-01-01 00:00:00 +0000
1773@@ -1,12 +0,0 @@
1774-[Desktop Entry]
1775-Type=Application
1776-Terminal=false
1777-Exec=aa-exec-click -p com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5 -- webbrowser-app --enable-back-forward --webapp --webappUrlPatterns=https?://m.facebook.com/* https://m.facebook.com/
1778-Name=Facebook
1779-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-facebook/./facebook.png
1780-X-Ubuntu-Touch=true
1781-X-Ubuntu-StageHint=SideStage
1782-X-Ubuntu-Single-Instance=true
1783-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-facebook
1784-X-Ubuntu-Old-Icon=./facebook.png
1785-X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5
1786
1787=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8.desktop'
1788--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8.desktop 2014-02-10 12:23:35 +0000
1789+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8.desktop 1970-01-01 00:00:00 +0000
1790@@ -1,11 +0,0 @@
1791-[Desktop Entry]
1792-Type=Application
1793-Terminal=false
1794-Exec=aa-exec-click -p com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8 -- webbrowser-app --enable-back-forward --webappModelSearchPath=. --webapp='R01haWwNCg==' https://mail.google.com/
1795-Name=Gmail
1796-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-gmail/./gmail.png
1797-X-Ubuntu-Touch=true
1798-X-Ubuntu-Single-Instance=true
1799-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-gmail
1800-X-Ubuntu-Old-Icon=./gmail.png
1801-X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8
1802
1803=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5.desktop'
1804--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5.desktop 2014-02-10 12:23:35 +0000
1805+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5.desktop 1970-01-01 00:00:00 +0000
1806@@ -1,12 +0,0 @@
1807-[Desktop Entry]
1808-Type=Application
1809-Terminal=false
1810-Exec=aa-exec-click -p com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5 -- webbrowser-app --enable-back-forward --webapp --webappUrlPatterns=https?://mobile.twitter.com/* https://mobile.twitter.com/session/new?bypass_interstitial=true
1811-Name=Twitter
1812-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-twitter/./twitter.png
1813-X-Ubuntu-Touch=true
1814-X-Ubuntu-StageHint=SideStage
1815-X-Ubuntu-Single-Instance=true
1816-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-twitter
1817-X-Ubuntu-Old-Icon=./twitter.png
1818-X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5
1819
1820=== removed file 'libclickscope/tests/applications/user/com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43.desktop'
1821--- libclickscope/tests/applications/user/com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43.desktop 2014-02-10 12:23:35 +0000
1822+++ libclickscope/tests/applications/user/com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43.desktop 1970-01-01 00:00:00 +0000
1823@@ -1,13 +0,0 @@
1824-[Desktop Entry]
1825-Version=1.0
1826-Type=Application
1827-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.dropping-letters/dropping-letters.png
1828-Terminal=false
1829-Name=Dropping Letters
1830-Exec=aa-exec-click -p com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43 -- qmlscene dropping-letters.qml
1831-X-Ubuntu-Touch=true
1832-X-Ubuntu-StageHint=SideStage
1833-
1834-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.dropping-letters
1835-X-Ubuntu-Old-Icon=dropping-letters.png
1836-X-Ubuntu-Application-ID=com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43
1837
1838=== removed file 'libclickscope/tests/applications/user/com.ubuntu.filemanager_filemanager_0.1.1.97.desktop'
1839--- libclickscope/tests/applications/user/com.ubuntu.filemanager_filemanager_0.1.1.97.desktop 2014-02-10 12:23:35 +0000
1840+++ libclickscope/tests/applications/user/com.ubuntu.filemanager_filemanager_0.1.1.97.desktop 1970-01-01 00:00:00 +0000
1841@@ -1,13 +0,0 @@
1842-[Desktop Entry]
1843-Version=1.0
1844-Type=Application
1845-Terminal=false
1846-Exec=aa-exec-click -p com.ubuntu.filemanager_filemanager_0.1.1.97 -- qmlscene ./ubuntu-filemanager-app.qml -I ./plugins
1847-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.filemanager/./filemanager64.png
1848-Name=File Manager
1849-X-Ubuntu-Touch=true
1850-X-Ubuntu-StageHint=SideStage
1851-
1852-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.filemanager
1853-X-Ubuntu-Old-Icon=./filemanager64.png
1854-X-Ubuntu-Application-ID=com.ubuntu.filemanager_filemanager_0.1.1.97
1855
1856=== removed file 'libclickscope/tests/applications/user/com.ubuntu.music_music_1.1.329.desktop'
1857--- libclickscope/tests/applications/user/com.ubuntu.music_music_1.1.329.desktop 2014-02-10 12:23:35 +0000
1858+++ libclickscope/tests/applications/user/com.ubuntu.music_music_1.1.329.desktop 1970-01-01 00:00:00 +0000
1859@@ -1,15 +0,0 @@
1860-[Desktop Entry]
1861-Version=1.0
1862-Name=Music
1863-Comment=Ubuntu Touch Music Player
1864-Exec=aa-exec-click -p com.ubuntu.music_music_1.1.329 -- qmlscene ./music-app.qml --file=%f -I ./plugins
1865-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.music/images/music.png
1866-Terminal=false
1867-Type=Application
1868-StartupNotify=true
1869-X-Ubuntu-Single-Instance=true
1870-X-Ubuntu-Touch=true
1871-
1872-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.music
1873-X-Ubuntu-Old-Icon=images/music.png
1874-X-Ubuntu-Application-ID=com.ubuntu.music_music_1.1.329
1875
1876=== removed file 'libclickscope/tests/applications/user/com.ubuntu.notes_notes_1.4.242.desktop'
1877--- libclickscope/tests/applications/user/com.ubuntu.notes_notes_1.4.242.desktop 2014-02-10 12:23:35 +0000
1878+++ libclickscope/tests/applications/user/com.ubuntu.notes_notes_1.4.242.desktop 1970-01-01 00:00:00 +0000
1879@@ -1,14 +0,0 @@
1880-[Desktop Entry]
1881-Type=Application
1882-Exec=aa-exec-click -p com.ubuntu.notes_notes_1.4.242 -- qmlscene $@ -I ./usr/lib/arm-linux-gnueabihf/qt5/qml NotesApp.qml
1883-Name=Notes
1884-GenericName=Notes application for Ubuntu
1885-Icon=notepad
1886-Terminal=false
1887-
1888-X-Ubuntu-Touch=true
1889-X-Ubuntu-StageHint=SideStage
1890-X-Ubuntu-Gettext-Domain=com.ubuntu.notes
1891-X-Ubuntu-Single-Instance=true
1892-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.notes
1893-X-Ubuntu-Application-ID=com.ubuntu.notes_notes_1.4.242
1894
1895=== removed file 'libclickscope/tests/applications/user/com.ubuntu.shorts_shorts_0.2.162.desktop'
1896--- libclickscope/tests/applications/user/com.ubuntu.shorts_shorts_0.2.162.desktop 2014-02-10 12:23:35 +0000
1897+++ libclickscope/tests/applications/user/com.ubuntu.shorts_shorts_0.2.162.desktop 1970-01-01 00:00:00 +0000
1898@@ -1,14 +0,0 @@
1899-[Desktop Entry]
1900-Version=1.0
1901-Type=Application
1902-Terminal=false
1903-Exec=aa-exec-click -p com.ubuntu.shorts_shorts_0.2.162 -- qmlscene ./rssreader-app.qml
1904-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.shorts/./rssreader64.png
1905-Name=Shorts
1906-Keywords=shorts;rss;reader
1907-X-Ubuntu-Touch=true
1908-X-Ubuntu-StageHint=SideStage
1909-
1910-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.shorts
1911-X-Ubuntu-Old-Icon=./rssreader64.png
1912-X-Ubuntu-Application-ID=com.ubuntu.shorts_shorts_0.2.162
1913
1914=== removed file 'libclickscope/tests/applications/user/com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop'
1915--- libclickscope/tests/applications/user/com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop 2014-02-10 12:23:35 +0000
1916+++ libclickscope/tests/applications/user/com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop 1970-01-01 00:00:00 +0000
1917@@ -1,16 +0,0 @@
1918-[Desktop Entry]
1919-Version=1.0
1920-Name=Stock Ticker
1921-GenericName=Stock Ticker
1922-Comment=An awesome Stock Ticker application with all the features you could imagine
1923-Exec=aa-exec-click -p com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66 -- qmlscene Stock_Ticker.qml
1924-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.stock-ticker-mobile/icons/stock_icon_48.png
1925-Terminal=false
1926-Type=Application
1927-X-Ubuntu-Touch=true
1928-X-Ubuntu-StageHint=SideStage
1929-Categories=Utility;
1930-
1931-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.stock-ticker-mobile
1932-X-Ubuntu-Old-Icon=icons/stock_icon_48.png
1933-X-Ubuntu-Application-ID=com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66
1934
1935=== removed file 'libclickscope/tests/applications/user/com.ubuntu.sudoku_sudoku_1.0.142.desktop'
1936--- libclickscope/tests/applications/user/com.ubuntu.sudoku_sudoku_1.0.142.desktop 2014-02-10 12:23:35 +0000
1937+++ libclickscope/tests/applications/user/com.ubuntu.sudoku_sudoku_1.0.142.desktop 1970-01-01 00:00:00 +0000
1938@@ -1,15 +0,0 @@
1939-[Desktop Entry]
1940-Name=Sudoku
1941-Version=1.0
1942-Comment=Sudoku Game for Ubuntu Touch
1943-Exec=aa-exec-click -p com.ubuntu.sudoku_sudoku_1.0.142 -- qmlscene sudoku-app.qml
1944-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.sudoku/SudokuGameIcon.png
1945-Terminal=false
1946-Type=Application
1947-X-Ubuntu-Touch=true
1948-X-Ubuntu-StageHint=SideStage
1949-X-Ubuntu-Gettext-Domain=com.ubuntu.sudoku
1950-
1951-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.sudoku
1952-X-Ubuntu-Old-Icon=SudokuGameIcon.png
1953-X-Ubuntu-Application-ID=com.ubuntu.sudoku_sudoku_1.0.142
1954
1955=== removed file 'libclickscope/tests/applications/user/com.ubuntu.terminal_terminal_0.5.29.desktop'
1956--- libclickscope/tests/applications/user/com.ubuntu.terminal_terminal_0.5.29.desktop 2014-02-10 12:23:35 +0000
1957+++ libclickscope/tests/applications/user/com.ubuntu.terminal_terminal_0.5.29.desktop 1970-01-01 00:00:00 +0000
1958@@ -1,13 +0,0 @@
1959-[Desktop Entry]
1960-Version=1.0
1961-Type=Application
1962-Terminal=false
1963-Exec=aa-exec-click -p com.ubuntu.terminal_terminal_0.5.29 -- qmlscene ./ubuntu-terminal-app.qml -I ./plugins
1964-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.terminal/./terminal64.png
1965-Name=Terminal
1966-X-Ubuntu-Touch=true
1967-X-Ubuntu-StageHint=SideStage
1968-
1969-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.terminal
1970-X-Ubuntu-Old-Icon=./terminal64.png
1971-X-Ubuntu-Application-ID=com.ubuntu.terminal_terminal_0.5.29
1972
1973=== removed file 'libclickscope/tests/applications/user/com.ubuntu.weather_weather_1.0.168.desktop'
1974--- libclickscope/tests/applications/user/com.ubuntu.weather_weather_1.0.168.desktop 2014-04-10 17:29:49 +0000
1975+++ libclickscope/tests/applications/user/com.ubuntu.weather_weather_1.0.168.desktop 1970-01-01 00:00:00 +0000
1976@@ -1,15 +0,0 @@
1977-[Desktop Entry]
1978-Version=1.0
1979-Type=Application
1980-Terminal=false
1981-Exec=aa-exec-click -p com.ubuntu.weather_weather_1.0.168 -- qmlscene ./ubuntu-weather-app.qml
1982-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.weather/./weather64.png
1983-Name=Weather
1984-X-Ubuntu-Touch=true
1985-X-Ubuntu-StageHint=SideStage
1986-X-Ubuntu-Gettext-Domain=com.ubuntu.weather
1987-
1988-# Fake an app installed from a .deb
1989-#Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.weather
1990-#X-Ubuntu-Old-Icon=./weather64.png
1991-#X-Ubuntu-Application-ID=com.ubuntu.weather_weather_1.0.168
1992
1993=== removed file 'libclickscope/tests/applications/user/non-click-app-nodisplay.desktop'
1994--- libclickscope/tests/applications/user/non-click-app-nodisplay.desktop 2014-04-08 20:04:45 +0000
1995+++ libclickscope/tests/applications/user/non-click-app-nodisplay.desktop 1970-01-01 00:00:00 +0000
1996@@ -1,9 +0,0 @@
1997-[Desktop Entry]
1998-Type=Application
1999-Name=Sample Desktop-only non-click app
2000-GenericName=NonClickAppWithoutException
2001-Comment=multiline description goes here
2002-Exec=messaging-app %u
2003-Terminal=false
2004-MimeType=x-scheme-handler/contact;x-scheme-handler/call
2005-NoDisplay=true
2006
2007=== removed file 'libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome-unity.desktop'
2008--- libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome-unity.desktop 2014-04-08 20:04:45 +0000
2009+++ libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome-unity.desktop 1970-01-01 00:00:00 +0000
2010@@ -1,10 +0,0 @@
2011-[Desktop Entry]
2012-Type=Application
2013-Name=Sample Desktop-only non-click app
2014-GenericName=NonClickAppWithoutException
2015-Comment=multiline description goes here
2016-Exec=messaging-app %u
2017-Terminal=false
2018-MimeType=x-scheme-handler/contact;x-scheme-handler/call
2019-OnlyShowIn=GNOME;Unity;
2020-Name[en_US]=non-click-app-onlyshowin-gnome-unity.desktop
2021
2022=== removed file 'libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome.desktop'
2023--- libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome.desktop 2014-04-08 20:04:45 +0000
2024+++ libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome.desktop 1970-01-01 00:00:00 +0000
2025@@ -1,10 +0,0 @@
2026-[Desktop Entry]
2027-Type=Application
2028-Name=Sample Desktop-only non-click app
2029-GenericName=NonClickAppWithoutException
2030-Comment=multiline description goes here
2031-Exec=messaging-app %u
2032-Terminal=false
2033-MimeType=x-scheme-handler/contact;x-scheme-handler/call
2034-OnlyShowIn=GNOME;
2035-Name[en_US]=non-click-app-onlyshowin-gnome.desktop
2036
2037=== removed file 'libclickscope/tests/applications/user/non-click-app-onlyshowin-unity.desktop'
2038--- libclickscope/tests/applications/user/non-click-app-onlyshowin-unity.desktop 2014-04-08 20:04:45 +0000
2039+++ libclickscope/tests/applications/user/non-click-app-onlyshowin-unity.desktop 1970-01-01 00:00:00 +0000
2040@@ -1,10 +0,0 @@
2041-[Desktop Entry]
2042-Type=Application
2043-Name=Sample Desktop-only non-click app
2044-GenericName=NonClickAppWithoutException
2045-Comment=multiline description goes here
2046-Exec=messaging-app %u
2047-Terminal=false
2048-MimeType=x-scheme-handler/contact;x-scheme-handler/call
2049-OnlyShowIn=Unity;
2050-Name[en_US]=non-click-app-onlyshowin-unity.desktop
2051
2052=== removed file 'libclickscope/tests/applications/user/non-click-app-without-exception.desktop'
2053--- libclickscope/tests/applications/user/non-click-app-without-exception.desktop 2014-04-08 21:16:25 +0000
2054+++ libclickscope/tests/applications/user/non-click-app-without-exception.desktop 1970-01-01 00:00:00 +0000
2055@@ -1,9 +0,0 @@
2056-[Desktop Entry]
2057-Type=Application
2058-Name=Sample Desktop-only non-click app
2059-GenericName=NonClickAppWithoutException
2060-Comment=multiline description goes here
2061-Exec=messaging-app %u
2062-Terminal=false
2063-Icon=sample-desktop-app
2064-MimeType=x-scheme-handler/contact;x-scheme-handler/call
2065
2066=== removed file 'libclickscope/tests/applications/user/pre-translated.desktop'
2067--- libclickscope/tests/applications/user/pre-translated.desktop 2015-11-24 18:23:23 +0000
2068+++ libclickscope/tests/applications/user/pre-translated.desktop 1970-01-01 00:00:00 +0000
2069@@ -1,14 +0,0 @@
2070-[Desktop Entry]
2071-Version=1.0
2072-Type=Application
2073-Terminal=false
2074-Exec=aa-exec-click -p com.ubuntu.clock_clock_1.0.300 -- qmlscene ./ubuntu-clock-app.qml
2075-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock/./clock64.png
2076-_Name=Untranslated Clock
2077-X-Ubuntu-Touch=true
2078-X-Ubuntu-StageHint=SideStage
2079-X-Ubuntu-Gettext-Domain=com.ubuntu.clock
2080-
2081-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock
2082-X-Ubuntu-Old-Icon=./clock64.png
2083-X-Ubuntu-Application-ID=com.ubuntu.clock_clock_1.0.300
2084
2085=== removed file 'libclickscope/tests/applications/user/semi-broken.desktop'
2086--- libclickscope/tests/applications/user/semi-broken.desktop 2014-04-28 22:10:15 +0000
2087+++ libclickscope/tests/applications/user/semi-broken.desktop 1970-01-01 00:00:00 +0000
2088@@ -1,1 +0,0 @@
2089-semi broken file
2090
2091=== added file 'libclickscope/tests/mock_ual.h'
2092--- libclickscope/tests/mock_ual.h 1970-01-01 00:00:00 +0000
2093+++ libclickscope/tests/mock_ual.h 2016-08-24 21:39:08 +0000
2094@@ -0,0 +1,156 @@
2095+/*
2096+ * Copyright (C) 2016 Canonical Ltd.
2097+ *
2098+ * This program is free software: you can redistribute it and/or modify it
2099+ * under the terms of the GNU General Public License version 3, as published
2100+ * by the Free Software Foundation.
2101+ *
2102+ * This program is distributed in the hope that it will be useful, but
2103+ * WITHOUT ANY WARRANTY; without even the implied warranties of
2104+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2105+ * PURPOSE. See the GNU General Public License for more details.
2106+ *
2107+ * You should have received a copy of the GNU General Public License along
2108+ * with this program. If not, see <http://www.gnu.org/licenses/>.
2109+ *
2110+ * In addition, as a special exception, the copyright holders give
2111+ * permission to link the code of portions of this program with the
2112+ * OpenSSL library under certain conditions as described in each
2113+ * individual source file, and distribute linked combinations
2114+ * including the two.
2115+ * You must obey the GNU General Public License in all respects
2116+ * for all of the code used other than OpenSSL. If you modify
2117+ * file(s) with this exception, you may extend this exception to your
2118+ * version of the file(s), but you are not obligated to do so. If you
2119+ * do not wish to do so, delete this exception statement from your
2120+ * version. If you delete this exception statement from all source
2121+ * files in the program, then also delete it here.
2122+ */
2123+
2124+#include <ubuntu-app-launch/registry.h>
2125+
2126+using namespace ubuntu::app_launch;
2127+namespace ual = ubuntu::app_launch;
2128+
2129+#include <gtest/gtest.h>
2130+#include <gmock/gmock.h>
2131+
2132+using namespace ::testing;
2133+
2134+namespace
2135+{
2136+
2137+ class MockUALRegistry : public ual::Registry {
2138+ public:
2139+ MockUALRegistry()
2140+ {
2141+ }
2142+
2143+ MOCK_METHOD1(installedApps, std::list<std::shared_ptr<ual::Application>>(std::shared_ptr<ual::Registry>));
2144+ };
2145+
2146+ class MockUALApplication : public ual::Application {
2147+ public:
2148+ class MockInfo;
2149+ class MockInstance;
2150+
2151+ MockUALApplication(const ual::AppID& app_id,
2152+ const std::shared_ptr<MockInfo>& info = {})
2153+ : _app_id(app_id),
2154+ _info(info)
2155+ {
2156+ }
2157+
2158+ ual::AppID appId()
2159+ {
2160+ return _app_id;
2161+ }
2162+
2163+ std::shared_ptr<ual::Application::Info> info()
2164+ {
2165+ return _info;
2166+ }
2167+
2168+ static std::shared_ptr<MockUALApplication> create(ual::AppID app_id,
2169+ std::shared_ptr<MockInfo> info = {})
2170+ {
2171+ std::shared_ptr<MockUALApplication> result{new MockUALApplication(app_id, info)};
2172+ return result;
2173+ }
2174+
2175+ class MockInfo : public ual::Application::Info
2176+ {
2177+ public:
2178+ MockInfo(const std::string& title,
2179+ const std::string& description,
2180+ const std::string& iconPath)
2181+ : _name(ual::Application::Info::Name::from_raw(title)),
2182+ _description(ual::Application::Info::Description::from_raw(description)),
2183+ _iconPath(ual::Application::Info::IconPath::from_raw(iconPath)),
2184+ _defaultDept(ual::Application::Info::DefaultDepartment::from_raw("")),
2185+ _ssPath(ual::Application::Info::IconPath::from_raw("")),
2186+ _keywords(ual::Application::Info::Keywords::from_raw(std::vector<std::string>{}))
2187+ {
2188+ DefaultValue<const ual::Application::Info::DefaultDepartment&>::Set(_defaultDept);
2189+ DefaultValue<const ual::Application::Info::IconPath&>::Set(_ssPath);
2190+ DefaultValue<const ual::Application::Info::Keywords&>::Set(_keywords);
2191+ }
2192+
2193+ const ual::Application::Info::Name& name()
2194+ {
2195+ return _name;
2196+ }
2197+
2198+ const ual::Application::Info::Description& description()
2199+ {
2200+ return _description;
2201+ }
2202+
2203+ const ual::Application::Info::IconPath& iconPath()
2204+ {
2205+ return _iconPath;
2206+ }
2207+
2208+ MOCK_METHOD0(defaultDepartment, const ual::Application::Info::DefaultDepartment&());
2209+ MOCK_METHOD0(screenshotPath, const ual::Application::Info::IconPath&());
2210+ MOCK_METHOD0(keywords, const ual::Application::Info::Keywords&());
2211+
2212+ MOCK_METHOD0(splash, ual::Application::Info::Splash());
2213+ MOCK_METHOD0(supportedOrientations, ual::Application::Info::Orientations());
2214+ MOCK_METHOD0(rotatesWindowContents, ual::Application::Info::RotatesWindow());
2215+ MOCK_METHOD0(supportsUbuntuLifecycle, ual::Application::Info::UbuntuLifecycle());
2216+
2217+ private:
2218+ ual::Application::Info::Name _name;
2219+ ual::Application::Info::Description _description;
2220+ ual::Application::Info::IconPath _iconPath;
2221+ ual::Application::Info::DefaultDepartment _defaultDept;
2222+ ual::Application::Info::IconPath _ssPath;
2223+ ual::Application::Info::Keywords _keywords;
2224+ };
2225+
2226+ class MockInstance : public ual::Application::Instance
2227+ {
2228+ public:
2229+ MOCK_METHOD0(isRunning, bool());
2230+ MOCK_METHOD0(logPath, std::string());
2231+ MOCK_METHOD0(primaryPid, pid_t());
2232+ MOCK_METHOD1(hasPid, bool(pid_t));
2233+ MOCK_METHOD0(pids, std::vector<pid_t>());
2234+ MOCK_METHOD0(pause, void());
2235+ MOCK_METHOD0(resume, void());
2236+ MOCK_METHOD0(stop, void());
2237+ };
2238+
2239+ MOCK_METHOD0(hasInstances, bool());
2240+ MOCK_METHOD0(instances, std::vector<std::shared_ptr<ual::Application::Instance>>());
2241+ MOCK_METHOD1(launch, std::shared_ptr<ual::Application::Instance>(const std::vector<ual::Application::URL>&));
2242+ MOCK_METHOD1(launchTest, std::shared_ptr<ual::Application::Instance>(const std::vector<ual::Application::URL>&));
2243+
2244+ private:
2245+ ual::AppID _app_id;
2246+ std::shared_ptr<MockInfo> _info;
2247+ };
2248+
2249+} // namespace
2250+
2251
2252=== modified file 'libclickscope/tests/mock_webclient.h'
2253--- libclickscope/tests/mock_webclient.h 2016-05-25 16:19:51 +0000
2254+++ libclickscope/tests/mock_webclient.h 2016-08-24 21:39:08 +0000
2255@@ -61,13 +61,6 @@
2256 Mock instance;
2257 };
2258
2259-QSharedPointer<click::web::Response> responseForReply(const QSharedPointer<click::network::Reply>& reply)
2260-{
2261- auto response = QSharedPointer<click::web::Response>(new click::web::Response(QSharedPointer<QNetworkRequest>(new QNetworkRequest()), QSharedPointer<QBuffer>(new QBuffer())));
2262- response->setReply(reply);
2263- return response;
2264-}
2265-
2266 class MockClient : public click::web::Client
2267 {
2268 public:
2269@@ -76,6 +69,7 @@
2270 {
2271 }
2272
2273+ MOCK_METHOD2(signUrl, std::string(const std::string&, const std::string&));
2274 // Mocking default arguments: https://groups.google.com/forum/#!topic/googlemock/XrabW20vV7o
2275 MOCK_METHOD6(callImpl, QSharedPointer<click::web::Response>(
2276 const std::string& iri,
2277@@ -102,6 +96,14 @@
2278
2279 MOCK_METHOD1(has_header, bool(const std::string& header));
2280 MOCK_METHOD1(get_header, std::string(const std::string&header));
2281+
2282+ static QSharedPointer<click::web::Response> responseForReply(const QSharedPointer<click::network::Reply>& reply)
2283+ {
2284+ auto response = QSharedPointer<click::web::Response>(new click::web::Response(QSharedPointer<QNetworkRequest>(new QNetworkRequest()), QSharedPointer<QBuffer>(new QBuffer())));
2285+ response->setReply(reply);
2286+ return response;
2287+ }
2288+
2289 };
2290
2291 }
2292
2293=== modified file 'libclickscope/tests/test_bootstrap.cpp'
2294--- libclickscope/tests/test_bootstrap.cpp 2016-06-30 20:42:56 +0000
2295+++ libclickscope/tests/test_bootstrap.cpp 2016-08-24 21:39:08 +0000
2296@@ -70,7 +70,7 @@
2297 TEST_F(BootstrapTest, testBootstrapCallsWebservice)
2298 {
2299 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2300- auto response = responseForReply(reply.asSharedPtr());
2301+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2302
2303 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::BOOTSTRAP_PATH), "GET", _, _, _, _))
2304 .Times(1)
2305@@ -81,7 +81,7 @@
2306 TEST_F(BootstrapTest, testBootstrapJsonIsParsed)
2307 {
2308 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2309- auto response = responseForReply(reply.asSharedPtr());
2310+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2311
2312 QByteArray fake_json(FAKE_JSON_BOOTSTRAP.c_str());
2313 EXPECT_CALL(reply.instance, readAll())
2314
2315=== removed file 'libclickscope/tests/test_data.cpp.in'
2316--- libclickscope/tests/test_data.cpp.in 2014-05-26 14:27:31 +0000
2317+++ libclickscope/tests/test_data.cpp.in 1970-01-01 00:00:00 +0000
2318@@ -1,43 +0,0 @@
2319-/*
2320- * Copyright (C) 2014 Canonical Ltd.
2321- *
2322- * This program is free software: you can redistribute it and/or modify it
2323- * under the terms of the GNU General Public License version 3, as published
2324- * by the Free Software Foundation.
2325- *
2326- * This program is distributed in the hope that it will be useful, but
2327- * WITHOUT ANY WARRANTY; without even the implied warranties of
2328- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2329- * PURPOSE. See the GNU General Public License for more details.
2330- *
2331- * You should have received a copy of the GNU General Public License along
2332- * with this program. If not, see <http://www.gnu.org/licenses/>.
2333- *
2334- * In addition, as a special exception, the copyright holders give
2335- * permission to link the code of portions of this program with the
2336- * OpenSSL library under certain conditions as described in each
2337- * individual source file, and distribute linked combinations
2338- * including the two.
2339- * You must obey the GNU General Public License in all respects
2340- * for all of the code used other than OpenSSL. If you modify
2341- * file(s) with this exception, you may extend this exception to your
2342- * version of the file(s), but you are not obligated to do so. If you
2343- * do not wish to do so, delete this exception statement from your
2344- * version. If you delete this exception statement from all source
2345- * files in the program, then also delete it here.
2346- */
2347-
2348-
2349-#include "test_data.h"
2350-
2351-const std::string& testing::systemApplicationsDirectoryForTesting()
2352-{
2353- static const std::string s{"@CMAKE_CURRENT_SOURCE_DIR@/applications/system"};
2354- return s;
2355-}
2356-
2357-const std::string& testing::userApplicationsDirectoryForTesting()
2358-{
2359- static const std::string s{"@CMAKE_CURRENT_SOURCE_DIR@/applications/user"};
2360- return s;
2361-}
2362
2363=== modified file 'libclickscope/tests/test_data.h'
2364--- libclickscope/tests/test_data.h 2014-05-26 14:27:31 +0000
2365+++ libclickscope/tests/test_data.h 2016-08-24 21:39:08 +0000
2366@@ -38,9 +38,6 @@
2367 const std::string FAKE_PATH = "fake/api/path";
2368 const std::string FAKE_QUERY = "FAKE_QUERY";
2369 const std::string FAKE_PACKAGENAME = "com.example.fakepackage";
2370-
2371-const std::string& systemApplicationsDirectoryForTesting();
2372-const std::string& userApplicationsDirectoryForTesting();
2373 }
2374
2375 #endif // TEST_DATA_H
2376
2377=== modified file 'libclickscope/tests/test_download_manager.cpp'
2378--- libclickscope/tests/test_download_manager.cpp 2016-05-10 13:42:12 +0000
2379+++ libclickscope/tests/test_download_manager.cpp 2016-08-24 21:39:08 +0000
2380@@ -63,6 +63,7 @@
2381
2382 virtual void SetUp()
2383 {
2384+ sdmPtr.reset(new MockSystemDownloadManager());
2385 ssoPtr.reset(new MockCredentialsService());
2386 namPtr.reset(new MockNetworkAccessManager());
2387 clientPtr.reset(new NiceMock<MockClient>(namPtr));
2388@@ -76,138 +77,165 @@
2389
2390 }
2391
2392-TEST_F(DownloadManagerTest, testStartCallsWebservice)
2393+TEST_F(DownloadManagerTest, testStartCallsSignUrl)
2394 {
2395- LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2396- auto response = responseForReply(reply.asSharedPtr());
2397-
2398- EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2399- .Times(1)
2400- .WillOnce(Return(response));
2401-
2402+ EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
2403+ EXPECT_CALL(*sdmPtr, createDownload(_, _, _)).Times(1);
2404 dmPtr->start("", "", "",
2405 [](std::string, click::DownloadManager::Error) {});
2406 }
2407
2408-TEST_F(DownloadManagerTest, testStartCallbackCalled)
2409-{
2410- LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2411- auto response = responseForReply(reply.asSharedPtr());
2412-
2413- EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(0)));
2414- EXPECT_CALL(reply.instance, readAll())
2415- .Times(1)
2416- .WillOnce(Return(""));
2417- EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2418- .Times(1)
2419- .WillOnce(Return(response));
2420- EXPECT_CALL(*this, start_callback(_, _)).Times(1);
2421-
2422- dmPtr->start("", "", "",
2423- [this](std::string msg, click::DownloadManager::Error err) {
2424- start_callback(msg, err);
2425- });
2426- response->replyFinished();
2427-}
2428-
2429-TEST_F(DownloadManagerTest, testStartHTTPForbidden)
2430-{
2431- LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2432- auto response = responseForReply(reply.asSharedPtr());
2433-
2434- EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(403)));
2435- EXPECT_CALL(reply.instance, readAll())
2436- .Times(1)
2437- .WillOnce(Return(""));
2438- EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2439- .Times(1)
2440- .WillOnce(Return(response));
2441- EXPECT_CALL(*this, start_callback(StartsWith("Unhandled HTTP response code:"),
2442- click::DownloadManager::Error::DownloadInstallError)).Times(1);
2443-
2444- dmPtr->start("", "", "",
2445- [this](std::string msg, click::DownloadManager::Error err) {
2446- start_callback(msg, err);
2447- });
2448- response->replyFinished();
2449-}
2450-
2451-TEST_F(DownloadManagerTest, testStartHTTPError)
2452-{
2453- LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2454- auto response = responseForReply(reply.asSharedPtr());
2455-
2456- EXPECT_CALL(reply.instance, errorString())
2457- .WillOnce(Return(QString("ERROR")));
2458- EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(404)));
2459- EXPECT_CALL(reply.instance, readAll())
2460- .Times(1)
2461- .WillOnce(Return(""));
2462- EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2463- .Times(1)
2464- .WillOnce(Return(response));
2465- EXPECT_CALL(*this, start_callback("ERROR (203)",
2466- click::DownloadManager::Error::DownloadInstallError)).Times(1);
2467-
2468- dmPtr->start("", "", "",
2469- [this](std::string msg, click::DownloadManager::Error err) {
2470- start_callback(msg, err);
2471- });
2472- response->errorHandler(QNetworkReply::ContentNotFoundError);
2473-}
2474-
2475-TEST_F(DownloadManagerTest, testStartCredentialsError)
2476-{
2477- LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2478- auto response = responseForReply(reply.asSharedPtr());
2479-
2480- EXPECT_CALL(reply.instance, errorString())
2481- .WillOnce(Return(QString("ERROR")));
2482- EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(401)));
2483- EXPECT_CALL(reply.instance, readAll())
2484- .Times(1)
2485- .WillOnce(Return(""));
2486- EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2487- .Times(1)
2488- .WillOnce(Return(response));
2489- EXPECT_CALL(*ssoPtr, invalidateCredentials());
2490- EXPECT_CALL(*this, start_callback("ERROR (201)",
2491- click::DownloadManager::Error::CredentialsError)).Times(1);
2492-
2493- dmPtr->start("", "", "test.package",
2494- [this](std::string msg, click::DownloadManager::Error err) {
2495- start_callback(msg, err);
2496- });
2497- response->errorHandler(QNetworkReply::ContentAccessDenied);
2498-}
2499-
2500-// FIXME: createDownload() SEGV under tests
2501-TEST_F(DownloadManagerTest, DISABLED_testStartDownloadCreated)
2502-{
2503- LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2504- auto response = responseForReply(reply.asSharedPtr());
2505-
2506- EXPECT_CALL(reply.instance, rawHeader(QByteArray("X-Click-Token")))
2507- .Times(1)
2508- .WillOnce(Return(QString("clicktoken")));
2509- EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));
2510- EXPECT_CALL(reply.instance, readAll())
2511- .Times(1)
2512- .WillOnce(Return(""));
2513- EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2514- .Times(1)
2515- .WillOnce(Return(response));
2516-
2517- EXPECT_CALL(*sdmPtr, createDownload(_, _, _));
2518- dmPtr->start("", "", "test.package",
2519- [this](std::string msg, click::DownloadManager::Error err) {
2520- start_callback(msg, err);
2521- });
2522- response->replyFinished();
2523-}
2524-
2525-// FIXME: getAllDownloadsWithMetadata() SEGV under tests
2526-TEST_F(DownloadManagerTest, DISABLED_testGetProgressNoDownloads)
2527+TEST_F(DownloadManagerTest, testStartDownloadSuccssIsError)
2528+{
2529+ auto mockDownload = new MockDownload();
2530+ auto mockError = new MockError();
2531+ EXPECT_CALL(*mockDownload, isError())
2532+ .Times(1)
2533+ .WillOnce(Return(true));
2534+ EXPECT_CALL(*mockDownload, error())
2535+ .Times(1)
2536+ .WillOnce(Return(mockError));
2537+ EXPECT_CALL(*mockError, errorString())
2538+ .Times(1)
2539+ .WillOnce(Return(QStringLiteral("")));
2540+
2541+ EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
2542+ EXPECT_CALL(*sdmPtr, createDownload(_, _, _))
2543+ .Times(1)
2544+ .WillOnce(InvokeArgument<1>(mockDownload));
2545+ EXPECT_CALL(*this, start_callback(_, _)).Times(1);
2546+
2547+ dmPtr->start("", "", "",
2548+ [this](std::string msg, click::DownloadManager::Error err) {
2549+ start_callback(msg, err);
2550+ });
2551+
2552+ delete mockError;
2553+ delete mockDownload;
2554+}
2555+
2556+TEST_F(DownloadManagerTest, testStartDownloadSuccssCallsStart)
2557+{
2558+ auto mockDownload = new MockDownload();
2559+ EXPECT_CALL(*mockDownload, isError())
2560+ .Times(1)
2561+ .WillOnce(Return(false));
2562+ EXPECT_CALL(*mockDownload, start()).Times(1);
2563+ EXPECT_CALL(*mockDownload, id())
2564+ .Times(1)
2565+ .WillOnce(Return(QStringLiteral("download")));
2566+
2567+ EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
2568+ EXPECT_CALL(*sdmPtr, createDownload(_, _, _))
2569+ .Times(1)
2570+ .WillOnce(InvokeArgument<1>(mockDownload));
2571+ EXPECT_CALL(*this, start_callback(_, _)).Times(1);
2572+
2573+ dmPtr->start("", "", "",
2574+ [this](std::string msg, click::DownloadManager::Error err) {
2575+ start_callback(msg, err);
2576+ });
2577+
2578+ delete mockDownload;
2579+}
2580+
2581+TEST_F(DownloadManagerTest, testStartErrorCallback)
2582+{
2583+ auto mockDownload = new MockDownload();
2584+ auto mockError = new MockError();
2585+ EXPECT_CALL(*mockDownload, error())
2586+ .Times(1)
2587+ .WillOnce(Return(mockError));
2588+ EXPECT_CALL(*mockError, errorString())
2589+ .Times(1)
2590+ .WillOnce(Return(QStringLiteral("")));
2591+
2592+ EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
2593+ EXPECT_CALL(*sdmPtr, createDownload(_, _, _))
2594+ .Times(1)
2595+ .WillOnce(InvokeArgument<2>(mockDownload));
2596+ EXPECT_CALL(*this, start_callback(_, _)).Times(1);
2597+
2598+ dmPtr->start("", "", "",
2599+ [this](std::string msg, click::DownloadManager::Error err) {
2600+ start_callback(msg, err);
2601+ });
2602+
2603+ delete mockError;
2604+ delete mockDownload;
2605+}
2606+
2607+TEST_F(DownloadManagerTest, testGetProgressDownloadFound)
2608+{
2609+ auto mockDownloadsList = new MockDownloadsList();
2610+ auto mockDownload = QSharedPointer<MockDownload>(new MockDownload());
2611+
2612+ QList<QSharedPointer<Ubuntu::DownloadManager::Download>> downloads{mockDownload};
2613+
2614+ EXPECT_CALL(*mockDownload, id())
2615+ .Times(1)
2616+ .WillOnce(Return("download"));
2617+ EXPECT_CALL(*mockDownloadsList, downloads())
2618+ .Times(1)
2619+ .WillOnce(Return(downloads));
2620+ EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
2621+ .Times(1)
2622+ .WillOnce(InvokeArgument<2>(QStringLiteral(""), QStringLiteral(""),
2623+ mockDownloadsList));
2624+ dmPtr->get_progress("com.example.test",
2625+ [this](std::string object_path) {
2626+ progress_callback(object_path);
2627+ });
2628+
2629+ delete mockDownloadsList;
2630+}
2631+
2632+TEST_F(DownloadManagerTest, testGetProgressMultipleDownloadsFound)
2633+{
2634+ auto mockDownloadsList = new MockDownloadsList();
2635+ auto mockDownload = QSharedPointer<MockDownload>(new MockDownload());
2636+ auto mockDownload2 = QSharedPointer<MockDownload>(new MockDownload());
2637+
2638+ QList<QSharedPointer<Ubuntu::DownloadManager::Download>> downloads{mockDownload, mockDownload2};
2639+
2640+ EXPECT_CALL(*mockDownload, id())
2641+ .Times(1)
2642+ .WillOnce(Return("download"));
2643+ EXPECT_CALL(*mockDownloadsList, downloads())
2644+ .Times(1)
2645+ .WillOnce(Return(downloads));
2646+ EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
2647+ .Times(1)
2648+ .WillOnce(InvokeArgument<2>(QStringLiteral(""), QStringLiteral(""),
2649+ mockDownloadsList));
2650+ dmPtr->get_progress("com.example.test",
2651+ [this](std::string object_path) {
2652+ progress_callback(object_path);
2653+ });
2654+
2655+ delete mockDownloadsList;
2656+}
2657+
2658+TEST_F(DownloadManagerTest, testGetProgressNoDownloadsFound)
2659+{
2660+ auto mockDownloadsList = new MockDownloadsList();
2661+ QList<QSharedPointer<Ubuntu::DownloadManager::Download>> emptyDownloads{};
2662+ EXPECT_CALL(*mockDownloadsList, downloads())
2663+ .Times(1)
2664+ .WillOnce(Return(emptyDownloads));
2665+ EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
2666+ .Times(1)
2667+ .WillOnce(InvokeArgument<2>(QStringLiteral(""), QStringLiteral(""),
2668+ mockDownloadsList));
2669+ dmPtr->get_progress("com.example.test",
2670+ [this](std::string object_path) {
2671+ progress_callback(object_path);
2672+ });
2673+
2674+ delete mockDownloadsList;
2675+}
2676+
2677+TEST_F(DownloadManagerTest, testGetProgressErrorCallback)
2678 {
2679 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
2680 .Times(1)
2681
2682=== modified file 'libclickscope/tests/test_index.cpp'
2683--- libclickscope/tests/test_index.cpp 2016-05-10 13:42:12 +0000
2684+++ libclickscope/tests/test_index.cpp 2016-08-24 21:39:08 +0000
2685@@ -97,7 +97,7 @@
2686 TEST_F(IndexTest, testSearchCallsWebservice)
2687 {
2688 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2689- auto response = responseForReply(reply.asSharedPtr());
2690+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2691
2692 EXPECT_CALL(*configPtr, get_architecture())
2693 .Times(1)
2694@@ -120,7 +120,7 @@
2695 TEST_F(IndexTest, testSearchQueryIsLowercase)
2696 {
2697 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2698- auto response = responseForReply(reply.asSharedPtr());
2699+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2700
2701 EXPECT_CALL(*configPtr, get_architecture())
2702 .Times(1)
2703@@ -139,7 +139,7 @@
2704 TEST_F(IndexTest, testSearchSignsCall)
2705 {
2706 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2707- auto response = responseForReply(reply.asSharedPtr());
2708+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2709
2710 EXPECT_CALL(*configPtr, get_architecture())
2711 .Times(1)
2712@@ -154,10 +154,160 @@
2713 indexPtr->search("", "", [](click::Packages, click::Packages) {});
2714 }
2715
2716+TEST_F(IndexTest, testSearchSnapsCallsWebservice)
2717+{
2718+ LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2719+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2720+
2721+ EXPECT_CALL(*configPtr, get_architecture())
2722+ .Times(1)
2723+ .WillOnce(Return(fake_arch));
2724+ EXPECT_CALL(*configPtr, get_available_frameworks())
2725+ .Times(1)
2726+ .WillOnce(Return(fake_frameworks));
2727+ EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2728+ .Times(1)
2729+ .WillOnce(Return(response));
2730+
2731+ indexPtr->search_snaps("", [](click::Packages, click::Packages) {});
2732+}
2733+
2734+TEST_F(IndexTest, testSearchSnapsSendsRightPath)
2735+{
2736+ LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2737+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2738+
2739+ EXPECT_CALL(*configPtr, get_architecture())
2740+ .Times(1)
2741+ .WillOnce(Return(fake_arch));
2742+ EXPECT_CALL(*configPtr, get_available_frameworks())
2743+ .Times(1)
2744+ .WillOnce(Return(fake_frameworks));
2745+ EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::SNAP_SEARCH_PATH),
2746+ _, _, _, _, _))
2747+ .Times(1)
2748+ .WillOnce(Return(response));
2749+
2750+ indexPtr->search_snaps("", [](click::Packages, click::Packages) {});
2751+}
2752+
2753+TEST_F(IndexTest, testSearchSnapsQueryIsLowercase)
2754+{
2755+ LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2756+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2757+
2758+ EXPECT_CALL(*configPtr, get_architecture())
2759+ .Times(1)
2760+ .WillOnce(Return(fake_arch));
2761+ EXPECT_CALL(*configPtr, get_available_frameworks())
2762+ .Times(1)
2763+ .WillOnce(Return(fake_frameworks));
2764+ EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, QueryContains("foobar")))
2765+ .Times(1)
2766+ .WillOnce(Return(response));
2767+
2768+ indexPtr->search_snaps("FooBar", [](click::Packages, click::Packages) {});
2769+}
2770+
2771+
2772+TEST_F(IndexTest, testSearcSnapshSignsCall)
2773+{
2774+ LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2775+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2776+
2777+ EXPECT_CALL(*configPtr, get_architecture())
2778+ .Times(1)
2779+ .WillOnce(Return(fake_arch));
2780+ EXPECT_CALL(*configPtr, get_available_frameworks())
2781+ .Times(1)
2782+ .WillOnce(Return(fake_frameworks));
2783+ EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))
2784+ .Times(1)
2785+ .WillOnce(Return(response));
2786+
2787+ indexPtr->search_snaps("", [](click::Packages, click::Packages) {});
2788+}
2789+
2790+TEST_F(IndexTest, testSearchSnapsIsCancellable)
2791+{
2792+ LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2793+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2794+
2795+ EXPECT_CALL(*configPtr, get_architecture())
2796+ .Times(1)
2797+ .WillOnce(Return(fake_arch));
2798+ EXPECT_CALL(*configPtr, get_available_frameworks())
2799+ .Times(1)
2800+ .WillOnce(Return(fake_frameworks));
2801+ EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2802+ .Times(1)
2803+ .WillOnce(Return(response));
2804+
2805+ auto search_operation = indexPtr->search_snaps("", [](click::Packages,
2806+ click::Packages) {});
2807+ EXPECT_CALL(reply.instance, abort()).Times(1);
2808+ search_operation.cancel();
2809+}
2810+
2811+TEST_F(IndexTest, testSearchSnapsEmptyJsonIsParsed)
2812+{
2813+ LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2814+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2815+
2816+ QByteArray fake_json("[]");
2817+ EXPECT_CALL(reply.instance, readAll())
2818+ .Times(1)
2819+ .WillOnce(Return(fake_json));
2820+ EXPECT_CALL(*configPtr, get_architecture())
2821+ .Times(1)
2822+ .WillOnce(Return(fake_arch));
2823+ EXPECT_CALL(*configPtr, get_available_frameworks())
2824+ .Times(1)
2825+ .WillOnce(Return(fake_frameworks));
2826+ EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2827+ .Times(1)
2828+ .WillOnce(Return(response));
2829+ click::Packages empty_package_list;
2830+ EXPECT_CALL(*this, search_callback(empty_package_list, _)).Times(1);
2831+
2832+ indexPtr->search_snaps("", [this](click::Packages packages,
2833+ click::Packages recommends){
2834+ search_callback(packages, recommends);
2835+ });
2836+ response->replyFinished();
2837+}
2838+
2839+TEST_F(IndexTest, testSearchSnapsNetworkErrorIgnored)
2840+{
2841+ LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2842+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2843+
2844+ EXPECT_CALL(*configPtr, get_architecture())
2845+ .Times(1)
2846+ .WillOnce(Return(fake_arch));
2847+ EXPECT_CALL(*configPtr, get_available_frameworks())
2848+ .Times(1)
2849+ .WillOnce(Return(fake_frameworks));
2850+ EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2851+ .Times(1)
2852+ .WillOnce(Return(response));
2853+ EXPECT_CALL(reply.instance, errorString()).Times(1)
2854+ .WillOnce(Return("fake error"));
2855+ indexPtr->search_snaps("", [this](click::Packages packages,
2856+ click::Packages recommends){
2857+ search_callback(packages, recommends);
2858+ });
2859+
2860+ click::Packages empty_package_list;
2861+ EXPECT_CALL(*this, search_callback(empty_package_list, _)).Times(1);
2862+
2863+ emit reply.instance.error(QNetworkReply::UnknownNetworkError);
2864+}
2865+
2866 TEST_F(IndexTest, testBootstrapSignsCall)
2867 {
2868 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2869- auto response = responseForReply(reply.asSharedPtr());
2870+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2871
2872 EXPECT_CALL(*configPtr, get_architecture())
2873 .Times(1)
2874@@ -175,7 +325,7 @@
2875 TEST_F(IndexTest, testDepartmentsSignsCall)
2876 {
2877 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2878- auto response = responseForReply(reply.asSharedPtr());
2879+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2880
2881 EXPECT_CALL(*configPtr, get_architecture())
2882 .Times(1)
2883@@ -193,8 +343,14 @@
2884 TEST_F(IndexTest, testDetailsSignsCall)
2885 {
2886 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2887- auto response = responseForReply(reply.asSharedPtr());
2888+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2889
2890+ EXPECT_CALL(*configPtr, get_architecture())
2891+ .Times(1)
2892+ .WillOnce(Return(fake_arch));
2893+ EXPECT_CALL(*configPtr, get_available_frameworks())
2894+ .Times(1)
2895+ .WillOnce(Return(fake_frameworks));
2896 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))
2897 .Times(1)
2898 .WillOnce(Return(response));
2899@@ -205,7 +361,7 @@
2900 TEST_F(IndexTest, testSearchSendsRightPath)
2901 {
2902 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2903- auto response = responseForReply(reply.asSharedPtr());
2904+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2905
2906 EXPECT_CALL(*configPtr, get_architecture())
2907 .Times(1)
2908@@ -224,7 +380,7 @@
2909 TEST_F(IndexTest, testSearchCallbackIsCalled)
2910 {
2911 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2912- auto response = responseForReply(reply.asSharedPtr());
2913+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2914
2915 QByteArray fake_json("[]");
2916 EXPECT_CALL(reply.instance, readAll())
2917@@ -251,7 +407,7 @@
2918 TEST_F(IndexTest, testSearchEmptyJsonIsParsed)
2919 {
2920 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2921- auto response = responseForReply(reply.asSharedPtr());
2922+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2923
2924 QByteArray fake_json("[]");
2925 EXPECT_CALL(reply.instance, readAll())
2926@@ -279,7 +435,7 @@
2927 TEST_F(IndexTest, testSearchSingleJsonIsParsed)
2928 {
2929 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2930- auto response = responseForReply(reply.asSharedPtr());
2931+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2932
2933 QByteArray fake_json(FAKE_JSON_SEARCH_RESULT_ONE.c_str());
2934 EXPECT_CALL(reply.instance, readAll())
2935@@ -315,7 +471,7 @@
2936 TEST_F(IndexTest, testSearchIsCancellable)
2937 {
2938 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2939- auto response = responseForReply(reply.asSharedPtr());
2940+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2941
2942 EXPECT_CALL(*configPtr, get_architecture())
2943 .Times(1)
2944@@ -341,7 +497,7 @@
2945 TEST_F(IndexTest, testSearchNetworkErrorIgnored)
2946 {
2947 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2948- auto response = responseForReply(reply.asSharedPtr());
2949+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2950
2951 EXPECT_CALL(*configPtr, get_architecture())
2952 .Times(1)
2953@@ -367,8 +523,14 @@
2954 TEST_F(IndexTest, testGetDetailsCallsWebservice)
2955 {
2956 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2957- auto response = responseForReply(reply.asSharedPtr());
2958+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2959
2960+ EXPECT_CALL(*configPtr, get_architecture())
2961+ .Times(1)
2962+ .WillOnce(Return(fake_arch));
2963+ EXPECT_CALL(*configPtr, get_available_frameworks())
2964+ .Times(1)
2965+ .WillOnce(Return(fake_frameworks));
2966 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
2967 .Times(1)
2968 .WillOnce(Return(response));
2969@@ -379,8 +541,14 @@
2970 TEST_F(IndexTest, testGetDetailsSendsPackagename)
2971 {
2972 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2973- auto response = responseForReply(reply.asSharedPtr());
2974+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2975
2976+ EXPECT_CALL(*configPtr, get_architecture())
2977+ .Times(1)
2978+ .WillOnce(Return(fake_arch));
2979+ EXPECT_CALL(*configPtr, get_available_frameworks())
2980+ .Times(1)
2981+ .WillOnce(Return(fake_frameworks));
2982 EXPECT_CALL(*clientPtr, callImpl(EndsWith(FAKE_PACKAGENAME),
2983 _, _, _, _, _))
2984 .Times(1)
2985@@ -392,8 +560,14 @@
2986 TEST_F(IndexTest, testGetDetailsSendsRightPath)
2987 {
2988 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
2989- auto response = responseForReply(reply.asSharedPtr());
2990+ auto response = MockClient::responseForReply(reply.asSharedPtr());
2991
2992+ EXPECT_CALL(*configPtr, get_architecture())
2993+ .Times(1)
2994+ .WillOnce(Return(fake_arch));
2995+ EXPECT_CALL(*configPtr, get_available_frameworks())
2996+ .Times(1)
2997+ .WillOnce(Return(fake_frameworks));
2998 EXPECT_CALL(*clientPtr, callImpl(StartsWith(click::SEARCH_BASE_URL +
2999 click::DETAILS_PATH),
3000 _, _, _, _, _))
3001@@ -406,8 +580,14 @@
3002 TEST_F(IndexTest, testGetDetailsCallbackIsCalled)
3003 {
3004 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3005- auto response = responseForReply(reply.asSharedPtr());
3006+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3007
3008+ EXPECT_CALL(*configPtr, get_architecture())
3009+ .Times(1)
3010+ .WillOnce(Return(fake_arch));
3011+ EXPECT_CALL(*configPtr, get_available_frameworks())
3012+ .Times(1)
3013+ .WillOnce(Return(fake_frameworks));
3014 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());
3015 EXPECT_CALL(reply.instance, readAll())
3016 .Times(1)
3017@@ -425,8 +605,14 @@
3018 TEST_F(IndexTest, testGetDetailsJsonIsParsed)
3019 {
3020 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3021- auto response = responseForReply(reply.asSharedPtr());
3022+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3023
3024+ EXPECT_CALL(*configPtr, get_architecture())
3025+ .Times(1)
3026+ .WillOnce(Return(fake_arch));
3027+ EXPECT_CALL(*configPtr, get_available_frameworks())
3028+ .Times(1)
3029+ .WillOnce(Return(fake_frameworks));
3030 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());
3031 EXPECT_CALL(reply.instance, readAll())
3032 .Times(1)
3033@@ -486,7 +672,14 @@
3034 TEST_F(IndexTest, testGetDetailsJsonUtf8)
3035 {
3036 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3037- auto response = responseForReply(reply.asSharedPtr());
3038+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3039+
3040+ EXPECT_CALL(*configPtr, get_architecture())
3041+ .Times(1)
3042+ .WillOnce(Return(fake_arch));
3043+ EXPECT_CALL(*configPtr, get_available_frameworks())
3044+ .Times(1)
3045+ .WillOnce(Return(fake_frameworks));
3046
3047 QByteArray appname_utf8("\xe5\xb0\x8f\xe6\xb5\xb7");
3048 QByteArray appname_json("\\u5c0f\\u6d77");
3049@@ -554,8 +747,14 @@
3050 TEST_F(IndexTest, testGetDetailsNetworkErrorReported)
3051 {
3052 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3053- auto response = responseForReply(reply.asSharedPtr());
3054+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3055
3056+ EXPECT_CALL(*configPtr, get_architecture())
3057+ .Times(1)
3058+ .WillOnce(Return(fake_arch));
3059+ EXPECT_CALL(*configPtr, get_available_frameworks())
3060+ .Times(1)
3061+ .WillOnce(Return(fake_frameworks));
3062 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
3063 .Times(1)
3064 .WillOnce(Return(response));
3065@@ -571,8 +770,14 @@
3066 TEST_F(IndexTest, testGetDetailsIsCancellable)
3067 {
3068 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3069- auto response = responseForReply(reply.asSharedPtr());
3070+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3071
3072+ EXPECT_CALL(*configPtr, get_architecture())
3073+ .Times(1)
3074+ .WillOnce(Return(fake_arch));
3075+ EXPECT_CALL(*configPtr, get_available_frameworks())
3076+ .Times(1)
3077+ .WillOnce(Return(fake_frameworks));
3078 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
3079 .Times(1)
3080 .WillOnce(Return(response));
3081
3082=== modified file 'libclickscope/tests/test_interface.cpp'
3083--- libclickscope/tests/test_interface.cpp 2016-07-11 19:12:17 +0000
3084+++ libclickscope/tests/test_interface.cpp 2016-08-24 21:39:08 +0000
3085@@ -28,6 +28,7 @@
3086 */
3087
3088 #include "fake_json.h"
3089+#include "mock_ual.h"
3090 #include "test_data.h"
3091
3092 #include <QCoreApplication>
3093@@ -41,7 +42,6 @@
3094 #include <gtest/gtest.h>
3095
3096 #include <click/interface.h>
3097-#include <click/key_file_locator.h>
3098 #include <click/departments-db.h>
3099
3100 using namespace click;
3101@@ -99,30 +99,6 @@
3102 {
3103 const std::string emptyQuery{};
3104
3105-struct MockKeyFileLocator : public click::KeyFileLocator
3106-{
3107- typedef click::KeyFileLocator Super;
3108-
3109- MockKeyFileLocator()
3110- {
3111- using namespace ::testing;
3112-
3113- ON_CALL(*this, enumerateKeyFilesForInstalledApplications(_))
3114- .WillByDefault(
3115- Invoke(
3116- this,
3117- &MockKeyFileLocator::doEnumerateKeyFilesForInstalledApplications));
3118- }
3119-
3120- MOCK_METHOD1(enumerateKeyFilesForInstalledApplications,
3121- void(const Super::Enumerator&));
3122-
3123- void doEnumerateKeyFilesForInstalledApplications(const Super::Enumerator& enumerator)
3124- {
3125- Super::enumerateKeyFilesForInstalledApplications(enumerator);
3126- }
3127-};
3128-
3129 class ClickInterfaceTest : public ::testing::Test {
3130 public:
3131 MOCK_METHOD2(manifest_callback, void(Manifest, InterfaceError));
3132@@ -136,11 +112,10 @@
3133
3134 class FakeClickInterface : public click::Interface {
3135 public:
3136- FakeClickInterface(const QSharedPointer<KeyFileLocator>& keyFileLocator) : Interface(keyFileLocator) {}
3137 FakeClickInterface() {}
3138
3139- MOCK_METHOD0(show_desktop_apps, bool());
3140- MOCK_METHOD2(run_process, void(const std::string&, std::function<void(int, const std::string&, const std::string&)>));
3141+ MOCK_METHOD1(get_manifest_json, std::string(const std::string&));
3142+ MOCK_METHOD0(installed_apps, std::list<std::shared_ptr<ual::Application>>());
3143 };
3144
3145 TEST(ClickInterface, testIsNonClickAppFalse)
3146@@ -154,114 +129,104 @@
3147 // If this ever breaks, something is very very wrong.
3148 for (const auto& element : nonClickDesktopFiles())
3149 {
3150- QString filename = element.c_str();
3151- EXPECT_TRUE(Interface::is_non_click_app(filename));
3152+ EXPECT_TRUE(Interface::is_non_click_app(element));
3153 }
3154 }
3155
3156-TEST(ClickInterface, testCallsIntoKeyFileLocatorForFindingInstalledApps)
3157-{
3158- using namespace ::testing;
3159- MockKeyFileLocator mockKeyFileLocator;
3160- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3161- &mockKeyFileLocator,
3162- [](click::KeyFileLocator*){});
3163-
3164-
3165- FakeClickInterface iface(keyFileLocator);
3166- EXPECT_CALL(iface, show_desktop_apps())
3167- .Times(1)
3168- .WillOnce(Return(false));
3169-
3170- EXPECT_CALL(mockKeyFileLocator, enumerateKeyFilesForInstalledApplications(_)).Times(1);
3171-
3172- iface.find_installed_apps(emptyQuery);
3173-}
3174-
3175 TEST(ClickInterface, testFindAppsInDirEmpty)
3176 {
3177- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3178- new click::KeyFileLocator(
3179- testing::systemApplicationsDirectoryForTesting(),
3180- testing::userApplicationsDirectoryForTesting()));
3181-
3182- click::Interface iface(keyFileLocator);
3183-
3184- auto results = iface.find_installed_apps("xyzzygy");
3185+ FakeClickInterface iface;
3186+
3187+ EXPECT_CALL(iface, installed_apps()).Times(1).
3188+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{}));
3189+ auto results = iface.search("xyzzygy");
3190
3191 EXPECT_TRUE(results.empty());
3192 }
3193
3194 TEST_F(ClickInterfaceTest, testFindAppsInDirIgnoredApps)
3195 {
3196- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3197- new click::KeyFileLocator(
3198- testing::systemApplicationsDirectoryForTesting(),
3199- testing::userApplicationsDirectoryForTesting()));
3200+ FakeClickInterface iface;
3201+ std::list<std::shared_ptr<ual::Application>> applist{
3202+ MockUALApplication::create(ual::AppID::parse("com.ubuntu.calculator_calculator_0.1"),
3203+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Calculator", "The calculator", "/opt/click.ubuntu.com/foo/bar/calculator.png")}),
3204+ MockUALApplication::create(ual::AppID::find("webbrowser-app"),
3205+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Browser", "The browser", "webbrowser-app")}),
3206+ MockUALApplication::create(ual::AppID::find("messaging-app"),
3207+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Messaging", "Your messages", "messaging-app")}),
3208+ };
3209
3210- click::Interface iface(keyFileLocator);
3211 ignoredApps.push_back("messaging-app.desktop");
3212 ignoredApps.push_back("com.ubuntu.calculator");
3213
3214- auto results = iface.find_installed_apps("", ignoredApps);
3215- EXPECT_EQ(20, results.size());
3216+ EXPECT_CALL(iface, installed_apps()).Times(1).
3217+ WillOnce(Return(applist));
3218+ auto results = iface.search("", ignoredApps);
3219+ ASSERT_EQ(1, results.size());
3220 }
3221
3222 TEST_F(ClickInterfaceTest, testFindClockUsesShortAppid)
3223 {
3224- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3225- new click::KeyFileLocator(
3226- testing::systemApplicationsDirectoryForTesting(),
3227- testing::userApplicationsDirectoryForTesting()));
3228-
3229- click::Interface iface(keyFileLocator);
3230-
3231- auto results = iface.find_installed_apps("Clock");
3232- EXPECT_EQ(1u, results.size());
3233+ FakeClickInterface iface;
3234+
3235+ EXPECT_CALL(iface, installed_apps()).Times(1).
3236+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
3237+ MockUALApplication::create(ual::AppID::parse("com.ubuntu.clock_clock_0.1"),
3238+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Clock", "The clock", "/opt/click.ubuntu.com/foo/bar/clock.png")}),
3239+ }));
3240+ auto results = iface.search("Clock");
3241+ ASSERT_EQ(1u, results.size());
3242 EXPECT_EQ("appid://com.ubuntu.clock/clock/current-user-version", results.begin()->url);
3243 }
3244
3245 TEST_F(ClickInterfaceTest, testFindLegacyAppUsesDeskopId)
3246 {
3247- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3248- new click::KeyFileLocator(
3249- testing::systemApplicationsDirectoryForTesting(),
3250- testing::userApplicationsDirectoryForTesting()));
3251-
3252- click::Interface iface(keyFileLocator);
3253-
3254- auto results = iface.find_installed_apps("Messaging");
3255- EXPECT_EQ(1u, results.size());
3256+ FakeClickInterface iface;
3257+
3258+ EXPECT_CALL(iface, installed_apps()).Times(1).
3259+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
3260+ MockUALApplication::create(ual::AppID::find("messaging-app"),
3261+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Messaging", "Your messages", "messaging-app")})
3262+ }));
3263+ auto results = iface.search("Messaging");
3264+ ASSERT_EQ(1u, results.size());
3265 EXPECT_EQ("application:///messaging-app.desktop", results.begin()->url);
3266 }
3267
3268-//
3269 // test that application with a default department id key in the desktop
3270 // file is returned when department matches
3271 TEST_F(ClickInterfaceTest, testFindAppsWithAppWithDefaultDepartmentId)
3272 {
3273- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3274- new click::KeyFileLocator(
3275- testing::systemApplicationsDirectoryForTesting(),
3276- testing::userApplicationsDirectoryForTesting()));
3277-
3278- click::Interface iface(keyFileLocator);
3279+ FakeClickInterface iface;
3280+
3281+ auto mockapp = MockUALApplication::create(ual::AppID::find("address-book-app"),
3282+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Contacts", "Address book", "address-book-app")});
3283+
3284+ auto dept = ual::Application::Info::DefaultDepartment::from_raw("accessories");
3285+ DefaultValue<const ual::Application::Info::DefaultDepartment&>::Set(dept);
3286+
3287+ EXPECT_CALL(iface, installed_apps()).Times(1).
3288+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{mockapp}));
3289
3290 auto depts_db = std::make_shared<click::DepartmentsDb>(":memory:");
3291- auto results = iface.find_installed_apps("", ignoredApps, "accessories", depts_db);
3292+ auto results = iface.search("", ignoredApps, "accessories", depts_db);
3293
3294- EXPECT_EQ(1u, results.size());
3295+ ASSERT_EQ(1u, results.size());
3296 EXPECT_EQ("Contacts", results.begin()->title);
3297 }
3298
3299 TEST_F(ClickInterfaceTest, testFindAppsWithAppWithDefaultDepartmentIdOverriden)
3300 {
3301- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3302- new click::KeyFileLocator(
3303- testing::systemApplicationsDirectoryForTesting(),
3304- testing::userApplicationsDirectoryForTesting()));
3305-
3306- click::Interface iface(keyFileLocator);
3307+ FakeClickInterface iface;
3308+
3309+ auto mockapp = MockUALApplication::create(ual::AppID::find("address-book-app"),
3310+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Contacts", "Address book", "address-book-app")});
3311+
3312+ auto dept = ual::Application::Info::DefaultDepartment::from_raw("accessories");
3313+ DefaultValue<const ual::Application::Info::DefaultDepartment&>::Set(dept);
3314+
3315+ EXPECT_CALL(iface, installed_apps()).
3316+ WillRepeatedly(Return(std::list<std::shared_ptr<ual::Application>>{mockapp}));
3317
3318 auto depts_db = std::make_shared<click::DepartmentsDb>(":memory:");
3319
3320@@ -270,32 +235,42 @@
3321 depts_db->store_department_mapping("utilities", "");
3322 depts_db->store_department_mapping("accessories", "");
3323
3324- auto results = iface.find_installed_apps("", ignoredApps, "utilies", depts_db);
3325- EXPECT_EQ(0, results.size());
3326+ auto results = iface.search("", ignoredApps, "utilies", depts_db);
3327+ ASSERT_EQ(0, results.size());
3328
3329 // address book applicaton moved to utilities
3330 depts_db->store_package_mapping("address-book-app.desktop", "utilities");
3331- results = iface.find_installed_apps("", ignoredApps, "utilities", depts_db);
3332+ results = iface.search("", ignoredApps, "utilities", depts_db);
3333
3334- EXPECT_EQ(1u, results.size());
3335+ ASSERT_EQ(1u, results.size());
3336 EXPECT_EQ("Contacts", results.begin()->title);
3337 }
3338
3339 TEST(ClickInterface, testFindAppsInDirSorted)
3340 {
3341- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3342- new click::KeyFileLocator(
3343- testing::systemApplicationsDirectoryForTesting(),
3344- testing::userApplicationsDirectoryForTesting()));
3345-
3346- click::Interface iface(keyFileLocator);
3347-
3348- auto results = iface.find_installed_apps("ock");
3349+ FakeClickInterface iface;
3350+
3351+ EXPECT_CALL(iface, installed_apps()).Times(1).
3352+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
3353+ MockUALApplication::create(ual::AppID::parse("com.ubuntu.clock_clock_0.1"),
3354+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Clock", "The clock", "/opt/click.ubuntu.com/foo/bar/clock.png")}),
3355+ MockUALApplication::create(ual::AppID::find("address-book-app"),
3356+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Contacts", "Address book", "address-book-app")}),
3357+ MockUALApplication::create(ual::AppID::parse("com.ubuntu.stock-ticker-mobile_stockticker_0.1"),
3358+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Stock Ticker", "A stock ticker.", "/opt/click.ubuntu.com/foo/bar/stock_icon_48.png")}),
3359+ }));
3360+
3361+ auto results = iface.search("ock");
3362
3363 const std::vector<click::Application> expected_results = {
3364- {"com.ubuntu.clock", "Clock", 0.0, "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock/./clock64.png", "application:///com.ubuntu.clock_clock_1.0.300.desktop", "", "", ""},
3365+ {"com.ubuntu.clock", "Clock", 0.0,
3366+ "/opt/click.ubuntu.com/foo/bar/clock.png",
3367+ "appid://com.ubuntu.clock/clock/current-user-version",
3368+ "The clock", "", ""},
3369 {"com.ubuntu.stock-ticker-mobile", "Stock Ticker", 0.0,
3370- "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.stock-ticker-mobile/icons/stock_icon_48.png", "application:///com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop", "An awesome Stock Ticker application with all the features you could imagine", "", ""},
3371+ "/opt/click.ubuntu.com/foo/bar/stock_icon_48.png",
3372+ "appid://com.ubuntu.stock-ticker-mobile/stockticker/current-user-version",
3373+ "A stock ticker.", "", ""},
3374 };
3375 EXPECT_EQ(expected_results, results);
3376 }
3377@@ -382,58 +357,70 @@
3378 ASSERT_EQ(unsetenv(Configuration::LANGUAGE_ENVVAR), 0);
3379 }
3380
3381-TEST(ClickInterface, testFindAppByKeyword)
3382-{
3383- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3384- new click::KeyFileLocator(
3385- testing::systemApplicationsDirectoryForTesting(),
3386- testing::userApplicationsDirectoryForTesting()));
3387-
3388- click::Interface iface(keyFileLocator);
3389-
3390- auto results = iface.find_installed_apps("rss");
3391-
3392- EXPECT_EQ(1, results.size());
3393-}
3394-
3395-TEST(ClickInterface, testFindAppByKeywordCaseInsensitive)
3396-{
3397- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3398- new click::KeyFileLocator(
3399- testing::systemApplicationsDirectoryForTesting(),
3400- testing::userApplicationsDirectoryForTesting()));
3401-
3402- click::Interface iface(keyFileLocator);
3403-
3404- auto results = iface.find_installed_apps("RsS");
3405-
3406- EXPECT_EQ(1, results.size());
3407-}
3408-
3409-TEST(ClickInterface, testFindAppAccented)
3410-{
3411- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3412- new click::KeyFileLocator(
3413- testing::systemApplicationsDirectoryForTesting(),
3414- testing::userApplicationsDirectoryForTesting()));
3415-
3416- click::Interface iface(keyFileLocator);
3417-
3418- auto results = iface.find_installed_apps("Cámara");
3419-
3420- EXPECT_EQ(1, results.size());
3421-}
3422-
3423-TEST(ClickInterface, testFindAppAccented2)
3424-{
3425- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3426- new click::KeyFileLocator(
3427- testing::systemApplicationsDirectoryForTesting(),
3428- testing::userApplicationsDirectoryForTesting()));
3429-
3430- click::Interface iface(keyFileLocator);
3431-
3432- auto results = iface.find_installed_apps("Camara");
3433+TEST_F(ClickInterfaceTest, testFindAppByKeyword)
3434+{
3435+ FakeClickInterface iface;
3436+
3437+ auto mockapp = MockUALApplication::create(ual::AppID::parse("com.ubuntu.camera_camera_5"),
3438+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Cámara", "La cámara", "/opt/click.ubuntu.com/foo/bar/camera.png")});
3439+
3440+ std::vector<std::string>keys{"foo", "bar", "rss", "baz"};
3441+ auto mockkw = ual::Application::Info::Keywords::from_raw(keys);
3442+ DefaultValue<const ual::Application::Info::Keywords&>::Set(mockkw);
3443+
3444+ EXPECT_CALL(iface, installed_apps()).Times(1).
3445+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{mockapp}));
3446+
3447+ auto results = iface.search("rss");
3448+
3449+ EXPECT_EQ(1, results.size());
3450+}
3451+
3452+TEST_F(ClickInterfaceTest, testFindAppByKeywordCaseInsensitive)
3453+{
3454+ FakeClickInterface iface;
3455+
3456+ auto mockapp = MockUALApplication::create(ual::AppID::parse("com.ubuntu.camera_camera_5"),
3457+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Cámara", "La cámara", "/opt/click.ubuntu.com/foo/bar/camera.png")});
3458+
3459+ std::vector<std::string>keys{"foo", "bar", "rss", "baz"};
3460+ auto mockkw = ual::Application::Info::Keywords::from_raw(keys);
3461+ DefaultValue<const ual::Application::Info::Keywords&>::Set(mockkw);
3462+
3463+ EXPECT_CALL(iface, installed_apps()).Times(1).
3464+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{mockapp}));
3465+
3466+ auto results = iface.search("RsS");
3467+
3468+ EXPECT_EQ(1, results.size());
3469+}
3470+
3471+TEST_F(ClickInterfaceTest, testFindAppAccented)
3472+{
3473+ FakeClickInterface iface;
3474+
3475+ EXPECT_CALL(iface, installed_apps()).Times(1).
3476+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
3477+ MockUALApplication::create(ual::AppID::parse("com.ubuntu.camera_camera_5"),
3478+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Cámara", "La cámara", "/opt/click.ubuntu.com/foo/bar/camera.png")}),
3479+ }));
3480+
3481+ auto results = iface.search("Cámara");
3482+
3483+ EXPECT_EQ(1, results.size());
3484+}
3485+
3486+TEST_F(ClickInterfaceTest, testFindAppAccented2)
3487+{
3488+ FakeClickInterface iface;
3489+
3490+ EXPECT_CALL(iface, installed_apps()).Times(1).
3491+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
3492+ MockUALApplication::create(ual::AppID::parse("com.ubuntu.camera_camera_5"),
3493+ std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Cámara", "La cámara", "/opt/click.ubuntu.com/foo/bar/camera.png")}),
3494+ }));
3495+
3496+ auto results = iface.search("Camara");
3497
3498 EXPECT_EQ(1, results.size());
3499 }
3500@@ -453,130 +440,6 @@
3501 Interface::add_theme_scheme("/usr/share/unity8/graphics/applicationIcons/contacts-app@18.png"));
3502 }
3503
3504-std::vector<click::Application> find_installed_apps(const std::string& query, bool include_desktop_results)
3505-{
3506- using namespace ::testing;
3507- QSharedPointer<click::KeyFileLocator> keyFileLocator(
3508- new click::KeyFileLocator(
3509- testing::systemApplicationsDirectoryForTesting(),
3510- testing::userApplicationsDirectoryForTesting()));
3511-
3512- FakeClickInterface iface(keyFileLocator);
3513- EXPECT_CALL(iface, show_desktop_apps())
3514- .Times(1)
3515- .WillOnce(Return(include_desktop_results));
3516-
3517- return iface.find_installed_apps(query);
3518-}
3519-
3520-TEST(ClickInterface, testFindInstalledAppsOnPhone)
3521-{
3522- auto result = find_installed_apps(emptyQuery, false);
3523-
3524- EXPECT_TRUE(result.size() > 0);
3525-
3526- for (const auto& app : non_desktop_applications)
3527- {
3528- qDebug() << "comparing" << QString::fromStdString(app.title);
3529- EXPECT_NE(result.end(), std::find(result.begin(), result.end(), app));
3530- }
3531-
3532- EXPECT_EQ(result.end(), std::find(result.begin(), result.end(), desktop_application));
3533-}
3534-
3535-TEST(ClickInterface, testFindInstalledAppsOnDesktop)
3536-{
3537- auto result = find_installed_apps(emptyQuery, true);
3538-
3539- std::vector<click::Application> expected_apps(non_desktop_applications);
3540- expected_apps.push_back(desktop_application);
3541-
3542- EXPECT_TRUE(result.size() > 0);
3543-
3544- for (const auto& app : expected_apps)
3545- {
3546- qDebug() << "comparing" << QString::fromStdString(app.title);
3547- EXPECT_NE(result.end(), std::find(result.begin(), result.end(), app));
3548- }
3549-}
3550-
3551-TEST(ClickInterface, testInlineTranslationsLoaded)
3552-{
3553- QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
3554- click::Interface iface(keyFileLocator);
3555-
3556- auto nodisplay = testing::systemApplicationsDirectoryForTesting() + "/translated.desktop";
3557- unity::util::IniParser parser(nodisplay.data());
3558-
3559- ASSERT_EQ(setenv(Configuration::LANGUAGE_ENVVAR, "es_ES.UTF-8", 1), 0);
3560- auto app = iface.load_app_from_desktop(parser, nodisplay);
3561- EXPECT_EQ("Translated App in Spanish", app.title);
3562- EXPECT_EQ("Translated application in Spanish", app.description);
3563- ASSERT_EQ(unsetenv(Configuration::LANGUAGE_ENVVAR), 0);
3564-}
3565-
3566-TEST(ClickInterface, testIncludeInResultsNoDisplayTrue)
3567-{
3568- QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
3569- click::Interface iface(keyFileLocator);
3570-
3571- auto nodisplay = testing::userApplicationsDirectoryForTesting() + "/non-click-app-nodisplay.desktop";
3572- unity::util::IniParser parser(nodisplay.data());
3573-
3574- EXPECT_FALSE(iface.is_visible_app(parser));
3575-}
3576-
3577-TEST(ClickInterface, testIncludeInResultsOnlyShowInGnome)
3578-{
3579- QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
3580- click::Interface iface(keyFileLocator);
3581-
3582- auto nodisplay = testing::userApplicationsDirectoryForTesting() + "/non-click-app-onlyshowin-gnome.desktop";
3583- unity::util::IniParser parser(nodisplay.data());
3584-
3585- EXPECT_FALSE(iface.is_visible_app(parser));
3586-}
3587-
3588-TEST(ClickInterface, testIncludeInResultsOnlyShowInGnomeUnity)
3589-{
3590- QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
3591- click::Interface iface(keyFileLocator);
3592-
3593- auto nodisplay = testing::userApplicationsDirectoryForTesting() + "/non-click-app-onlyshowin-gnome-unity.desktop";
3594- unity::util::IniParser parser(nodisplay.data());
3595-
3596- EXPECT_TRUE(iface.is_visible_app(parser));
3597-}
3598-
3599-TEST(ClickInterface, testIncludeInResultsOnlyShowInUnity)
3600-{
3601- QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
3602- click::Interface iface(keyFileLocator);
3603-
3604- auto nodisplay = testing::userApplicationsDirectoryForTesting() + "/non-click-app-onlyshowin-unity.desktop";
3605- unity::util::IniParser parser(nodisplay.data());
3606-
3607- EXPECT_TRUE(iface.is_visible_app(parser));
3608-}
3609-
3610-TEST(ClickInterface, testEnableDesktopApps)
3611-{
3612- QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
3613- click::Interface iface(keyFileLocator);
3614-
3615- setenv(Interface::ENV_SHOW_DESKTOP_APPS, "YesPlease", true);
3616- EXPECT_TRUE(iface.show_desktop_apps());
3617-}
3618-
3619-TEST(ClickInterface, testDisableDesktopApps)
3620-{
3621- QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
3622- click::Interface iface(keyFileLocator);
3623-
3624- unsetenv(Interface::ENV_SHOW_DESKTOP_APPS);
3625- EXPECT_FALSE(iface.show_desktop_apps());
3626-}
3627-
3628 TEST(ClickInterface, testManifestFromJsonOneApp)
3629 {
3630 Manifest m = manifest_from_json(FAKE_JSON_MANIFEST_ONE_APP);
3631@@ -611,25 +474,12 @@
3632 ASSERT_TRUE(m.has_any_scopes());
3633 }
3634
3635-TEST(ClickInterface, testGetManifestForAppCorrectCommand)
3636-{
3637- FakeClickInterface iface;
3638- std::string command = "click info " + FAKE_PACKAGENAME;
3639- EXPECT_CALL(iface, run_process(command, _)).
3640- Times(1);
3641- iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest, InterfaceError){});
3642-}
3643-
3644 TEST_F(ClickInterfaceTest, testGetManifestForAppParseError)
3645 {
3646 FakeClickInterface iface;
3647- EXPECT_CALL(iface, run_process(_, _)).
3648+ EXPECT_CALL(iface, get_manifest_json(_)).
3649 Times(1).
3650- WillOnce(Invoke([&](const std::string&,
3651- std::function<void(int, const std::string&,
3652- const std::string&)> callback){
3653- callback(0, "INVALID JSON", "");
3654- }));
3655+ WillOnce(Return("INVALID JSON"));
3656 EXPECT_CALL(*this, manifest_callback(_, InterfaceError::ParseError));
3657 iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest,
3658 InterfaceError error){
3659@@ -637,33 +487,12 @@
3660 });
3661 }
3662
3663-TEST_F(ClickInterfaceTest, testGetManifestForAppCommandFailed)
3664-{
3665- FakeClickInterface iface;
3666- EXPECT_CALL(iface, run_process(_, _)).
3667- Times(1).
3668- WillOnce(Invoke([&](const std::string&,
3669- std::function<void(int, const std::string&,
3670- const std::string&)> callback){
3671- callback(-1, "", "CRITICAL: FAIL");
3672- }));
3673- EXPECT_CALL(*this, manifest_callback(_, InterfaceError::CallError));
3674- iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest,
3675- InterfaceError error){
3676- manifest_callback(manifest, error);
3677- });
3678-}
3679-
3680 TEST_F(ClickInterfaceTest, testGetManifestForAppIsRemovable)
3681 {
3682 FakeClickInterface iface;
3683- EXPECT_CALL(iface, run_process(_, _)).
3684+ EXPECT_CALL(iface, get_manifest_json(_)).
3685 Times(1).
3686- WillOnce(Invoke([&](const std::string&,
3687- std::function<void(int, const std::string&,
3688- const std::string&)> callback){
3689- callback(0, FAKE_JSON_MANIFEST_REMOVABLE, "");
3690- }));
3691+ WillOnce(Return(FAKE_JSON_MANIFEST_REMOVABLE));
3692 iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest,
3693 InterfaceError error){
3694 ASSERT_TRUE(error == InterfaceError::NoError);
3695@@ -674,13 +503,9 @@
3696 TEST_F(ClickInterfaceTest, testGetManifestForAppIsNotRemovable)
3697 {
3698 FakeClickInterface iface;
3699- EXPECT_CALL(iface, run_process(_, _)).
3700+ EXPECT_CALL(iface, get_manifest_json(_)).
3701 Times(1).
3702- WillOnce(Invoke([&](const std::string&,
3703- std::function<void(int, const std::string&,
3704- const std::string&)> callback){
3705- callback(0, FAKE_JSON_MANIFEST_NONREMOVABLE, "");
3706- }));
3707+ WillOnce(Return(FAKE_JSON_MANIFEST_NONREMOVABLE));
3708 iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest,
3709 InterfaceError error){
3710 ASSERT_TRUE(error == InterfaceError::NoError);
3711@@ -688,125 +513,16 @@
3712 });
3713 }
3714
3715-TEST(ClickInterface, testGetManifestsCorrectCommand)
3716-{
3717- FakeClickInterface iface;
3718- std::string command = "click list --manifest";
3719- EXPECT_CALL(iface, run_process(command, _)).
3720- Times(1);
3721- iface.get_manifests([](ManifestList, InterfaceError){});
3722-}
3723-
3724-TEST_F(ClickInterfaceTest, testGetManifestsParseError)
3725-{
3726- FakeClickInterface iface;
3727- EXPECT_CALL(iface, run_process(_, _)).
3728- Times(1).
3729- WillOnce(Invoke([&](const std::string&,
3730- std::function<void(int, const std::string&,
3731- const std::string&)> callback){
3732- callback(0, "INVALID JSON", "");
3733- }));
3734- EXPECT_CALL(*this, manifests_callback(_, InterfaceError::ParseError));
3735- iface.get_manifests([this](ManifestList manifests, InterfaceError error){
3736- manifests_callback(manifests, error);
3737- });
3738-}
3739-
3740-TEST_F(ClickInterfaceTest, testGetManifestsCommandFailed)
3741-{
3742- FakeClickInterface iface;
3743- EXPECT_CALL(iface, run_process(_, _)).
3744- Times(1).
3745- WillOnce(Invoke([&](const std::string&,
3746- std::function<void(int, const std::string&,
3747- const std::string&)> callback){
3748- callback(-1, "", "CRITICAL: FAIL");
3749- }));
3750- EXPECT_CALL(*this, manifests_callback(_, InterfaceError::CallError));
3751- iface.get_manifests([this](ManifestList manifests, InterfaceError error){
3752- manifests_callback(manifests, error);
3753- });
3754-}
3755-
3756-TEST_F(ClickInterfaceTest, testGetManifestsParsed)
3757-{
3758- FakeClickInterface iface;
3759- std::string expected_str = "[" + FAKE_JSON_MANIFEST_NONREMOVABLE + "," +
3760- FAKE_JSON_MANIFEST_REMOVABLE + "]";
3761- ManifestList expected = manifest_list_from_json(expected_str);
3762-
3763- EXPECT_CALL(iface, run_process(_, _)).
3764- Times(1).
3765- WillOnce(Invoke([&](const std::string&,
3766- std::function<void(int, const std::string&,
3767- const std::string&)> callback){
3768- callback(0, expected_str, "");
3769- }));
3770- iface.get_manifests([expected](ManifestList manifests, InterfaceError error){
3771- ASSERT_TRUE(error == InterfaceError::NoError);
3772- ASSERT_TRUE(manifests.size() == expected.size());
3773- });
3774-}
3775-
3776-TEST(ClickInterface, testGetInstalledPackagesCorrectCommand)
3777-{
3778- FakeClickInterface iface;
3779- std::string command = "click list";
3780- EXPECT_CALL(iface, run_process(command, _)).
3781- Times(1);
3782- iface.get_installed_packages([](PackageSet, InterfaceError){});
3783-}
3784-
3785-TEST_F(ClickInterfaceTest, testGetInstalledPackagesParseError)
3786-{
3787- FakeClickInterface iface;
3788- std::string bad_stdout = "INVALID: err\nvalid.package\t1.0\n";
3789- PackageSet expected{{"valid.package", "1.0"}};
3790-
3791- EXPECT_CALL(iface, run_process(_, _)).
3792- Times(1).
3793- WillOnce(Invoke([&](const std::string&,
3794- std::function<void(int, const std::string&,
3795- const std::string&)> callback){
3796- callback(0, bad_stdout, "");
3797- }));
3798- EXPECT_CALL(*this, installed_callback(_, InterfaceError::NoError));
3799- iface.get_installed_packages([this, expected](PackageSet package_names, InterfaceError error){
3800- installed_callback(package_names, error);
3801- ASSERT_EQ(package_names, expected);
3802- });
3803-}
3804-
3805-TEST_F(ClickInterfaceTest, testGetInstalledPackagesCommandFailed)
3806-{
3807- FakeClickInterface iface;
3808- EXPECT_CALL(iface, run_process(_, _)).
3809- Times(1).
3810- WillOnce(Invoke([&](const std::string&,
3811- std::function<void(int, const std::string&,
3812- const std::string&)> callback){
3813- callback(-1, "", "CRITICAL: FAIL");
3814- }));
3815- EXPECT_CALL(*this, installed_callback(_, InterfaceError::CallError));
3816- iface.get_installed_packages([this](PackageSet package_names, InterfaceError error){
3817- installed_callback(package_names, error);
3818- });
3819-}
3820-
3821 TEST_F(ClickInterfaceTest, testGetInstalledPackagesParsed)
3822 {
3823 FakeClickInterface iface;
3824- std::string sample_stdout = "ABC\t0.1\nDEF\t0.2\n";
3825- PackageSet expected{{"ABC", "0.1"}, {"DEF", "0.2"}};
3826+ PackageSet expected{{"foo.bar", "0.1"}, {"baz.foo", "0.2"}};
3827
3828- EXPECT_CALL(iface, run_process(_, _)).
3829- Times(1).
3830- WillOnce(Invoke([&](const std::string&,
3831- std::function<void(int, const std::string&,
3832- const std::string&)> callback){
3833- callback(0, sample_stdout, "");
3834- }));
3835+ EXPECT_CALL(iface, installed_apps()).Times(1).
3836+ WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
3837+ MockUALApplication::create(ual::AppID::parse("foo.bar_foo_0.1")),
3838+ MockUALApplication::create(ual::AppID::parse("baz.foo_foo_0.2"))
3839+ }));
3840 iface.get_installed_packages([expected](PackageSet package_names, InterfaceError error){
3841 ASSERT_EQ(error, InterfaceError::NoError);
3842 ASSERT_EQ(package_names, expected);
3843
3844=== modified file 'libclickscope/tests/test_pay.cpp'
3845--- libclickscope/tests/test_pay.cpp 2016-06-30 20:42:56 +0000
3846+++ libclickscope/tests/test_pay.cpp 2016-08-24 21:39:08 +0000
3847@@ -68,7 +68,7 @@
3848 TEST_F(PayTest, testPayPackageRefundCalled)
3849 {
3850 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3851- auto response = responseForReply(reply.asSharedPtr());
3852+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3853
3854 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);
3855 EXPECT_FALSE(package->refund("foo"));
3856@@ -77,7 +77,7 @@
3857 TEST_F(PayTest, testPayPackageRefundNotCalledIfCallbackExists)
3858 {
3859 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3860- auto response = responseForReply(reply.asSharedPtr());
3861+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3862
3863 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_REFUND;
3864 package->callbacks[callback_id] = [](const std::string&, bool) {};
3865@@ -88,7 +88,7 @@
3866 TEST_F(PayTest, testRefundReturnsTrueForPurchasedItem)
3867 {
3868 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3869- auto response = responseForReply(reply.asSharedPtr());
3870+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3871
3872 package->success = true;
3873 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);
3874@@ -98,7 +98,7 @@
3875 TEST_F(PayTest, testPayPackageVerifyCalled)
3876 {
3877 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3878- auto response = responseForReply(reply.asSharedPtr());
3879+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3880
3881 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);
3882 EXPECT_FALSE(package->verify("foo"));
3883@@ -107,7 +107,7 @@
3884 TEST_F(PayTest, testPayPackageVerifyNotCalledIfCallbackExists)
3885 {
3886 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3887- auto response = responseForReply(reply.asSharedPtr());
3888+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3889
3890 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_VERIFY;
3891 package->callbacks[callback_id] = [](const std::string&, bool) {};
3892@@ -118,7 +118,7 @@
3893 TEST_F(PayTest, testVerifyReturnsTrueForPurchasedItem)
3894 {
3895 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3896- auto response = responseForReply(reply.asSharedPtr());
3897+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3898
3899 package->success = true;
3900 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);
3901@@ -128,7 +128,7 @@
3902 TEST_F(PayTest, testGetPurchasesCallsWebservice)
3903 {
3904 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3905- auto response = responseForReply(reply.asSharedPtr());
3906+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3907
3908 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
3909 .Times(1)
3910@@ -140,7 +140,7 @@
3911 TEST_F(PayTest, testGetPurchasesSendsCorrectPath)
3912 {
3913 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3914- auto response = responseForReply(reply.asSharedPtr());
3915+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3916
3917 EXPECT_CALL(*clientPtr, callImpl(EndsWith(pay::PURCHASES_API_PATH),
3918 _, _, _, _, _))
3919@@ -153,7 +153,7 @@
3920 TEST_F(PayTest, testGetPurchasesCallbackCalled)
3921 {
3922 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3923- auto response = responseForReply(reply.asSharedPtr());
3924+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3925
3926 QByteArray fake_json("[]");
3927 EXPECT_CALL(reply.instance, readAll())
3928@@ -173,7 +173,7 @@
3929 TEST_F(PayTest, testGetPurchasesEmptyJsonIsParsed)
3930 {
3931 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3932- auto response = responseForReply(reply.asSharedPtr());
3933+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3934
3935 QByteArray fake_json("[]");
3936 EXPECT_CALL(reply.instance, readAll())
3937@@ -194,7 +194,7 @@
3938 TEST_F(PayTest, testGetPurchasesSingleJsonIsParsedNullTimestamp)
3939 {
3940 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3941- auto response = responseForReply(reply.asSharedPtr());
3942+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3943
3944 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON_NULL_TIMESTAMP);
3945 EXPECT_CALL(reply.instance, readAll())
3946@@ -215,7 +215,7 @@
3947 TEST_F(PayTest, testGetPurchasesTimestampIsParsed)
3948 {
3949 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3950- auto response = responseForReply(reply.asSharedPtr());
3951+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3952
3953 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON);
3954 EXPECT_CALL(reply.instance, readAll())
3955@@ -237,7 +237,7 @@
3956 TEST_F(PayTest, testGetPurchasesIsCancellable)
3957 {
3958 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3959- auto response = responseForReply(reply.asSharedPtr());
3960+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3961
3962 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
3963 .Times(1)
3964
3965=== modified file 'libclickscope/tests/test_preview.cpp'
3966--- libclickscope/tests/test_preview.cpp 2016-07-13 20:30:09 +0000
3967+++ libclickscope/tests/test_preview.cpp 2016-08-24 21:39:08 +0000
3968@@ -1,5 +1,5 @@
3969 /*
3970- * Copyright (C) 2014 Canonical Ltd.
3971+ * Copyright (C) 2014-2016 Canonical Ltd.
3972 *
3973 * This program is free software: you can redistribute it and/or modify it
3974 * under the terms of the GNU General Public License version 3, as published
3975@@ -64,7 +64,7 @@
3976 FakeIndex() {
3977
3978 }
3979- click::web::Cancellable get_details(const std::string& /*package_name*/, std::function<void(click::PackageDetails, Error)> callback, bool) override {
3980+ click::web::Cancellable get_details(const std::string& /*package_name*/, std::function<void(click::PackageDetails, Error)> callback, bool, bool) override {
3981 callback(click::PackageDetails(), Error::NetworkError);
3982 return click::web::Cancellable();
3983 }
3984
3985=== modified file 'libclickscope/tests/test_reviews.cpp'
3986--- libclickscope/tests/test_reviews.cpp 2016-05-10 13:42:12 +0000
3987+++ libclickscope/tests/test_reviews.cpp 2016-08-24 21:39:08 +0000
3988@@ -140,7 +140,7 @@
3989 TEST_F(ReviewsTest, testFetchReviewsCallsWebservice)
3990 {
3991 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
3992- auto response = responseForReply(reply.asSharedPtr());
3993+ auto response = MockClient::responseForReply(reply.asSharedPtr());
3994
3995 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
3996 .Times(1)
3997@@ -153,7 +153,7 @@
3998 TEST_F(ReviewsTest, testFetchReviewsDoesNotSignCall)
3999 {
4000 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4001- auto response = responseForReply(reply.asSharedPtr());
4002+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4003
4004 EXPECT_CALL(*clientPtr, callImpl(_, _, false, _, _, _))
4005 .Times(1)
4006@@ -166,7 +166,7 @@
4007 TEST_F(ReviewsTest, testFetchReviewsSendsQueryAsParam)
4008 {
4009 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4010- auto response = responseForReply(reply.asSharedPtr());
4011+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4012
4013 click::web::CallParams params;
4014 params.add(click::REVIEWS_QUERY_ARGNAME, FAKE_PACKAGENAME);
4015@@ -181,7 +181,7 @@
4016 TEST_F(ReviewsTest, testFetchReviewsSendsCorrectPath)
4017 {
4018 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4019- auto response = responseForReply(reply.asSharedPtr());
4020+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4021
4022 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::REVIEWS_API_PATH),
4023 _, _, _, _, _))
4024@@ -195,7 +195,7 @@
4025 TEST_F(ReviewsTest, testFetchReviewsCallbackCalled)
4026 {
4027 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4028- auto response = responseForReply(reply.asSharedPtr());
4029+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4030
4031 QByteArray fake_json("[]");
4032 EXPECT_CALL(reply.instance, readAll())
4033@@ -216,7 +216,7 @@
4034 TEST_F(ReviewsTest, testFetchReviewsNot200)
4035 {
4036 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4037- auto response = responseForReply(reply.asSharedPtr());
4038+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4039
4040 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(301)));
4041 EXPECT_CALL(reply.instance, readAll())
4042@@ -238,7 +238,7 @@
4043 TEST_F(ReviewsTest, testFetchReviewsEmptyJsonIsParsed)
4044 {
4045 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4046- auto response = responseForReply(reply.asSharedPtr());
4047+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4048
4049 QByteArray fake_json("[]");
4050 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));
4051@@ -261,7 +261,7 @@
4052 TEST_F(ReviewsTest, testFetchReviewsSingleJsonIsParsed)
4053 {
4054 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4055- auto response = responseForReply(reply.asSharedPtr());
4056+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4057
4058 QByteArray fake_json(FAKE_JSON_REVIEWS_RESULT_ONE.c_str());
4059 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));
4060@@ -295,7 +295,7 @@
4061 TEST_F(ReviewsTest, testFetchReviewsNetworkErrorReported)
4062 {
4063 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4064- auto response = responseForReply(reply.asSharedPtr());
4065+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4066
4067 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
4068 .Times(1)
4069@@ -318,7 +318,7 @@
4070 TEST_F(ReviewsTest, testFetchReviewsIsCancellable)
4071 {
4072 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4073- auto response = responseForReply(reply.asSharedPtr());
4074+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4075
4076 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
4077 .Times(1)
4078@@ -333,7 +333,7 @@
4079 TEST_F(ReviewsTest, testSubmitReviewIsCancellable)
4080 {
4081 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4082- auto response = responseForReply(reply.asSharedPtr());
4083+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4084
4085 click::Review review;
4086 review.rating = 3;
4087@@ -354,7 +354,7 @@
4088 TEST_F(ReviewsTest, testSubmitReviewUtf8)
4089 {
4090 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4091- auto response = responseForReply(reply.asSharedPtr());
4092+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4093
4094 click::Review review;
4095 review.rating = 3;
4096@@ -378,7 +378,7 @@
4097 TEST_F(ReviewsTest, testSubmitReviewLanguageCorrect)
4098 {
4099 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4100- auto response = responseForReply(reply.asSharedPtr());
4101+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4102
4103 click::Review review;
4104 review.rating = 3;
4105@@ -402,7 +402,7 @@
4106 TEST_F(ReviewsTest, testSubmitReviewLanguageCorrectForFullLangCodes)
4107 {
4108 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4109- auto response = responseForReply(reply.asSharedPtr());
4110+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4111
4112 click::Review review;
4113 review.rating = 3;
4114@@ -428,7 +428,7 @@
4115 TEST_F(ReviewsTest, testEditReviewUrlHasReviewId)
4116 {
4117 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4118- auto response = responseForReply(reply.asSharedPtr());
4119+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4120
4121 click::Review review;
4122 review.id = 1234;
4123@@ -448,7 +448,7 @@
4124 TEST_F(ReviewsTest, testEditReviewIsCancellable)
4125 {
4126 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
4127- auto response = responseForReply(reply.asSharedPtr());
4128+ auto response = MockClient::responseForReply(reply.asSharedPtr());
4129
4130 click::Review review;
4131 review.id = 1234;
4132
4133=== modified file 'scope/clickapps/apps-query.cpp'
4134--- scope/clickapps/apps-query.cpp 2016-06-22 20:46:28 +0000
4135+++ scope/clickapps/apps-query.cpp 2016-08-24 21:39:08 +0000
4136@@ -1,5 +1,5 @@
4137 /*
4138- * Copyright (C) 2014-2015 Canonical Ltd.
4139+ * Copyright (C) 2014-2016 Canonical Ltd.
4140 *
4141 * This program is free software: you can redistribute it and/or modify it
4142 * under the terms of the GNU General Public License version 3, as published
4143@@ -27,10 +27,12 @@
4144 * files in the program, then also delete it here.
4145 */
4146
4147+#include "apps-query.h"
4148+
4149 #include <click/application.h>
4150 #include <click/departments-db.h>
4151
4152-#include <click/key_file_locator.h>
4153+#include <QDebug>
4154
4155 #include <unity/scopes/CategoryRenderer.h>
4156 #include <unity/scopes/CategorisedResult.h>
4157@@ -39,12 +41,11 @@
4158 #include <unity/scopes/SearchMetadata.h>
4159 #include <unity/scopes/Department.h>
4160
4161+#include <locale>
4162+#include <memory>
4163 #include <vector>
4164-#include <locale>
4165
4166 #include <click/click-i18n.h>
4167-#include "apps-query.h"
4168-#include <QDebug>
4169
4170 namespace
4171 {
4172@@ -259,8 +260,7 @@
4173
4174 click::Interface& click::apps::Query::clickInterfaceInstance()
4175 {
4176- static QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
4177- static click::Interface iface(keyFileLocator);
4178+ static click::Interface iface;
4179
4180 return iface;
4181 }
4182@@ -420,7 +420,7 @@
4183 const bool show_top_apps = querystr.empty() && current_dept.empty();
4184 ResultPusher pusher(searchReply, show_top_apps ? impl->configuration.get_core_apps() : std::vector<std::string>());
4185 auto const ignoredApps = impl->configuration.get_ignored_apps();
4186- auto const localResults = clickInterfaceInstance().find_installed_apps(querystr, ignoredApps, current_dept, impl->depts_db);
4187+ auto const localResults = clickInterfaceInstance().search(querystr, ignoredApps, current_dept, impl->depts_db);
4188
4189 if (impl->depts_db)
4190 {
4191
4192=== modified file 'scope/clickapps/apps-scope.cpp'
4193--- scope/clickapps/apps-scope.cpp 2016-05-18 12:35:56 +0000
4194+++ scope/clickapps/apps-scope.cpp 2016-08-24 21:39:08 +0000
4195@@ -38,7 +38,6 @@
4196
4197 #include <QSharedPointer>
4198
4199-#include <click/key_file_locator.h>
4200 #include <click/network_access_manager.h>
4201 #include <click/click-i18n.h>
4202 #include <click/utils.h>
4203
4204=== modified file 'scope/clickstore/store-query.cpp'
4205--- scope/clickstore/store-query.cpp 2016-07-13 19:46:17 +0000
4206+++ scope/clickstore/store-query.cpp 2016-08-24 21:39:08 +0000
4207@@ -1,5 +1,5 @@
4208 /*
4209- * Copyright (C) 2014-2015 Canonical Ltd.
4210+ * Copyright (C) 2014-2016 Canonical Ltd.
4211 *
4212 * This program is free software: you can redistribute it and/or modify it
4213 * under the terms of the GNU General Public License version 3, as published
4214@@ -32,7 +32,6 @@
4215
4216 #include <click/application.h>
4217 #include <click/interface.h>
4218-#include <click/key_file_locator.h>
4219 #include <click/qtbridge.h>
4220 #include <click/departments-db.h>
4221 #include <click/utils.h>
4222@@ -47,12 +46,13 @@
4223 #include <unity/scopes/Variant.h>
4224 #include <unity/scopes/VariantBuilder.h>
4225
4226+#include <cassert>
4227 #include <iomanip>
4228-#include<vector>
4229-#include<set>
4230-#include<sstream>
4231-#include <cassert>
4232 #include <locale>
4233+#include <memory>
4234+#include <set>
4235+#include <sstream>
4236+#include <vector>
4237
4238 #include <QLocale>
4239
4240@@ -169,6 +169,7 @@
4241 click::HighlightList& highlights;
4242 scopes::SearchMetadata meta;
4243 click::web::Cancellable search_operation;
4244+ click::web::Cancellable search_snaps_operation;
4245 click::web::Cancellable purchases_operation;
4246 pay::Package& pay_package;
4247 std::shared_future<void> qt_ready_;
4248@@ -196,12 +197,12 @@
4249 {
4250 qDebug() << "cancelling search of" << QString::fromStdString(query().query_string());
4251 impl->search_operation.cancel();
4252+ impl->search_snaps_operation.cancel();
4253 }
4254
4255 click::Interface& click::Query::clickInterfaceInstance()
4256 {
4257- static QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
4258- static click::Interface iface(keyFileLocator);
4259+ static click::Interface iface;
4260
4261 return iface;
4262 }
4263@@ -291,7 +292,12 @@
4264 res.set_title(pkg.title);
4265 res.set_art(pkg.icon_url);
4266 res.set_uri(pkg.url);
4267- res[click::Query::ResultKeys::NAME] = pkg.name;
4268+ res["snap_id"] = pkg.snap_id;
4269+ if (pkg.snap_id.empty()) {
4270+ res[click::Query::ResultKeys::NAME] = pkg.name;
4271+ } else {
4272+ res[click::Query::ResultKeys::NAME] = pkg.alias;
4273+ }
4274 res["subtitle"] = pkg.publisher;
4275 auto installed = installedPackages.find(pkg);
4276
4277@@ -534,6 +540,7 @@
4278 push_package(searchReply, recommendsCategory,
4279 installedPackages, r);
4280 }
4281+
4282 qDebug() << "search completed";
4283 this->finished(searchReply); //FIXME: this shouldn't be needed
4284 };
4285@@ -597,7 +604,37 @@
4286 {
4287 qDebug() << "starting search of" << QString::fromStdString(query().query_string());
4288 push_departments(searchReply);
4289- impl->search_operation = impl->index.search(query().query_string(), query().department_id(), search_cb, force_cache);
4290+ impl->search_operation = impl->index.search
4291+ (query().query_string(), query().department_id(),
4292+ [this, search_cb, force_cache](Packages packages,
4293+ Packages recommends) {
4294+ if (Configuration().is_snapd_running()) {
4295+ qDebug() << "Searching for snaps too.";
4296+ impl->search_snaps_operation = impl->index.search_snaps
4297+ (query().query_string(),
4298+ [this, packages, recommends, search_cb](Packages snap_packages,
4299+ Packages snap_recommends) {
4300+ qDebug() << "In the callback.";
4301+ Packages new_packages, new_recommends;
4302+ for (auto p: packages) {
4303+ new_packages.push_back(p);
4304+ }
4305+ for (auto p: snap_packages) {
4306+ new_packages.push_back(p);
4307+ }
4308+ for (auto r: recommends) {
4309+ new_recommends.push_back(r);
4310+ }
4311+ for (auto r: snap_recommends) {
4312+ new_recommends.push_back(r);
4313+ }
4314+ qDebug() << "Snaps appended.";
4315+ search_cb(new_packages, new_recommends);
4316+ }, force_cache);
4317+ } else {
4318+ search_cb(packages, recommends);
4319+ }
4320+ }, force_cache);
4321 }
4322 }
4323 });
4324
4325=== modified file 'scope/clickstore/store-scope.cpp'
4326--- scope/clickstore/store-scope.cpp 2016-05-25 16:19:58 +0000
4327+++ scope/clickstore/store-scope.cpp 2016-08-24 21:39:08 +0000
4328@@ -38,7 +38,6 @@
4329
4330 #include <QSharedPointer>
4331
4332-#include <click/key_file_locator.h>
4333 #include <click/network_access_manager.h>
4334 #include <click/click-i18n.h>
4335
4336
4337=== modified file 'scope/tests/test_apps_query.cpp'
4338--- scope/tests/test_apps_query.cpp 2016-03-09 13:08:13 +0000
4339+++ scope/tests/test_apps_query.cpp 2016-08-24 21:39:08 +0000
4340@@ -1,5 +1,5 @@
4341 /*
4342- * Copyright (C) 2014 Canonical Ltd.
4343+ * Copyright (C) 2014-2016 Canonical Ltd.
4344 *
4345 * This program is free software: you can redistribute it and/or modify it
4346 * under the terms of the GNU General Public License version 3, as published
4347@@ -61,7 +61,7 @@
4348 {
4349 public:
4350 MockClickInterface() = default;
4351- MOCK_METHOD4(find_installed_apps, std::vector<click::Application>(const std::string&, const std::vector<std::string>&, const std::string&, const std::shared_ptr<click::DepartmentsDb>&));
4352+ MOCK_METHOD4(search, std::vector<click::Application>(const std::string&, const std::vector<std::string>&, const std::string&, const std::shared_ptr<click::DepartmentsDb>&));
4353 };
4354
4355 class MockAppsQuery : public click::apps::Query
4356@@ -215,7 +215,7 @@
4357 // no apps in 'books' department, thus excluded
4358 std::list<std::string> expected_departments({{"", "games", "video"}});
4359
4360- EXPECT_CALL(*clickif, find_installed_apps(_, _, _, _)).WillOnce(Return(installed_apps));
4361+ EXPECT_CALL(*clickif, search(_, _, _, _)).WillOnce(Return(installed_apps));
4362 EXPECT_CALL(mock_reply, register_category("predefined", _, _, _)).WillOnce(Return(ptrCat));
4363 EXPECT_CALL(mock_reply, register_category("local", StrNe(""), _, _)).WillOnce(Return(ptrCat));
4364 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));
4365@@ -264,7 +264,7 @@
4366
4367 std::list<std::string> expected_departments({"", "games"});
4368
4369- EXPECT_CALL(*clickif, find_installed_apps(_, _, _, _)).WillOnce(Return(installed_apps));
4370+ EXPECT_CALL(*clickif, search(_, _, _, _)).WillOnce(Return(installed_apps));
4371 EXPECT_CALL(mock_reply, register_category("local", StrEq(""), _, _)).WillOnce(Return(ptrCat));
4372 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));
4373 EXPECT_CALL(mock_reply, register_departments(MatchesDepartments(expected_departments)));
4374@@ -296,7 +296,7 @@
4375 scopes::testing::MockSearchReply mock_reply;
4376 scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){});
4377
4378- EXPECT_CALL(*clickif, find_installed_apps(_, _, _, _)).WillOnce(Return(installed_apps));
4379+ EXPECT_CALL(*clickif, search(_, _, _, _)).WillOnce(Return(installed_apps));
4380 EXPECT_CALL(mock_reply, register_category("local", StrEq(""), _, _)).WillOnce(Return(ptrCat));
4381 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));
4382
4383@@ -323,7 +323,7 @@
4384
4385 std::list<std::string> expected_departments({"", "games"});
4386
4387- EXPECT_CALL(*clickif, find_installed_apps("Fooo", _, "games", _)).WillOnce(Return(installed_apps));
4388+ EXPECT_CALL(*clickif, search("Fooo", _, "games", _)).WillOnce(Return(installed_apps));
4389 EXPECT_CALL(mock_reply, register_category("local", StrEq(""), _, _)).WillOnce(Return(ptrCat));
4390 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));
4391 EXPECT_CALL(*depts_db, get_department_name("games", expected_locales)).WillOnce(Return("Games"));
4392
4393=== modified file 'tools/init-departments/init-departments.cpp'
4394--- tools/init-departments/init-departments.cpp 2014-07-15 13:30:05 +0000
4395+++ tools/init-departments/init-departments.cpp 2016-08-24 21:39:08 +0000
4396@@ -1,5 +1,5 @@
4397 /*
4398- * Copyright (C) 2014 Canonical Ltd.
4399+ * Copyright (C) 2014-2016 Canonical Ltd.
4400 *
4401 * This program is free software: you can redistribute it and/or modify it
4402 * under the terms of the GNU General Public License version 3, as published
4403@@ -28,14 +28,16 @@
4404 */
4405
4406 #include <click/interface.h>
4407-#include <click/key_file_locator.h>
4408 #include <click/index.h>
4409 #include <click/webclient.h>
4410 #include <click/network_access_manager.h>
4411 #include <click/qtbridge.h>
4412 #include <click/departments-db.h>
4413+
4414 #include <future>
4415 #include <iostream>
4416+#include <memory>
4417+
4418 #include <QDebug>
4419 #include <QtGlobal>
4420
4421@@ -65,8 +67,7 @@
4422 {"webbrowser-app.desktop", "web-browsers"}
4423 };
4424
4425-QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
4426-click::Interface iface(keyFileLocator);
4427+click::Interface iface;
4428
4429 void noDebug(QtMsgType, const QMessageLogContext&, const QString&) {}
4430

Subscribers

People subscribed via source and target branches

to all changes: