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
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-07-14 18:37:27 +0000
+++ CMakeLists.txt 2016-08-24 21:39:08 +0000
@@ -8,7 +8,7 @@
88
9# Some default CFLAGS9# Some default CFLAGS
10SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -Wall -Wextra -Werror -fPIC")10SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -Wall -Wextra -Werror -fPIC")
11SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -g -Wextra -Wall -Werror -Werror=conversion-null -fPIC")11SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -g -Wextra -Wall -Werror -Werror=conversion-null -Wno-ignored-qualifiers -fPIC")
1212
13set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)13set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
1414
@@ -24,6 +24,12 @@
24include(UseGSettings)24include(UseGSettings)
25find_package (PkgConfig REQUIRED)25find_package (PkgConfig REQUIRED)
2626
27pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2>=0.9)
28add_definitions(${UAL_CFLAGS} ${UAL_CFLAGS_OTHER})
29
30pkg_check_modules(CLICK REQUIRED click-0.4)
31add_definitions(${CLICK_CFLAGS} ${CLICK_CFLAGS_OTHER})
32
27pkg_check_modules(UNITY_SCOPES REQUIRED libunity-scopes>=0.6.7 libunity-api>=0.1.3)33pkg_check_modules(UNITY_SCOPES REQUIRED libunity-scopes>=0.6.7 libunity-api>=0.1.3)
28add_definitions(${UNITY_SCOPES_CFLAGS} ${UNITY_SCOPES_CFLAGS_OTHER})34add_definitions(${UNITY_SCOPES_CFLAGS} ${UNITY_SCOPES_CFLAGS_OTHER})
2935
3036
=== modified file 'bin/install-helper'
--- bin/install-helper 2014-06-20 05:09:01 +0000
+++ bin/install-helper 2016-08-24 21:39:08 +0000
@@ -1,6 +1,6 @@
1#!/bin/bash1#!/bin/bash
2#2#
3# Copyright (C) 2014 Canonical Ltd.3# Copyright (C) 2014-2016 Canonical Ltd.
4# 4#
5# This program is free software: you can redistribute it and/or modify it5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published6# under the terms of the GNU General Public License version 3, as published
@@ -47,7 +47,12 @@
4747
48function install-package {48function install-package {
49 FILE_NAME="$1"49 FILE_NAME="$1"
50 pkcon -p install-local "$FILE_NAME"50 FILE_TYPE="${FILE_NAME##*.}"
51 if [ ${FILE_TYPE} = "click" ]; then
52 pkcon -p install-local "${FILE_NAME}"
53 else
54 pkexec snap install "${FILE_NAME}"
55 fi
51}56}
5257
53function app_id-from-package_name {58function app_id-from-package_name {
5459
=== modified file 'debian/control'
--- debian/control 2016-05-25 16:17:00 +0000
+++ debian/control 2016-08-24 21:39:08 +0000
@@ -1,8 +1,7 @@
1Source: unity-scope-click1Source: unity-scope-click
2Section: x112Section: x11
3Priority: optional3Priority: optional
4Build-Depends: click,4Build-Depends: cmake (>= 2.8.10),
5 cmake (>= 2.8.10),
6 cmake-extras,5 cmake-extras,
7 dbus-x11,6 dbus-x11,
8 debhelper (>= 9),7 debhelper (>= 9),
@@ -12,9 +11,11 @@
12 intltool,11 intltool,
13 lcov,12 lcov,
14 libboost-locale-dev,13 libboost-locale-dev,
14 libclick-0.4-dev,
15 libglib2.0-dev (>= 2.32),15 libglib2.0-dev (>= 2.32),
16 libjsoncpp-dev,16 libjsoncpp-dev,
17 libpay2-dev (>= 2.0.0+15.04.20150701),17 libpay2-dev (>= 2.0.0+15.04.20150701),
18 libubuntu-app-launch2-dev (>= 0.9),
18 libubuntu-download-manager-client-dev (>= 0.3+14.10.20140430-0ubuntu1),19 libubuntu-download-manager-client-dev (>= 0.3+14.10.20140430-0ubuntu1),
19 libubuntu-download-manager-common-dev (>= 0.3+14.10.20140430-0ubuntu1),20 libubuntu-download-manager-common-dev (>= 0.3+14.10.20140430-0ubuntu1),
20 libubuntuoneauth-2.0-dev (>= 15.10),21 libubuntuoneauth-2.0-dev (>= 15.10),
2122
=== modified file 'libclickscope/click/CMakeLists.txt'
--- libclickscope/click/CMakeLists.txt 2015-04-14 21:19:21 +0000
+++ libclickscope/click/CMakeLists.txt 2016-08-24 21:39:08 +0000
@@ -22,7 +22,6 @@
22 highlights.cpp22 highlights.cpp
23 index.cpp23 index.cpp
24 interface.cpp24 interface.cpp
25 key_file_locator.cpp
26 launcher.cpp25 launcher.cpp
27 network_access_manager.cpp26 network_access_manager.cpp
28 package.cpp27 package.cpp
@@ -43,6 +42,8 @@
43 ${JSON_CPP_INCLUDE_DIRS}42 ${JSON_CPP_INCLUDE_DIRS}
44 ${LIBPAY_INCLUDE_DIRS}43 ${LIBPAY_INCLUDE_DIRS}
45 ${GSETTINGS_QT_INCLUDE_DIRS}44 ${GSETTINGS_QT_INCLUDE_DIRS}
45 ${UAL_INCLUDE_DIRS}
46 ${CLICK_INCLUDE_DIRS}
46 ${CMAKE_SOURCE_DIR}/libclickscope47 ${CMAKE_SOURCE_DIR}/libclickscope
47)48)
4849
@@ -54,5 +55,7 @@
54 ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS}55 ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS}
55 ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS}56 ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS}
56 ${GSETTINGS_QT_LIBRARIES}57 ${GSETTINGS_QT_LIBRARIES}
58 ${UAL_LDFLAGS}
59 ${CLICK_LDFLAGS}
57 -lboost_locale60 -lboost_locale
58)61)
5962
=== modified file 'libclickscope/click/configuration.cpp'
--- libclickscope/click/configuration.cpp 2016-02-19 03:35:43 +0000
+++ libclickscope/click/configuration.cpp 2016-08-24 21:39:08 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014-2015 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -27,6 +27,8 @@
27 * files in the program, then also delete it here.27 * files in the program, then also delete it here.
28 */28 */
2929
30#include "configuration.h"
31
30#include <string>32#include <string>
31#include <vector>33#include <vector>
3234
@@ -43,8 +45,9 @@
4345
44#include <boost/algorithm/string.hpp>46#include <boost/algorithm/string.hpp>
45#include <boost/algorithm/string/replace.hpp>47#include <boost/algorithm/string/replace.hpp>
4648#include <sys/stat.h>
47#include "configuration.h"49#include <sys/types.h>
50#include <unistd.h>
4851
49namespace click {52namespace click {
5053
@@ -121,6 +124,17 @@
121 return arch;124 return arch;
122}125}
123126
127bool Configuration::is_snapd_running() const
128{
129 struct stat sb;
130 int retval = stat("/run/snapd.socket", &sb);
131 if (retval == 0 && (sb.st_mode & S_IFMT) == S_IFSOCK) {
132 return true;
133 }
134
135 return false;
136}
137
124bool Configuration::get_purchases_enabled()138bool Configuration::get_purchases_enabled()
125{139{
126 const char* env_value = std::getenv(PURCHASES_ENVVAR);140 const char* env_value = std::getenv(PURCHASES_ENVVAR);
127141
=== modified file 'libclickscope/click/configuration.h'
--- libclickscope/click/configuration.h 2016-02-19 03:35:43 +0000
+++ libclickscope/click/configuration.h 2016-08-24 21:39:08 +0000
@@ -54,6 +54,7 @@
5454
55 virtual std::vector<std::string> get_available_frameworks();55 virtual std::vector<std::string> get_available_frameworks();
56 virtual std::string get_architecture();56 virtual std::string get_architecture();
57 virtual bool is_snapd_running() const;
57 static bool get_purchases_enabled();58 static bool get_purchases_enabled();
58 static std::string get_currency(const std::string& fallback = CURRENCY_DEFAULT);59 static std::string get_currency(const std::string& fallback = CURRENCY_DEFAULT);
5960
@@ -78,11 +79,11 @@
78 virtual const std::vector<std::string> get_dconf_strings(const std::string& schema, const std::string& key) const;79 virtual const std::vector<std::string> get_dconf_strings(const std::string& schema, const std::string& key) const;
79 static const std::vector<std::string>& get_default_core_apps() {80 static const std::vector<std::string>& get_default_core_apps() {
80 static std::vector<std::string> default_apps {81 static std::vector<std::string> default_apps {
81 "dialer-app",82 "dialer-app.desktop",
82 "messaging-app",83 "messaging-app.desktop",
83 "address-book-app",84 "address-book-app.desktop",
84 "com.ubuntu.camera_camera",85 "com.ubuntu.camera_camera",
85 "webbrowser-app",86 "webbrowser-app.desktop",
86 "com.ubuntu.clock_clock"87 "com.ubuntu.clock_clock"
87 };88 };
88 return default_apps;89 return default_apps;
8990
=== modified file 'libclickscope/click/download-manager.cpp'
--- libclickscope/click/download-manager.cpp 2016-05-10 13:42:12 +0000
+++ libclickscope/click/download-manager.cpp 2016-08-24 21:39:08 +0000
@@ -57,12 +57,6 @@
5757
58static const QString DOWNLOAD_MANAGER_SHA512 = "sha512";58static const QString DOWNLOAD_MANAGER_SHA512 = "sha512";
5959
60const QByteArray& CLICK_TOKEN_HEADER()
61{
62 static const QByteArray result("X-Click-Token");
63 return result;
64}
65
66DownloadManager::DownloadManager(const QSharedPointer<click::web::Client>& client,60DownloadManager::DownloadManager(const QSharedPointer<click::web::Client>& client,
67 const QSharedPointer<udm::Manager>& manager) :61 const QSharedPointer<udm::Manager>& manager) :
68 client(client),62 client(client),
@@ -86,11 +80,11 @@
86 if (downloads.size() > 0) {80 if (downloads.size() > 0) {
87 auto download = downloads.at(0);81 auto download = downloads.at(0);
88 object_path = download->id().toStdString();82 object_path = download->id().toStdString();
89 }83 qDebug() << "Found object path" << QString::fromStdString(object_path)
90 qDebug() << "Found object path" << QString::fromStdString(object_path)84 << "for package" << QString::fromStdString(package_name);
91 << "for package" << QString::fromStdString(package_name);85 if (downloads.size() > 1) {
92 if (downloads.size() > 1) {86 qWarning() << "More than one download with the same object path";
93 qWarning() << "More than one download with the same object path";87 }
94 }88 }
95 callback(object_path);89 callback(object_path);
96 }, [callback, package_name](const QString& /*key*/, const QString& /*value*/, DownloadsList* /*downloads_list*/){90 }, [callback, package_name](const QString& /*key*/, const QString& /*value*/, DownloadsList* /*downloads_list*/){
@@ -100,78 +94,44 @@
100 });94 });
101}95}
10296
103click::web::Cancellable DownloadManager::start(const std::string& url,97void DownloadManager::start(const std::string& url,
104 const std::string& download_sha512,98 const std::string& download_sha512,
105 const std::string& package_name,99 const std::string& package_name,
106 const std::function<void (std::string, Error)>& callback)100 const std::function<void (std::string, Error)>& callback)
107{101{
108 QSharedPointer<click::web::Response> response = client->call102 auto signature = client->signUrl(url, "GET");
109 (url, "HEAD", true);103
110104 QVariantMap metadata;
111 QObject::connect(response.data(), &click::web::Response::finished,105
112 [this, callback, url, download_sha512, package_name,106 QVariant commandline = QVariant(QStringList() << DOWNLOAD_COMMAND << "$file" << package_name.c_str());
113 response](QString) {107 metadata[DOWNLOAD_COMMAND_KEY] = commandline;
114 auto status = response->get_status_code();108 metadata[DOWNLOAD_APP_ID_KEY] = package_name.c_str();
115 if (status == 200) {109 metadata["package_name"] = package_name.c_str();
116 auto clickToken = response->get_header(CLICK_TOKEN_HEADER().data());110
117 qDebug() << "Received click token:" << clickToken.c_str();111 QMap<QString, QString> headers;
118 QVariantMap metadata;112 headers[click::web::AUTHORIZATION_HEADER.c_str()] = signature.c_str();
119113
120 QVariant commandline = QVariant(QStringList() << DOWNLOAD_COMMAND << "$file" << package_name.c_str());114 udm::DownloadStruct downloadStruct(url.c_str(),
121 metadata[DOWNLOAD_COMMAND_KEY] = commandline;115 download_sha512.c_str(),
122 metadata[DOWNLOAD_APP_ID_KEY] = package_name.c_str();116 DOWNLOAD_MANAGER_SHA512,
123 metadata["package_name"] = package_name.c_str();117 metadata,
124118 headers);
125 QMap<QString, QString> headers;119
126 headers[CLICK_TOKEN_HEADER()] = clickToken.c_str();120 dm->createDownload(downloadStruct,
127121 [callback](Download* download) {
128 udm::DownloadStruct downloadStruct(url.c_str(),122 if (download->isError()) {
129 download_sha512.c_str(),123 auto error = download->error()->errorString().toUtf8().data();
130 DOWNLOAD_MANAGER_SHA512,124 qDebug() << "Received error from ubuntu-download-manager:" << error;
131 metadata,125 callback(error, Error::DownloadInstallError);
132 headers);126 } else {
133127 download->start();
134 dm->createDownload(downloadStruct,128 callback(download->id().toUtf8().data(), Error::NoError);
135 [callback](Download* download) {129 }
136 if (download->isError()) {130 },
137 auto error = download->error()->errorString().toUtf8().data();131 [callback](Download* download) {
138 qDebug() << "Received error from ubuntu-download-manager:" << error;132 callback(download->error()->errorString().toUtf8().data(),
139 callback(error, Error::DownloadInstallError);133 Error::DownloadInstallError);
140 } else {134 });
141 download->start();
142 callback(download->id().toUtf8().data(), Error::NoError);
143 }
144 },
145 [callback](Download* download) {
146 callback(download->error()->errorString().toUtf8().data(),
147 Error::DownloadInstallError);
148 });
149 } else {
150 std::string error{"Unhandled HTTP response code: "};
151 error += status;
152 callback(error, Error::DownloadInstallError);
153 }
154 });
155 QObject::connect(response.data(), &click::web::Response::error,
156 [this, callback, package_name](QString error, int error_code) {
157 qWarning() << QStringLiteral("Network error (%1) fetching click token for:").arg(error_code) << package_name.c_str();
158 switch(error_code) {
159 case 401:
160 case 403:
161 client->invalidateCredentials();
162 callback(error.toUtf8().data(), Error::CredentialsError);
163 break;
164 default:
165 callback(error.toUtf8().data(), Error::DownloadInstallError);
166 }
167 });
168
169 return click::web::Cancellable(response);
170}
171
172void DownloadManager::setCredentialsService(const QSharedPointer<click::CredentialsService>& credentialsService)
173{
174 sso = credentialsService;
175}135}
176136
177} // namespace click137} // namespace click
178138
=== modified file 'libclickscope/click/download-manager.h'
--- libclickscope/click/download-manager.h 2016-02-26 18:51:22 +0000
+++ libclickscope/click/download-manager.h 2016-08-24 21:39:08 +0000
@@ -68,18 +68,14 @@
6868
69 virtual void get_progress(const std::string& package_name,69 virtual void get_progress(const std::string& package_name,
70 const std::function<void (std::string)>& callback);70 const std::function<void (std::string)>& callback);
71 virtual click::web::Cancellable start(const std::string& url,71 virtual void start(const std::string& url,
72 const std::string& download_sha512,72 const std::string& download_sha512,
73 const std::string& package_name,73 const std::string& package_name,
74 const std::function<void (std::string,74 const std::function<void (std::string, Error)>& callback);
75 Error)>& callback);
76
77 virtual void setCredentialsService(const QSharedPointer<click::CredentialsService>& credentialsService);
7875
79protected:76protected:
80 QSharedPointer<click::web::Client> client;77 QSharedPointer<click::web::Client> client;
81 QSharedPointer<Ubuntu::DownloadManager::Manager> dm;78 QSharedPointer<Ubuntu::DownloadManager::Manager> dm;
82 QSharedPointer<click::CredentialsService> sso;
83};79};
8480
85}81}
8682
=== modified file 'libclickscope/click/index.cpp'
--- libclickscope/click/index.cpp 2016-04-26 10:56:47 +0000
+++ libclickscope/click/index.cpp 2016-08-24 21:39:08 +0000
@@ -123,6 +123,15 @@
123 };123 };
124}124}
125125
126std::map<std::string, std::string> Index::add_snap_headers(const std::map<std::string, std::string>& headers) const
127{
128 std::map<std::string, std::string> new_headers{headers};
129 new_headers["X-Ubuntu-Series"] = "16"; // Need to get from snapd
130 new_headers["X-Ubuntu-Slots"] = "unity8"; // Only want unity8-using snaps
131
132 return new_headers;
133}
134
126std::pair<Packages, Packages> Index::package_lists_from_json(const std::string& json)135std::pair<Packages, Packages> Index::package_lists_from_json(const std::string& json)
127{136{
128 Json::Reader reader;137 Json::Reader reader;
@@ -147,6 +156,36 @@
147 return std::pair<Packages, Packages>(pl, recommends);156 return std::pair<Packages, Packages>(pl, recommends);
148}157}
149158
159click::web::Cancellable Index::search_snaps(const std::string& query,
160 std::function<void(click::Packages search_results, click::Packages recommendations)> callback,
161 bool force_cache)
162{
163 click::web::CallParams params;
164 auto built_query = build_index_query(query, "" /* No dept for snaps */);
165 params.add(click::QUERY_ARGNAME, built_query.c_str());
166
167 auto headers = add_snap_headers(build_headers());
168
169 QSharedPointer<click::web::Response> response
170 (client->call(get_base_url() + click::SNAP_SEARCH_PATH,
171 "GET", true, headers, "", params, force_cache));
172
173 QObject::connect(response.data(), &click::web::Response::finished, [=](QString reply) {
174 std::pair<Packages, Packages> package_lists;
175 package_lists = package_lists_from_json(reply.toUtf8().constData());
176 callback(package_lists.first, package_lists.second);
177 });
178 QObject::connect(response.data(), &click::web::Response::error, [=](QString /*description*/) {
179 qDebug() << "No packages found due to network error";
180 click::Packages pl;
181 click::Packages recommends;
182 qDebug() << "calling callback";
183 callback(pl, recommends);
184 qDebug() << " ...Done!";
185 });
186 return click::web::Cancellable(response);
187}
188
150click::web::Cancellable Index::search (const std::string& query, const std::string& department,189click::web::Cancellable Index::search (const std::string& query, const std::string& department,
151 std::function<void(click::Packages search_results, click::Packages recommendations)> callback,190 std::function<void(click::Packages search_results, click::Packages recommendations)> callback,
152 bool force_cache)191 bool force_cache)
@@ -215,10 +254,21 @@
215 return click::web::Cancellable(response);254 return click::web::Cancellable(response);
216}255}
217256
218click::web::Cancellable Index::get_details (const std::string& package_name, std::function<void(PackageDetails, click::Index::Error)> callback, bool force_cache)257click::web::Cancellable Index::get_details (const std::string& package_name,
258 std::function<void(PackageDetails,
259 click::Index::Error)> callback,
260 bool is_snap,
261 bool force_cache)
219{262{
263 std::string details_path{click::DETAILS_PATH};
264 auto headers = build_headers();
265 if (is_snap) {
266 details_path = click::SNAP_DETAILS_PATH;
267 headers = add_snap_headers(headers);
268 }
220 QSharedPointer<click::web::Response> response = client->call269 QSharedPointer<click::web::Response> response = client->call
221 (get_base_url() + click::DETAILS_PATH + package_name,270 (get_base_url() + details_path + package_name,
271 "GET", true, headers, "",
222 click::web::CallParams(),272 click::web::CallParams(),
223 force_cache);273 force_cache);
224 qDebug() << "getting details for" << package_name.c_str();274 qDebug() << "getting details for" << package_name.c_str();
225275
=== modified file 'libclickscope/click/index.h'
--- libclickscope/click/index.h 2016-04-26 10:56:47 +0000
+++ libclickscope/click/index.h 2016-08-24 21:39:08 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -49,11 +49,13 @@
49const std::string SEARCH_BASE_URL_ENVVAR = "U1_SEARCH_BASE_URL";49const std::string SEARCH_BASE_URL_ENVVAR = "U1_SEARCH_BASE_URL";
50const std::string SEARCH_BASE_URL = "https://search.apps.ubuntu.com/";50const std::string SEARCH_BASE_URL = "https://search.apps.ubuntu.com/";
51const std::string SEARCH_PATH = "api/v1/search";51const std::string SEARCH_PATH = "api/v1/search";
52const std::string SNAP_SEARCH_PATH = "api/v1/snaps/search";
52const std::string BOOTSTRAP_PATH = "api/v1";53const std::string BOOTSTRAP_PATH = "api/v1";
53const std::string SUPPORTED_FRAMEWORKS = "framework:ubuntu-sdk-13.10";54const std::string SUPPORTED_FRAMEWORKS = "framework:ubuntu-sdk-13.10";
54const std::string QUERY_ARGNAME = "q";55const std::string QUERY_ARGNAME = "q";
55const std::string ARCHITECTURE = "architecture:";56const std::string ARCHITECTURE = "architecture:";
56const std::string DETAILS_PATH = "api/v1/package/";57const std::string DETAILS_PATH = "api/v1/package/";
58const std::string SNAP_DETAILS_PATH = "api/v1/snaps/details/";
57const std::string CURRENCY_HEADER = "X-Suggested-Currency";59const std::string CURRENCY_HEADER = "X-Suggested-Currency";
5860
59class PackageManager61class PackageManager
@@ -72,6 +74,7 @@
72 std::string m_suggested_currency;74 std::string m_suggested_currency;
73 virtual std::string build_index_query(const std::string& query, const std::string& department);75 virtual std::string build_index_query(const std::string& query, const std::string& department);
74 virtual std::map<std::string, std::string> build_headers();76 virtual std::map<std::string, std::string> build_headers();
77 virtual std::map<std::string, std::string> add_snap_headers(const std::map<std::string, std::string>& headers) const;
7578
76public:79public:
77 enum class Error {NoError, CredentialsError, NetworkError};80 enum class Error {NoError, CredentialsError, NetworkError};
@@ -79,9 +82,15 @@
79 Index(const QSharedPointer<click::web::Client>& client,82 Index(const QSharedPointer<click::web::Client>& client,
80 const QSharedPointer<Configuration> configuration=QSharedPointer<Configuration>(new Configuration()));83 const QSharedPointer<Configuration> configuration=QSharedPointer<Configuration>(new Configuration()));
81 virtual std::pair<Packages, Packages> package_lists_from_json(const std::string& json);84 virtual std::pair<Packages, Packages> package_lists_from_json(const std::string& json);
85 virtual click::web::Cancellable search_snaps(const std::string& query,
86 std::function<void(click::Packages search_results, click::Packages recommendations)> callback,
87 bool force_cache = false);
82 virtual click::web::Cancellable search (const std::string& query, const std::string& department, std::function<void(Packages, Packages)> callback, bool88 virtual click::web::Cancellable search (const std::string& query, const std::string& department, std::function<void(Packages, Packages)> callback, bool
83 force_cache = false);89 force_cache = false);
84 virtual click::web::Cancellable get_details(const std::string& package_name, std::function<void(PackageDetails, Error)> callback, bool force_cache = false);90 virtual click::web::Cancellable get_details(const std::string& package_name,
91 std::function<void(PackageDetails, Error)> callback,
92 bool is_snap = false,
93 bool force_cache = false);
85 virtual click::web::Cancellable bootstrap(std::function<void(const DepartmentList&, const HighlightList&, Error, int)> callback, bool force_cache = false);94 virtual click::web::Cancellable bootstrap(std::function<void(const DepartmentList&, const HighlightList&, Error, int)> callback, bool force_cache = false);
86 virtual click::web::Cancellable departments(const std::string& department_href, std::function<void(const DepartmentList&, const HighlightList&, Error, int)>95 virtual click::web::Cancellable departments(const std::string& department_href, std::function<void(const DepartmentList&, const HighlightList&, Error, int)>
87 callback, bool force_cache = false);96 callback, bool force_cache = false);
8897
=== modified file 'libclickscope/click/interface.cpp'
--- libclickscope/click/interface.cpp 2016-07-14 18:37:27 +0000
+++ libclickscope/click/interface.cpp 2016-08-24 21:39:08 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -27,6 +27,10 @@
27 * files in the program, then also delete it here.27 * files in the program, then also delete it here.
28 */28 */
2929
30#include <click.h>
31
32#include "interface.h"
33
30#include <QDebug>34#include <QDebug>
31#include <QDir>35#include <QDir>
32#include <QProcess>36#include <QProcess>
@@ -51,12 +55,15 @@
51#include <unity/UnityExceptions.h>55#include <unity/UnityExceptions.h>
52#include <unity/util/IniParser.h>56#include <unity/util/IniParser.h>
5357
54#include "interface.h"
55#include <click/key_file_locator.h>
56#include <click/departments-db.h>58#include <click/departments-db.h>
5759
60#include <ubuntu-app-launch/registry.h>
61
58#include <click/click-i18n.h>62#include <click/click-i18n.h>
5963
64using namespace ubuntu::app_launch;
65namespace ual = ubuntu::app_launch;
66
60namespace {67namespace {
6168
62/* Thanks to69/* Thanks to
@@ -122,114 +129,6 @@
122static const std::string DESKTOP_FILE_ONLYSHOWIN("OnlyShowIn");129static const std::string DESKTOP_FILE_ONLYSHOWIN("OnlyShowIn");
123static const std::string ONLYSHOWIN_UNITY("Unity");130static const std::string ONLYSHOWIN_UNITY("Unity");
124131
125Interface::Interface(const QSharedPointer<click::KeyFileLocator>& keyFileLocator)
126 : keyFileLocator(keyFileLocator)
127{
128}
129
130Interface::~Interface()
131{
132}
133
134bool Interface::show_desktop_apps()
135{
136 return getenv(ENV_SHOW_DESKTOP_APPS) != nullptr;
137}
138
139bool Interface::is_visible_app(const unity::util::IniParser &keyFile)
140{
141 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_NODISPLAY)) {
142 auto val = keyFile.get_string(DESKTOP_FILE_GROUP, DESKTOP_FILE_NODISPLAY);
143 if (val == std::string("true")) {
144 return false;
145 }
146 }
147
148 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_ONLYSHOWIN)) {
149 auto value = keyFile.get_string(DESKTOP_FILE_GROUP, DESKTOP_FILE_ONLYSHOWIN);
150 std::stringstream ss(value);
151 std::string item;
152
153 while (std::getline(ss, item, ';')) {
154 if (item == ONLYSHOWIN_UNITY) {
155 return true;
156 }
157 }
158 return false;
159 }
160
161 return true;
162}
163
164std::string Interface::get_translated_string(const unity::util::IniParser& keyFile,
165 const std::string& group,
166 const std::string& key,
167 const std::string& domain)
168{
169 std::string language = Configuration().get_language();
170 if (!domain.empty()) {
171 return dgettext(domain.c_str(),
172 keyFile.get_string(group, key).c_str());
173 } else {
174 return keyFile.get_locale_string(group, key, language);
175 }
176}
177
178click::Application Interface::load_app_from_desktop(const unity::util::IniParser& keyFile,
179 const std::string& filename)
180{
181 Application app;
182 std::string domain;
183 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_DOMAIN)) {
184 domain = keyFile.get_string(DESKTOP_FILE_GROUP,
185 DESKTOP_FILE_KEY_DOMAIN);
186 }
187 app.title = get_translated_string(keyFile,
188 DESKTOP_FILE_GROUP,
189 DESKTOP_FILE_KEY_NAME,
190 domain);
191
192 app.url = "application:///" + filename;
193 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_ICON)) {
194 app.icon_url = add_theme_scheme(keyFile.get_string(DESKTOP_FILE_GROUP,
195 DESKTOP_FILE_KEY_ICON));
196 }
197
198 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_KEYWORDS)) {
199 app.keywords = keyFile.get_string_array(DESKTOP_FILE_GROUP,
200 DESKTOP_FILE_KEY_KEYWORDS);
201 }
202
203 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_UBUNTU_DEFAULT_DEPARTMENT)) {
204 app.default_department = keyFile.get_string(DESKTOP_FILE_GROUP, DESKTOP_FILE_UBUNTU_DEFAULT_DEPARTMENT);
205 }
206
207 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_APP_ID)) {
208 QString app_id = QString::fromStdString(keyFile.get_string(
209 DESKTOP_FILE_GROUP,
210 DESKTOP_FILE_KEY_APP_ID));
211 QStringList id = app_id.split("_", QString::SkipEmptyParts);
212 if (id.length() == 3) {
213 app.name = id[0].toUtf8().data();
214 app.version = id[2].toUtf8().data();
215 app.url = "appid://" + id[0].toStdString() + "/" + id[1].toStdString() + "/current-user-version";
216 } else {
217 app.name = "unknown";
218 app.version = "unknown";
219 }
220 }
221 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_COMMENT)) {
222 app.description = get_translated_string(keyFile,
223 DESKTOP_FILE_GROUP,
224 DESKTOP_FILE_COMMENT,
225 domain);
226 }
227 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_SCREENSHOT)) {
228 app.main_screenshot = keyFile.get_string(DESKTOP_FILE_GROUP,
229 DESKTOP_FILE_SCREENSHOT);
230 }
231 return app;
232}
233132
234std::vector<click::Application> Interface::sort_apps(const std::vector<click::Application>& apps)133std::vector<click::Application> Interface::sort_apps(const std::vector<click::Application>& apps)
235{134{
@@ -264,11 +163,16 @@
264 return result;163 return result;
265}164}
266165
267/* find_installed_apps()166std::list<std::shared_ptr<ual::Application>> Interface::installed_apps()
167{
168 return ual::Registry::installedApps();
169}
170
171/* search()
268 *172 *
269 * Find all of the installed apps matching @search_query in a timeout.173 * Find all of the installed apps matching @query in a timeout.
270 */174 */
271std::vector<click::Application> Interface::find_installed_apps(const std::string& search_query,175std::vector<click::Application> Interface::search(const std::string& query,
272 const std::vector<std::string>& ignored_apps,176 const std::vector<std::string>& ignored_apps,
273 const std::string& current_department,177 const std::string& current_department,
274 const std::shared_ptr<click::DepartmentsDb>& depts_db)178 const std::shared_ptr<click::DepartmentsDb>& depts_db)
@@ -292,118 +196,109 @@
292 }196 }
293 }197 }
294198
295 std::vector<Application> result;199 std::vector<click::Application> result;
296200
297 bool include_desktop_results = show_desktop_apps();201 for (auto ualapp: installed_apps()) {
298 auto enumerator = [&result, this, search_query, ignored_apps, current_department, packages_in_department, apply_department_filter, include_desktop_results, depts_db]202 click::Application app;
299 (const unity::util::IniParser& keyFile, const std::string& filename)203
300 {204 // Get the package name and APP_ID info.
301 if (keyFile.has_group(DESKTOP_FILE_GROUP) == false) {205 app.name = ualapp->appId().package.value();
302 qWarning() << "Broken desktop file:" << QString::fromStdString(filename);206 if (app.name.empty()) {
303 return;207 app.name = std::string{ualapp->appId().appname.value()} + ".desktop";
304 }208 app.url = "application:///" + app.name;
305 if (is_visible_app(keyFile) == false) {209 if (!is_non_click_app(app.name)) {
306 return; // from the enumerator lambda210 qDebug() << "Skipping legacy app:" << QString::fromStdString(app.name);
307 }211 continue;
308212 }
309 if (include_desktop_results || keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_UBUNTU_TOUCH)213 } else {
310 || keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_APP_ID)214 app.url = "appid://" + app.name + "/" + ualapp->appId().appname.value() + "/current-user-version";
311 || Interface::is_non_click_app(QString::fromStdString(filename))) {215 }
312 auto app = load_app_from_desktop(keyFile, filename);216
313 auto app_id = app.name.empty() ? filename : app.name;217 if (!ignored_apps.empty() &&
314 if (!ignored_apps.empty() &&218 std::find(ignored_apps.begin(), ignored_apps.end(),
315 std::find(ignored_apps.begin(), ignored_apps.end(),219 app.name) != ignored_apps.end()) {
316 app_id) != ignored_apps.end())220 // The app is ignored. Get out of here.
317 {221 qDebug() << "App is ignored, skipping:" << QString::fromStdString(app.name);
318 // The app is ignored. Get out of here.222 continue;
319 return;223 }
320 }224
321225 // Get the .desktop file info from UAL, since we're not ignoring
322 // app from click package has non-empty name; for non-click apps use desktop filename226 auto appinfo = ualapp->info();
323 const std::string department_key = app.name.empty() ? filename : app.name;227 app.title = appinfo->name();
324228 app.description = appinfo->description();
325 // check if apps is present in current department229 app.icon_url = appinfo->iconPath();
326 if (apply_department_filter)230 app.default_department = appinfo->defaultDepartment();
327 {231 app.main_screenshot = appinfo->screenshotPath();
328 if (packages_in_department.find(department_key) == packages_in_department.end())232 app.keywords = appinfo->keywords();
329 {233
330 if (app.default_department.empty())234 // app from click package has non-empty name; for non-click apps use desktop filename
331 {235 auto department_key = app.name;
332 // default department not present in the keyfile, skip this app236 qDebug() << "Using department key:" << QString::fromStdString(department_key);
333 return;237
334 }238 // check if apps is present in current department
335 else239 if (apply_department_filter) {
336 {240 if (packages_in_department.find(department_key) ==
337 // default department not empty: check if this app is in a different241 packages_in_department.end()) {
338 // department in the db (i.e. got moved from the default department);242 if (app.default_department.empty()) {
339 if (depts_db->has_package(department_key))243 // default department not present in the keyfile, skip this app
340 {244 continue;
341 // app is now in a different department245 } else {
342 return;246 // default department not empty: check if this app is in a different
343 }247 // department in the db (i.e. got moved from the default department);
344248 if (depts_db->has_package(department_key)) {
345 if (app.default_department != current_department)249 // app is now in a different department
346 {250 continue;
347 return;251 }
348 }252
349 // else - this package is in current department253 if (app.default_department != current_department) {
350 }254 continue;
351 }255 }
352 }256 // else - this package is in current department
353257 }
354 //258 }
355 // the packages_in_department set contains packages from259 }
356 // all its subdepartments; we need to find actual department now260
357 // to update app.real_department.261 // the packages_in_department set contains packages from
358 if (depts_db)262 // all its subdepartments; we need to find actual department now
359 {263 // to update app.real_department.
360 if (depts_db->has_package(department_key))264 if (depts_db) {
361 {265 if (depts_db->has_package(department_key)) {
362 try266 try {
363 {267 app.real_department = depts_db->get_department_for_package(department_key);
364 app.real_department = depts_db->get_department_for_package(department_key);268 } catch (const std::exception &e) {
365 }269 qWarning() << "Failed to get department of package:" << QString::fromStdString(department_key);
366 catch (const std::exception &e)270 }
367 {271 } else {
368 qWarning() << "Failed to get department of package:" << QString::fromStdString(department_key);272 app.real_department = app.default_department;
369 }273 if (app.real_department.empty()) {
370 }274 qWarning() << "No default department set in the .desktop file and no entry in the database for" << QString::fromStdString(department_key);
371 else275 }
372 {276 }
373 app.real_department = app.default_department;277 }
374 if (app.real_department.empty())278
375 {279 if (query.empty()) {
376 qWarning() << "No default department set in the .desktop file and no entry in the database for" << QString::fromStdString(department_key);280 result.push_back(app);
377 }281 } else {
378 }282 QString lquery = ::unaccent(QString::fromStdString(query));
379 }283
380284 // Check keywords for the search query as well.
381 if (search_query.empty()) {285 for (auto kwd: app.keywords) {
286 QString keyword = ::unaccent(QString::fromStdString(kwd));
287 if (!keyword.isEmpty()
288 && keyword.contains(lquery, Qt::CaseInsensitive)) {
289 result.push_back(app);
290 }
291 }
292
293 QString search_title = ::unaccent(QString::fromStdString(app.title));
294 // check the app title for the search query.
295 if (!search_title.isEmpty()
296 && search_title.contains(lquery, Qt::CaseInsensitive)) {
382 result.push_back(app);297 result.push_back(app);
383 } else {
384 QString lquery = ::unaccent(QString::fromStdString(search_query));
385
386 // Check keywords for the search query as well.
387 for (auto kwd: app.keywords) {
388 QString keyword = ::unaccent(QString::fromStdString(kwd));
389 if (!keyword.isEmpty()
390 && keyword.contains(lquery, Qt::CaseInsensitive)) {
391 result.push_back(app);
392 return;
393 }
394 }
395
396 QString search_title = ::unaccent(QString::fromStdString(app.title));
397 // check the app title for the search query.
398 if (!search_title.isEmpty()
399 && search_title.contains(lquery, Qt::CaseInsensitive)) {
400 result.push_back(app);
401 }
402 }298 }
403 }299 }
404 };300 }
405301
406 keyFileLocator->enumerateKeyFilesForInstalledApplications(enumerator);
407 return sort_apps(result);302 return sort_apps(result);
408}303}
409304
@@ -412,9 +307,9 @@
412 * Tests that @filename is one of the special-cased filenames for apps307 * Tests that @filename is one of the special-cased filenames for apps
413 * which are not packaged as clicks, but required on Ubuntu Touch.308 * which are not packaged as clicks, but required on Ubuntu Touch.
414 */309 */
415bool Interface::is_non_click_app(const QString& filename)310bool Interface::is_non_click_app(const std::string& app_id)
416{311{
417 return click::nonClickDesktopFiles().count(filename.toUtf8().data()) > 0;312 return click::nonClickDesktopFiles().count(app_id) > 0;
418}313}
419314
420/*315/*
@@ -440,42 +335,6 @@
440 return icon_id;335 return icon_id;
441}336}
442337
443ManifestList manifest_list_from_json(const std::string& json)
444{
445 using namespace boost::property_tree;
446
447 std::istringstream is(json);
448
449 ptree pt;
450 read_json(is, pt);
451
452 ManifestList manifests;
453
454 BOOST_FOREACH(ptree::value_type &v, pt)
455 {
456 assert(v.first.empty()); // array elements have no names
457 auto node = v.second;
458 Manifest manifest;
459
460 manifest.name = node.get<std::string>("name");
461 manifest.version = node.get<std::string>("version");
462 manifest.removable = node.get<bool>("_removable");
463
464 BOOST_FOREACH(ptree::value_type &sv, node.get_child("hooks"))
465 {
466 // FIXME: "primary app" for a package is not defined, we just
467 // use first one here:
468 manifest.first_app_name = sv.first;
469 break;
470 }
471 qDebug() << "adding manifest: " << manifest.name.c_str() << manifest.version.c_str() << manifest.first_app_name.c_str();
472
473 manifests.push_back(manifest);
474 }
475
476 return manifests;
477}
478
479Manifest manifest_from_json(const std::string& json)338Manifest manifest_from_json(const std::string& json)
480{339{
481 using namespace boost::property_tree;340 using namespace boost::property_tree;
@@ -509,124 +368,62 @@
509 return manifest;368 return manifest;
510}369}
511370
512void Interface::get_manifests(std::function<void(ManifestList, InterfaceError)> callback)
513{
514 std::string command = "click list --manifest";
515 qDebug() << "Running command:" << command.c_str();
516 run_process(command, [callback](int code, const std::string& stdout_data, const std::string& stderr_data) {
517 if (code == 0) {
518 try {
519 ManifestList manifests = manifest_list_from_json(stdout_data);
520 callback(manifests, InterfaceError::NoError);
521 } catch (...) {
522 qWarning() << "Can't parse 'click list --manifest' output: " << QString::fromStdString(stdout_data);
523 callback(ManifestList(), InterfaceError::ParseError);
524 }
525 } else {
526 qWarning() << "Error" << code << "running 'click list --manifest': " << QString::fromStdString(stderr_data);
527 callback(ManifestList(), InterfaceError::CallError);
528 }
529 });
530}
531
532PackageSet package_names_from_stdout(const std::string& stdout_data)
533{
534 const char TAB='\t', NEWLINE='\n';
535 std::istringstream iss(stdout_data);
536 PackageSet installed_packages;
537
538 while (iss.peek() != EOF) {
539 std::string line;
540 std::getline(iss, line, NEWLINE);
541
542 if (!line.empty()) {
543 // Must initialize linestream after line is filled.
544 std::istringstream linestream(line);
545
546 Package p;
547 std::getline(linestream, p.name, TAB);
548 std::getline(linestream, p.version);
549 if (iss.eof() || p.name.empty() || p.version.empty()) {
550 qWarning() << "Error encountered parsing 'click list' output:" << QString::fromStdString(line);
551 } else {
552 installed_packages.insert(p);
553 }
554 }
555 }
556
557 return installed_packages;
558}
559
560void Interface::get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback)371void Interface::get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback)
561{372{
562 std::string command = "click list";373 PackageSet packages;
563 qDebug() << "Running command:" << command.c_str();374 for (auto app: installed_apps()) {
564 run_process(command, [callback](int code, const std::string& stdout_data, const std::string& stderr_data) {375 Package p;
565 if (code == 0) {376 p.name = app->appId().package.value();
566 try {377 p.version = app->appId().version.value();
567 PackageSet package_names = package_names_from_stdout(stdout_data);378 if (!p.name.empty() && !p.version.empty()) {
568 callback(package_names, InterfaceError::NoError);379 packages.insert(p);
569 } catch (...) {
570 qWarning() << "Can't parse 'click list' output: " << QString::fromStdString(stdout_data);
571 callback(PackageSet(), InterfaceError::ParseError);
572 }
573 } else {
574 qWarning() << "Error" << code << "running 'click list': " << QString::fromStdString(stderr_data);
575 callback(PackageSet(), InterfaceError::CallError);
576 }380 }
577 });381 }
382 callback(packages, InterfaceError::NoError);
383}
384
385std::string Interface::get_manifest_json(const std::string &package)
386{
387 GError* error = NULL;
388
389 auto clickdb = click_db_new();
390 click_db_read(clickdb, NULL, &error);
391 if (error != NULL) {
392 qCritical() << "Error reading click DB:" << error->message;
393 g_error_free(error);
394 return "";
395 }
396
397 auto clickuser = click_user_new_for_user(clickdb, NULL, &error);
398 if (error != NULL) {
399 qCritical() << "Error setting up click user:" << error->message;
400 g_error_free(error);
401 return "";
402 }
403
404 auto result = click_user_get_manifest_as_string(clickuser, package.c_str(),
405 &error);
406 if (error != NULL) {
407 qCritical() << "Error getting manifest:" << error->message;
408 g_error_free(error);
409 return "";
410 }
411
412 std::string retval{result};
413 g_free(result);
414 return retval;
578}415}
579416
580void Interface::get_manifest_for_app(const std::string &app_id,417void Interface::get_manifest_for_app(const std::string &app_id,
581 std::function<void(Manifest, InterfaceError)> callback)418 std::function<void(Manifest, InterfaceError)> callback)
582{419{
583 std::string command = "click info " + app_id;420 try {
584 qDebug() << "Running command:" << command.c_str();421 Manifest manifest = manifest_from_json(get_manifest_json(app_id));
585 run_process(command, [callback, app_id](int code, const std::string& stdout_data, const std::string& stderr_data) {422 callback(manifest, InterfaceError::NoError);
586 if (code == 0) {423 } catch (...) {
587 try {424 qWarning() << "Can't parse manifest for:" << QString::fromStdString(app_id);
588 Manifest manifest = manifest_from_json(stdout_data);425 callback(Manifest(), InterfaceError::ParseError);
589 callback(manifest, InterfaceError::NoError);426 }
590 } catch (...) {
591 qWarning() << "Can't parse 'click info" << QString::fromStdString(app_id)
592 << "' output: " << QString::fromStdString(stdout_data);
593 callback(Manifest(), InterfaceError::ParseError);
594 }
595 } else {
596 qWarning() << "Error" << code << "running 'click info" << QString::fromStdString(app_id)
597 << "': " << QString::fromStdString(stderr_data);
598 callback(Manifest(), InterfaceError::CallError);
599 }
600 });
601}
602
603void Interface::run_process(const std::string& command,
604 std::function<void(int code,
605 const std::string& stdout_data,
606 const std::string& stderr_data)> callback)
607{
608 QSharedPointer<QProcess> process(new QProcess());
609 typedef void(QProcess::*QProcessFinished)(int, QProcess::ExitStatus);
610 typedef void(QProcess::*QProcessError)(QProcess::ProcessError);
611 QObject::connect(process.data(),
612 static_cast<QProcessFinished>(&QProcess::finished),
613 [callback, process](int code, QProcess::ExitStatus /*status*/) {
614 qDebug() << "command finished with exit code:" << code;
615 std::string data{process->readAllStandardOutput().data()};
616 std::string errors{process->readAllStandardError().data()};
617 callback(code, data, errors);
618 } );
619
620 QObject::connect(process.data(),
621 static_cast<QProcessError>(&QProcess::error),
622 [callback, process](QProcess::ProcessError error) {
623 qCritical() << "error running command:" << error;
624 std::string data{process->readAllStandardOutput().data()};
625 std::string errors{process->readAllStandardError().data()};
626 callback(process->exitCode(), data, errors);
627 } );
628
629 process->start(command.c_str());
630}427}
631428
632} // namespace click429} // namespace click
633430
=== modified file 'libclickscope/click/interface.h'
--- libclickscope/click/interface.h 2016-07-14 18:37:27 +0000
+++ libclickscope/click/interface.h 2016-08-24 21:39:08 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -30,15 +30,19 @@
30#ifndef CLICK_INTERFACE_H30#ifndef CLICK_INTERFACE_H
31#define CLICK_INTERFACE_H31#define CLICK_INTERFACE_H
3232
33#include <QObject>33#include "application.h"
34#include <QStringList>34#include "package.h"
35
36#include <ubuntu-app-launch/application.h>
37
35#include <unity/util/IniParser.h>38#include <unity/util/IniParser.h>
3639
40#include <memory>
41#include <unordered_set>
37#include <vector>42#include <vector>
38#include <unordered_set>
3943
40#include "application.h"44using namespace ubuntu::app_launch;
41#include "package.h"45namespace ual = ubuntu::app_launch;
4246
43namespace click47namespace click
44{48{
@@ -74,46 +78,28 @@
74enum class InterfaceError {NoError, CallError, ParseError};78enum class InterfaceError {NoError, CallError, ParseError};
75typedef std::list<Manifest> ManifestList;79typedef std::list<Manifest> ManifestList;
7680
77ManifestList manifest_list_from_json(const std::string& json);
78Manifest manifest_from_json(const std::string& json);81Manifest manifest_from_json(const std::string& json);
79PackageSet package_names_from_stdout(const std::string& stdout_data);
8082
81class Interface83class Interface
82{84{
83public:85public:
84 Interface(const QSharedPointer<KeyFileLocator>& keyFileLocator);
85 Interface() = default;86 Interface() = default;
86 virtual ~Interface();87 virtual ~Interface() = default;
8788
88 virtual std::string get_translated_string(const unity::util::IniParser& keyFile,
89 const std::string& group,
90 const std::string& key,
91 const std::string& domain);
92 virtual Application load_app_from_desktop(const unity::util::IniParser& keyFile,
93 const std::string& filename);
94 static std::vector<Application> sort_apps(const std::vector<Application>& apps);89 static std::vector<Application> sort_apps(const std::vector<Application>& apps);
95 virtual std::vector<Application> find_installed_apps(const std::string& search_query,90 virtual std::list<std::shared_ptr<ual::Application>> installed_apps();
91 virtual std::vector<Application> search(const std::string& query,
96 const std::vector<std::string>& ignored_apps = std::vector<std::string>{},92 const std::vector<std::string>& ignored_apps = std::vector<std::string>{},
97 const std::string& current_department = "",93 const std::string& current_department = "",
98 const std::shared_ptr<click::DepartmentsDb>& depts_db = nullptr);94 const std::shared_ptr<click::DepartmentsDb>& depts_db = nullptr);
9995
100 static bool is_non_click_app(const QString& filename);96 static bool is_non_click_app(const std::string& app_id);
10197
102 static bool is_icon_identifier(const std::string &icon_id);98 static bool is_icon_identifier(const std::string &icon_id);
103 static std::string add_theme_scheme(const std::string &filename);99 static std::string add_theme_scheme(const std::string &filename);
104 virtual void get_manifests(std::function<void(ManifestList, InterfaceError)> callback);
105 virtual void get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback);100 virtual void get_installed_packages(std::function<void(PackageSet, InterfaceError)> callback);
101 virtual std::string get_manifest_json(const std::string &package);
106 virtual void get_manifest_for_app(const std::string &app_id, std::function<void(Manifest, InterfaceError)> callback);102 virtual void get_manifest_for_app(const std::string &app_id, std::function<void(Manifest, InterfaceError)> callback);
107 constexpr static const char* ENV_SHOW_DESKTOP_APPS {"CLICK_SCOPE_SHOW_DESKTOP_APPS"};
108 virtual bool is_visible_app(const unity::util::IniParser& keyFile);
109 virtual bool show_desktop_apps();
110
111 virtual void run_process(const std::string& command,
112 std::function<void(int code,
113 const std::string& stdout_data,
114 const std::string& stderr_data)> callback);
115private:
116 QSharedPointer<KeyFileLocator> keyFileLocator;
117};103};
118104
119} // namespace click105} // namespace click
120106
=== removed file 'libclickscope/click/key_file_locator.cpp'
--- libclickscope/click/key_file_locator.cpp 2015-11-24 18:23:23 +0000
+++ libclickscope/click/key_file_locator.cpp 1970-01-01 00:00:00 +0000
@@ -1,94 +0,0 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * In addition, as a special exception, the copyright holders give
17 * permission to link the code of portions of this program with the
18 * OpenSSL library under certain conditions as described in each
19 * individual source file, and distribute linked combinations
20 * including the two.
21 * You must obey the GNU General Public License in all respects
22 * for all of the code used other than OpenSSL. If you modify
23 * file(s) with this exception, you may extend this exception to your
24 * version of the file(s), but you are not obligated to do so. If you
25 * do not wish to do so, delete this exception statement from your
26 * version. If you delete this exception statement from all source
27 * files in the program, then also delete it here.
28 */
29
30#include "key_file_locator.h"
31
32#include <unity/Exception.h>
33#include <unity/UnityExceptions.h>
34#include <unity/util/IniParser.h>
35
36#include <QDebug>
37#include <QDir>
38#include <QStandardPaths>
39#include <QString>
40
41namespace
42{
43static const QString NON_CLICK_PATH("/usr/share/applications");
44
45void find_apps_in_dir(const QString& dir_path,
46 const click::KeyFileLocator::Enumerator& enumerator)
47{
48 QDir dir(dir_path, "*.desktop",
49 QDir::Unsorted, QDir::Readable | QDir::Files);
50 QStringList entries = dir.entryList();
51 for (int i = 0; i < entries.size(); ++i) {
52 QString filename = entries.at(i);
53 QString full_path = dir.absoluteFilePath(filename);
54 try {
55 enumerator(unity::util::IniParser(full_path.toUtf8().data()),
56 filename.toUtf8().data());
57 } catch (const unity::FileException& file_exp) {
58 qWarning() << "Error reading file:" << file_exp.to_string().c_str();
59 } catch (const unity::LogicException& logic_exp) {
60 qCritical() << "Error reading file:" << logic_exp.to_string().c_str();
61 }
62 }
63}
64}
65
66const std::string& click::KeyFileLocator::systemApplicationsDirectory()
67{
68 static const std::string s{"/usr/share/applications"};
69 return s;
70}
71
72const std::string& click::KeyFileLocator::userApplicationsDirectory()
73{
74 static const std::string s
75 {
76 qPrintable(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/applications")
77 };
78 return s;
79}
80
81click::KeyFileLocator::KeyFileLocator(
82 const std::string& systemApplicationsDir,
83 const std::string& userApplicationsDir)
84 : systemApplicationsDir(systemApplicationsDir),
85 userApplicationsDir(userApplicationsDir)
86{
87}
88
89void click::KeyFileLocator::enumerateKeyFilesForInstalledApplications(
90 const click::KeyFileLocator::Enumerator& enumerator)
91{
92 find_apps_in_dir(QString::fromStdString(systemApplicationsDir), enumerator);
93 find_apps_in_dir(QString::fromStdString(userApplicationsDir), enumerator);
94}
950
=== removed file 'libclickscope/click/key_file_locator.h'
--- libclickscope/click/key_file_locator.h 2014-05-13 19:32:29 +0000
+++ libclickscope/click/key_file_locator.h 1970-01-01 00:00:00 +0000
@@ -1,70 +0,0 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * In addition, as a special exception, the copyright holders give
17 * permission to link the code of portions of this program with the
18 * OpenSSL library under certain conditions as described in each
19 * individual source file, and distribute linked combinations
20 * including the two.
21 * You must obey the GNU General Public License in all respects
22 * for all of the code used other than OpenSSL. If you modify
23 * file(s) with this exception, you may extend this exception to your
24 * version of the file(s), but you are not obligated to do so. If you
25 * do not wish to do so, delete this exception statement from your
26 * version. If you delete this exception statement from all source
27 * files in the program, then also delete it here.
28 */
29
30#ifndef CLICK_KEY_FILE_LOCATOR_H
31#define CLICK_KEY_FILE_LOCATOR_H
32
33#include <functional>
34#include <string>
35
36namespace unity
37{
38namespace util
39{
40class IniParser;
41}
42}
43
44namespace click
45{
46class KeyFileLocator
47{
48public:
49 static const std::string& systemApplicationsDirectory();
50 static const std::string& userApplicationsDirectory();
51
52 typedef std::function<void(const unity::util::IniParser&, const std::string&)> Enumerator;
53
54 KeyFileLocator(const std::string& systemApplicationsDir = systemApplicationsDirectory(),
55 const std::string& userApplicationsDir = userApplicationsDirectory());
56 KeyFileLocator(const KeyFileLocator&) = delete;
57 virtual ~KeyFileLocator() = default;
58
59 KeyFileLocator& operator=(const KeyFileLocator&) = delete;
60 bool operator==(const KeyFileLocator&) const = delete;
61
62 virtual void enumerateKeyFilesForInstalledApplications(const Enumerator& enumerator);
63
64private:
65 std::string systemApplicationsDir;
66 std::string userApplicationsDir;
67};
68}
69
70#endif // CLICK_KEY_FILE_LOCATOR_H
710
=== modified file 'libclickscope/click/package.cpp'
--- libclickscope/click/package.cpp 2015-11-24 18:23:23 +0000
+++ libclickscope/click/package.cpp 2016-08-24 21:39:08 +0000
@@ -95,6 +95,10 @@
95 p.publisher = item[Package::JsonKeys::publisher].asString();95 p.publisher = item[Package::JsonKeys::publisher].asString();
96 p.rating = item[Package::JsonKeys::rating].asDouble();96 p.rating = item[Package::JsonKeys::rating].asDouble();
97 p.version = item[Package::JsonKeys::version].asString();97 p.version = item[Package::JsonKeys::version].asString();
98
99 p.snap_id = item[Package::JsonKeys::snap_id].asString();
100 p.alias = item[Package::JsonKeys::alias].asString();
101
98 return p;102 return p;
99}103}
100104
101105
=== modified file 'libclickscope/click/package.h'
--- libclickscope/click/package.h 2015-11-24 18:23:23 +0000
+++ libclickscope/click/package.h 2016-08-24 21:39:08 +0000
@@ -64,6 +64,8 @@
64 constexpr static const char* publisher{"publisher"};64 constexpr static const char* publisher{"publisher"};
65 constexpr static const char* rating{"ratings_average"};65 constexpr static const char* rating{"ratings_average"};
66 constexpr static const char* version{"version"};66 constexpr static const char* version{"version"};
67 constexpr static const char* snap_id{"snap_id"};
68 constexpr static const char* alias{"alias"};
6769
68 // NOTE: The "price" field is deprecated in favor of "prices"70 // NOTE: The "price" field is deprecated in favor of "prices"
69 constexpr static const char* prices{"prices"};71 constexpr static const char* prices{"prices"};
@@ -107,6 +109,8 @@
107 void matches (std::string query, std::function<bool> callback);109 void matches (std::string query, std::function<bool> callback);
108 std::string content;110 std::string content;
109 std::map<std::string, double> prices;111 std::map<std::string, double> prices;
112 std::string snap_id;
113 std::string alias;
110114
111 struct hash_name {115 struct hash_name {
112 public :116 public :
113117
=== modified file 'libclickscope/click/preview.cpp'
--- libclickscope/click/preview.cpp 2016-07-18 15:38:22 +0000
+++ libclickscope/click/preview.cpp 2016-08-24 21:39:08 +0000
@@ -413,6 +413,9 @@
413 }413 }
414}414}
415415
416// Need to use this in a couple places, so it's a static const.
417static const std::regex desktop_match("^(.*)\\.desktop$");
418
416// TODO: error handling - once get_details provides errors, we can419// TODO: error handling - once get_details provides errors, we can
417// return them from populateDetails and check them in the calling code420// return them from populateDetails and check them in the calling code
418// to decide whether to show error widgets. see bug LP: #1289541421// to decide whether to show error widgets. see bug LP: #1289541
@@ -422,8 +425,9 @@
422{425{
423426
424 std::string app_name = get_string_maybe_null(result["name"]);427 std::string app_name = get_string_maybe_null(result["name"]);
428 std::string snap_id = get_string_maybe_null(result["snap_id"]);
425429
426 if (app_name.empty()) {430 if (app_name.empty() || std::regex_match(app_name, desktop_match)) {
427 click::PackageDetails details;431 click::PackageDetails details;
428 qDebug() << "in populateDetails(), app_name is empty";432 qDebug() << "in populateDetails(), app_name is empty";
429 details.package.title = result.title();433 details.package.title = result.title();
@@ -437,9 +441,13 @@
437 // I think this should not be required when we switch the click::Index over441 // I think this should not be required when we switch the click::Index over
438 // to using the Qt bridge. With that, the qt dependency becomes an implementation detail442 // to using the Qt bridge. With that, the qt dependency becomes an implementation detail
439 // and code using it does not need to worry about threading/event loop topics.443 // and code using it does not need to worry about threading/event loop topics.
440 run_under_qt([this, details_callback, reviews_callback, app_name, force_cache]()444 run_under_qt([this, details_callback, reviews_callback, app_name, snap_id, force_cache]()
441 {445 {
442 index_operation = index->get_details(app_name, [this, app_name, details_callback, reviews_callback, force_cache](PackageDetails details, click::Index::Error error){446 index_operation = index->get_details(app_name,
447 [this, app_name, snap_id,
448 details_callback,
449 reviews_callback,
450 force_cache](PackageDetails details, click::Index::Error error){
443 if(error == click::Index::Error::NoError) {451 if(error == click::Index::Error::NoError) {
444 qDebug() << "Got details:" << app_name.c_str();452 qDebug() << "Got details:" << app_name.c_str();
445 details_callback(details);453 details_callback(details);
@@ -452,10 +460,17 @@
452 details.main_screenshot_url = get_string_maybe_null(result["main_screenshot"]);460 details.main_screenshot_url = get_string_maybe_null(result["main_screenshot"]);
453 details_callback(details);461 details_callback(details);
454 }462 }
455 reviews_operation = reviews->fetch_reviews(app_name,463 // FIXME: No RNR support for v2 snaps yet, so avoid the
456 reviews_callback,464 // network hit if we're showing a snap preview
457 force_cache);465 if (snap_id.empty()) {
458 }, force_cache);466 reviews_operation = reviews->fetch_reviews(app_name,
467 reviews_callback,
468 force_cache);
469 } else {
470 reviews_callback(click::ReviewList{},
471 click::Reviews::Error::NoError);
472 }
473 }, !snap_id.empty(), force_cache);
459 });474 });
460 }475 }
461}476}
@@ -900,7 +915,7 @@
900 std::promise<Manifest> manifest_promise;915 std::promise<Manifest> manifest_promise;
901 std::future<Manifest> manifest_future = manifest_promise.get_future();916 std::future<Manifest> manifest_future = manifest_promise.get_future();
902 std::string app_name = result["name"].get_string();917 std::string app_name = result["name"].get_string();
903 if (!app_name.empty()) {918 if (!app_name.empty() && !std::regex_match(app_name, desktop_match)) {
904 qt::core::world::enter_with_task([&]() {919 qt::core::world::enter_with_task([&]() {
905 click::Interface().get_manifest_for_app(app_name,920 click::Interface().get_manifest_for_app(app_name,
906 [&](Manifest found_manifest, InterfaceError error) {921 [&](Manifest found_manifest, InterfaceError error) {
907922
=== modified file 'libclickscope/click/webclient.cpp'
--- libclickscope/click/webclient.cpp 2016-05-25 16:19:51 +0000
+++ libclickscope/click/webclient.cpp 2016-08-24 21:39:08 +0000
@@ -78,6 +78,26 @@
78{78{
79}79}
8080
81std::string click::web::Client::signUrl(const std::string& url,
82 const std::string& method)
83{
84 QString signature;
85
86 if (impl->sso.isNull()) {
87 qCritical() << "Unable to sign request without SSO object.";
88 } else {
89 auto token = impl->sso->getToken();
90 if (token.isValid()) {
91 signature = token.signUrl(QString::fromStdString(url),
92 QString::fromStdString(method));
93 qDebug() << "Signed URL:" << QString::fromStdString(url);
94 } else {
95 qWarning() << "Signing requested but returned token is invalid.";
96 }
97 }
98 return signature.toStdString();
99}
100
81QSharedPointer<click::web::Response> click::web::Client::call(101QSharedPointer<click::web::Response> click::web::Client::call(
82 const std::string& iri,102 const std::string& iri,
83 const click::web::CallParams& params,103 const click::web::CallParams& params,
@@ -137,25 +157,14 @@
137 auto deviceId = Configuration().get_device_id();157 auto deviceId = Configuration().get_device_id();
138 request->setRawHeader(DEVICE_ID_HEADER.c_str(), deviceId.data());158 request->setRawHeader(DEVICE_ID_HEADER.c_str(), deviceId.data());
139159
140 if (sign && !impl->sso.isNull()) {160 if (sign) {
141 auto token = impl->sso->getToken();161 auto auth_header = signUrl(url.toString().toStdString(), method);
142 if (token.isValid()) {162 if (!auth_header.empty())
143 QString auth_header = token.signUrl(url.toString(),163 request->setRawHeader(AUTHORIZATION_HEADER.c_str(),
144 method.c_str());164 auth_header.c_str());
145 qDebug() << "Signed URL:" << request->url().toString();
146 request->setRawHeader(AUTHORIZATION_HEADER.c_str(), auth_header.toUtf8());
147 } else {
148 qWarning() << "Signing reuested but returned token is invalid.";
149 }
150
151 doConnect();
152 } else {
153 if (sign && impl->sso.isNull()) {
154 qCritical() << "Unable to sign request without SSO object.";
155 }
156 doConnect();
157 }165 }
158166
167 doConnect();
159168
160 return responsePtr;169 return responsePtr;
161}170}
162171
=== modified file 'libclickscope/click/webclient.h'
--- libclickscope/click/webclient.h 2016-05-25 16:19:51 +0000
+++ libclickscope/click/webclient.h 2016-08-24 21:39:08 +0000
@@ -115,6 +115,8 @@
115 Client(const QSharedPointer<click::network::AccessManager>& networkAccessManager);115 Client(const QSharedPointer<click::network::AccessManager>& networkAccessManager);
116 virtual ~Client();116 virtual ~Client();
117117
118 virtual std::string signUrl(const std::string& url,
119 const std::string& method);
118 virtual QSharedPointer<Response> call(120 virtual QSharedPointer<Response> call(
119 const std::string& iri,121 const std::string& iri,
120 const CallParams& params = CallParams(), bool force_cache = false);122 const CallParams& params = CallParams(), bool force_cache = false);
121123
=== modified file 'libclickscope/tests/CMakeLists.txt'
--- libclickscope/tests/CMakeLists.txt 2015-07-02 21:56:45 +0000
+++ libclickscope/tests/CMakeLists.txt 2016-08-24 21:39:08 +0000
@@ -15,11 +15,13 @@
15 ${GMOCK_INCLUDE_DIR}15 ${GMOCK_INCLUDE_DIR}
16)16)
1717
18configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test_data.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp)
19add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}")18add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}")
2019
21add_executable (${LIBCLICKSCOPE_TESTS_TARGET}20add_executable (${LIBCLICKSCOPE_TESTS_TARGET}
22 mock_network_access_manager.h21 mock_network_access_manager.h
22 mock_pay.h
23 mock_ual.h
24 mock_ubuntu_download_manager.h
23 mock_ubuntuone_credentials.h25 mock_ubuntuone_credentials.h
24 mock_webclient.h26 mock_webclient.h
25 fake_json.cpp27 fake_json.cpp
@@ -37,8 +39,6 @@
37 test_smartconnect.cpp39 test_smartconnect.cpp
38 test_utils.cpp40 test_utils.cpp
39 test_webclient.cpp41 test_webclient.cpp
40
41 ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp
42)42)
4343
44qt5_use_modules(${LIBCLICKSCOPE_TESTS_TARGET} Core Sql)44qt5_use_modules(${LIBCLICKSCOPE_TESTS_TARGET} Core Sql)
4545
=== removed directory 'libclickscope/tests/applications'
=== removed directory 'libclickscope/tests/applications/system'
=== removed file 'libclickscope/tests/applications/system/address-book-app.desktop'
--- libclickscope/tests/applications/system/address-book-app.desktop 2014-07-21 12:41:31 +0000
+++ libclickscope/tests/applications/system/address-book-app.desktop 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1[Desktop Entry]
2Encoding=UTF-8
3Version=1.0
4Terminal=false
5Type=Application
6Name=Contacts
7GenericName=Contacts
8Exec=/usr/bin/address-book-app %u
9Icon=contacts-app
10X-Ubuntu-Touch=true
11X-Ubuntu-StageHint=SideStage
12X-Ubuntu-Gettext-Domain=address-book-app
13X-Ubuntu-Single-Instance=true
14X-Ubuntu-Default-Department-ID=accessories
15# this one has no screenshot nor comment, to test how it breaks
160
=== removed file 'libclickscope/tests/applications/system/messaging-app.desktop'
--- libclickscope/tests/applications/system/messaging-app.desktop 2014-04-02 11:56:49 +0000
+++ libclickscope/tests/applications/system/messaging-app.desktop 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
1[Desktop Entry]
2Type=Application
3Name=Messaging
4GenericName=Messaging
5Comment=Messaging application
6Exec=messaging-app %u
7Terminal=false
8Icon=messages-app
9MimeType=x-scheme-handler/contact;x-scheme-handler/call
10X-Ubuntu-Touch=true
11X-Ubuntu-StageHint=SideStage
12X-Ubuntu-Gettext-Domain=messaging-app
13X-Ubuntu-Single-Instance=true
14X-Screenshot=/usr/share/messaging-app/assets/messaging-app-screenshot.png
150
=== removed file 'libclickscope/tests/applications/system/translated.desktop'
--- libclickscope/tests/applications/system/translated.desktop 2014-05-05 20:21:53 +0000
+++ libclickscope/tests/applications/system/translated.desktop 1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
1[Desktop Entry]
2Type=Application
3Name=Translated App
4Name[en]=Translated App
5Name[es]=Translated App in Spanish
6Comment=Translated application
7Comment[en]=Translated application
8Comment[es]=Translated application in Spanish
9X-Ubuntu-Touch=true
100
=== removed directory 'libclickscope/tests/applications/user'
=== removed file 'libclickscope/tests/applications/user/badd-appid.desktop'
--- libclickscope/tests/applications/user/badd-appid.desktop 2016-01-04 20:50:16 +0000
+++ libclickscope/tests/applications/user/badd-appid.desktop 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=processTest
6Icon=/home/phablet/animatedDemos/football-ball.png
7Path=/home/phablet/processTest
8Name=Football
9X-Ubuntu-Touch=true
10X-Ubuntu-Application-ID=football
110
=== removed file 'libclickscope/tests/applications/user/broken.desktop'
12Binary 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 differ1Binary 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
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.accented_accented_0.5.29.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.accented_accented_0.5.29.desktop 2016-03-03 14:19:50 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.accented_accented_0.5.29.desktop 1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=aa-exec-click -p com.ubuntu.accented_accented_0.5.29 -- qmlscene ./ubuntu-accented-app.qml -I ./plugins
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.accented/./accented64.png
7Name=Cámara
8X-Ubuntu-Touch=true
9X-Ubuntu-StageHint=SideStage
10
11Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.accented
12X-Ubuntu-Old-Icon=./accented64.png
13X-Ubuntu-Application-ID=com.ubuntu.accented_accented_0.5.29
140
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.calculator_calculator_0.1.3.206.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.calculator_calculator_0.1.3.206.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.calculator_calculator_0.1.3.206.desktop 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=aa-exec-click -p com.ubuntu.calculator_calculator_0.1.3.206 -- qmlscene ./ubuntu-calculator-app.qml
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/./calculator64.png
7Name=Calculator
8X-Ubuntu-Touch=true
9X-Ubuntu-StageHint=SideStage
10X-Ubuntu-Gettext-Domain=com.ubuntu.calculator
11
12Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator
13X-Ubuntu-Old-Icon=./calculator64.png
14X-Ubuntu-Application-ID=com.ubuntu.calculator_calculator_0.1.3.206
150
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.calendar_calendar_0.4.182.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.calendar_calendar_0.4.182.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.calendar_calendar_0.4.182.desktop 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=aa-exec-click -p com.ubuntu.calendar_calendar_0.4.182 -- qmlscene %u ./calendar.qml
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calendar/./calendar64.png
7Name=Calendar
8X-Ubuntu-Touch=true
9X-Ubuntu-StageHint=SideStage
10X-Ubuntu-Gettext-Domain=com.ubuntu.calendar
11
12Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calendar
13X-Ubuntu-Old-Icon=./calendar64.png
14X-Ubuntu-Application-ID=com.ubuntu.calendar_calendar_0.4.182
150
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.clock_clock_1.0.300.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.clock_clock_1.0.300.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.clock_clock_1.0.300.desktop 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=aa-exec-click -p com.ubuntu.clock_clock_1.0.300 -- qmlscene ./ubuntu-clock-app.qml
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock/./clock64.png
7Name=Clock
8X-Ubuntu-Touch=true
9X-Ubuntu-StageHint=SideStage
10X-Ubuntu-Gettext-Domain=com.ubuntu.clock
11
12Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock
13X-Ubuntu-Old-Icon=./clock64.png
14X-Ubuntu-Application-ID=com.ubuntu.clock_clock_1.0.300
150
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6.desktop 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
1[Desktop Entry]
2Type=Application
3Terminal=false
4Exec=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
5Name=Amazon
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-amazon/./amazon.png
7X-Ubuntu-Touch=true
8Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-amazon
9X-Ubuntu-Old-Icon=./amazon.png
10X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-amazon_webapp-amazon_1.0.6
110
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8.desktop 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
1[Desktop Entry]
2Type=Application
3Terminal=false
4Exec=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/
5Name=eBay
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-ebay/./ebay.png
7X-Ubuntu-Touch=true
8X-Ubuntu-Single-Instance=true
9Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-ebay
10X-Ubuntu-Old-Icon=./ebay.png
11X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-ebay_webapp-ebay_1.0.8
120
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5.desktop 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
1[Desktop Entry]
2Type=Application
3Terminal=false
4Exec=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/
5Name=Facebook
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-facebook/./facebook.png
7X-Ubuntu-Touch=true
8X-Ubuntu-StageHint=SideStage
9X-Ubuntu-Single-Instance=true
10Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-facebook
11X-Ubuntu-Old-Icon=./facebook.png
12X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook_1.0.5
130
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8.desktop 1970-01-01 00:00:00 +0000
@@ -1,11 +0,0 @@
1[Desktop Entry]
2Type=Application
3Terminal=false
4Exec=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/
5Name=Gmail
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-gmail/./gmail.png
7X-Ubuntu-Touch=true
8X-Ubuntu-Single-Instance=true
9Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-gmail
10X-Ubuntu-Old-Icon=./gmail.png
11X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail_1.0.8
120
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5.desktop 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
1[Desktop Entry]
2Type=Application
3Terminal=false
4Exec=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
5Name=Twitter
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-twitter/./twitter.png
7X-Ubuntu-Touch=true
8X-Ubuntu-StageHint=SideStage
9X-Ubuntu-Single-Instance=true
10Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-twitter
11X-Ubuntu-Old-Icon=./twitter.png
12X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5
130
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43.desktop 1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.dropping-letters/dropping-letters.png
5Terminal=false
6Name=Dropping Letters
7Exec=aa-exec-click -p com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43 -- qmlscene dropping-letters.qml
8X-Ubuntu-Touch=true
9X-Ubuntu-StageHint=SideStage
10
11Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.dropping-letters
12X-Ubuntu-Old-Icon=dropping-letters.png
13X-Ubuntu-Application-ID=com.ubuntu.dropping-letters_dropping-letters_0.1.2.2.43
140
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.filemanager_filemanager_0.1.1.97.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.filemanager_filemanager_0.1.1.97.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.filemanager_filemanager_0.1.1.97.desktop 1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=aa-exec-click -p com.ubuntu.filemanager_filemanager_0.1.1.97 -- qmlscene ./ubuntu-filemanager-app.qml -I ./plugins
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.filemanager/./filemanager64.png
7Name=File Manager
8X-Ubuntu-Touch=true
9X-Ubuntu-StageHint=SideStage
10
11Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.filemanager
12X-Ubuntu-Old-Icon=./filemanager64.png
13X-Ubuntu-Application-ID=com.ubuntu.filemanager_filemanager_0.1.1.97
140
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.music_music_1.1.329.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.music_music_1.1.329.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.music_music_1.1.329.desktop 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Name=Music
4Comment=Ubuntu Touch Music Player
5Exec=aa-exec-click -p com.ubuntu.music_music_1.1.329 -- qmlscene ./music-app.qml --file=%f -I ./plugins
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.music/images/music.png
7Terminal=false
8Type=Application
9StartupNotify=true
10X-Ubuntu-Single-Instance=true
11X-Ubuntu-Touch=true
12
13Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.music
14X-Ubuntu-Old-Icon=images/music.png
15X-Ubuntu-Application-ID=com.ubuntu.music_music_1.1.329
160
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.notes_notes_1.4.242.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.notes_notes_1.4.242.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.notes_notes_1.4.242.desktop 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
1[Desktop Entry]
2Type=Application
3Exec=aa-exec-click -p com.ubuntu.notes_notes_1.4.242 -- qmlscene $@ -I ./usr/lib/arm-linux-gnueabihf/qt5/qml NotesApp.qml
4Name=Notes
5GenericName=Notes application for Ubuntu
6Icon=notepad
7Terminal=false
8
9X-Ubuntu-Touch=true
10X-Ubuntu-StageHint=SideStage
11X-Ubuntu-Gettext-Domain=com.ubuntu.notes
12X-Ubuntu-Single-Instance=true
13Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.notes
14X-Ubuntu-Application-ID=com.ubuntu.notes_notes_1.4.242
150
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.shorts_shorts_0.2.162.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.shorts_shorts_0.2.162.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.shorts_shorts_0.2.162.desktop 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=aa-exec-click -p com.ubuntu.shorts_shorts_0.2.162 -- qmlscene ./rssreader-app.qml
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.shorts/./rssreader64.png
7Name=Shorts
8Keywords=shorts;rss;reader
9X-Ubuntu-Touch=true
10X-Ubuntu-StageHint=SideStage
11
12Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.shorts
13X-Ubuntu-Old-Icon=./rssreader64.png
14X-Ubuntu-Application-ID=com.ubuntu.shorts_shorts_0.2.162
150
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop 1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Name=Stock Ticker
4GenericName=Stock Ticker
5Comment=An awesome Stock Ticker application with all the features you could imagine
6Exec=aa-exec-click -p com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66 -- qmlscene Stock_Ticker.qml
7Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.stock-ticker-mobile/icons/stock_icon_48.png
8Terminal=false
9Type=Application
10X-Ubuntu-Touch=true
11X-Ubuntu-StageHint=SideStage
12Categories=Utility;
13
14Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.stock-ticker-mobile
15X-Ubuntu-Old-Icon=icons/stock_icon_48.png
16X-Ubuntu-Application-ID=com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66
170
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.sudoku_sudoku_1.0.142.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.sudoku_sudoku_1.0.142.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.sudoku_sudoku_1.0.142.desktop 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1[Desktop Entry]
2Name=Sudoku
3Version=1.0
4Comment=Sudoku Game for Ubuntu Touch
5Exec=aa-exec-click -p com.ubuntu.sudoku_sudoku_1.0.142 -- qmlscene sudoku-app.qml
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.sudoku/SudokuGameIcon.png
7Terminal=false
8Type=Application
9X-Ubuntu-Touch=true
10X-Ubuntu-StageHint=SideStage
11X-Ubuntu-Gettext-Domain=com.ubuntu.sudoku
12
13Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.sudoku
14X-Ubuntu-Old-Icon=SudokuGameIcon.png
15X-Ubuntu-Application-ID=com.ubuntu.sudoku_sudoku_1.0.142
160
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.terminal_terminal_0.5.29.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.terminal_terminal_0.5.29.desktop 2014-02-10 12:23:35 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.terminal_terminal_0.5.29.desktop 1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=aa-exec-click -p com.ubuntu.terminal_terminal_0.5.29 -- qmlscene ./ubuntu-terminal-app.qml -I ./plugins
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.terminal/./terminal64.png
7Name=Terminal
8X-Ubuntu-Touch=true
9X-Ubuntu-StageHint=SideStage
10
11Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.terminal
12X-Ubuntu-Old-Icon=./terminal64.png
13X-Ubuntu-Application-ID=com.ubuntu.terminal_terminal_0.5.29
140
=== removed file 'libclickscope/tests/applications/user/com.ubuntu.weather_weather_1.0.168.desktop'
--- libclickscope/tests/applications/user/com.ubuntu.weather_weather_1.0.168.desktop 2014-04-10 17:29:49 +0000
+++ libclickscope/tests/applications/user/com.ubuntu.weather_weather_1.0.168.desktop 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=aa-exec-click -p com.ubuntu.weather_weather_1.0.168 -- qmlscene ./ubuntu-weather-app.qml
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.weather/./weather64.png
7Name=Weather
8X-Ubuntu-Touch=true
9X-Ubuntu-StageHint=SideStage
10X-Ubuntu-Gettext-Domain=com.ubuntu.weather
11
12# Fake an app installed from a .deb
13#Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.weather
14#X-Ubuntu-Old-Icon=./weather64.png
15#X-Ubuntu-Application-ID=com.ubuntu.weather_weather_1.0.168
160
=== removed file 'libclickscope/tests/applications/user/non-click-app-nodisplay.desktop'
--- libclickscope/tests/applications/user/non-click-app-nodisplay.desktop 2014-04-08 20:04:45 +0000
+++ libclickscope/tests/applications/user/non-click-app-nodisplay.desktop 1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
1[Desktop Entry]
2Type=Application
3Name=Sample Desktop-only non-click app
4GenericName=NonClickAppWithoutException
5Comment=multiline description goes here
6Exec=messaging-app %u
7Terminal=false
8MimeType=x-scheme-handler/contact;x-scheme-handler/call
9NoDisplay=true
100
=== removed file 'libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome-unity.desktop'
--- libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome-unity.desktop 2014-04-08 20:04:45 +0000
+++ libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome-unity.desktop 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
1[Desktop Entry]
2Type=Application
3Name=Sample Desktop-only non-click app
4GenericName=NonClickAppWithoutException
5Comment=multiline description goes here
6Exec=messaging-app %u
7Terminal=false
8MimeType=x-scheme-handler/contact;x-scheme-handler/call
9OnlyShowIn=GNOME;Unity;
10Name[en_US]=non-click-app-onlyshowin-gnome-unity.desktop
110
=== removed file 'libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome.desktop'
--- libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome.desktop 2014-04-08 20:04:45 +0000
+++ libclickscope/tests/applications/user/non-click-app-onlyshowin-gnome.desktop 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
1[Desktop Entry]
2Type=Application
3Name=Sample Desktop-only non-click app
4GenericName=NonClickAppWithoutException
5Comment=multiline description goes here
6Exec=messaging-app %u
7Terminal=false
8MimeType=x-scheme-handler/contact;x-scheme-handler/call
9OnlyShowIn=GNOME;
10Name[en_US]=non-click-app-onlyshowin-gnome.desktop
110
=== removed file 'libclickscope/tests/applications/user/non-click-app-onlyshowin-unity.desktop'
--- libclickscope/tests/applications/user/non-click-app-onlyshowin-unity.desktop 2014-04-08 20:04:45 +0000
+++ libclickscope/tests/applications/user/non-click-app-onlyshowin-unity.desktop 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
1[Desktop Entry]
2Type=Application
3Name=Sample Desktop-only non-click app
4GenericName=NonClickAppWithoutException
5Comment=multiline description goes here
6Exec=messaging-app %u
7Terminal=false
8MimeType=x-scheme-handler/contact;x-scheme-handler/call
9OnlyShowIn=Unity;
10Name[en_US]=non-click-app-onlyshowin-unity.desktop
110
=== removed file 'libclickscope/tests/applications/user/non-click-app-without-exception.desktop'
--- libclickscope/tests/applications/user/non-click-app-without-exception.desktop 2014-04-08 21:16:25 +0000
+++ libclickscope/tests/applications/user/non-click-app-without-exception.desktop 1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
1[Desktop Entry]
2Type=Application
3Name=Sample Desktop-only non-click app
4GenericName=NonClickAppWithoutException
5Comment=multiline description goes here
6Exec=messaging-app %u
7Terminal=false
8Icon=sample-desktop-app
9MimeType=x-scheme-handler/contact;x-scheme-handler/call
100
=== removed file 'libclickscope/tests/applications/user/pre-translated.desktop'
--- libclickscope/tests/applications/user/pre-translated.desktop 2015-11-24 18:23:23 +0000
+++ libclickscope/tests/applications/user/pre-translated.desktop 1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
1[Desktop Entry]
2Version=1.0
3Type=Application
4Terminal=false
5Exec=aa-exec-click -p com.ubuntu.clock_clock_1.0.300 -- qmlscene ./ubuntu-clock-app.qml
6Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock/./clock64.png
7_Name=Untranslated Clock
8X-Ubuntu-Touch=true
9X-Ubuntu-StageHint=SideStage
10X-Ubuntu-Gettext-Domain=com.ubuntu.clock
11
12Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock
13X-Ubuntu-Old-Icon=./clock64.png
14X-Ubuntu-Application-ID=com.ubuntu.clock_clock_1.0.300
150
=== removed file 'libclickscope/tests/applications/user/semi-broken.desktop'
--- libclickscope/tests/applications/user/semi-broken.desktop 2014-04-28 22:10:15 +0000
+++ libclickscope/tests/applications/user/semi-broken.desktop 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
1semi broken file
20
=== added file 'libclickscope/tests/mock_ual.h'
--- libclickscope/tests/mock_ual.h 1970-01-01 00:00:00 +0000
+++ libclickscope/tests/mock_ual.h 2016-08-24 21:39:08 +0000
@@ -0,0 +1,156 @@
1/*
2 * Copyright (C) 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * In addition, as a special exception, the copyright holders give
17 * permission to link the code of portions of this program with the
18 * OpenSSL library under certain conditions as described in each
19 * individual source file, and distribute linked combinations
20 * including the two.
21 * You must obey the GNU General Public License in all respects
22 * for all of the code used other than OpenSSL. If you modify
23 * file(s) with this exception, you may extend this exception to your
24 * version of the file(s), but you are not obligated to do so. If you
25 * do not wish to do so, delete this exception statement from your
26 * version. If you delete this exception statement from all source
27 * files in the program, then also delete it here.
28 */
29
30#include <ubuntu-app-launch/registry.h>
31
32using namespace ubuntu::app_launch;
33namespace ual = ubuntu::app_launch;
34
35#include <gtest/gtest.h>
36#include <gmock/gmock.h>
37
38using namespace ::testing;
39
40namespace
41{
42
43 class MockUALRegistry : public ual::Registry {
44 public:
45 MockUALRegistry()
46 {
47 }
48
49 MOCK_METHOD1(installedApps, std::list<std::shared_ptr<ual::Application>>(std::shared_ptr<ual::Registry>));
50 };
51
52 class MockUALApplication : public ual::Application {
53 public:
54 class MockInfo;
55 class MockInstance;
56
57 MockUALApplication(const ual::AppID& app_id,
58 const std::shared_ptr<MockInfo>& info = {})
59 : _app_id(app_id),
60 _info(info)
61 {
62 }
63
64 ual::AppID appId()
65 {
66 return _app_id;
67 }
68
69 std::shared_ptr<ual::Application::Info> info()
70 {
71 return _info;
72 }
73
74 static std::shared_ptr<MockUALApplication> create(ual::AppID app_id,
75 std::shared_ptr<MockInfo> info = {})
76 {
77 std::shared_ptr<MockUALApplication> result{new MockUALApplication(app_id, info)};
78 return result;
79 }
80
81 class MockInfo : public ual::Application::Info
82 {
83 public:
84 MockInfo(const std::string& title,
85 const std::string& description,
86 const std::string& iconPath)
87 : _name(ual::Application::Info::Name::from_raw(title)),
88 _description(ual::Application::Info::Description::from_raw(description)),
89 _iconPath(ual::Application::Info::IconPath::from_raw(iconPath)),
90 _defaultDept(ual::Application::Info::DefaultDepartment::from_raw("")),
91 _ssPath(ual::Application::Info::IconPath::from_raw("")),
92 _keywords(ual::Application::Info::Keywords::from_raw(std::vector<std::string>{}))
93 {
94 DefaultValue<const ual::Application::Info::DefaultDepartment&>::Set(_defaultDept);
95 DefaultValue<const ual::Application::Info::IconPath&>::Set(_ssPath);
96 DefaultValue<const ual::Application::Info::Keywords&>::Set(_keywords);
97 }
98
99 const ual::Application::Info::Name& name()
100 {
101 return _name;
102 }
103
104 const ual::Application::Info::Description& description()
105 {
106 return _description;
107 }
108
109 const ual::Application::Info::IconPath& iconPath()
110 {
111 return _iconPath;
112 }
113
114 MOCK_METHOD0(defaultDepartment, const ual::Application::Info::DefaultDepartment&());
115 MOCK_METHOD0(screenshotPath, const ual::Application::Info::IconPath&());
116 MOCK_METHOD0(keywords, const ual::Application::Info::Keywords&());
117
118 MOCK_METHOD0(splash, ual::Application::Info::Splash());
119 MOCK_METHOD0(supportedOrientations, ual::Application::Info::Orientations());
120 MOCK_METHOD0(rotatesWindowContents, ual::Application::Info::RotatesWindow());
121 MOCK_METHOD0(supportsUbuntuLifecycle, ual::Application::Info::UbuntuLifecycle());
122
123 private:
124 ual::Application::Info::Name _name;
125 ual::Application::Info::Description _description;
126 ual::Application::Info::IconPath _iconPath;
127 ual::Application::Info::DefaultDepartment _defaultDept;
128 ual::Application::Info::IconPath _ssPath;
129 ual::Application::Info::Keywords _keywords;
130 };
131
132 class MockInstance : public ual::Application::Instance
133 {
134 public:
135 MOCK_METHOD0(isRunning, bool());
136 MOCK_METHOD0(logPath, std::string());
137 MOCK_METHOD0(primaryPid, pid_t());
138 MOCK_METHOD1(hasPid, bool(pid_t));
139 MOCK_METHOD0(pids, std::vector<pid_t>());
140 MOCK_METHOD0(pause, void());
141 MOCK_METHOD0(resume, void());
142 MOCK_METHOD0(stop, void());
143 };
144
145 MOCK_METHOD0(hasInstances, bool());
146 MOCK_METHOD0(instances, std::vector<std::shared_ptr<ual::Application::Instance>>());
147 MOCK_METHOD1(launch, std::shared_ptr<ual::Application::Instance>(const std::vector<ual::Application::URL>&));
148 MOCK_METHOD1(launchTest, std::shared_ptr<ual::Application::Instance>(const std::vector<ual::Application::URL>&));
149
150 private:
151 ual::AppID _app_id;
152 std::shared_ptr<MockInfo> _info;
153 };
154
155} // namespace
156
0157
=== modified file 'libclickscope/tests/mock_webclient.h'
--- libclickscope/tests/mock_webclient.h 2016-05-25 16:19:51 +0000
+++ libclickscope/tests/mock_webclient.h 2016-08-24 21:39:08 +0000
@@ -61,13 +61,6 @@
61 Mock instance;61 Mock instance;
62};62};
6363
64QSharedPointer<click::web::Response> responseForReply(const QSharedPointer<click::network::Reply>& reply)
65{
66 auto response = QSharedPointer<click::web::Response>(new click::web::Response(QSharedPointer<QNetworkRequest>(new QNetworkRequest()), QSharedPointer<QBuffer>(new QBuffer())));
67 response->setReply(reply);
68 return response;
69}
70
71class MockClient : public click::web::Client64class MockClient : public click::web::Client
72{65{
73public:66public:
@@ -76,6 +69,7 @@
76 {69 {
77 }70 }
7871
72 MOCK_METHOD2(signUrl, std::string(const std::string&, const std::string&));
79 // Mocking default arguments: https://groups.google.com/forum/#!topic/googlemock/XrabW20vV7o73 // Mocking default arguments: https://groups.google.com/forum/#!topic/googlemock/XrabW20vV7o
80 MOCK_METHOD6(callImpl, QSharedPointer<click::web::Response>(74 MOCK_METHOD6(callImpl, QSharedPointer<click::web::Response>(
81 const std::string& iri,75 const std::string& iri,
@@ -102,6 +96,14 @@
10296
103 MOCK_METHOD1(has_header, bool(const std::string& header));97 MOCK_METHOD1(has_header, bool(const std::string& header));
104 MOCK_METHOD1(get_header, std::string(const std::string&header));98 MOCK_METHOD1(get_header, std::string(const std::string&header));
99
100 static QSharedPointer<click::web::Response> responseForReply(const QSharedPointer<click::network::Reply>& reply)
101 {
102 auto response = QSharedPointer<click::web::Response>(new click::web::Response(QSharedPointer<QNetworkRequest>(new QNetworkRequest()), QSharedPointer<QBuffer>(new QBuffer())));
103 response->setReply(reply);
104 return response;
105 }
106
105};107};
106108
107}109}
108110
=== modified file 'libclickscope/tests/test_bootstrap.cpp'
--- libclickscope/tests/test_bootstrap.cpp 2016-06-30 20:42:56 +0000
+++ libclickscope/tests/test_bootstrap.cpp 2016-08-24 21:39:08 +0000
@@ -70,7 +70,7 @@
70TEST_F(BootstrapTest, testBootstrapCallsWebservice)70TEST_F(BootstrapTest, testBootstrapCallsWebservice)
71{71{
72 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;72 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
73 auto response = responseForReply(reply.asSharedPtr());73 auto response = MockClient::responseForReply(reply.asSharedPtr());
7474
75 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::BOOTSTRAP_PATH), "GET", _, _, _, _))75 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::BOOTSTRAP_PATH), "GET", _, _, _, _))
76 .Times(1)76 .Times(1)
@@ -81,7 +81,7 @@
81TEST_F(BootstrapTest, testBootstrapJsonIsParsed)81TEST_F(BootstrapTest, testBootstrapJsonIsParsed)
82{82{
83 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;83 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
84 auto response = responseForReply(reply.asSharedPtr());84 auto response = MockClient::responseForReply(reply.asSharedPtr());
8585
86 QByteArray fake_json(FAKE_JSON_BOOTSTRAP.c_str());86 QByteArray fake_json(FAKE_JSON_BOOTSTRAP.c_str());
87 EXPECT_CALL(reply.instance, readAll())87 EXPECT_CALL(reply.instance, readAll())
8888
=== removed file 'libclickscope/tests/test_data.cpp.in'
--- libclickscope/tests/test_data.cpp.in 2014-05-26 14:27:31 +0000
+++ libclickscope/tests/test_data.cpp.in 1970-01-01 00:00:00 +0000
@@ -1,43 +0,0 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * In addition, as a special exception, the copyright holders give
17 * permission to link the code of portions of this program with the
18 * OpenSSL library under certain conditions as described in each
19 * individual source file, and distribute linked combinations
20 * including the two.
21 * You must obey the GNU General Public License in all respects
22 * for all of the code used other than OpenSSL. If you modify
23 * file(s) with this exception, you may extend this exception to your
24 * version of the file(s), but you are not obligated to do so. If you
25 * do not wish to do so, delete this exception statement from your
26 * version. If you delete this exception statement from all source
27 * files in the program, then also delete it here.
28 */
29
30
31#include "test_data.h"
32
33const std::string& testing::systemApplicationsDirectoryForTesting()
34{
35 static const std::string s{"@CMAKE_CURRENT_SOURCE_DIR@/applications/system"};
36 return s;
37}
38
39const std::string& testing::userApplicationsDirectoryForTesting()
40{
41 static const std::string s{"@CMAKE_CURRENT_SOURCE_DIR@/applications/user"};
42 return s;
43}
440
=== modified file 'libclickscope/tests/test_data.h'
--- libclickscope/tests/test_data.h 2014-05-26 14:27:31 +0000
+++ libclickscope/tests/test_data.h 2016-08-24 21:39:08 +0000
@@ -38,9 +38,6 @@
38const std::string FAKE_PATH = "fake/api/path";38const std::string FAKE_PATH = "fake/api/path";
39const std::string FAKE_QUERY = "FAKE_QUERY";39const std::string FAKE_QUERY = "FAKE_QUERY";
40const std::string FAKE_PACKAGENAME = "com.example.fakepackage";40const std::string FAKE_PACKAGENAME = "com.example.fakepackage";
41
42const std::string& systemApplicationsDirectoryForTesting();
43const std::string& userApplicationsDirectoryForTesting();
44}41}
4542
46#endif // TEST_DATA_H43#endif // TEST_DATA_H
4744
=== modified file 'libclickscope/tests/test_download_manager.cpp'
--- libclickscope/tests/test_download_manager.cpp 2016-05-10 13:42:12 +0000
+++ libclickscope/tests/test_download_manager.cpp 2016-08-24 21:39:08 +0000
@@ -63,6 +63,7 @@
6363
64 virtual void SetUp()64 virtual void SetUp()
65 {65 {
66 sdmPtr.reset(new MockSystemDownloadManager());
66 ssoPtr.reset(new MockCredentialsService());67 ssoPtr.reset(new MockCredentialsService());
67 namPtr.reset(new MockNetworkAccessManager());68 namPtr.reset(new MockNetworkAccessManager());
68 clientPtr.reset(new NiceMock<MockClient>(namPtr));69 clientPtr.reset(new NiceMock<MockClient>(namPtr));
@@ -76,138 +77,165 @@
7677
77}78}
7879
79TEST_F(DownloadManagerTest, testStartCallsWebservice)80TEST_F(DownloadManagerTest, testStartCallsSignUrl)
80{81{
81 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;82 EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
82 auto response = responseForReply(reply.asSharedPtr());83 EXPECT_CALL(*sdmPtr, createDownload(_, _, _)).Times(1);
83
84 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
85 .Times(1)
86 .WillOnce(Return(response));
87
88 dmPtr->start("", "", "",84 dmPtr->start("", "", "",
89 [](std::string, click::DownloadManager::Error) {});85 [](std::string, click::DownloadManager::Error) {});
90}86}
9187
92TEST_F(DownloadManagerTest, testStartCallbackCalled)88TEST_F(DownloadManagerTest, testStartDownloadSuccssIsError)
93{89{
94 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;90 auto mockDownload = new MockDownload();
95 auto response = responseForReply(reply.asSharedPtr());91 auto mockError = new MockError();
9692 EXPECT_CALL(*mockDownload, isError())
97 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(0)));93 .Times(1)
98 EXPECT_CALL(reply.instance, readAll())94 .WillOnce(Return(true));
99 .Times(1)95 EXPECT_CALL(*mockDownload, error())
100 .WillOnce(Return(""));96 .Times(1)
101 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))97 .WillOnce(Return(mockError));
102 .Times(1)98 EXPECT_CALL(*mockError, errorString())
103 .WillOnce(Return(response));99 .Times(1)
104 EXPECT_CALL(*this, start_callback(_, _)).Times(1);100 .WillOnce(Return(QStringLiteral("")));
105101
106 dmPtr->start("", "", "",102 EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
107 [this](std::string msg, click::DownloadManager::Error err) {103 EXPECT_CALL(*sdmPtr, createDownload(_, _, _))
108 start_callback(msg, err);104 .Times(1)
109 });105 .WillOnce(InvokeArgument<1>(mockDownload));
110 response->replyFinished();106 EXPECT_CALL(*this, start_callback(_, _)).Times(1);
111}107
112108 dmPtr->start("", "", "",
113TEST_F(DownloadManagerTest, testStartHTTPForbidden)109 [this](std::string msg, click::DownloadManager::Error err) {
114{110 start_callback(msg, err);
115 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;111 });
116 auto response = responseForReply(reply.asSharedPtr());112
117113 delete mockError;
118 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(403)));114 delete mockDownload;
119 EXPECT_CALL(reply.instance, readAll())115}
120 .Times(1)116
121 .WillOnce(Return(""));117TEST_F(DownloadManagerTest, testStartDownloadSuccssCallsStart)
122 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))118{
123 .Times(1)119 auto mockDownload = new MockDownload();
124 .WillOnce(Return(response));120 EXPECT_CALL(*mockDownload, isError())
125 EXPECT_CALL(*this, start_callback(StartsWith("Unhandled HTTP response code:"),121 .Times(1)
126 click::DownloadManager::Error::DownloadInstallError)).Times(1);122 .WillOnce(Return(false));
127123 EXPECT_CALL(*mockDownload, start()).Times(1);
128 dmPtr->start("", "", "",124 EXPECT_CALL(*mockDownload, id())
129 [this](std::string msg, click::DownloadManager::Error err) {125 .Times(1)
130 start_callback(msg, err);126 .WillOnce(Return(QStringLiteral("download")));
131 });127
132 response->replyFinished();128 EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
133}129 EXPECT_CALL(*sdmPtr, createDownload(_, _, _))
134130 .Times(1)
135TEST_F(DownloadManagerTest, testStartHTTPError)131 .WillOnce(InvokeArgument<1>(mockDownload));
136{132 EXPECT_CALL(*this, start_callback(_, _)).Times(1);
137 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;133
138 auto response = responseForReply(reply.asSharedPtr());134 dmPtr->start("", "", "",
139135 [this](std::string msg, click::DownloadManager::Error err) {
140 EXPECT_CALL(reply.instance, errorString())136 start_callback(msg, err);
141 .WillOnce(Return(QString("ERROR")));137 });
142 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(404)));138
143 EXPECT_CALL(reply.instance, readAll())139 delete mockDownload;
144 .Times(1)140}
145 .WillOnce(Return(""));141
146 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))142TEST_F(DownloadManagerTest, testStartErrorCallback)
147 .Times(1)143{
148 .WillOnce(Return(response));144 auto mockDownload = new MockDownload();
149 EXPECT_CALL(*this, start_callback("ERROR (203)",145 auto mockError = new MockError();
150 click::DownloadManager::Error::DownloadInstallError)).Times(1);146 EXPECT_CALL(*mockDownload, error())
151147 .Times(1)
152 dmPtr->start("", "", "",148 .WillOnce(Return(mockError));
153 [this](std::string msg, click::DownloadManager::Error err) {149 EXPECT_CALL(*mockError, errorString())
154 start_callback(msg, err);150 .Times(1)
155 });151 .WillOnce(Return(QStringLiteral("")));
156 response->errorHandler(QNetworkReply::ContentNotFoundError);152
157}153 EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
158154 EXPECT_CALL(*sdmPtr, createDownload(_, _, _))
159TEST_F(DownloadManagerTest, testStartCredentialsError)155 .Times(1)
160{156 .WillOnce(InvokeArgument<2>(mockDownload));
161 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;157 EXPECT_CALL(*this, start_callback(_, _)).Times(1);
162 auto response = responseForReply(reply.asSharedPtr());158
163159 dmPtr->start("", "", "",
164 EXPECT_CALL(reply.instance, errorString())160 [this](std::string msg, click::DownloadManager::Error err) {
165 .WillOnce(Return(QString("ERROR")));161 start_callback(msg, err);
166 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(401)));162 });
167 EXPECT_CALL(reply.instance, readAll())163
168 .Times(1)164 delete mockError;
169 .WillOnce(Return(""));165 delete mockDownload;
170 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))166}
171 .Times(1)167
172 .WillOnce(Return(response));168TEST_F(DownloadManagerTest, testGetProgressDownloadFound)
173 EXPECT_CALL(*ssoPtr, invalidateCredentials());169{
174 EXPECT_CALL(*this, start_callback("ERROR (201)",170 auto mockDownloadsList = new MockDownloadsList();
175 click::DownloadManager::Error::CredentialsError)).Times(1);171 auto mockDownload = QSharedPointer<MockDownload>(new MockDownload());
176172
177 dmPtr->start("", "", "test.package",173 QList<QSharedPointer<Ubuntu::DownloadManager::Download>> downloads{mockDownload};
178 [this](std::string msg, click::DownloadManager::Error err) {174
179 start_callback(msg, err);175 EXPECT_CALL(*mockDownload, id())
180 });176 .Times(1)
181 response->errorHandler(QNetworkReply::ContentAccessDenied);177 .WillOnce(Return("download"));
182}178 EXPECT_CALL(*mockDownloadsList, downloads())
183179 .Times(1)
184// FIXME: createDownload() SEGV under tests180 .WillOnce(Return(downloads));
185TEST_F(DownloadManagerTest, DISABLED_testStartDownloadCreated)181 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
186{182 .Times(1)
187 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;183 .WillOnce(InvokeArgument<2>(QStringLiteral(""), QStringLiteral(""),
188 auto response = responseForReply(reply.asSharedPtr());184 mockDownloadsList));
189185 dmPtr->get_progress("com.example.test",
190 EXPECT_CALL(reply.instance, rawHeader(QByteArray("X-Click-Token")))186 [this](std::string object_path) {
191 .Times(1)187 progress_callback(object_path);
192 .WillOnce(Return(QString("clicktoken")));188 });
193 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));189
194 EXPECT_CALL(reply.instance, readAll())190 delete mockDownloadsList;
195 .Times(1)191}
196 .WillOnce(Return(""));192
197 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))193TEST_F(DownloadManagerTest, testGetProgressMultipleDownloadsFound)
198 .Times(1)194{
199 .WillOnce(Return(response));195 auto mockDownloadsList = new MockDownloadsList();
200196 auto mockDownload = QSharedPointer<MockDownload>(new MockDownload());
201 EXPECT_CALL(*sdmPtr, createDownload(_, _, _));197 auto mockDownload2 = QSharedPointer<MockDownload>(new MockDownload());
202 dmPtr->start("", "", "test.package",198
203 [this](std::string msg, click::DownloadManager::Error err) {199 QList<QSharedPointer<Ubuntu::DownloadManager::Download>> downloads{mockDownload, mockDownload2};
204 start_callback(msg, err);200
205 });201 EXPECT_CALL(*mockDownload, id())
206 response->replyFinished();202 .Times(1)
207}203 .WillOnce(Return("download"));
208204 EXPECT_CALL(*mockDownloadsList, downloads())
209// FIXME: getAllDownloadsWithMetadata() SEGV under tests205 .Times(1)
210TEST_F(DownloadManagerTest, DISABLED_testGetProgressNoDownloads)206 .WillOnce(Return(downloads));
207 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
208 .Times(1)
209 .WillOnce(InvokeArgument<2>(QStringLiteral(""), QStringLiteral(""),
210 mockDownloadsList));
211 dmPtr->get_progress("com.example.test",
212 [this](std::string object_path) {
213 progress_callback(object_path);
214 });
215
216 delete mockDownloadsList;
217}
218
219TEST_F(DownloadManagerTest, testGetProgressNoDownloadsFound)
220{
221 auto mockDownloadsList = new MockDownloadsList();
222 QList<QSharedPointer<Ubuntu::DownloadManager::Download>> emptyDownloads{};
223 EXPECT_CALL(*mockDownloadsList, downloads())
224 .Times(1)
225 .WillOnce(Return(emptyDownloads));
226 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
227 .Times(1)
228 .WillOnce(InvokeArgument<2>(QStringLiteral(""), QStringLiteral(""),
229 mockDownloadsList));
230 dmPtr->get_progress("com.example.test",
231 [this](std::string object_path) {
232 progress_callback(object_path);
233 });
234
235 delete mockDownloadsList;
236}
237
238TEST_F(DownloadManagerTest, testGetProgressErrorCallback)
211{239{
212 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))240 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
213 .Times(1)241 .Times(1)
214242
=== modified file 'libclickscope/tests/test_index.cpp'
--- libclickscope/tests/test_index.cpp 2016-05-10 13:42:12 +0000
+++ libclickscope/tests/test_index.cpp 2016-08-24 21:39:08 +0000
@@ -97,7 +97,7 @@
97TEST_F(IndexTest, testSearchCallsWebservice)97TEST_F(IndexTest, testSearchCallsWebservice)
98{98{
99 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;99 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
100 auto response = responseForReply(reply.asSharedPtr());100 auto response = MockClient::responseForReply(reply.asSharedPtr());
101101
102 EXPECT_CALL(*configPtr, get_architecture())102 EXPECT_CALL(*configPtr, get_architecture())
103 .Times(1)103 .Times(1)
@@ -120,7 +120,7 @@
120TEST_F(IndexTest, testSearchQueryIsLowercase)120TEST_F(IndexTest, testSearchQueryIsLowercase)
121{121{
122 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;122 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
123 auto response = responseForReply(reply.asSharedPtr());123 auto response = MockClient::responseForReply(reply.asSharedPtr());
124124
125 EXPECT_CALL(*configPtr, get_architecture())125 EXPECT_CALL(*configPtr, get_architecture())
126 .Times(1)126 .Times(1)
@@ -139,7 +139,7 @@
139TEST_F(IndexTest, testSearchSignsCall)139TEST_F(IndexTest, testSearchSignsCall)
140{140{
141 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;141 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
142 auto response = responseForReply(reply.asSharedPtr());142 auto response = MockClient::responseForReply(reply.asSharedPtr());
143143
144 EXPECT_CALL(*configPtr, get_architecture())144 EXPECT_CALL(*configPtr, get_architecture())
145 .Times(1)145 .Times(1)
@@ -154,10 +154,160 @@
154 indexPtr->search("", "", [](click::Packages, click::Packages) {});154 indexPtr->search("", "", [](click::Packages, click::Packages) {});
155}155}
156156
157TEST_F(IndexTest, testSearchSnapsCallsWebservice)
158{
159 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
160 auto response = MockClient::responseForReply(reply.asSharedPtr());
161
162 EXPECT_CALL(*configPtr, get_architecture())
163 .Times(1)
164 .WillOnce(Return(fake_arch));
165 EXPECT_CALL(*configPtr, get_available_frameworks())
166 .Times(1)
167 .WillOnce(Return(fake_frameworks));
168 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
169 .Times(1)
170 .WillOnce(Return(response));
171
172 indexPtr->search_snaps("", [](click::Packages, click::Packages) {});
173}
174
175TEST_F(IndexTest, testSearchSnapsSendsRightPath)
176{
177 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
178 auto response = MockClient::responseForReply(reply.asSharedPtr());
179
180 EXPECT_CALL(*configPtr, get_architecture())
181 .Times(1)
182 .WillOnce(Return(fake_arch));
183 EXPECT_CALL(*configPtr, get_available_frameworks())
184 .Times(1)
185 .WillOnce(Return(fake_frameworks));
186 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::SNAP_SEARCH_PATH),
187 _, _, _, _, _))
188 .Times(1)
189 .WillOnce(Return(response));
190
191 indexPtr->search_snaps("", [](click::Packages, click::Packages) {});
192}
193
194TEST_F(IndexTest, testSearchSnapsQueryIsLowercase)
195{
196 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
197 auto response = MockClient::responseForReply(reply.asSharedPtr());
198
199 EXPECT_CALL(*configPtr, get_architecture())
200 .Times(1)
201 .WillOnce(Return(fake_arch));
202 EXPECT_CALL(*configPtr, get_available_frameworks())
203 .Times(1)
204 .WillOnce(Return(fake_frameworks));
205 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, QueryContains("foobar")))
206 .Times(1)
207 .WillOnce(Return(response));
208
209 indexPtr->search_snaps("FooBar", [](click::Packages, click::Packages) {});
210}
211
212
213TEST_F(IndexTest, testSearcSnapshSignsCall)
214{
215 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
216 auto response = MockClient::responseForReply(reply.asSharedPtr());
217
218 EXPECT_CALL(*configPtr, get_architecture())
219 .Times(1)
220 .WillOnce(Return(fake_arch));
221 EXPECT_CALL(*configPtr, get_available_frameworks())
222 .Times(1)
223 .WillOnce(Return(fake_frameworks));
224 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))
225 .Times(1)
226 .WillOnce(Return(response));
227
228 indexPtr->search_snaps("", [](click::Packages, click::Packages) {});
229}
230
231TEST_F(IndexTest, testSearchSnapsIsCancellable)
232{
233 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
234 auto response = MockClient::responseForReply(reply.asSharedPtr());
235
236 EXPECT_CALL(*configPtr, get_architecture())
237 .Times(1)
238 .WillOnce(Return(fake_arch));
239 EXPECT_CALL(*configPtr, get_available_frameworks())
240 .Times(1)
241 .WillOnce(Return(fake_frameworks));
242 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
243 .Times(1)
244 .WillOnce(Return(response));
245
246 auto search_operation = indexPtr->search_snaps("", [](click::Packages,
247 click::Packages) {});
248 EXPECT_CALL(reply.instance, abort()).Times(1);
249 search_operation.cancel();
250}
251
252TEST_F(IndexTest, testSearchSnapsEmptyJsonIsParsed)
253{
254 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
255 auto response = MockClient::responseForReply(reply.asSharedPtr());
256
257 QByteArray fake_json("[]");
258 EXPECT_CALL(reply.instance, readAll())
259 .Times(1)
260 .WillOnce(Return(fake_json));
261 EXPECT_CALL(*configPtr, get_architecture())
262 .Times(1)
263 .WillOnce(Return(fake_arch));
264 EXPECT_CALL(*configPtr, get_available_frameworks())
265 .Times(1)
266 .WillOnce(Return(fake_frameworks));
267 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
268 .Times(1)
269 .WillOnce(Return(response));
270 click::Packages empty_package_list;
271 EXPECT_CALL(*this, search_callback(empty_package_list, _)).Times(1);
272
273 indexPtr->search_snaps("", [this](click::Packages packages,
274 click::Packages recommends){
275 search_callback(packages, recommends);
276 });
277 response->replyFinished();
278}
279
280TEST_F(IndexTest, testSearchSnapsNetworkErrorIgnored)
281{
282 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
283 auto response = MockClient::responseForReply(reply.asSharedPtr());
284
285 EXPECT_CALL(*configPtr, get_architecture())
286 .Times(1)
287 .WillOnce(Return(fake_arch));
288 EXPECT_CALL(*configPtr, get_available_frameworks())
289 .Times(1)
290 .WillOnce(Return(fake_frameworks));
291 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
292 .Times(1)
293 .WillOnce(Return(response));
294 EXPECT_CALL(reply.instance, errorString()).Times(1)
295 .WillOnce(Return("fake error"));
296 indexPtr->search_snaps("", [this](click::Packages packages,
297 click::Packages recommends){
298 search_callback(packages, recommends);
299 });
300
301 click::Packages empty_package_list;
302 EXPECT_CALL(*this, search_callback(empty_package_list, _)).Times(1);
303
304 emit reply.instance.error(QNetworkReply::UnknownNetworkError);
305}
306
157TEST_F(IndexTest, testBootstrapSignsCall)307TEST_F(IndexTest, testBootstrapSignsCall)
158{308{
159 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;309 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
160 auto response = responseForReply(reply.asSharedPtr());310 auto response = MockClient::responseForReply(reply.asSharedPtr());
161311
162 EXPECT_CALL(*configPtr, get_architecture())312 EXPECT_CALL(*configPtr, get_architecture())
163 .Times(1)313 .Times(1)
@@ -175,7 +325,7 @@
175TEST_F(IndexTest, testDepartmentsSignsCall)325TEST_F(IndexTest, testDepartmentsSignsCall)
176{326{
177 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;327 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
178 auto response = responseForReply(reply.asSharedPtr());328 auto response = MockClient::responseForReply(reply.asSharedPtr());
179329
180 EXPECT_CALL(*configPtr, get_architecture())330 EXPECT_CALL(*configPtr, get_architecture())
181 .Times(1)331 .Times(1)
@@ -193,8 +343,14 @@
193TEST_F(IndexTest, testDetailsSignsCall)343TEST_F(IndexTest, testDetailsSignsCall)
194{344{
195 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;345 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
196 auto response = responseForReply(reply.asSharedPtr());346 auto response = MockClient::responseForReply(reply.asSharedPtr());
197347
348 EXPECT_CALL(*configPtr, get_architecture())
349 .Times(1)
350 .WillOnce(Return(fake_arch));
351 EXPECT_CALL(*configPtr, get_available_frameworks())
352 .Times(1)
353 .WillOnce(Return(fake_frameworks));
198 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))354 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))
199 .Times(1)355 .Times(1)
200 .WillOnce(Return(response));356 .WillOnce(Return(response));
@@ -205,7 +361,7 @@
205TEST_F(IndexTest, testSearchSendsRightPath)361TEST_F(IndexTest, testSearchSendsRightPath)
206{362{
207 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;363 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
208 auto response = responseForReply(reply.asSharedPtr());364 auto response = MockClient::responseForReply(reply.asSharedPtr());
209365
210 EXPECT_CALL(*configPtr, get_architecture())366 EXPECT_CALL(*configPtr, get_architecture())
211 .Times(1)367 .Times(1)
@@ -224,7 +380,7 @@
224TEST_F(IndexTest, testSearchCallbackIsCalled)380TEST_F(IndexTest, testSearchCallbackIsCalled)
225{381{
226 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;382 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
227 auto response = responseForReply(reply.asSharedPtr());383 auto response = MockClient::responseForReply(reply.asSharedPtr());
228384
229 QByteArray fake_json("[]");385 QByteArray fake_json("[]");
230 EXPECT_CALL(reply.instance, readAll())386 EXPECT_CALL(reply.instance, readAll())
@@ -251,7 +407,7 @@
251TEST_F(IndexTest, testSearchEmptyJsonIsParsed)407TEST_F(IndexTest, testSearchEmptyJsonIsParsed)
252{408{
253 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;409 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
254 auto response = responseForReply(reply.asSharedPtr());410 auto response = MockClient::responseForReply(reply.asSharedPtr());
255411
256 QByteArray fake_json("[]");412 QByteArray fake_json("[]");
257 EXPECT_CALL(reply.instance, readAll())413 EXPECT_CALL(reply.instance, readAll())
@@ -279,7 +435,7 @@
279TEST_F(IndexTest, testSearchSingleJsonIsParsed)435TEST_F(IndexTest, testSearchSingleJsonIsParsed)
280{436{
281 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;437 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
282 auto response = responseForReply(reply.asSharedPtr());438 auto response = MockClient::responseForReply(reply.asSharedPtr());
283439
284 QByteArray fake_json(FAKE_JSON_SEARCH_RESULT_ONE.c_str());440 QByteArray fake_json(FAKE_JSON_SEARCH_RESULT_ONE.c_str());
285 EXPECT_CALL(reply.instance, readAll())441 EXPECT_CALL(reply.instance, readAll())
@@ -315,7 +471,7 @@
315TEST_F(IndexTest, testSearchIsCancellable)471TEST_F(IndexTest, testSearchIsCancellable)
316{472{
317 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;473 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
318 auto response = responseForReply(reply.asSharedPtr());474 auto response = MockClient::responseForReply(reply.asSharedPtr());
319475
320 EXPECT_CALL(*configPtr, get_architecture())476 EXPECT_CALL(*configPtr, get_architecture())
321 .Times(1)477 .Times(1)
@@ -341,7 +497,7 @@
341TEST_F(IndexTest, testSearchNetworkErrorIgnored)497TEST_F(IndexTest, testSearchNetworkErrorIgnored)
342{498{
343 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;499 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
344 auto response = responseForReply(reply.asSharedPtr());500 auto response = MockClient::responseForReply(reply.asSharedPtr());
345501
346 EXPECT_CALL(*configPtr, get_architecture())502 EXPECT_CALL(*configPtr, get_architecture())
347 .Times(1)503 .Times(1)
@@ -367,8 +523,14 @@
367TEST_F(IndexTest, testGetDetailsCallsWebservice)523TEST_F(IndexTest, testGetDetailsCallsWebservice)
368{524{
369 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;525 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
370 auto response = responseForReply(reply.asSharedPtr());526 auto response = MockClient::responseForReply(reply.asSharedPtr());
371527
528 EXPECT_CALL(*configPtr, get_architecture())
529 .Times(1)
530 .WillOnce(Return(fake_arch));
531 EXPECT_CALL(*configPtr, get_available_frameworks())
532 .Times(1)
533 .WillOnce(Return(fake_frameworks));
372 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))534 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
373 .Times(1)535 .Times(1)
374 .WillOnce(Return(response));536 .WillOnce(Return(response));
@@ -379,8 +541,14 @@
379TEST_F(IndexTest, testGetDetailsSendsPackagename)541TEST_F(IndexTest, testGetDetailsSendsPackagename)
380{542{
381 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;543 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
382 auto response = responseForReply(reply.asSharedPtr());544 auto response = MockClient::responseForReply(reply.asSharedPtr());
383545
546 EXPECT_CALL(*configPtr, get_architecture())
547 .Times(1)
548 .WillOnce(Return(fake_arch));
549 EXPECT_CALL(*configPtr, get_available_frameworks())
550 .Times(1)
551 .WillOnce(Return(fake_frameworks));
384 EXPECT_CALL(*clientPtr, callImpl(EndsWith(FAKE_PACKAGENAME),552 EXPECT_CALL(*clientPtr, callImpl(EndsWith(FAKE_PACKAGENAME),
385 _, _, _, _, _))553 _, _, _, _, _))
386 .Times(1)554 .Times(1)
@@ -392,8 +560,14 @@
392TEST_F(IndexTest, testGetDetailsSendsRightPath)560TEST_F(IndexTest, testGetDetailsSendsRightPath)
393{561{
394 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;562 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
395 auto response = responseForReply(reply.asSharedPtr());563 auto response = MockClient::responseForReply(reply.asSharedPtr());
396564
565 EXPECT_CALL(*configPtr, get_architecture())
566 .Times(1)
567 .WillOnce(Return(fake_arch));
568 EXPECT_CALL(*configPtr, get_available_frameworks())
569 .Times(1)
570 .WillOnce(Return(fake_frameworks));
397 EXPECT_CALL(*clientPtr, callImpl(StartsWith(click::SEARCH_BASE_URL +571 EXPECT_CALL(*clientPtr, callImpl(StartsWith(click::SEARCH_BASE_URL +
398 click::DETAILS_PATH),572 click::DETAILS_PATH),
399 _, _, _, _, _))573 _, _, _, _, _))
@@ -406,8 +580,14 @@
406TEST_F(IndexTest, testGetDetailsCallbackIsCalled)580TEST_F(IndexTest, testGetDetailsCallbackIsCalled)
407{581{
408 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;582 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
409 auto response = responseForReply(reply.asSharedPtr());583 auto response = MockClient::responseForReply(reply.asSharedPtr());
410584
585 EXPECT_CALL(*configPtr, get_architecture())
586 .Times(1)
587 .WillOnce(Return(fake_arch));
588 EXPECT_CALL(*configPtr, get_available_frameworks())
589 .Times(1)
590 .WillOnce(Return(fake_frameworks));
411 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());591 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());
412 EXPECT_CALL(reply.instance, readAll())592 EXPECT_CALL(reply.instance, readAll())
413 .Times(1)593 .Times(1)
@@ -425,8 +605,14 @@
425TEST_F(IndexTest, testGetDetailsJsonIsParsed)605TEST_F(IndexTest, testGetDetailsJsonIsParsed)
426{606{
427 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;607 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
428 auto response = responseForReply(reply.asSharedPtr());608 auto response = MockClient::responseForReply(reply.asSharedPtr());
429609
610 EXPECT_CALL(*configPtr, get_architecture())
611 .Times(1)
612 .WillOnce(Return(fake_arch));
613 EXPECT_CALL(*configPtr, get_available_frameworks())
614 .Times(1)
615 .WillOnce(Return(fake_frameworks));
430 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());616 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());
431 EXPECT_CALL(reply.instance, readAll())617 EXPECT_CALL(reply.instance, readAll())
432 .Times(1)618 .Times(1)
@@ -486,7 +672,14 @@
486TEST_F(IndexTest, testGetDetailsJsonUtf8)672TEST_F(IndexTest, testGetDetailsJsonUtf8)
487{673{
488 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;674 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
489 auto response = responseForReply(reply.asSharedPtr());675 auto response = MockClient::responseForReply(reply.asSharedPtr());
676
677 EXPECT_CALL(*configPtr, get_architecture())
678 .Times(1)
679 .WillOnce(Return(fake_arch));
680 EXPECT_CALL(*configPtr, get_available_frameworks())
681 .Times(1)
682 .WillOnce(Return(fake_frameworks));
490683
491 QByteArray appname_utf8("\xe5\xb0\x8f\xe6\xb5\xb7");684 QByteArray appname_utf8("\xe5\xb0\x8f\xe6\xb5\xb7");
492 QByteArray appname_json("\\u5c0f\\u6d77");685 QByteArray appname_json("\\u5c0f\\u6d77");
@@ -554,8 +747,14 @@
554TEST_F(IndexTest, testGetDetailsNetworkErrorReported)747TEST_F(IndexTest, testGetDetailsNetworkErrorReported)
555{748{
556 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;749 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
557 auto response = responseForReply(reply.asSharedPtr());750 auto response = MockClient::responseForReply(reply.asSharedPtr());
558751
752 EXPECT_CALL(*configPtr, get_architecture())
753 .Times(1)
754 .WillOnce(Return(fake_arch));
755 EXPECT_CALL(*configPtr, get_available_frameworks())
756 .Times(1)
757 .WillOnce(Return(fake_frameworks));
559 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))758 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
560 .Times(1)759 .Times(1)
561 .WillOnce(Return(response));760 .WillOnce(Return(response));
@@ -571,8 +770,14 @@
571TEST_F(IndexTest, testGetDetailsIsCancellable)770TEST_F(IndexTest, testGetDetailsIsCancellable)
572{771{
573 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;772 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
574 auto response = responseForReply(reply.asSharedPtr());773 auto response = MockClient::responseForReply(reply.asSharedPtr());
575774
775 EXPECT_CALL(*configPtr, get_architecture())
776 .Times(1)
777 .WillOnce(Return(fake_arch));
778 EXPECT_CALL(*configPtr, get_available_frameworks())
779 .Times(1)
780 .WillOnce(Return(fake_frameworks));
576 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))781 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
577 .Times(1)782 .Times(1)
578 .WillOnce(Return(response));783 .WillOnce(Return(response));
579784
=== modified file 'libclickscope/tests/test_interface.cpp'
--- libclickscope/tests/test_interface.cpp 2016-07-11 19:12:17 +0000
+++ libclickscope/tests/test_interface.cpp 2016-08-24 21:39:08 +0000
@@ -28,6 +28,7 @@
28 */28 */
2929
30#include "fake_json.h"30#include "fake_json.h"
31#include "mock_ual.h"
31#include "test_data.h"32#include "test_data.h"
3233
33#include <QCoreApplication>34#include <QCoreApplication>
@@ -41,7 +42,6 @@
41#include <gtest/gtest.h>42#include <gtest/gtest.h>
4243
43#include <click/interface.h>44#include <click/interface.h>
44#include <click/key_file_locator.h>
45#include <click/departments-db.h>45#include <click/departments-db.h>
4646
47using namespace click;47using namespace click;
@@ -99,30 +99,6 @@
99{99{
100const std::string emptyQuery{};100const std::string emptyQuery{};
101101
102struct MockKeyFileLocator : public click::KeyFileLocator
103{
104 typedef click::KeyFileLocator Super;
105
106 MockKeyFileLocator()
107 {
108 using namespace ::testing;
109
110 ON_CALL(*this, enumerateKeyFilesForInstalledApplications(_))
111 .WillByDefault(
112 Invoke(
113 this,
114 &MockKeyFileLocator::doEnumerateKeyFilesForInstalledApplications));
115 }
116
117 MOCK_METHOD1(enumerateKeyFilesForInstalledApplications,
118 void(const Super::Enumerator&));
119
120 void doEnumerateKeyFilesForInstalledApplications(const Super::Enumerator& enumerator)
121 {
122 Super::enumerateKeyFilesForInstalledApplications(enumerator);
123 }
124};
125
126class ClickInterfaceTest : public ::testing::Test {102class ClickInterfaceTest : public ::testing::Test {
127public:103public:
128 MOCK_METHOD2(manifest_callback, void(Manifest, InterfaceError));104 MOCK_METHOD2(manifest_callback, void(Manifest, InterfaceError));
@@ -136,11 +112,10 @@
136112
137class FakeClickInterface : public click::Interface {113class FakeClickInterface : public click::Interface {
138public:114public:
139 FakeClickInterface(const QSharedPointer<KeyFileLocator>& keyFileLocator) : Interface(keyFileLocator) {}
140 FakeClickInterface() {}115 FakeClickInterface() {}
141116
142 MOCK_METHOD0(show_desktop_apps, bool());117 MOCK_METHOD1(get_manifest_json, std::string(const std::string&));
143 MOCK_METHOD2(run_process, void(const std::string&, std::function<void(int, const std::string&, const std::string&)>));118 MOCK_METHOD0(installed_apps, std::list<std::shared_ptr<ual::Application>>());
144};119};
145120
146TEST(ClickInterface, testIsNonClickAppFalse)121TEST(ClickInterface, testIsNonClickAppFalse)
@@ -154,114 +129,104 @@
154 // If this ever breaks, something is very very wrong.129 // If this ever breaks, something is very very wrong.
155 for (const auto& element : nonClickDesktopFiles())130 for (const auto& element : nonClickDesktopFiles())
156 {131 {
157 QString filename = element.c_str();132 EXPECT_TRUE(Interface::is_non_click_app(element));
158 EXPECT_TRUE(Interface::is_non_click_app(filename));
159 }133 }
160}134}
161135
162TEST(ClickInterface, testCallsIntoKeyFileLocatorForFindingInstalledApps)
163{
164 using namespace ::testing;
165 MockKeyFileLocator mockKeyFileLocator;
166 QSharedPointer<click::KeyFileLocator> keyFileLocator(
167 &mockKeyFileLocator,
168 [](click::KeyFileLocator*){});
169
170
171 FakeClickInterface iface(keyFileLocator);
172 EXPECT_CALL(iface, show_desktop_apps())
173 .Times(1)
174 .WillOnce(Return(false));
175
176 EXPECT_CALL(mockKeyFileLocator, enumerateKeyFilesForInstalledApplications(_)).Times(1);
177
178 iface.find_installed_apps(emptyQuery);
179}
180
181TEST(ClickInterface, testFindAppsInDirEmpty)136TEST(ClickInterface, testFindAppsInDirEmpty)
182{137{
183 QSharedPointer<click::KeyFileLocator> keyFileLocator(138 FakeClickInterface iface;
184 new click::KeyFileLocator(139
185 testing::systemApplicationsDirectoryForTesting(),140 EXPECT_CALL(iface, installed_apps()).Times(1).
186 testing::userApplicationsDirectoryForTesting()));141 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{}));
187142 auto results = iface.search("xyzzygy");
188 click::Interface iface(keyFileLocator);
189
190 auto results = iface.find_installed_apps("xyzzygy");
191143
192 EXPECT_TRUE(results.empty());144 EXPECT_TRUE(results.empty());
193}145}
194146
195TEST_F(ClickInterfaceTest, testFindAppsInDirIgnoredApps)147TEST_F(ClickInterfaceTest, testFindAppsInDirIgnoredApps)
196{148{
197 QSharedPointer<click::KeyFileLocator> keyFileLocator(149 FakeClickInterface iface;
198 new click::KeyFileLocator(150 std::list<std::shared_ptr<ual::Application>> applist{
199 testing::systemApplicationsDirectoryForTesting(),151 MockUALApplication::create(ual::AppID::parse("com.ubuntu.calculator_calculator_0.1"),
200 testing::userApplicationsDirectoryForTesting()));152 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Calculator", "The calculator", "/opt/click.ubuntu.com/foo/bar/calculator.png")}),
153 MockUALApplication::create(ual::AppID::find("webbrowser-app"),
154 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Browser", "The browser", "webbrowser-app")}),
155 MockUALApplication::create(ual::AppID::find("messaging-app"),
156 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Messaging", "Your messages", "messaging-app")}),
157 };
201158
202 click::Interface iface(keyFileLocator);
203 ignoredApps.push_back("messaging-app.desktop");159 ignoredApps.push_back("messaging-app.desktop");
204 ignoredApps.push_back("com.ubuntu.calculator");160 ignoredApps.push_back("com.ubuntu.calculator");
205161
206 auto results = iface.find_installed_apps("", ignoredApps);162 EXPECT_CALL(iface, installed_apps()).Times(1).
207 EXPECT_EQ(20, results.size());163 WillOnce(Return(applist));
164 auto results = iface.search("", ignoredApps);
165 ASSERT_EQ(1, results.size());
208}166}
209167
210TEST_F(ClickInterfaceTest, testFindClockUsesShortAppid)168TEST_F(ClickInterfaceTest, testFindClockUsesShortAppid)
211{169{
212 QSharedPointer<click::KeyFileLocator> keyFileLocator(170 FakeClickInterface iface;
213 new click::KeyFileLocator(171
214 testing::systemApplicationsDirectoryForTesting(),172 EXPECT_CALL(iface, installed_apps()).Times(1).
215 testing::userApplicationsDirectoryForTesting()));173 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
216174 MockUALApplication::create(ual::AppID::parse("com.ubuntu.clock_clock_0.1"),
217 click::Interface iface(keyFileLocator);175 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Clock", "The clock", "/opt/click.ubuntu.com/foo/bar/clock.png")}),
218176 }));
219 auto results = iface.find_installed_apps("Clock");177 auto results = iface.search("Clock");
220 EXPECT_EQ(1u, results.size());178 ASSERT_EQ(1u, results.size());
221 EXPECT_EQ("appid://com.ubuntu.clock/clock/current-user-version", results.begin()->url);179 EXPECT_EQ("appid://com.ubuntu.clock/clock/current-user-version", results.begin()->url);
222}180}
223181
224TEST_F(ClickInterfaceTest, testFindLegacyAppUsesDeskopId)182TEST_F(ClickInterfaceTest, testFindLegacyAppUsesDeskopId)
225{183{
226 QSharedPointer<click::KeyFileLocator> keyFileLocator(184 FakeClickInterface iface;
227 new click::KeyFileLocator(185
228 testing::systemApplicationsDirectoryForTesting(),186 EXPECT_CALL(iface, installed_apps()).Times(1).
229 testing::userApplicationsDirectoryForTesting()));187 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
230188 MockUALApplication::create(ual::AppID::find("messaging-app"),
231 click::Interface iface(keyFileLocator);189 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Messaging", "Your messages", "messaging-app")})
232190 }));
233 auto results = iface.find_installed_apps("Messaging");191 auto results = iface.search("Messaging");
234 EXPECT_EQ(1u, results.size());192 ASSERT_EQ(1u, results.size());
235 EXPECT_EQ("application:///messaging-app.desktop", results.begin()->url);193 EXPECT_EQ("application:///messaging-app.desktop", results.begin()->url);
236}194}
237195
238//
239// test that application with a default department id key in the desktop196// test that application with a default department id key in the desktop
240// file is returned when department matches197// file is returned when department matches
241TEST_F(ClickInterfaceTest, testFindAppsWithAppWithDefaultDepartmentId)198TEST_F(ClickInterfaceTest, testFindAppsWithAppWithDefaultDepartmentId)
242{199{
243 QSharedPointer<click::KeyFileLocator> keyFileLocator(200 FakeClickInterface iface;
244 new click::KeyFileLocator(201
245 testing::systemApplicationsDirectoryForTesting(),202 auto mockapp = MockUALApplication::create(ual::AppID::find("address-book-app"),
246 testing::userApplicationsDirectoryForTesting()));203 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Contacts", "Address book", "address-book-app")});
247204
248 click::Interface iface(keyFileLocator);205 auto dept = ual::Application::Info::DefaultDepartment::from_raw("accessories");
206 DefaultValue<const ual::Application::Info::DefaultDepartment&>::Set(dept);
207
208 EXPECT_CALL(iface, installed_apps()).Times(1).
209 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{mockapp}));
249210
250 auto depts_db = std::make_shared<click::DepartmentsDb>(":memory:");211 auto depts_db = std::make_shared<click::DepartmentsDb>(":memory:");
251 auto results = iface.find_installed_apps("", ignoredApps, "accessories", depts_db);212 auto results = iface.search("", ignoredApps, "accessories", depts_db);
252213
253 EXPECT_EQ(1u, results.size());214 ASSERT_EQ(1u, results.size());
254 EXPECT_EQ("Contacts", results.begin()->title);215 EXPECT_EQ("Contacts", results.begin()->title);
255}216}
256217
257TEST_F(ClickInterfaceTest, testFindAppsWithAppWithDefaultDepartmentIdOverriden)218TEST_F(ClickInterfaceTest, testFindAppsWithAppWithDefaultDepartmentIdOverriden)
258{219{
259 QSharedPointer<click::KeyFileLocator> keyFileLocator(220 FakeClickInterface iface;
260 new click::KeyFileLocator(221
261 testing::systemApplicationsDirectoryForTesting(),222 auto mockapp = MockUALApplication::create(ual::AppID::find("address-book-app"),
262 testing::userApplicationsDirectoryForTesting()));223 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Contacts", "Address book", "address-book-app")});
263224
264 click::Interface iface(keyFileLocator);225 auto dept = ual::Application::Info::DefaultDepartment::from_raw("accessories");
226 DefaultValue<const ual::Application::Info::DefaultDepartment&>::Set(dept);
227
228 EXPECT_CALL(iface, installed_apps()).
229 WillRepeatedly(Return(std::list<std::shared_ptr<ual::Application>>{mockapp}));
265230
266 auto depts_db = std::make_shared<click::DepartmentsDb>(":memory:");231 auto depts_db = std::make_shared<click::DepartmentsDb>(":memory:");
267232
@@ -270,32 +235,42 @@
270 depts_db->store_department_mapping("utilities", "");235 depts_db->store_department_mapping("utilities", "");
271 depts_db->store_department_mapping("accessories", "");236 depts_db->store_department_mapping("accessories", "");
272237
273 auto results = iface.find_installed_apps("", ignoredApps, "utilies", depts_db);238 auto results = iface.search("", ignoredApps, "utilies", depts_db);
274 EXPECT_EQ(0, results.size());239 ASSERT_EQ(0, results.size());
275240
276 // address book applicaton moved to utilities241 // address book applicaton moved to utilities
277 depts_db->store_package_mapping("address-book-app.desktop", "utilities");242 depts_db->store_package_mapping("address-book-app.desktop", "utilities");
278 results = iface.find_installed_apps("", ignoredApps, "utilities", depts_db);243 results = iface.search("", ignoredApps, "utilities", depts_db);
279244
280 EXPECT_EQ(1u, results.size());245 ASSERT_EQ(1u, results.size());
281 EXPECT_EQ("Contacts", results.begin()->title);246 EXPECT_EQ("Contacts", results.begin()->title);
282}247}
283248
284TEST(ClickInterface, testFindAppsInDirSorted)249TEST(ClickInterface, testFindAppsInDirSorted)
285{250{
286 QSharedPointer<click::KeyFileLocator> keyFileLocator(251 FakeClickInterface iface;
287 new click::KeyFileLocator(252
288 testing::systemApplicationsDirectoryForTesting(),253 EXPECT_CALL(iface, installed_apps()).Times(1).
289 testing::userApplicationsDirectoryForTesting()));254 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
290255 MockUALApplication::create(ual::AppID::parse("com.ubuntu.clock_clock_0.1"),
291 click::Interface iface(keyFileLocator);256 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Clock", "The clock", "/opt/click.ubuntu.com/foo/bar/clock.png")}),
292257 MockUALApplication::create(ual::AppID::find("address-book-app"),
293 auto results = iface.find_installed_apps("ock");258 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Contacts", "Address book", "address-book-app")}),
259 MockUALApplication::create(ual::AppID::parse("com.ubuntu.stock-ticker-mobile_stockticker_0.1"),
260 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Stock Ticker", "A stock ticker.", "/opt/click.ubuntu.com/foo/bar/stock_icon_48.png")}),
261 }));
262
263 auto results = iface.search("ock");
294264
295 const std::vector<click::Application> expected_results = {265 const std::vector<click::Application> expected_results = {
296 {"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", "", "", ""},266 {"com.ubuntu.clock", "Clock", 0.0,
267 "/opt/click.ubuntu.com/foo/bar/clock.png",
268 "appid://com.ubuntu.clock/clock/current-user-version",
269 "The clock", "", ""},
297 {"com.ubuntu.stock-ticker-mobile", "Stock Ticker", 0.0,270 {"com.ubuntu.stock-ticker-mobile", "Stock Ticker", 0.0,
298 "/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", "", ""},271 "/opt/click.ubuntu.com/foo/bar/stock_icon_48.png",
272 "appid://com.ubuntu.stock-ticker-mobile/stockticker/current-user-version",
273 "A stock ticker.", "", ""},
299 };274 };
300 EXPECT_EQ(expected_results, results);275 EXPECT_EQ(expected_results, results);
301}276}
@@ -382,58 +357,70 @@
382 ASSERT_EQ(unsetenv(Configuration::LANGUAGE_ENVVAR), 0);357 ASSERT_EQ(unsetenv(Configuration::LANGUAGE_ENVVAR), 0);
383}358}
384359
385TEST(ClickInterface, testFindAppByKeyword)360TEST_F(ClickInterfaceTest, testFindAppByKeyword)
386{361{
387 QSharedPointer<click::KeyFileLocator> keyFileLocator(362 FakeClickInterface iface;
388 new click::KeyFileLocator(363
389 testing::systemApplicationsDirectoryForTesting(),364 auto mockapp = MockUALApplication::create(ual::AppID::parse("com.ubuntu.camera_camera_5"),
390 testing::userApplicationsDirectoryForTesting()));365 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Cámara", "La cámara", "/opt/click.ubuntu.com/foo/bar/camera.png")});
391366
392 click::Interface iface(keyFileLocator);367 std::vector<std::string>keys{"foo", "bar", "rss", "baz"};
393368 auto mockkw = ual::Application::Info::Keywords::from_raw(keys);
394 auto results = iface.find_installed_apps("rss");369 DefaultValue<const ual::Application::Info::Keywords&>::Set(mockkw);
395370
396 EXPECT_EQ(1, results.size());371 EXPECT_CALL(iface, installed_apps()).Times(1).
397}372 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{mockapp}));
398373
399TEST(ClickInterface, testFindAppByKeywordCaseInsensitive)374 auto results = iface.search("rss");
400{375
401 QSharedPointer<click::KeyFileLocator> keyFileLocator(376 EXPECT_EQ(1, results.size());
402 new click::KeyFileLocator(377}
403 testing::systemApplicationsDirectoryForTesting(),378
404 testing::userApplicationsDirectoryForTesting()));379TEST_F(ClickInterfaceTest, testFindAppByKeywordCaseInsensitive)
405380{
406 click::Interface iface(keyFileLocator);381 FakeClickInterface iface;
407382
408 auto results = iface.find_installed_apps("RsS");383 auto mockapp = MockUALApplication::create(ual::AppID::parse("com.ubuntu.camera_camera_5"),
409384 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Cámara", "La cámara", "/opt/click.ubuntu.com/foo/bar/camera.png")});
410 EXPECT_EQ(1, results.size());385
411}386 std::vector<std::string>keys{"foo", "bar", "rss", "baz"};
412387 auto mockkw = ual::Application::Info::Keywords::from_raw(keys);
413TEST(ClickInterface, testFindAppAccented)388 DefaultValue<const ual::Application::Info::Keywords&>::Set(mockkw);
414{389
415 QSharedPointer<click::KeyFileLocator> keyFileLocator(390 EXPECT_CALL(iface, installed_apps()).Times(1).
416 new click::KeyFileLocator(391 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{mockapp}));
417 testing::systemApplicationsDirectoryForTesting(),392
418 testing::userApplicationsDirectoryForTesting()));393 auto results = iface.search("RsS");
419394
420 click::Interface iface(keyFileLocator);395 EXPECT_EQ(1, results.size());
421396}
422 auto results = iface.find_installed_apps("Cámara");397
423398TEST_F(ClickInterfaceTest, testFindAppAccented)
424 EXPECT_EQ(1, results.size());399{
425}400 FakeClickInterface iface;
426401
427TEST(ClickInterface, testFindAppAccented2)402 EXPECT_CALL(iface, installed_apps()).Times(1).
428{403 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
429 QSharedPointer<click::KeyFileLocator> keyFileLocator(404 MockUALApplication::create(ual::AppID::parse("com.ubuntu.camera_camera_5"),
430 new click::KeyFileLocator(405 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Cámara", "La cámara", "/opt/click.ubuntu.com/foo/bar/camera.png")}),
431 testing::systemApplicationsDirectoryForTesting(),406 }));
432 testing::userApplicationsDirectoryForTesting()));407
433408 auto results = iface.search("Cámara");
434 click::Interface iface(keyFileLocator);409
435410 EXPECT_EQ(1, results.size());
436 auto results = iface.find_installed_apps("Camara");411}
412
413TEST_F(ClickInterfaceTest, testFindAppAccented2)
414{
415 FakeClickInterface iface;
416
417 EXPECT_CALL(iface, installed_apps()).Times(1).
418 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
419 MockUALApplication::create(ual::AppID::parse("com.ubuntu.camera_camera_5"),
420 std::shared_ptr<MockUALApplication::MockInfo>{new MockUALApplication::MockInfo("Cámara", "La cámara", "/opt/click.ubuntu.com/foo/bar/camera.png")}),
421 }));
422
423 auto results = iface.search("Camara");
437424
438 EXPECT_EQ(1, results.size());425 EXPECT_EQ(1, results.size());
439}426}
@@ -453,130 +440,6 @@
453 Interface::add_theme_scheme("/usr/share/unity8/graphics/applicationIcons/contacts-app@18.png"));440 Interface::add_theme_scheme("/usr/share/unity8/graphics/applicationIcons/contacts-app@18.png"));
454}441}
455442
456std::vector<click::Application> find_installed_apps(const std::string& query, bool include_desktop_results)
457{
458 using namespace ::testing;
459 QSharedPointer<click::KeyFileLocator> keyFileLocator(
460 new click::KeyFileLocator(
461 testing::systemApplicationsDirectoryForTesting(),
462 testing::userApplicationsDirectoryForTesting()));
463
464 FakeClickInterface iface(keyFileLocator);
465 EXPECT_CALL(iface, show_desktop_apps())
466 .Times(1)
467 .WillOnce(Return(include_desktop_results));
468
469 return iface.find_installed_apps(query);
470}
471
472TEST(ClickInterface, testFindInstalledAppsOnPhone)
473{
474 auto result = find_installed_apps(emptyQuery, false);
475
476 EXPECT_TRUE(result.size() > 0);
477
478 for (const auto& app : non_desktop_applications)
479 {
480 qDebug() << "comparing" << QString::fromStdString(app.title);
481 EXPECT_NE(result.end(), std::find(result.begin(), result.end(), app));
482 }
483
484 EXPECT_EQ(result.end(), std::find(result.begin(), result.end(), desktop_application));
485}
486
487TEST(ClickInterface, testFindInstalledAppsOnDesktop)
488{
489 auto result = find_installed_apps(emptyQuery, true);
490
491 std::vector<click::Application> expected_apps(non_desktop_applications);
492 expected_apps.push_back(desktop_application);
493
494 EXPECT_TRUE(result.size() > 0);
495
496 for (const auto& app : expected_apps)
497 {
498 qDebug() << "comparing" << QString::fromStdString(app.title);
499 EXPECT_NE(result.end(), std::find(result.begin(), result.end(), app));
500 }
501}
502
503TEST(ClickInterface, testInlineTranslationsLoaded)
504{
505 QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
506 click::Interface iface(keyFileLocator);
507
508 auto nodisplay = testing::systemApplicationsDirectoryForTesting() + "/translated.desktop";
509 unity::util::IniParser parser(nodisplay.data());
510
511 ASSERT_EQ(setenv(Configuration::LANGUAGE_ENVVAR, "es_ES.UTF-8", 1), 0);
512 auto app = iface.load_app_from_desktop(parser, nodisplay);
513 EXPECT_EQ("Translated App in Spanish", app.title);
514 EXPECT_EQ("Translated application in Spanish", app.description);
515 ASSERT_EQ(unsetenv(Configuration::LANGUAGE_ENVVAR), 0);
516}
517
518TEST(ClickInterface, testIncludeInResultsNoDisplayTrue)
519{
520 QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
521 click::Interface iface(keyFileLocator);
522
523 auto nodisplay = testing::userApplicationsDirectoryForTesting() + "/non-click-app-nodisplay.desktop";
524 unity::util::IniParser parser(nodisplay.data());
525
526 EXPECT_FALSE(iface.is_visible_app(parser));
527}
528
529TEST(ClickInterface, testIncludeInResultsOnlyShowInGnome)
530{
531 QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
532 click::Interface iface(keyFileLocator);
533
534 auto nodisplay = testing::userApplicationsDirectoryForTesting() + "/non-click-app-onlyshowin-gnome.desktop";
535 unity::util::IniParser parser(nodisplay.data());
536
537 EXPECT_FALSE(iface.is_visible_app(parser));
538}
539
540TEST(ClickInterface, testIncludeInResultsOnlyShowInGnomeUnity)
541{
542 QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
543 click::Interface iface(keyFileLocator);
544
545 auto nodisplay = testing::userApplicationsDirectoryForTesting() + "/non-click-app-onlyshowin-gnome-unity.desktop";
546 unity::util::IniParser parser(nodisplay.data());
547
548 EXPECT_TRUE(iface.is_visible_app(parser));
549}
550
551TEST(ClickInterface, testIncludeInResultsOnlyShowInUnity)
552{
553 QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
554 click::Interface iface(keyFileLocator);
555
556 auto nodisplay = testing::userApplicationsDirectoryForTesting() + "/non-click-app-onlyshowin-unity.desktop";
557 unity::util::IniParser parser(nodisplay.data());
558
559 EXPECT_TRUE(iface.is_visible_app(parser));
560}
561
562TEST(ClickInterface, testEnableDesktopApps)
563{
564 QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
565 click::Interface iface(keyFileLocator);
566
567 setenv(Interface::ENV_SHOW_DESKTOP_APPS, "YesPlease", true);
568 EXPECT_TRUE(iface.show_desktop_apps());
569}
570
571TEST(ClickInterface, testDisableDesktopApps)
572{
573 QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());
574 click::Interface iface(keyFileLocator);
575
576 unsetenv(Interface::ENV_SHOW_DESKTOP_APPS);
577 EXPECT_FALSE(iface.show_desktop_apps());
578}
579
580TEST(ClickInterface, testManifestFromJsonOneApp)443TEST(ClickInterface, testManifestFromJsonOneApp)
581{444{
582 Manifest m = manifest_from_json(FAKE_JSON_MANIFEST_ONE_APP);445 Manifest m = manifest_from_json(FAKE_JSON_MANIFEST_ONE_APP);
@@ -611,25 +474,12 @@
611 ASSERT_TRUE(m.has_any_scopes());474 ASSERT_TRUE(m.has_any_scopes());
612}475}
613476
614TEST(ClickInterface, testGetManifestForAppCorrectCommand)
615{
616 FakeClickInterface iface;
617 std::string command = "click info " + FAKE_PACKAGENAME;
618 EXPECT_CALL(iface, run_process(command, _)).
619 Times(1);
620 iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest, InterfaceError){});
621}
622
623TEST_F(ClickInterfaceTest, testGetManifestForAppParseError)477TEST_F(ClickInterfaceTest, testGetManifestForAppParseError)
624{478{
625 FakeClickInterface iface;479 FakeClickInterface iface;
626 EXPECT_CALL(iface, run_process(_, _)).480 EXPECT_CALL(iface, get_manifest_json(_)).
627 Times(1).481 Times(1).
628 WillOnce(Invoke([&](const std::string&,482 WillOnce(Return("INVALID JSON"));
629 std::function<void(int, const std::string&,
630 const std::string&)> callback){
631 callback(0, "INVALID JSON", "");
632 }));
633 EXPECT_CALL(*this, manifest_callback(_, InterfaceError::ParseError));483 EXPECT_CALL(*this, manifest_callback(_, InterfaceError::ParseError));
634 iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest,484 iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest,
635 InterfaceError error){485 InterfaceError error){
@@ -637,33 +487,12 @@
637 });487 });
638}488}
639489
640TEST_F(ClickInterfaceTest, testGetManifestForAppCommandFailed)
641{
642 FakeClickInterface iface;
643 EXPECT_CALL(iface, run_process(_, _)).
644 Times(1).
645 WillOnce(Invoke([&](const std::string&,
646 std::function<void(int, const std::string&,
647 const std::string&)> callback){
648 callback(-1, "", "CRITICAL: FAIL");
649 }));
650 EXPECT_CALL(*this, manifest_callback(_, InterfaceError::CallError));
651 iface.get_manifest_for_app(FAKE_PACKAGENAME, [this](Manifest manifest,
652 InterfaceError error){
653 manifest_callback(manifest, error);
654 });
655}
656
657TEST_F(ClickInterfaceTest, testGetManifestForAppIsRemovable)490TEST_F(ClickInterfaceTest, testGetManifestForAppIsRemovable)
658{491{
659 FakeClickInterface iface;492 FakeClickInterface iface;
660 EXPECT_CALL(iface, run_process(_, _)).493 EXPECT_CALL(iface, get_manifest_json(_)).
661 Times(1).494 Times(1).
662 WillOnce(Invoke([&](const std::string&,495 WillOnce(Return(FAKE_JSON_MANIFEST_REMOVABLE));
663 std::function<void(int, const std::string&,
664 const std::string&)> callback){
665 callback(0, FAKE_JSON_MANIFEST_REMOVABLE, "");
666 }));
667 iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest,496 iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest,
668 InterfaceError error){497 InterfaceError error){
669 ASSERT_TRUE(error == InterfaceError::NoError);498 ASSERT_TRUE(error == InterfaceError::NoError);
@@ -674,13 +503,9 @@
674TEST_F(ClickInterfaceTest, testGetManifestForAppIsNotRemovable)503TEST_F(ClickInterfaceTest, testGetManifestForAppIsNotRemovable)
675{504{
676 FakeClickInterface iface;505 FakeClickInterface iface;
677 EXPECT_CALL(iface, run_process(_, _)).506 EXPECT_CALL(iface, get_manifest_json(_)).
678 Times(1).507 Times(1).
679 WillOnce(Invoke([&](const std::string&,508 WillOnce(Return(FAKE_JSON_MANIFEST_NONREMOVABLE));
680 std::function<void(int, const std::string&,
681 const std::string&)> callback){
682 callback(0, FAKE_JSON_MANIFEST_NONREMOVABLE, "");
683 }));
684 iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest,509 iface.get_manifest_for_app(FAKE_PACKAGENAME, [](Manifest manifest,
685 InterfaceError error){510 InterfaceError error){
686 ASSERT_TRUE(error == InterfaceError::NoError);511 ASSERT_TRUE(error == InterfaceError::NoError);
@@ -688,125 +513,16 @@
688 });513 });
689}514}
690515
691TEST(ClickInterface, testGetManifestsCorrectCommand)
692{
693 FakeClickInterface iface;
694 std::string command = "click list --manifest";
695 EXPECT_CALL(iface, run_process(command, _)).
696 Times(1);
697 iface.get_manifests([](ManifestList, InterfaceError){});
698}
699
700TEST_F(ClickInterfaceTest, testGetManifestsParseError)
701{
702 FakeClickInterface iface;
703 EXPECT_CALL(iface, run_process(_, _)).
704 Times(1).
705 WillOnce(Invoke([&](const std::string&,
706 std::function<void(int, const std::string&,
707 const std::string&)> callback){
708 callback(0, "INVALID JSON", "");
709 }));
710 EXPECT_CALL(*this, manifests_callback(_, InterfaceError::ParseError));
711 iface.get_manifests([this](ManifestList manifests, InterfaceError error){
712 manifests_callback(manifests, error);
713 });
714}
715
716TEST_F(ClickInterfaceTest, testGetManifestsCommandFailed)
717{
718 FakeClickInterface iface;
719 EXPECT_CALL(iface, run_process(_, _)).
720 Times(1).
721 WillOnce(Invoke([&](const std::string&,
722 std::function<void(int, const std::string&,
723 const std::string&)> callback){
724 callback(-1, "", "CRITICAL: FAIL");
725 }));
726 EXPECT_CALL(*this, manifests_callback(_, InterfaceError::CallError));
727 iface.get_manifests([this](ManifestList manifests, InterfaceError error){
728 manifests_callback(manifests, error);
729 });
730}
731
732TEST_F(ClickInterfaceTest, testGetManifestsParsed)
733{
734 FakeClickInterface iface;
735 std::string expected_str = "[" + FAKE_JSON_MANIFEST_NONREMOVABLE + "," +
736 FAKE_JSON_MANIFEST_REMOVABLE + "]";
737 ManifestList expected = manifest_list_from_json(expected_str);
738
739 EXPECT_CALL(iface, run_process(_, _)).
740 Times(1).
741 WillOnce(Invoke([&](const std::string&,
742 std::function<void(int, const std::string&,
743 const std::string&)> callback){
744 callback(0, expected_str, "");
745 }));
746 iface.get_manifests([expected](ManifestList manifests, InterfaceError error){
747 ASSERT_TRUE(error == InterfaceError::NoError);
748 ASSERT_TRUE(manifests.size() == expected.size());
749 });
750}
751
752TEST(ClickInterface, testGetInstalledPackagesCorrectCommand)
753{
754 FakeClickInterface iface;
755 std::string command = "click list";
756 EXPECT_CALL(iface, run_process(command, _)).
757 Times(1);
758 iface.get_installed_packages([](PackageSet, InterfaceError){});
759}
760
761TEST_F(ClickInterfaceTest, testGetInstalledPackagesParseError)
762{
763 FakeClickInterface iface;
764 std::string bad_stdout = "INVALID: err\nvalid.package\t1.0\n";
765 PackageSet expected{{"valid.package", "1.0"}};
766
767 EXPECT_CALL(iface, run_process(_, _)).
768 Times(1).
769 WillOnce(Invoke([&](const std::string&,
770 std::function<void(int, const std::string&,
771 const std::string&)> callback){
772 callback(0, bad_stdout, "");
773 }));
774 EXPECT_CALL(*this, installed_callback(_, InterfaceError::NoError));
775 iface.get_installed_packages([this, expected](PackageSet package_names, InterfaceError error){
776 installed_callback(package_names, error);
777 ASSERT_EQ(package_names, expected);
778 });
779}
780
781TEST_F(ClickInterfaceTest, testGetInstalledPackagesCommandFailed)
782{
783 FakeClickInterface iface;
784 EXPECT_CALL(iface, run_process(_, _)).
785 Times(1).
786 WillOnce(Invoke([&](const std::string&,
787 std::function<void(int, const std::string&,
788 const std::string&)> callback){
789 callback(-1, "", "CRITICAL: FAIL");
790 }));
791 EXPECT_CALL(*this, installed_callback(_, InterfaceError::CallError));
792 iface.get_installed_packages([this](PackageSet package_names, InterfaceError error){
793 installed_callback(package_names, error);
794 });
795}
796
797TEST_F(ClickInterfaceTest, testGetInstalledPackagesParsed)516TEST_F(ClickInterfaceTest, testGetInstalledPackagesParsed)
798{517{
799 FakeClickInterface iface;518 FakeClickInterface iface;
800 std::string sample_stdout = "ABC\t0.1\nDEF\t0.2\n";519 PackageSet expected{{"foo.bar", "0.1"}, {"baz.foo", "0.2"}};
801 PackageSet expected{{"ABC", "0.1"}, {"DEF", "0.2"}};
802520
803 EXPECT_CALL(iface, run_process(_, _)).521 EXPECT_CALL(iface, installed_apps()).Times(1).
804 Times(1).522 WillOnce(Return(std::list<std::shared_ptr<ual::Application>>{
805 WillOnce(Invoke([&](const std::string&,523 MockUALApplication::create(ual::AppID::parse("foo.bar_foo_0.1")),
806 std::function<void(int, const std::string&,524 MockUALApplication::create(ual::AppID::parse("baz.foo_foo_0.2"))
807 const std::string&)> callback){525 }));
808 callback(0, sample_stdout, "");
809 }));
810 iface.get_installed_packages([expected](PackageSet package_names, InterfaceError error){526 iface.get_installed_packages([expected](PackageSet package_names, InterfaceError error){
811 ASSERT_EQ(error, InterfaceError::NoError);527 ASSERT_EQ(error, InterfaceError::NoError);
812 ASSERT_EQ(package_names, expected);528 ASSERT_EQ(package_names, expected);
813529
=== modified file 'libclickscope/tests/test_pay.cpp'
--- libclickscope/tests/test_pay.cpp 2016-06-30 20:42:56 +0000
+++ libclickscope/tests/test_pay.cpp 2016-08-24 21:39:08 +0000
@@ -68,7 +68,7 @@
68TEST_F(PayTest, testPayPackageRefundCalled)68TEST_F(PayTest, testPayPackageRefundCalled)
69{69{
70 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;70 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
71 auto response = responseForReply(reply.asSharedPtr());71 auto response = MockClient::responseForReply(reply.asSharedPtr());
7272
73 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);73 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);
74 EXPECT_FALSE(package->refund("foo"));74 EXPECT_FALSE(package->refund("foo"));
@@ -77,7 +77,7 @@
77TEST_F(PayTest, testPayPackageRefundNotCalledIfCallbackExists)77TEST_F(PayTest, testPayPackageRefundNotCalledIfCallbackExists)
78{78{
79 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;79 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
80 auto response = responseForReply(reply.asSharedPtr());80 auto response = MockClient::responseForReply(reply.asSharedPtr());
8181
82 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_REFUND;82 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_REFUND;
83 package->callbacks[callback_id] = [](const std::string&, bool) {};83 package->callbacks[callback_id] = [](const std::string&, bool) {};
@@ -88,7 +88,7 @@
88TEST_F(PayTest, testRefundReturnsTrueForPurchasedItem)88TEST_F(PayTest, testRefundReturnsTrueForPurchasedItem)
89{89{
90 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;90 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
91 auto response = responseForReply(reply.asSharedPtr());91 auto response = MockClient::responseForReply(reply.asSharedPtr());
9292
93 package->success = true;93 package->success = true;
94 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);94 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);
@@ -98,7 +98,7 @@
98TEST_F(PayTest, testPayPackageVerifyCalled)98TEST_F(PayTest, testPayPackageVerifyCalled)
99{99{
100 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;100 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
101 auto response = responseForReply(reply.asSharedPtr());101 auto response = MockClient::responseForReply(reply.asSharedPtr());
102102
103 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);103 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);
104 EXPECT_FALSE(package->verify("foo"));104 EXPECT_FALSE(package->verify("foo"));
@@ -107,7 +107,7 @@
107TEST_F(PayTest, testPayPackageVerifyNotCalledIfCallbackExists)107TEST_F(PayTest, testPayPackageVerifyNotCalledIfCallbackExists)
108{108{
109 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;109 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
110 auto response = responseForReply(reply.asSharedPtr());110 auto response = MockClient::responseForReply(reply.asSharedPtr());
111111
112 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_VERIFY;112 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_VERIFY;
113 package->callbacks[callback_id] = [](const std::string&, bool) {};113 package->callbacks[callback_id] = [](const std::string&, bool) {};
@@ -118,7 +118,7 @@
118TEST_F(PayTest, testVerifyReturnsTrueForPurchasedItem)118TEST_F(PayTest, testVerifyReturnsTrueForPurchasedItem)
119{119{
120 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;120 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
121 auto response = responseForReply(reply.asSharedPtr());121 auto response = MockClient::responseForReply(reply.asSharedPtr());
122122
123 package->success = true;123 package->success = true;
124 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);124 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);
@@ -128,7 +128,7 @@
128TEST_F(PayTest, testGetPurchasesCallsWebservice)128TEST_F(PayTest, testGetPurchasesCallsWebservice)
129{129{
130 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;130 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
131 auto response = responseForReply(reply.asSharedPtr());131 auto response = MockClient::responseForReply(reply.asSharedPtr());
132132
133 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))133 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
134 .Times(1)134 .Times(1)
@@ -140,7 +140,7 @@
140TEST_F(PayTest, testGetPurchasesSendsCorrectPath)140TEST_F(PayTest, testGetPurchasesSendsCorrectPath)
141{141{
142 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;142 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
143 auto response = responseForReply(reply.asSharedPtr());143 auto response = MockClient::responseForReply(reply.asSharedPtr());
144144
145 EXPECT_CALL(*clientPtr, callImpl(EndsWith(pay::PURCHASES_API_PATH),145 EXPECT_CALL(*clientPtr, callImpl(EndsWith(pay::PURCHASES_API_PATH),
146 _, _, _, _, _))146 _, _, _, _, _))
@@ -153,7 +153,7 @@
153TEST_F(PayTest, testGetPurchasesCallbackCalled)153TEST_F(PayTest, testGetPurchasesCallbackCalled)
154{154{
155 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;155 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
156 auto response = responseForReply(reply.asSharedPtr());156 auto response = MockClient::responseForReply(reply.asSharedPtr());
157157
158 QByteArray fake_json("[]");158 QByteArray fake_json("[]");
159 EXPECT_CALL(reply.instance, readAll())159 EXPECT_CALL(reply.instance, readAll())
@@ -173,7 +173,7 @@
173TEST_F(PayTest, testGetPurchasesEmptyJsonIsParsed)173TEST_F(PayTest, testGetPurchasesEmptyJsonIsParsed)
174{174{
175 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;175 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
176 auto response = responseForReply(reply.asSharedPtr());176 auto response = MockClient::responseForReply(reply.asSharedPtr());
177177
178 QByteArray fake_json("[]");178 QByteArray fake_json("[]");
179 EXPECT_CALL(reply.instance, readAll())179 EXPECT_CALL(reply.instance, readAll())
@@ -194,7 +194,7 @@
194TEST_F(PayTest, testGetPurchasesSingleJsonIsParsedNullTimestamp)194TEST_F(PayTest, testGetPurchasesSingleJsonIsParsedNullTimestamp)
195{195{
196 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;196 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
197 auto response = responseForReply(reply.asSharedPtr());197 auto response = MockClient::responseForReply(reply.asSharedPtr());
198198
199 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON_NULL_TIMESTAMP);199 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON_NULL_TIMESTAMP);
200 EXPECT_CALL(reply.instance, readAll())200 EXPECT_CALL(reply.instance, readAll())
@@ -215,7 +215,7 @@
215TEST_F(PayTest, testGetPurchasesTimestampIsParsed)215TEST_F(PayTest, testGetPurchasesTimestampIsParsed)
216{216{
217 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;217 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
218 auto response = responseForReply(reply.asSharedPtr());218 auto response = MockClient::responseForReply(reply.asSharedPtr());
219219
220 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON);220 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON);
221 EXPECT_CALL(reply.instance, readAll())221 EXPECT_CALL(reply.instance, readAll())
@@ -237,7 +237,7 @@
237TEST_F(PayTest, testGetPurchasesIsCancellable)237TEST_F(PayTest, testGetPurchasesIsCancellable)
238{238{
239 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;239 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
240 auto response = responseForReply(reply.asSharedPtr());240 auto response = MockClient::responseForReply(reply.asSharedPtr());
241241
242 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))242 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
243 .Times(1)243 .Times(1)
244244
=== modified file 'libclickscope/tests/test_preview.cpp'
--- libclickscope/tests/test_preview.cpp 2016-07-13 20:30:09 +0000
+++ libclickscope/tests/test_preview.cpp 2016-08-24 21:39:08 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -64,7 +64,7 @@
64 FakeIndex() {64 FakeIndex() {
6565
66 }66 }
67 click::web::Cancellable get_details(const std::string& /*package_name*/, std::function<void(click::PackageDetails, Error)> callback, bool) override {67 click::web::Cancellable get_details(const std::string& /*package_name*/, std::function<void(click::PackageDetails, Error)> callback, bool, bool) override {
68 callback(click::PackageDetails(), Error::NetworkError);68 callback(click::PackageDetails(), Error::NetworkError);
69 return click::web::Cancellable();69 return click::web::Cancellable();
70 }70 }
7171
=== modified file 'libclickscope/tests/test_reviews.cpp'
--- libclickscope/tests/test_reviews.cpp 2016-05-10 13:42:12 +0000
+++ libclickscope/tests/test_reviews.cpp 2016-08-24 21:39:08 +0000
@@ -140,7 +140,7 @@
140TEST_F(ReviewsTest, testFetchReviewsCallsWebservice)140TEST_F(ReviewsTest, testFetchReviewsCallsWebservice)
141{141{
142 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;142 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
143 auto response = responseForReply(reply.asSharedPtr());143 auto response = MockClient::responseForReply(reply.asSharedPtr());
144144
145 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))145 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
146 .Times(1)146 .Times(1)
@@ -153,7 +153,7 @@
153TEST_F(ReviewsTest, testFetchReviewsDoesNotSignCall)153TEST_F(ReviewsTest, testFetchReviewsDoesNotSignCall)
154{154{
155 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;155 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
156 auto response = responseForReply(reply.asSharedPtr());156 auto response = MockClient::responseForReply(reply.asSharedPtr());
157157
158 EXPECT_CALL(*clientPtr, callImpl(_, _, false, _, _, _))158 EXPECT_CALL(*clientPtr, callImpl(_, _, false, _, _, _))
159 .Times(1)159 .Times(1)
@@ -166,7 +166,7 @@
166TEST_F(ReviewsTest, testFetchReviewsSendsQueryAsParam)166TEST_F(ReviewsTest, testFetchReviewsSendsQueryAsParam)
167{167{
168 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;168 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
169 auto response = responseForReply(reply.asSharedPtr());169 auto response = MockClient::responseForReply(reply.asSharedPtr());
170170
171 click::web::CallParams params;171 click::web::CallParams params;
172 params.add(click::REVIEWS_QUERY_ARGNAME, FAKE_PACKAGENAME);172 params.add(click::REVIEWS_QUERY_ARGNAME, FAKE_PACKAGENAME);
@@ -181,7 +181,7 @@
181TEST_F(ReviewsTest, testFetchReviewsSendsCorrectPath)181TEST_F(ReviewsTest, testFetchReviewsSendsCorrectPath)
182{182{
183 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;183 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
184 auto response = responseForReply(reply.asSharedPtr());184 auto response = MockClient::responseForReply(reply.asSharedPtr());
185185
186 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::REVIEWS_API_PATH),186 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::REVIEWS_API_PATH),
187 _, _, _, _, _))187 _, _, _, _, _))
@@ -195,7 +195,7 @@
195TEST_F(ReviewsTest, testFetchReviewsCallbackCalled)195TEST_F(ReviewsTest, testFetchReviewsCallbackCalled)
196{196{
197 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;197 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
198 auto response = responseForReply(reply.asSharedPtr());198 auto response = MockClient::responseForReply(reply.asSharedPtr());
199199
200 QByteArray fake_json("[]");200 QByteArray fake_json("[]");
201 EXPECT_CALL(reply.instance, readAll())201 EXPECT_CALL(reply.instance, readAll())
@@ -216,7 +216,7 @@
216TEST_F(ReviewsTest, testFetchReviewsNot200)216TEST_F(ReviewsTest, testFetchReviewsNot200)
217{217{
218 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;218 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
219 auto response = responseForReply(reply.asSharedPtr());219 auto response = MockClient::responseForReply(reply.asSharedPtr());
220220
221 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(301)));221 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(301)));
222 EXPECT_CALL(reply.instance, readAll())222 EXPECT_CALL(reply.instance, readAll())
@@ -238,7 +238,7 @@
238TEST_F(ReviewsTest, testFetchReviewsEmptyJsonIsParsed)238TEST_F(ReviewsTest, testFetchReviewsEmptyJsonIsParsed)
239{239{
240 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;240 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
241 auto response = responseForReply(reply.asSharedPtr());241 auto response = MockClient::responseForReply(reply.asSharedPtr());
242242
243 QByteArray fake_json("[]");243 QByteArray fake_json("[]");
244 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));244 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));
@@ -261,7 +261,7 @@
261TEST_F(ReviewsTest, testFetchReviewsSingleJsonIsParsed)261TEST_F(ReviewsTest, testFetchReviewsSingleJsonIsParsed)
262{262{
263 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;263 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
264 auto response = responseForReply(reply.asSharedPtr());264 auto response = MockClient::responseForReply(reply.asSharedPtr());
265265
266 QByteArray fake_json(FAKE_JSON_REVIEWS_RESULT_ONE.c_str());266 QByteArray fake_json(FAKE_JSON_REVIEWS_RESULT_ONE.c_str());
267 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));267 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));
@@ -295,7 +295,7 @@
295TEST_F(ReviewsTest, testFetchReviewsNetworkErrorReported)295TEST_F(ReviewsTest, testFetchReviewsNetworkErrorReported)
296{296{
297 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;297 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
298 auto response = responseForReply(reply.asSharedPtr());298 auto response = MockClient::responseForReply(reply.asSharedPtr());
299299
300 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))300 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
301 .Times(1)301 .Times(1)
@@ -318,7 +318,7 @@
318TEST_F(ReviewsTest, testFetchReviewsIsCancellable)318TEST_F(ReviewsTest, testFetchReviewsIsCancellable)
319{319{
320 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;320 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
321 auto response = responseForReply(reply.asSharedPtr());321 auto response = MockClient::responseForReply(reply.asSharedPtr());
322322
323 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))323 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
324 .Times(1)324 .Times(1)
@@ -333,7 +333,7 @@
333TEST_F(ReviewsTest, testSubmitReviewIsCancellable)333TEST_F(ReviewsTest, testSubmitReviewIsCancellable)
334{334{
335 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;335 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
336 auto response = responseForReply(reply.asSharedPtr());336 auto response = MockClient::responseForReply(reply.asSharedPtr());
337337
338 click::Review review;338 click::Review review;
339 review.rating = 3;339 review.rating = 3;
@@ -354,7 +354,7 @@
354TEST_F(ReviewsTest, testSubmitReviewUtf8)354TEST_F(ReviewsTest, testSubmitReviewUtf8)
355{355{
356 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;356 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
357 auto response = responseForReply(reply.asSharedPtr());357 auto response = MockClient::responseForReply(reply.asSharedPtr());
358358
359 click::Review review;359 click::Review review;
360 review.rating = 3;360 review.rating = 3;
@@ -378,7 +378,7 @@
378TEST_F(ReviewsTest, testSubmitReviewLanguageCorrect)378TEST_F(ReviewsTest, testSubmitReviewLanguageCorrect)
379{379{
380 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;380 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
381 auto response = responseForReply(reply.asSharedPtr());381 auto response = MockClient::responseForReply(reply.asSharedPtr());
382382
383 click::Review review;383 click::Review review;
384 review.rating = 3;384 review.rating = 3;
@@ -402,7 +402,7 @@
402TEST_F(ReviewsTest, testSubmitReviewLanguageCorrectForFullLangCodes)402TEST_F(ReviewsTest, testSubmitReviewLanguageCorrectForFullLangCodes)
403{403{
404 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;404 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
405 auto response = responseForReply(reply.asSharedPtr());405 auto response = MockClient::responseForReply(reply.asSharedPtr());
406406
407 click::Review review;407 click::Review review;
408 review.rating = 3;408 review.rating = 3;
@@ -428,7 +428,7 @@
428TEST_F(ReviewsTest, testEditReviewUrlHasReviewId)428TEST_F(ReviewsTest, testEditReviewUrlHasReviewId)
429{429{
430 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;430 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
431 auto response = responseForReply(reply.asSharedPtr());431 auto response = MockClient::responseForReply(reply.asSharedPtr());
432432
433 click::Review review;433 click::Review review;
434 review.id = 1234;434 review.id = 1234;
@@ -448,7 +448,7 @@
448TEST_F(ReviewsTest, testEditReviewIsCancellable)448TEST_F(ReviewsTest, testEditReviewIsCancellable)
449{449{
450 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;450 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
451 auto response = responseForReply(reply.asSharedPtr());451 auto response = MockClient::responseForReply(reply.asSharedPtr());
452452
453 click::Review review;453 click::Review review;
454 review.id = 1234;454 review.id = 1234;
455455
=== modified file 'scope/clickapps/apps-query.cpp'
--- scope/clickapps/apps-query.cpp 2016-06-22 20:46:28 +0000
+++ scope/clickapps/apps-query.cpp 2016-08-24 21:39:08 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014-2015 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -27,10 +27,12 @@
27 * files in the program, then also delete it here.27 * files in the program, then also delete it here.
28 */28 */
2929
30#include "apps-query.h"
31
30#include <click/application.h>32#include <click/application.h>
31#include <click/departments-db.h>33#include <click/departments-db.h>
3234
33#include <click/key_file_locator.h>35#include <QDebug>
3436
35#include <unity/scopes/CategoryRenderer.h>37#include <unity/scopes/CategoryRenderer.h>
36#include <unity/scopes/CategorisedResult.h>38#include <unity/scopes/CategorisedResult.h>
@@ -39,12 +41,11 @@
39#include <unity/scopes/SearchMetadata.h>41#include <unity/scopes/SearchMetadata.h>
40#include <unity/scopes/Department.h>42#include <unity/scopes/Department.h>
4143
44#include <locale>
45#include <memory>
42#include <vector>46#include <vector>
43#include <locale>
4447
45#include <click/click-i18n.h>48#include <click/click-i18n.h>
46#include "apps-query.h"
47#include <QDebug>
4849
49namespace50namespace
50{51{
@@ -259,8 +260,7 @@
259260
260click::Interface& click::apps::Query::clickInterfaceInstance()261click::Interface& click::apps::Query::clickInterfaceInstance()
261{262{
262 static QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());263 static click::Interface iface;
263 static click::Interface iface(keyFileLocator);
264264
265 return iface;265 return iface;
266}266}
@@ -420,7 +420,7 @@
420 const bool show_top_apps = querystr.empty() && current_dept.empty();420 const bool show_top_apps = querystr.empty() && current_dept.empty();
421 ResultPusher pusher(searchReply, show_top_apps ? impl->configuration.get_core_apps() : std::vector<std::string>());421 ResultPusher pusher(searchReply, show_top_apps ? impl->configuration.get_core_apps() : std::vector<std::string>());
422 auto const ignoredApps = impl->configuration.get_ignored_apps();422 auto const ignoredApps = impl->configuration.get_ignored_apps();
423 auto const localResults = clickInterfaceInstance().find_installed_apps(querystr, ignoredApps, current_dept, impl->depts_db);423 auto const localResults = clickInterfaceInstance().search(querystr, ignoredApps, current_dept, impl->depts_db);
424424
425 if (impl->depts_db)425 if (impl->depts_db)
426 {426 {
427427
=== modified file 'scope/clickapps/apps-scope.cpp'
--- scope/clickapps/apps-scope.cpp 2016-05-18 12:35:56 +0000
+++ scope/clickapps/apps-scope.cpp 2016-08-24 21:39:08 +0000
@@ -38,7 +38,6 @@
3838
39#include <QSharedPointer>39#include <QSharedPointer>
4040
41#include <click/key_file_locator.h>
42#include <click/network_access_manager.h>41#include <click/network_access_manager.h>
43#include <click/click-i18n.h>42#include <click/click-i18n.h>
44#include <click/utils.h>43#include <click/utils.h>
4544
=== modified file 'scope/clickstore/store-query.cpp'
--- scope/clickstore/store-query.cpp 2016-07-13 19:46:17 +0000
+++ scope/clickstore/store-query.cpp 2016-08-24 21:39:08 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014-2015 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -32,7 +32,6 @@
3232
33#include <click/application.h>33#include <click/application.h>
34#include <click/interface.h>34#include <click/interface.h>
35#include <click/key_file_locator.h>
36#include <click/qtbridge.h>35#include <click/qtbridge.h>
37#include <click/departments-db.h>36#include <click/departments-db.h>
38#include <click/utils.h>37#include <click/utils.h>
@@ -47,12 +46,13 @@
47#include <unity/scopes/Variant.h>46#include <unity/scopes/Variant.h>
48#include <unity/scopes/VariantBuilder.h>47#include <unity/scopes/VariantBuilder.h>
4948
49#include <cassert>
50#include <iomanip>50#include <iomanip>
51#include<vector>
52#include<set>
53#include<sstream>
54#include <cassert>
55#include <locale>51#include <locale>
52#include <memory>
53#include <set>
54#include <sstream>
55#include <vector>
5656
57#include <QLocale>57#include <QLocale>
5858
@@ -169,6 +169,7 @@
169 click::HighlightList& highlights;169 click::HighlightList& highlights;
170 scopes::SearchMetadata meta;170 scopes::SearchMetadata meta;
171 click::web::Cancellable search_operation;171 click::web::Cancellable search_operation;
172 click::web::Cancellable search_snaps_operation;
172 click::web::Cancellable purchases_operation;173 click::web::Cancellable purchases_operation;
173 pay::Package& pay_package;174 pay::Package& pay_package;
174 std::shared_future<void> qt_ready_;175 std::shared_future<void> qt_ready_;
@@ -196,12 +197,12 @@
196{197{
197 qDebug() << "cancelling search of" << QString::fromStdString(query().query_string());198 qDebug() << "cancelling search of" << QString::fromStdString(query().query_string());
198 impl->search_operation.cancel();199 impl->search_operation.cancel();
200 impl->search_snaps_operation.cancel();
199}201}
200202
201click::Interface& click::Query::clickInterfaceInstance()203click::Interface& click::Query::clickInterfaceInstance()
202{204{
203 static QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());205 static click::Interface iface;
204 static click::Interface iface(keyFileLocator);
205206
206 return iface;207 return iface;
207}208}
@@ -291,7 +292,12 @@
291 res.set_title(pkg.title);292 res.set_title(pkg.title);
292 res.set_art(pkg.icon_url);293 res.set_art(pkg.icon_url);
293 res.set_uri(pkg.url);294 res.set_uri(pkg.url);
294 res[click::Query::ResultKeys::NAME] = pkg.name;295 res["snap_id"] = pkg.snap_id;
296 if (pkg.snap_id.empty()) {
297 res[click::Query::ResultKeys::NAME] = pkg.name;
298 } else {
299 res[click::Query::ResultKeys::NAME] = pkg.alias;
300 }
295 res["subtitle"] = pkg.publisher;301 res["subtitle"] = pkg.publisher;
296 auto installed = installedPackages.find(pkg);302 auto installed = installedPackages.find(pkg);
297303
@@ -534,6 +540,7 @@
534 push_package(searchReply, recommendsCategory,540 push_package(searchReply, recommendsCategory,
535 installedPackages, r);541 installedPackages, r);
536 }542 }
543
537 qDebug() << "search completed";544 qDebug() << "search completed";
538 this->finished(searchReply); //FIXME: this shouldn't be needed545 this->finished(searchReply); //FIXME: this shouldn't be needed
539 };546 };
@@ -597,7 +604,37 @@
597 {604 {
598 qDebug() << "starting search of" << QString::fromStdString(query().query_string());605 qDebug() << "starting search of" << QString::fromStdString(query().query_string());
599 push_departments(searchReply);606 push_departments(searchReply);
600 impl->search_operation = impl->index.search(query().query_string(), query().department_id(), search_cb, force_cache);607 impl->search_operation = impl->index.search
608 (query().query_string(), query().department_id(),
609 [this, search_cb, force_cache](Packages packages,
610 Packages recommends) {
611 if (Configuration().is_snapd_running()) {
612 qDebug() << "Searching for snaps too.";
613 impl->search_snaps_operation = impl->index.search_snaps
614 (query().query_string(),
615 [this, packages, recommends, search_cb](Packages snap_packages,
616 Packages snap_recommends) {
617 qDebug() << "In the callback.";
618 Packages new_packages, new_recommends;
619 for (auto p: packages) {
620 new_packages.push_back(p);
621 }
622 for (auto p: snap_packages) {
623 new_packages.push_back(p);
624 }
625 for (auto r: recommends) {
626 new_recommends.push_back(r);
627 }
628 for (auto r: snap_recommends) {
629 new_recommends.push_back(r);
630 }
631 qDebug() << "Snaps appended.";
632 search_cb(new_packages, new_recommends);
633 }, force_cache);
634 } else {
635 search_cb(packages, recommends);
636 }
637 }, force_cache);
601 }638 }
602 }639 }
603 });640 });
604641
=== modified file 'scope/clickstore/store-scope.cpp'
--- scope/clickstore/store-scope.cpp 2016-05-25 16:19:58 +0000
+++ scope/clickstore/store-scope.cpp 2016-08-24 21:39:08 +0000
@@ -38,7 +38,6 @@
3838
39#include <QSharedPointer>39#include <QSharedPointer>
4040
41#include <click/key_file_locator.h>
42#include <click/network_access_manager.h>41#include <click/network_access_manager.h>
43#include <click/click-i18n.h>42#include <click/click-i18n.h>
4443
4544
=== modified file 'scope/tests/test_apps_query.cpp'
--- scope/tests/test_apps_query.cpp 2016-03-09 13:08:13 +0000
+++ scope/tests/test_apps_query.cpp 2016-08-24 21:39:08 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -61,7 +61,7 @@
61{61{
62public:62public:
63 MockClickInterface() = default;63 MockClickInterface() = default;
64 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>&));64 MOCK_METHOD4(search, std::vector<click::Application>(const std::string&, const std::vector<std::string>&, const std::string&, const std::shared_ptr<click::DepartmentsDb>&));
65};65};
6666
67class MockAppsQuery : public click::apps::Query67class MockAppsQuery : public click::apps::Query
@@ -215,7 +215,7 @@
215 // no apps in 'books' department, thus excluded215 // no apps in 'books' department, thus excluded
216 std::list<std::string> expected_departments({{"", "games", "video"}});216 std::list<std::string> expected_departments({{"", "games", "video"}});
217217
218 EXPECT_CALL(*clickif, find_installed_apps(_, _, _, _)).WillOnce(Return(installed_apps));218 EXPECT_CALL(*clickif, search(_, _, _, _)).WillOnce(Return(installed_apps));
219 EXPECT_CALL(mock_reply, register_category("predefined", _, _, _)).WillOnce(Return(ptrCat));219 EXPECT_CALL(mock_reply, register_category("predefined", _, _, _)).WillOnce(Return(ptrCat));
220 EXPECT_CALL(mock_reply, register_category("local", StrNe(""), _, _)).WillOnce(Return(ptrCat));220 EXPECT_CALL(mock_reply, register_category("local", StrNe(""), _, _)).WillOnce(Return(ptrCat));
221 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));221 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));
@@ -264,7 +264,7 @@
264264
265 std::list<std::string> expected_departments({"", "games"});265 std::list<std::string> expected_departments({"", "games"});
266266
267 EXPECT_CALL(*clickif, find_installed_apps(_, _, _, _)).WillOnce(Return(installed_apps));267 EXPECT_CALL(*clickif, search(_, _, _, _)).WillOnce(Return(installed_apps));
268 EXPECT_CALL(mock_reply, register_category("local", StrEq(""), _, _)).WillOnce(Return(ptrCat));268 EXPECT_CALL(mock_reply, register_category("local", StrEq(""), _, _)).WillOnce(Return(ptrCat));
269 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));269 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));
270 EXPECT_CALL(mock_reply, register_departments(MatchesDepartments(expected_departments)));270 EXPECT_CALL(mock_reply, register_departments(MatchesDepartments(expected_departments)));
@@ -296,7 +296,7 @@
296 scopes::testing::MockSearchReply mock_reply;296 scopes::testing::MockSearchReply mock_reply;
297 scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){});297 scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){});
298298
299 EXPECT_CALL(*clickif, find_installed_apps(_, _, _, _)).WillOnce(Return(installed_apps));299 EXPECT_CALL(*clickif, search(_, _, _, _)).WillOnce(Return(installed_apps));
300 EXPECT_CALL(mock_reply, register_category("local", StrEq(""), _, _)).WillOnce(Return(ptrCat));300 EXPECT_CALL(mock_reply, register_category("local", StrEq(""), _, _)).WillOnce(Return(ptrCat));
301 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));301 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));
302302
@@ -323,7 +323,7 @@
323323
324 std::list<std::string> expected_departments({"", "games"});324 std::list<std::string> expected_departments({"", "games"});
325325
326 EXPECT_CALL(*clickif, find_installed_apps("Fooo", _, "games", _)).WillOnce(Return(installed_apps));326 EXPECT_CALL(*clickif, search("Fooo", _, "games", _)).WillOnce(Return(installed_apps));
327 EXPECT_CALL(mock_reply, register_category("local", StrEq(""), _, _)).WillOnce(Return(ptrCat));327 EXPECT_CALL(mock_reply, register_category("local", StrEq(""), _, _)).WillOnce(Return(ptrCat));
328 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));328 EXPECT_CALL(mock_reply, register_category("store", _, _, _)).WillOnce(Return(ptrCat));
329 EXPECT_CALL(*depts_db, get_department_name("games", expected_locales)).WillOnce(Return("Games"));329 EXPECT_CALL(*depts_db, get_department_name("games", expected_locales)).WillOnce(Return("Games"));
330330
=== modified file 'tools/init-departments/init-departments.cpp'
--- tools/init-departments/init-departments.cpp 2014-07-15 13:30:05 +0000
+++ tools/init-departments/init-departments.cpp 2016-08-24 21:39:08 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -28,14 +28,16 @@
28 */28 */
2929
30#include <click/interface.h>30#include <click/interface.h>
31#include <click/key_file_locator.h>
32#include <click/index.h>31#include <click/index.h>
33#include <click/webclient.h>32#include <click/webclient.h>
34#include <click/network_access_manager.h>33#include <click/network_access_manager.h>
35#include <click/qtbridge.h>34#include <click/qtbridge.h>
36#include <click/departments-db.h>35#include <click/departments-db.h>
36
37#include <future>37#include <future>
38#include <iostream>38#include <iostream>
39#include <memory>
40
39#include <QDebug>41#include <QDebug>
40#include <QtGlobal>42#include <QtGlobal>
4143
@@ -65,8 +67,7 @@
65 {"webbrowser-app.desktop", "web-browsers"}67 {"webbrowser-app.desktop", "web-browsers"}
66};68};
6769
68QSharedPointer<click::KeyFileLocator> keyFileLocator(new click::KeyFileLocator());70click::Interface iface;
69click::Interface iface(keyFileLocator);
7071
71void noDebug(QtMsgType, const QMessageLogContext&, const QString&) {}72void noDebug(QtMsgType, const QMessageLogContext&, const QString&) {}
7273

Subscribers

People subscribed via source and target branches

to all changes: