Merge lp:~larryprice/libertine-scope/libertine-store-create-container into lp:~larryprice/libertine-scope/libertine-store-search

Proposed by Larry Price
Status: Needs review
Proposed branch: lp:~larryprice/libertine-scope/libertine-store-create-container
Merge into: lp:~larryprice/libertine-scope/libertine-store-search
Diff against target: 1588 lines (+882/-88)
32 files modified
CMakeLists.txt (+2/-0)
data/CMakeLists.txt (+4/-0)
lib/libertine-scope/CMakeLists.txt (+1/-0)
lib/libertine-scope/action.h (+1/-1)
lib/libertine-scope/container.cpp (+50/-0)
lib/libertine-scope/container.h (+44/-0)
lib/libertine-scope/preview.cpp (+2/-2)
lib/libertine-scope/service_manager.cpp (+23/-6)
lib/libertine-scope/service_manager.h (+3/-0)
scope/apps/action.cpp (+0/-1)
scope/apps/action.h (+0/-1)
scope/store/action.cpp (+43/-0)
scope/store/action.h (+48/-0)
scope/store/create_preview.cpp (+113/-0)
scope/store/create_preview.h (+65/-0)
scope/store/entry_point.cpp (+1/-1)
scope/store/query.cpp (+56/-12)
scope/store/query.h (+15/-13)
scope/store/scope.cpp (+13/-7)
scope/store/scope.h (+4/-7)
service/libertine_service/container.py (+14/-4)
service/libertine_service/dbus.py (+31/-10)
service/libertine_service/tasks.py (+23/-7)
tests/lib/libertine-scope/CMakeLists.txt (+3/-2)
tests/lib/libertine-scope/mock_service_manager.h (+2/-0)
tests/lib/libertine-scope/test_action.cpp (+3/-3)
tests/lib/libertine-scope/test_container.cpp (+53/-0)
tests/lib/libertine-scope/test_preview.cpp (+2/-2)
tests/scope/store/CMakeLists.txt (+2/-0)
tests/scope/store/test_action.cpp (+85/-0)
tests/scope/store/test_create_preview.cpp (+137/-0)
tests/scope/store/test_query.cpp (+39/-9)
To merge this branch: bzr merge lp:~larryprice/libertine-scope/libertine-store-create-container
Reviewer Review Type Date Requested Status
Libertine Developers Pending
Review via email: mp+307754@code.launchpad.net

Commit message

Warn user on data usage before container creation.

Description of the change

Warn user on data usage before container creation.

If the "palatine" container does not exist, present user with a special icon for creating the container. This takes the user to a special preview with a short warning message and the option to create the container.

I ended up changing some namespacing things here as I started running into collisions.

To post a comment you must log in.

Unmerged revisions

113. By Larry Price

further specify namespace for store scope

112. By Larry Price

Tests for new code

111. By Larry Price

Fix old tests

110. By Larry Price

Progress bar on create

109. By Larry Price

Special preview pane for creating the palatine container

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-09-23 14:36:02 +0000
+++ CMakeLists.txt 2016-10-05 19:26:10 +0000
@@ -65,8 +65,10 @@
65# Important project paths65# Important project paths
66if (CLICK_MODE)66if (CLICK_MODE)
67 set(SCOPE_INSTALL_DIR "/libertine-scope")67 set(SCOPE_INSTALL_DIR "/libertine-scope")
68 set(STORE_INSTALL_DIR "/libertine-store")
68else()69else()
69 set(SCOPE_INSTALL_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/unity-scopes/libertine-scope/)70 set(SCOPE_INSTALL_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/unity-scopes/libertine-scope/)
71 set(STORE_INSTALL_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/unity-scopes/libertine-store/)
70endif(CLICK_MODE)72endif(CLICK_MODE)
7173
72set(SCOPE_NAME "libertine-scope")74set(SCOPE_NAME "libertine-scope")
7375
=== modified file 'data/CMakeLists.txt'
--- data/CMakeLists.txt 2016-08-30 21:11:50 +0000
+++ data/CMakeLists.txt 2016-10-05 19:26:10 +0000
@@ -1,5 +1,6 @@
1# Copy data files into apps scope dir for dev1# Copy data files into apps scope dir for dev
2file(COPY store.svg blacklist DESTINATION ${CMAKE_BINARY_DIR}/scope/apps/)2file(COPY store.svg blacklist DESTINATION ${CMAKE_BINARY_DIR}/scope/apps/)
3file(COPY store.svg DESTINATION ${CMAKE_BINARY_DIR}/scope/store/)
34
4install(FILES apps.png apps.svg5install(FILES apps.png apps.svg
5 DESTINATION ${APPS_DATA_DIR})6 DESTINATION ${APPS_DATA_DIR})
@@ -7,5 +8,8 @@
7install(FILES blacklist store.svg8install(FILES blacklist store.svg
8 DESTINATION ${SCOPE_INSTALL_DIR})9 DESTINATION ${SCOPE_INSTALL_DIR})
910
11install(FILES store.svg
12 DESTINATION ${STORE_INSTALL_DIR})
13
10install(FILES com.canonical.libertine.ContainerManager.service14install(FILES com.canonical.libertine.ContainerManager.service
11 DESTINATION ${CMAKE_INSTALL_DATADIR}/dbus-1/services)15 DESTINATION ${CMAKE_INSTALL_DATADIR}/dbus-1/services)
1216
=== modified file 'lib/libertine-scope/CMakeLists.txt'
--- lib/libertine-scope/CMakeLists.txt 2016-08-24 16:21:47 +0000
+++ lib/libertine-scope/CMakeLists.txt 2016-10-05 19:26:10 +0000
@@ -5,6 +5,7 @@
5 preview.cpp5 preview.cpp
6 service_manager.cpp6 service_manager.cpp
7 package.cpp7 package.cpp
8 container.cpp
8 action.cpp9 action.cpp
9)10)
1011
1112
=== modified file 'lib/libertine-scope/action.h'
--- lib/libertine-scope/action.h 2016-09-20 20:09:51 +0000
+++ lib/libertine-scope/action.h 2016-10-05 19:26:10 +0000
@@ -38,7 +38,7 @@
3838
39 virtual unity::scopes::ActivationResponse activate() override;39 virtual unity::scopes::ActivationResponse activate() override;
4040
41private:41protected:
42 std::string action_id_;42 std::string action_id_;
43 std::shared_ptr<ServiceManager> service_;43 std::shared_ptr<ServiceManager> service_;
44};44};
4545
=== added file 'lib/libertine-scope/container.cpp'
--- lib/libertine-scope/container.cpp 1970-01-01 00:00:00 +0000
+++ lib/libertine-scope/container.cpp 2016-10-05 19:26:10 +0000
@@ -0,0 +1,50 @@
1/*
2 * Copyright 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the
6 * Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "libertine-scope/container.h"
17
18
19namespace
20{
21libertine::scope::Container::ContainerStatus string_to_status(QString const& status)
22{
23 if (status == "ready")
24 {
25 return libertine::scope::Container::ContainerStatus::ready;
26 }
27 else if (status == "installing")
28 {
29 return libertine::scope::Container::ContainerStatus::installing;
30 }
31 else if (status == "removing")
32 {
33 return libertine::scope::Container::ContainerStatus::removing;
34 }
35
36 return libertine::scope::Container::ContainerStatus::none;
37}
38}
39
40
41libertine::scope::Container libertine::scope::Container::
42from_map(QVariantMap const& pkgMap)
43{
44 Container container;
45 container.id = pkgMap["id"].toString().toStdString();
46 container.progress = pkgMap["progress_id"].toString().toStdString();
47 container.status = string_to_status(pkgMap["status"].toString());
48
49 return container;
50}
051
=== added file 'lib/libertine-scope/container.h'
--- lib/libertine-scope/container.h 1970-01-01 00:00:00 +0000
+++ lib/libertine-scope/container.h 2016-10-05 19:26:10 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the
6 * Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include <QVariant>
19
20
21namespace libertine
22{
23namespace scope
24{
25
26
27class Container
28{
29public:
30 explicit Container() = default;
31 virtual ~Container() = default;
32
33 static Container from_map(QVariantMap const&);
34
35 enum class ContainerStatus {ready, installing, removing, none};
36
37 std::string id;
38 ContainerStatus status;
39 std::string progress;
40};
41
42
43} // Store
44} // Libertine
045
=== modified file 'lib/libertine-scope/preview.cpp'
--- lib/libertine-scope/preview.cpp 2016-09-23 14:19:44 +0000
+++ lib/libertine-scope/preview.cpp 2016-10-05 19:26:10 +0000
@@ -18,8 +18,8 @@
1818
19#include "libertine-scope/i18n.h"19#include "libertine-scope/i18n.h"
20#include "libertine-scope/service_manager.h"20#include "libertine-scope/service_manager.h"
21#include <future>
22#include <QDebug>21#include <QDebug>
22#include <thread>
23#include <unity/UnityExceptions.h>23#include <unity/UnityExceptions.h>
24#include <unity/scopes/ColumnLayout.h>24#include <unity/scopes/ColumnLayout.h>
25#include <unity/scopes/PreviewReply.h>25#include <unity/scopes/PreviewReply.h>
@@ -164,7 +164,7 @@
164 if (app.status == "installing" || app.status == "removing") {164 if (app.status == "installing" || app.status == "removing") {
165 thread_.reset(new std::thread([=](){165 thread_.reset(new std::thread([=](){
166 std::this_thread::sleep_for(update_progress_after);166 std::this_thread::sleep_for(update_progress_after);
167 service_->update_progress(QString::fromStdString(app.id));167 service_->update_progress(QString::fromStdString(app.progress));
168 }));168 }));
169 }169 }
170}170}
171171
=== modified file 'lib/libertine-scope/service_manager.cpp'
--- lib/libertine-scope/service_manager.cpp 2016-09-20 17:56:18 +0000
+++ lib/libertine-scope/service_manager.cpp 2016-10-05 19:26:10 +0000
@@ -26,6 +26,9 @@
26constexpr auto INSTALL_METHOD = "install";26constexpr auto INSTALL_METHOD = "install";
27constexpr auto REMOVE_METHOD = "remove";27constexpr auto REMOVE_METHOD = "remove";
28constexpr auto UPDATE_PROGRESS_METHOD = "update_progress";28constexpr auto UPDATE_PROGRESS_METHOD = "update_progress";
29constexpr auto CONTAINER_INFO_METHOD = "container_info";
30constexpr auto CONTAINER_PROGRESS_METHOD = "container_progress";
31constexpr auto CREATE_METHOD = "create_container";
29constexpr auto LIBERTINE_SERVICE_DESTINATION = "com.canonical.libertine.ContainerManager";32constexpr auto LIBERTINE_SERVICE_DESTINATION = "com.canonical.libertine.ContainerManager";
30constexpr auto LIBERTINE_SERVICE_INTERFACE = "com.canonical.libertine.ContainerManager";33constexpr auto LIBERTINE_SERVICE_INTERFACE = "com.canonical.libertine.ContainerManager";
31constexpr auto LIBERTINE_SERVICE_OBJECT = "/Manager";34constexpr auto LIBERTINE_SERVICE_OBJECT = "/Manager";
@@ -39,6 +42,20 @@
39}42}
4043
4144
45QList<libertine::scope::Package> libertine::scope::ServiceManager::
46search_cache(const QString &query) const
47{
48 return Package::from_map(call<QList<QVariantMap > >(SEARCH_CACHE_METHOD, QVariant(query)));
49}
50
51
52libertine::scope::Package libertine::scope::ServiceManager::
53app_info(const QString &app_id) const
54{
55 return Package::from_map(call<QVariantMap >(APP_INFO_METHOD, QVariant(app_id)));
56}
57
58
42void libertine::scope::ServiceManager::59void libertine::scope::ServiceManager::
43install(QString const& package_name) const60install(QString const& package_name) const
44{61{
@@ -53,10 +70,10 @@
53}70}
5471
5572
56libertine::scope::Package libertine::scope::ServiceManager::73void libertine::scope::ServiceManager::
57app_info(const QString &app_id) const74create(QString const& container_id) const
58{75{
59 return Package::from_map(call<QVariantMap >(APP_INFO_METHOD, QVariant(app_id)));76 call<qlonglong>(CREATE_METHOD, QVariant(container_id));
60}77}
6178
6279
@@ -67,10 +84,10 @@
67}84}
6885
6986
70QList<libertine::scope::Package> libertine::scope::ServiceManager::87libertine::scope::Container libertine::scope::ServiceManager::
71search_cache(const QString &query) const88container_info(const QString &container_id) const
72{89{
73 return Package::from_map(call<QList<QVariantMap > >(SEARCH_CACHE_METHOD, QVariant(query)));90 return Container::from_map(call<QVariantMap >(CONTAINER_INFO_METHOD, QVariant(container_id)));
74}91}
7592
7693
7794
=== modified file 'lib/libertine-scope/service_manager.h'
--- lib/libertine-scope/service_manager.h 2016-09-20 17:56:18 +0000
+++ lib/libertine-scope/service_manager.h 2016-10-05 19:26:10 +0000
@@ -16,6 +16,7 @@
16#pragma once16#pragma once
1717
18#include "libertine-scope/package.h"18#include "libertine-scope/package.h"
19#include "libertine-scope/container.h"
1920
20#include <QString>21#include <QString>
21#include <QVariant>22#include <QVariant>
@@ -38,6 +39,8 @@
38 virtual void install(QString const& package_name) const;39 virtual void install(QString const& package_name) const;
39 virtual void remove(QString const& package_name) const;40 virtual void remove(QString const& package_name) const;
40 virtual void update_progress(QString const& package_name) const;41 virtual void update_progress(QString const& package_name) const;
42 virtual Container container_info(QString const& container_id) const;
43 virtual void create(QString const& container_id) const;
4144
42private:45private:
43 bool valid() const;46 bool valid() const;
4447
=== modified file 'scope/apps/action.cpp'
--- scope/apps/action.cpp 2016-09-20 20:09:51 +0000
+++ scope/apps/action.cpp 2016-10-05 19:26:10 +0000
@@ -46,7 +46,6 @@
46 std::shared_ptr<HiddenApps> const& hidden,46 std::shared_ptr<HiddenApps> const& hidden,
47 unity::scopes::FilterState const& filter_state)47 unity::scopes::FilterState const& filter_state)
48 : libertine::scope::Action(result, metadata, action_id, service)48 : libertine::scope::Action(result, metadata, action_id, service)
49 , action_id_(action_id)
50 , hidden_(hidden)49 , hidden_(hidden)
51 , filter_state_(filter_state)50 , filter_state_(filter_state)
52{51{
5352
=== modified file 'scope/apps/action.h'
--- scope/apps/action.h 2016-09-20 20:09:51 +0000
+++ scope/apps/action.h 2016-10-05 19:26:10 +0000
@@ -43,7 +43,6 @@
43 virtual unity::scopes::ActivationResponse activate() override;43 virtual unity::scopes::ActivationResponse activate() override;
4444
45private:45private:
46 std::string action_id_;
47 std::string cache_dir_;46 std::string cache_dir_;
48 std::shared_ptr<HiddenApps> hidden_;47 std::shared_ptr<HiddenApps> hidden_;
49 unity::scopes::FilterState filter_state_;48 unity::scopes::FilterState filter_state_;
5049
=== added file 'scope/store/action.cpp'
--- scope/store/action.cpp 1970-01-01 00:00:00 +0000
+++ scope/store/action.cpp 2016-10-05 19:26:10 +0000
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2016 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "scope/store/action.h"
18#include <libertine-scope/service_manager.h>
19#include <unity/scopes/CannedQuery.h>
20#include <QString>
21
22
23libertine::scope::store::Action::
24Action(unity::scopes::Result const& result,
25 unity::scopes::ActionMetadata const& metadata,
26 std::string const& action_id,
27 std::shared_ptr<libertine::scope::ServiceManager> const& service)
28 : ::libertine::scope::Action(result, metadata, action_id, service)
29{
30}
31
32
33unity::scopes::ActivationResponse libertine::scope::store::Action::
34activate()
35{
36 if (action_id_ == "create")
37 {
38 service_->create("palatine");
39 return unity::scopes::ActivationResponse(unity::scopes::ActivationResponse::Status::ShowPreview);
40 }
41
42 return ::libertine::scope::Action::activate();
43}
044
=== added file 'scope/store/action.h'
--- scope/store/action.h 1970-01-01 00:00:00 +0000
+++ scope/store/action.h 2016-10-05 19:26:10 +0000
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2016 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18
19#include <libertine-scope/action.h>
20#include <unity/scopes/ActionMetadata.h>
21#include <unity/scopes/ActivationResponse.h>
22#include <unity/scopes/Result.h>
23
24
25namespace libertine
26{
27namespace scope
28{
29namespace store
30{
31class Action : public ::libertine::scope::Action
32{
33public:
34 explicit
35 Action(unity::scopes::Result const& result,
36 unity::scopes::ActionMetadata const& metadata,
37 std::string const& action_id,
38 std::shared_ptr<libertine::scope::ServiceManager> const& service);
39
40 virtual
41 ~Action() = default;
42
43 virtual
44 unity::scopes::ActivationResponse activate() override;
45};
46} // namespace store
47} // namespace scope
48} // namespace libertine
049
=== added file 'scope/store/create_preview.cpp'
--- scope/store/create_preview.cpp 1970-01-01 00:00:00 +0000
+++ scope/store/create_preview.cpp 2016-10-05 19:26:10 +0000
@@ -0,0 +1,113 @@
1/*
2 * Copyright 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the
6 * Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "scope/store/create_preview.h"
17
18#include "libertine-scope/i18n.h"
19#include "libertine-scope/service_manager.h"
20#include <thread>
21#include <unity/scopes/PreviewReply.h>
22#include <unity/scopes/PreviewWidget.h>
23#include <unity/scopes/VariantBuilder.h>
24
25
26namespace
27{
28static unity::scopes::PreviewWidget
29warning()
30{
31 unity::scopes::PreviewWidget warning("warning", "text");
32 warning.add_attribute_value("title", unity::scopes::Variant(_("Initializing this scope may consume up to 500MB of data and could take several minutes.")));
33 return warning;
34}
35}
36
37
38std::chrono::milliseconds libertine::scope::store::CreatePreview::
39update_progress_after = std::chrono::milliseconds(500);
40
41
42libertine::scope::store::CreatePreview::
43CreatePreview(unity::scopes::Result const& result,
44 unity::scopes::ActionMetadata const& metadata,
45 std::shared_ptr<ServiceManager> const& service)
46: PreviewQueryBase(result, metadata)
47, service_(service)
48, thread_()
49{
50}
51
52
53libertine::scope::store::CreatePreview::
54~CreatePreview()
55{
56 if (thread_ != nullptr)
57 {
58 thread_->join();
59 }
60}
61
62
63void libertine::scope::store::CreatePreview::
64cancelled()
65{
66}
67
68
69void libertine::scope::store::CreatePreview::
70run(unity::scopes::PreviewReplyProxy const& reply)
71{
72 auto info = service_->container_info("palatine");
73
74 unity::scopes::PreviewWidgetList widgets;
75
76 if (info.status == Container::ContainerStatus::none)
77 {
78 widgets.push_back(warning());
79 unity::scopes::VariantBuilder builder;
80 builder.add_tuple(
81 {
82 {"id", unity::scopes::Variant("create")},
83 {"label", unity::scopes::Variant(_("Start"))},
84 });
85 unity::scopes::PreviewWidget start("actions", "actions");
86 start.add_attribute_value("actions", builder.end());
87 widgets.push_back(start);
88 }
89 else if (info.status != Container::ContainerStatus::ready)
90 {
91 widgets.push_back(warning());
92 unity::scopes::PreviewWidget progress("actions", "progress");
93 unity::scopes::VariantMap tuple;
94 tuple["dbus-name"] = "com.canonical.libertine.ContainerManager";
95 tuple["dbus-object"] = std::string("/Progress/") + info.progress;
96 progress.add_attribute_value("source", unity::scopes::Variant(tuple));
97 widgets.push_back(progress);
98
99 // update the progress bar asynchronously
100 thread_.reset(new std::thread([=](){
101 std::this_thread::sleep_for(update_progress_after);
102 service_->update_progress(QString::fromStdString(info.progress));
103 }));
104 }
105 else
106 {
107 unity::scopes::PreviewWidget info("info", "text");
108 info.add_attribute_value("title", unity::scopes::Variant(_("Scope is ready.")));
109 widgets.push_back(info);
110 }
111
112 reply->push(widgets);
113}
0114
=== added file 'scope/store/create_preview.h'
--- scope/store/create_preview.h 1970-01-01 00:00:00 +0000
+++ scope/store/create_preview.h 2016-10-05 19:26:10 +0000
@@ -0,0 +1,65 @@
1/*
2 * Copyright 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the
6 * Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include <chrono>
19#include <unity/scopes/PreviewQueryBase.h>
20
21
22namespace std
23{
24class thread;
25}
26
27
28namespace libertine
29{
30namespace scope
31{
32class ServiceManager;
33
34namespace store
35{
36
37class CreatePreview
38: public unity::scopes::PreviewQueryBase
39{
40public:
41 explicit
42 CreatePreview(unity::scopes::Result const& result,
43 unity::scopes::ActionMetadata const& metadata,
44 std::shared_ptr<ServiceManager> const& service);
45
46 virtual
47 ~CreatePreview();
48
49 virtual void
50 cancelled() override;
51
52 virtual void
53 run(unity::scopes::PreviewReplyProxy const& reply) override;
54
55 static
56 std::chrono::milliseconds update_progress_after;
57
58private:
59 std::shared_ptr<ServiceManager> service_;
60 std::unique_ptr<std::thread> thread_;
61};
62
63} // namespace store
64} // namespace scope
65} // namespace libertine
066
=== modified file 'scope/store/entry_point.cpp'
--- scope/store/entry_point.cpp 2016-08-24 19:18:32 +0000
+++ scope/store/entry_point.cpp 2016-10-05 19:26:10 +0000
@@ -29,7 +29,7 @@
29EXPORT unity::scopes::ScopeBase*29EXPORT unity::scopes::ScopeBase*
30UNITY_SCOPE_CREATE_FUNCTION()30UNITY_SCOPE_CREATE_FUNCTION()
31{31{
32 return new libertine::scope::Scope();32 return new libertine::scope::store::Scope();
33}33}
3434
3535
3636
=== modified file 'scope/store/query.cpp'
--- scope/store/query.cpp 2016-09-15 18:55:23 +0000
+++ scope/store/query.cpp 2016-10-05 19:26:10 +0000
@@ -65,33 +65,56 @@
65)";65)";
6666
6767
68static const auto CATEGORY_CREATE = R"(
69 {
70 "schema-version": 1,
71 "template": {
72 "category-layout": "grid",
73 "overlay": true,
74 "card-background": "color:///#E95420"
75 },
76 "components": {
77 "title": "title",
78 "art": {
79 "aspect-ratio": 0.55,
80 "field": "art"
81 },
82 "overlay-color": "overlay-color"
83 }
84 }
85)";
86
87
68static auto const SINGLE_RESULT_FOUND = _("%1 result found");88static auto const SINGLE_RESULT_FOUND = _("%1 result found");
69static auto const MULTIPLE_RESULTS_FOUND = _("%1 results found");89static auto const MULTIPLE_RESULTS_FOUND = _("%1 results found");
70static QString const APPID_URI_FORMAT = "appid://palatine/%1/0.0";90static QString const APPID_URI_FORMAT = "appid://palatine/%1/0.0";
71}91}
7292
7393
74std::string const libertine::scope::Query::USE_SEARCH_HINT = _("Use the searchbar to find software.");94std::string const libertine::scope::store::Query::USE_SEARCH_HINT = _("Use the searchbar to find software.");
75std::string const libertine::scope::Query::NO_SEARCH_RESULTS_HINT = _("No results found.");95std::string const libertine::scope::store::Query::NO_SEARCH_RESULTS_HINT = _("No results found.");
7696std::string const libertine::scope::store::Query::CREATE_CATEGORY_TITLE = _("Get started");
7797
78libertine::scope::Query::98
79Query(usc::CannedQuery const& query,99libertine::scope::store::Query::
80 usc::SearchMetadata const& metadata,100Query(usc::CannedQuery const& query,
81 std::shared_ptr<ServiceManager> const& service)101 usc::SearchMetadata const& metadata,
102 std::shared_ptr<ServiceManager> const& service,
103 std::string const & data_directory)
82 : usc::SearchQueryBase(query, metadata)104 : usc::SearchQueryBase(query, metadata)
83 , service_(service)105 , service_(service)
106 , data_directory_(data_directory)
84{107{
85}108}
86109
87110
88void libertine::scope::Query::111void libertine::scope::store::Query::
89cancelled()112cancelled()
90{113{
91}114}
92115
93116
94void libertine::scope::Query::117void libertine::scope::store::Query::
95show_hint(usc::SearchReplyProxy const& reply,118show_hint(usc::SearchReplyProxy const& reply,
96 std::string const& reason) const119 std::string const& reason) const
97{120{
@@ -103,7 +126,21 @@
103}126}
104127
105128
106void libertine::scope::Query::129void libertine::scope::store::Query::
130add_create_category(usc::SearchReplyProxy const& reply) const
131{
132 auto cat = reply->register_category("create", "", "", usc::CategoryRenderer(CATEGORY_CREATE));
133 usc::CategorisedResult res(cat);
134 res.set_title(CREATE_CATEGORY_TITLE);
135 res.set_art(data_directory_ + "/store.svg");
136 res.set_uri("libertine-store://create");
137 res["overlay-color"] = "transparent";
138 res["show_create_preview"] = true;
139 reply->push(res);
140}
141
142
143void libertine::scope::store::Query::
107run_search(usc::SearchReplyProxy const& reply) const144run_search(usc::SearchReplyProxy const& reply) const
108{145{
109 auto results = service_->search_cache(QString::fromStdString(query().query_string()));146 auto results = service_->search_cache(QString::fromStdString(query().query_string()));
@@ -136,9 +173,16 @@
136}173}
137174
138175
139void libertine::scope::Query::176void libertine::scope::store::Query::
140run(usc::SearchReplyProxy const& reply)177run(usc::SearchReplyProxy const& reply)
141{178{
179 auto info = service_->container_info("palatine");
180 if (info.status != Container::ContainerStatus::ready)
181 {
182 add_create_category(reply);
183 return;
184 }
185
142 if (!query().query_string().empty())186 if (!query().query_string().empty())
143 {187 {
144 run_search(reply);188 run_search(reply);
145189
=== modified file 'scope/store/query.h'
--- scope/store/query.h 2016-08-24 19:18:32 +0000
+++ scope/store/query.h 2016-10-05 19:26:10 +0000
@@ -13,23 +13,22 @@
13 * You should have received a copy of the GNU General Public License13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */15 */
16#ifndef LIBERTINE_STORE_QUERY_H_16#pragma once
17#define LIBERTINE_STORE_QUERY_H_
18
1917
20#include <unity/scopes/ReplyProxyFwd.h>18#include <unity/scopes/ReplyProxyFwd.h>
21#include <unity/scopes/SearchQueryBase.h>19#include <unity/scopes/SearchQueryBase.h>
2220#include <QString>
23class QStringList;
2421
2522
26namespace libertine23namespace libertine
27{24{
28namespace scope25namespace scope
29{26{
30
31class ServiceManager;27class ServiceManager;
3228
29namespace store
30{
31
33/**32/**
34 * Engine to run a specific store query.33 * Engine to run a specific store query.
35 */34 */
@@ -37,10 +36,12 @@
37 : public unity::scopes::SearchQueryBase36 : public unity::scopes::SearchQueryBase
38{37{
39public:38public:
40 explicit Query(unity::scopes::CannedQuery const& query,39 explicit Query(unity::scopes::CannedQuery const& query,
41 unity::scopes::SearchMetadata const& metadata,40 unity::scopes::SearchMetadata const& metadata,
42 std::shared_ptr<ServiceManager> const& service);41 std::shared_ptr<ServiceManager> const& service,
42 std::string const& data_directory = "");
4343
44 virtual
44 ~Query() = default;45 ~Query() = default;
4546
46 virtual void47 virtual void
@@ -51,6 +52,7 @@
5152
52 static std::string const USE_SEARCH_HINT;53 static std::string const USE_SEARCH_HINT;
53 static std::string const NO_SEARCH_RESULTS_HINT;54 static std::string const NO_SEARCH_RESULTS_HINT;
55 static std::string const CREATE_CATEGORY_TITLE;
5456
55private:57private:
56 void58 void
@@ -58,13 +60,13 @@
58 std::string const& reason) const;60 std::string const& reason) const;
59 void61 void
60 run_search(unity::scopes::SearchReplyProxy const& reply) const;62 run_search(unity::scopes::SearchReplyProxy const& reply) const;
63 void
64 add_create_category(unity::scopes::SearchReplyProxy const& reply) const;
6165
62 std::shared_ptr<ServiceManager> service_;66 std::shared_ptr<ServiceManager> service_;
67 const std::string data_directory_;
63};68};
6469
70} // namespace store
65} // namespace scope71} // namespace scope
66} // namespace libertine72} // namespace libertine
67
68#endif // LIBERTINE_STORE_QUERY_H_
69
70
7173
=== modified file 'scope/store/scope.cpp'
--- scope/store/scope.cpp 2016-09-20 17:56:18 +0000
+++ scope/store/scope.cpp 2016-10-05 19:26:10 +0000
@@ -19,6 +19,8 @@
19 */19 */
20#include "scope/store/scope.h"20#include "scope/store/scope.h"
2121
22#include "scope/store/action.h"
23#include "scope/store/create_preview.h"
22#include "scope/store/query.h"24#include "scope/store/query.h"
23#include <libertine-scope/action.h>25#include <libertine-scope/action.h>
24#include <libertine-scope/i18n.h>26#include <libertine-scope/i18n.h>
@@ -29,13 +31,13 @@
29namespace usc = unity::scopes;31namespace usc = unity::scopes;
3032
3133
32libertine::scope::Scope::34libertine::scope::store::Scope::
33Scope()35Scope()
34 : service_(std::make_shared<ServiceManager>())36 : service_(std::make_shared<ServiceManager>())
35{ }37{ }
3638
3739
38void libertine::scope::Scope::40void libertine::scope::store::Scope::
39start(std::string const&)41start(std::string const&)
40{42{
41 setlocale(LC_ALL, "");43 setlocale(LC_ALL, "");
@@ -45,23 +47,28 @@
45}47}
4648
4749
48usc::SearchQueryBase::UPtr libertine::scope::Scope::50usc::SearchQueryBase::UPtr libertine::scope::store::Scope::
49search(usc::CannedQuery const& query,51search(usc::CannedQuery const& query,
50 usc::SearchMetadata const& metadata)52 usc::SearchMetadata const& metadata)
51{53{
52 return usc::SearchQueryBase::UPtr(new Query(query, metadata, service_));54 return usc::SearchQueryBase::UPtr(new Query(query, metadata, service_, scope_directory()));
53}55}
5456
5557
56usc::PreviewQueryBase::UPtr libertine::scope::Scope::58usc::PreviewQueryBase::UPtr libertine::scope::store::Scope::
57preview(usc::Result const& result,59preview(usc::Result const& result,
58 usc::ActionMetadata const& metadata)60 usc::ActionMetadata const& metadata)
59{61{
62 if (result.contains("show_create_preview") && result["show_create_preview"].get_bool())
63 {
64 return usc::PreviewQueryBase::UPtr(new CreatePreview(result, metadata, service_));
65 }
66
60 return usc::PreviewQueryBase::UPtr(new Preview(result, metadata, service_));67 return usc::PreviewQueryBase::UPtr(new Preview(result, metadata, service_));
61}68}
6269
6370
64usc::ActivationQueryBase::UPtr libertine::scope::Scope::71usc::ActivationQueryBase::UPtr libertine::scope::store::Scope::
65perform_action(usc::Result const& result,72perform_action(usc::Result const& result,
66 usc::ActionMetadata const& metadata,73 usc::ActionMetadata const& metadata,
67 std::string const& /* widget_id */,74 std::string const& /* widget_id */,
@@ -72,4 +79,3 @@
72 action_id,79 action_id,
73 service_));80 service_));
74}81}
75
7682
=== modified file 'scope/store/scope.h'
--- scope/store/scope.h 2016-09-20 17:56:18 +0000
+++ scope/store/scope.h 2016-10-05 19:26:10 +0000
@@ -17,8 +17,7 @@
17 * You should have received a copy of the GNU General Public License17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */19 */
20#ifndef LIBERTINE_STORE_SCOPE_H_20#pragma once
21#define LIBERTINE_STORE_SCOPE_H_
2221
23#include <unity/scopes/ScopeBase.h>22#include <unity/scopes/ScopeBase.h>
2423
@@ -26,10 +25,10 @@
26{25{
27namespace scope26namespace scope
28{27{
29
30class ServiceManager;28class ServiceManager;
3129
3230namespace store
31{
33class Scope32class Scope
34: public unity::scopes::ScopeBase33: public unity::scopes::ScopeBase
35{34{
@@ -70,8 +69,6 @@
70 std::shared_ptr<ServiceManager> service_;69 std::shared_ptr<ServiceManager> service_;
71};70};
7271
7372} // namespace store
74} // namespace scope73} // namespace scope
75} // namespace libertine74} // namespace libertine
76
77#endif /* LIBERTINE_STORE_SCOPE_H_ */
7875
=== modified file 'service/libertine_service/container.py'
--- service/libertine_service/container.py 2016-08-22 15:28:57 +0000
+++ service/libertine_service/container.py 2016-10-05 19:26:10 +0000
@@ -56,12 +56,22 @@
56 task = tasks.RemoveTask(package_name, container_id, self.libertine_config, progress, self.lock, self.log)56 task = tasks.RemoveTask(package_name, container_id, self.libertine_config, progress, self.lock, self.log)
57 return task.start()57 return task.start()
5858
59 def status(self, package_name, container_id):59 def status(self, container, package=''):
60 self.log.debug("Checking status of package '%s'" % package_name)60 self.log.debug("Checking status of '%s':'%s'" % (container, package))
61 self.libertine_config.refresh_database()61 self.libertine_config.refresh_database()
62 if not self._container_exists(container_id):62 if not self._container_exists(container):
63 return ''63 return ''
64 return self.libertine_config.get_package_install_status(container_id, package_name) or ''64 if package == '':
65 return self.libertine_config._get_value_by_key(container, 'installStatus')
66 return self.libertine_config.get_package_install_status(container, package) or ''
67
68 def create(self, container_id, progress):
69 self.log.debug("Create container with ID '%s'" % container_id)
70 self.libertine_config.refresh_database()
71 if self._container_exists(container_id):
72 return -1
73 task = tasks.CreateTask(container_id, self.libertine_config, progress, self.lock, self.log)
74 return task.start()
6575
66 def _container_exists(self, container_id):76 def _container_exists(self, container_id):
67 self.log.debug("Checking if container '%s' exists" % container_id)77 self.log.debug("Checking if container '%s' exists" % container_id)
6878
=== modified file 'service/libertine_service/dbus.py'
--- service/libertine_service/dbus.py 2016-09-20 18:30:26 +0000
+++ service/libertine_service/dbus.py 2016-10-05 19:26:10 +0000
@@ -62,7 +62,6 @@
6262
6363
64class Service(dbus.service.Object):64class Service(dbus.service.Object):
65
66 def __init__(self, config):65 def __init__(self, config):
67 log.debug("creating service")66 log.debug("creating service")
68 DBusGMainLoop(set_as_default=True)67 DBusGMainLoop(set_as_default=True)
@@ -117,16 +116,37 @@
117 log.debug("app_info('{}') called".format(app_id))116 log.debug("app_info('{}') called".format(app_id))
118 app = self.cache.app_info(app_id)117 app = self.cache.app_info(app_id)
119 if 'package' in app:118 if 'package' in app:
120 app['status'] = self.container.status(app['package'], CONTAINER_ID)119 app['status'] = self.container.status(package=app['package'], container=CONTAINER_ID)
121 if app['id'] in self.progress:120 if app['id'] in self.progress:
122 app['progress_id'] = self.progress[app['id']].id121 app['progress_id'] = self.progress[app['id']].id
123122
124 return app123 return app
125124
126 @dbus.service.signal(LIBERTINE_STORE_INTERFACE,125 @dbus.service.method(LIBERTINE_STORE_INTERFACE,
127 signature='su')126 in_signature='s',
128 def updating(self, target, percent):127 out_signature='a{sv}')
129 log.debug("emit updating('{}', {})".format(target, percent))128 def container_info(self, container_id):
129 log.debug("container_info('{}')".format(container_id))
130 info = {"status": self.container.status(container=container_id)}
131 if info['status'] != '':
132 info['id'] = container_id
133 cid = '_%s' % container_id
134 if cid in self.progress:
135 info['progress_id'] = self.progress[cid].id
136
137 return info
138
139 @dbus.service.method(LIBERTINE_STORE_INTERFACE,
140 in_signature='s',
141 out_signature='x')
142 def create_container(self, container_id):
143 log.debug("create_container('{}')".format(container_id))
144 container_progress = Progress(self.connection)
145 self.progress["_%s" % container_id] = container_progress
146 retval = self.container.create(container_id, container_progress)
147 if retval <= 0:
148 container_progress.finished('')
149 return retval
130150
131 # Packaging151 # Packaging
132152
@@ -155,11 +175,12 @@
155 @dbus.service.method(LIBERTINE_STORE_INTERFACE,175 @dbus.service.method(LIBERTINE_STORE_INTERFACE,
156 in_signature='s',176 in_signature='s',
157 out_signature='b')177 out_signature='b')
158 def update_progress(self, app_id):178 def update_progress(self, progress_id):
159 log.debug("update_progress('%s')" % app_id)179 log.debug("update_progress('%s')" % progress_id)
160 self.cleanup_progress()180 self.cleanup_progress()
161 if app_id in self.progress:181 progress = [v for k, v in self.progress.items() if v.id == progress_id]
162 self.progress[app_id].emit_progress()182 if len(progress) == 1:
183 progress[0].emit_progress()
163 return True184 return True
164 return False185 return False
165186
166187
=== modified file 'service/libertine_service/tasks.py'
--- service/libertine_service/tasks.py 2016-09-16 21:35:57 +0000
+++ service/libertine_service/tasks.py 2016-10-05 19:26:10 +0000
@@ -12,13 +12,23 @@
12# You should have received a copy of the GNU General Public License12# You should have received a copy of the GNU General Public License
13# along with this program. If not, see <http://www.gnu.org/licenses/>.13# along with this program. If not, see <http://www.gnu.org/licenses/>.
1414
15from subprocess import Popen, PIPE15import shlex
16from subprocess import Popen, DEVNULL
16from threading import Thread17from threading import Thread
17from abc import ABCMeta, abstractmethod18from abc import ABCMeta, abstractmethod
18from libertine import LibertineContainer, HostInfo, utils19from libertine import LibertineContainer, HostInfo, utils
19from dbus import UInt6420from dbus import UInt64
2021
2122
23def refresh_libertine_store_scope():
24 scopes_object_path = "/com/canonical/unity/scopes"
25 invalidate_signal = "com.canonical.unity.scopes.InvalidateResults"
26 libertine_scope_id = "libertine-scope.ubuntu_libertine-store"
27 gdbus_cmd = ("gdbus emit --session --object-path %s --signal %s %s" %
28 (scopes_object_path, invalidate_signal, libertine_scope_id))
29 Popen(shlex.split(gdbus_cmd), stdout=DEVNULL, stderr=DEVNULL)
30
31
22class LibertineTask(metaclass=ABCMeta):32class LibertineTask(metaclass=ABCMeta):
23 """33 """
24 Abstract class for performing long-running, synchronous operations on a34 Abstract class for performing long-running, synchronous operations on a
@@ -120,24 +130,29 @@
120 self.log.debug("Package '%s' already exists, skipping install" % self.package)130 self.log.debug("Package '%s' already exists, skipping install" % self.package)
121 return False131 return False
122132
123133import time
124class CreateTask(LibertineTask):134class CreateTask(ProgressTask):
125 def __init__(self, container_id, config, lock, log):135 def __init__(self, container_id, config, progress, lock, log):
126 super().__init__(lock, log)136 super().__init__("", container_id, config, progress, lock, log)
127 self.container = container_id
128 self.config = config
129137
130 def _run(self):138 def _run(self):
131 self.log.debug("Creating container '%s'" % self.container)139 self.log.debug("Creating container '%s'" % self.container)
140 self._progress()
141
132 container = LibertineContainer(self.container, self.config)142 container = LibertineContainer(self.container, self.config)
133 if not container.create_libertine_container(password=''):143 if not container.create_libertine_container(password=''):
134 self.log.debug("Creating container '%s' failed" % self.container)144 self.log.debug("Creating container '%s' failed" % self.container)
135 self.config.delete_container(self.container)145 self.config.delete_container(self.container)
136 return146 return
147 self._progress()
148
137 self.config.update_container_install_status(self.container, "ready")149 self.config.update_container_install_status(self.container, "ready")
150 self.progress.finished(self.container)
151 refresh_libertine_store_scope()
138152
139 def _before(self):153 def _before(self):
140 self.log.debug("CreateTask::_before")154 self.log.debug("CreateTask::_before")
155 self._progress()
141 if self.config.container_exists(self.container):156 if self.config.container_exists(self.container):
142 return False157 return False
143158
@@ -146,4 +161,5 @@
146 self.config.add_new_container(self.container, 'User Applications', info.select_container_type_by_kernel(),161 self.config.add_new_container(self.container, 'User Applications', info.select_container_type_by_kernel(),
147 info.get_host_distro_release())162 info.get_host_distro_release())
148 self.config.update_container_install_status(self.container, 'installing')163 self.config.update_container_install_status(self.container, 'installing')
164 self._progress()
149 return True165 return True
150166
=== modified file 'tests/lib/libertine-scope/CMakeLists.txt'
--- tests/lib/libertine-scope/CMakeLists.txt 2016-08-24 16:21:47 +0000
+++ tests/lib/libertine-scope/CMakeLists.txt 2016-10-05 19:26:10 +0000
@@ -19,6 +19,7 @@
19 add_test(${test_name} ${test_name}_exe)19 add_test(${test_name} ${test_name}_exe)
20endfunction(create_test)20endfunction(create_test)
2121
22create_test(test_action)
23create_test(test_container)
24create_test(test_package)
22create_test(test_preview)25create_test(test_preview)
23create_test(test_package)
24create_test(test_action)
2526
=== modified file 'tests/lib/libertine-scope/mock_service_manager.h'
--- tests/lib/libertine-scope/mock_service_manager.h 2016-09-20 17:56:18 +0000
+++ tests/lib/libertine-scope/mock_service_manager.h 2016-10-05 19:26:10 +0000
@@ -40,6 +40,8 @@
40 MOCK_CONST_METHOD1(update_progress, void(QString const&));40 MOCK_CONST_METHOD1(update_progress, void(QString const&));
41 MOCK_CONST_METHOD1(install, void(QString const&));41 MOCK_CONST_METHOD1(install, void(QString const&));
42 MOCK_CONST_METHOD1(remove, void(QString const&));42 MOCK_CONST_METHOD1(remove, void(QString const&));
43 MOCK_CONST_METHOD1(container_info, Container(QString const&));
44 MOCK_CONST_METHOD1(create, void(QString const&));
43};45};
4446
4547
4648
=== modified file 'tests/lib/libertine-scope/test_action.cpp'
--- tests/lib/libertine-scope/test_action.cpp 2016-08-25 12:59:32 +0000
+++ tests/lib/libertine-scope/test_action.cpp 2016-10-05 19:26:10 +0000
@@ -23,7 +23,7 @@
2323
24namespace24namespace
25{25{
26TEST(StoreActionTest, CallsInstallOnServiceManager)26TEST(ActionTest, CallsInstallOnServiceManager)
27{27{
28 unity::scopes::testing::Result result;28 unity::scopes::testing::Result result;
29 result["id"] = "vim-common";29 result["id"] = "vim-common";
@@ -39,7 +39,7 @@
39}39}
4040
4141
42TEST(StoreActionTest, CallsRemoveOnServiceManager)42TEST(ActionTest, CallsRemoveOnServiceManager)
43{43{
44 unity::scopes::testing::Result result;44 unity::scopes::testing::Result result;
45 result["id"] = "gedit";45 result["id"] = "gedit";
@@ -55,7 +55,7 @@
55}55}
5656
5757
58TEST(StoreActionTest, OpenAllowsDefaultHandlerToRun)58TEST(ActionTest, OpenAllowsDefaultHandlerToRun)
59{59{
60 unity::scopes::testing::Result result;60 unity::scopes::testing::Result result;
61 result["id"] = "gedit";61 result["id"] = "gedit";
6262
=== added file 'tests/lib/libertine-scope/test_container.cpp'
--- tests/lib/libertine-scope/test_container.cpp 1970-01-01 00:00:00 +0000
+++ tests/lib/libertine-scope/test_container.cpp 2016-10-05 19:26:10 +0000
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the
6 * Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "libertine-scope/container.h"
17
18#include <gmock/gmock.h>
19
20
21namespace
22{
23using namespace libertine::scope;
24
25
26TEST(PackageTest, FromMapCreatesPackage)
27{
28 QVariantMap attributes;
29 attributes["id"] = "foobar";
30 attributes["status"] = "ready";
31 attributes["progress_id"] = "1234321";
32
33 auto container = Container::from_map(attributes);
34 EXPECT_EQ("foobar", container.id);
35 EXPECT_EQ(Container::ContainerStatus::ready, container.status);
36 EXPECT_EQ("1234321", container.progress);
37}
38
39
40TEST(PackageTest, FromMapConvertsStatusStrings)
41{
42 QVariantMap attributes;
43
44 attributes["status"] = "ready";
45 EXPECT_EQ(Container::ContainerStatus::ready, Container::from_map(attributes).status);
46 attributes["status"] = "installing";
47 EXPECT_EQ(Container::ContainerStatus::installing, Container::from_map(attributes).status);
48 attributes["status"] = "removing";
49 EXPECT_EQ(Container::ContainerStatus::removing, Container::from_map(attributes).status);
50 attributes["status"] = "";
51 EXPECT_EQ(Container::ContainerStatus::none, Container::from_map(attributes).status);
52}
53}
054
=== modified file 'tests/lib/libertine-scope/test_preview.cpp'
--- tests/lib/libertine-scope/test_preview.cpp 2016-09-20 17:56:18 +0000
+++ tests/lib/libertine-scope/test_preview.cpp 2016-10-05 19:26:10 +0000
@@ -249,7 +249,7 @@
249 package.status = "removing";249 package.status = "removing";
250 package.progress = "something";250 package.progress = "something";
251 usePackage(package);251 usePackage(package);
252 EXPECT_CALL(*service, update_progress(QString::fromStdString(package.id)));252 EXPECT_CALL(*service, update_progress(QString::fromStdString(package.progress)));
253253
254 std::unique_ptr<Preview> preview(new Preview(result, metadata, service));254 std::unique_ptr<Preview> preview(new Preview(result, metadata, service));
255 preview->run(proxy);255 preview->run(proxy);
@@ -273,7 +273,7 @@
273 package.status = "installing";273 package.status = "installing";
274 package.progress = "foobar";274 package.progress = "foobar";
275 usePackage(package);275 usePackage(package);
276 EXPECT_CALL(*service, update_progress(QString::fromStdString(package.id)));276 EXPECT_CALL(*service, update_progress(QString::fromStdString(package.progress)));
277277
278 std::unique_ptr<Preview> preview(new Preview(result, metadata, service));278 std::unique_ptr<Preview> preview(new Preview(result, metadata, service));
279 preview->run(proxy);279 preview->run(proxy);
280280
=== modified file 'tests/scope/store/CMakeLists.txt'
--- tests/scope/store/CMakeLists.txt 2016-08-24 16:21:47 +0000
+++ tests/scope/store/CMakeLists.txt 2016-10-05 19:26:10 +0000
@@ -20,4 +20,6 @@
20 add_test(${full_test_name} ${full_test_name}_exe)20 add_test(${full_test_name} ${full_test_name}_exe)
21endfunction(create_test)21endfunction(create_test)
2222
23create_test(test_action)
24create_test(test_create_preview)
23create_test(test_query)25create_test(test_query)
2426
=== added file 'tests/scope/store/test_action.cpp'
--- tests/scope/store/test_action.cpp 1970-01-01 00:00:00 +0000
+++ tests/scope/store/test_action.cpp 2016-10-05 19:26:10 +0000
@@ -0,0 +1,85 @@
1/*
2 * Copyright 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the
6 * Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "scope/store/action.h"
17
18#include <gmock/gmock.h>
19#include <tests/lib/libertine-scope/mock_service_manager.h>
20#include <unity/scopes/ActionMetadata.h>
21#include <unity/scopes/testing/Result.h>
22
23
24namespace
25{
26TEST(ActionTest, OpenAllowsDefaultHandlerToRun)
27{
28 unity::scopes::testing::Result result;
29 result.set_uri("app://this/is/my/app");
30 unity::scopes::ActionMetadata metadata("en_US", "phone");
31 auto service = std::make_shared<testing::NiceMock<libertine::scope::MockServiceManager> >();
32
33 libertine::scope::store::Action action(result, metadata, "open", service);
34
35 auto response = action.activate();
36 EXPECT_EQ(unity::scopes::ActivationResponse::Status::NotHandled, response.status());
37}
38
39
40TEST(ActionTest, CallsCreateOnServiceManager)
41{
42 unity::scopes::testing::Result result;
43 unity::scopes::ActionMetadata metadata("en_US", "phone");
44 auto service = std::make_shared<testing::NiceMock<libertine::scope::MockServiceManager> >();
45
46 libertine::scope::store::Action action(result, metadata, "create", service);
47
48 EXPECT_CALL(*service, create(QString("palatine")));
49
50 auto response = action.activate();
51 EXPECT_EQ(unity::scopes::ActivationResponse::Status::ShowPreview, response.status());
52}
53
54
55TEST(ActionTest, CallsInstallOnServiceManager)
56{
57 unity::scopes::testing::Result result;
58 result["id"] = "vim-common";
59 unity::scopes::ActionMetadata metadata("en_US", "phone");
60 auto service = std::make_shared<testing::NiceMock<libertine::scope::MockServiceManager> >();
61
62 libertine::scope::store::Action action(result, metadata, "install", service);
63
64 EXPECT_CALL(*service, install(QString("vim-common")));
65
66 auto response = action.activate();
67 EXPECT_EQ(unity::scopes::ActivationResponse::Status::ShowPreview, response.status());
68}
69
70
71TEST(ActionTest, CallsRemoveOnServiceManager)
72{
73 unity::scopes::testing::Result result;
74 result["id"] = "gedit";
75 unity::scopes::ActionMetadata metadata("en_US", "phone");
76 auto service = std::make_shared<testing::NiceMock<libertine::scope::MockServiceManager> >();
77
78 libertine::scope::store::Action action(result, metadata, "remove", service);
79
80 EXPECT_CALL(*service, remove(QString("gedit")));
81
82 auto response = action.activate();
83 EXPECT_EQ(unity::scopes::ActivationResponse::Status::ShowPreview, response.status());
84}
85}
086
=== added file 'tests/scope/store/test_create_preview.cpp'
--- tests/scope/store/test_create_preview.cpp 1970-01-01 00:00:00 +0000
+++ tests/scope/store/test_create_preview.cpp 2016-10-05 19:26:10 +0000
@@ -0,0 +1,137 @@
1/*
2 * Copyright 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, version 3, as published by the
6 * Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "scope/store/create_preview.h"
17
18#include <gtest/gtest.h>
19#include <memory>
20#include <unity/scopes/Variant.h>
21#include <unity/scopes/ActionMetadata.h>
22#include <unity/scopes/testing/Result.h>
23#include <unity/scopes/testing/MockPreviewReply.h>
24#include <unity/scopes/PreviewWidget.h>
25#include <tests/lib/libertine-scope/mock_service_manager.h>
26
27
28namespace
29{
30using namespace libertine::scope::store;
31
32
33class CreatePreviewTest : public testing::Test
34{
35protected:
36 CreatePreviewTest()
37 : testing::Test()
38 , result()
39 , metadata("en_US", "phone")
40 , list(new unity::scopes::PreviewWidgetList())
41 , reply()
42 , proxy(&reply, [](unity::scopes::PreviewReply*) {})
43 , service(new testing::NiceMock<libertine::scope::MockServiceManager>())
44 {
45 }
46
47 virtual void
48 SetUp()
49 {
50 EXPECT_CALL(reply, push(testing::_)).WillOnce(testing::SaveArg<0>(list.get()));
51 CreatePreview::update_progress_after = std::chrono::milliseconds(0);
52 }
53
54 unity::scopes::testing::Result result;
55 unity::scopes::ActionMetadata metadata;
56 std::unique_ptr<unity::scopes::PreviewWidgetList> list;
57 testing::NiceMock<unity::scopes::testing::MockPreviewReply> reply;
58 unity::scopes::PreviewReplyProxy proxy;
59 std::shared_ptr<testing::NiceMock<libertine::scope::MockServiceManager> > service;
60};
61
62
63TEST_F(CreatePreviewTest, ShowsCreateWarningWithInstallButton)
64{
65 ::libertine::scope::Container c;
66 c.status = ::libertine::scope::Container::ContainerStatus::none;
67 EXPECT_CALL(*service, container_info(QString("palatine"))).WillOnce(testing::Return(c));
68
69 CreatePreview preview(result, metadata, service);
70 preview.run(proxy);
71
72 ASSERT_NE(nullptr, list);
73 ASSERT_EQ(2, list->size());
74
75 auto description = list->front();
76 EXPECT_EQ("warning", description.id());
77 EXPECT_EQ("text", description.widget_type());
78 EXPECT_EQ("Initializing this scope may consume up to 500MB of data and could take several minutes.", description.attribute_values()["title"].get_string());
79 list->pop_front();
80
81 auto buttons = list->front();
82 EXPECT_EQ("actions", buttons.id());
83 EXPECT_EQ("actions", buttons.widget_type());
84 auto buttons_actions = buttons.attribute_values()["actions"].get_array();
85 ASSERT_EQ(1, buttons_actions.size());
86 EXPECT_EQ("create", buttons_actions[0].get_dict()["id"].get_string());
87 EXPECT_EQ("Start", buttons_actions[0].get_dict()["label"].get_string());
88}
89
90
91TEST_F(CreatePreviewTest, ShowsCreateWarningWithProgressBar)
92{
93 ::libertine::scope::Container c;
94 c.status = ::libertine::scope::Container::ContainerStatus::installing;
95 c.progress = "12321";
96 EXPECT_CALL(*service, container_info(QString("palatine"))).WillOnce(testing::Return(c));
97 EXPECT_CALL(*service, update_progress(QString::fromStdString(c.progress)));
98
99 CreatePreview preview(result, metadata, service);
100 preview.run(proxy);
101
102 ASSERT_NE(nullptr, list);
103 ASSERT_EQ(2, list->size());
104
105 auto description = list->front();
106 EXPECT_EQ("warning", description.id());
107 EXPECT_EQ("text", description.widget_type());
108 EXPECT_EQ("Initializing this scope may consume up to 500MB of data and could take several minutes.", description.attribute_values()["title"].get_string());
109
110 list->pop_front();
111 auto buttons = list->front();
112 EXPECT_EQ("actions", buttons.id());
113 EXPECT_EQ("progress", buttons.widget_type());
114 auto source = buttons.attribute_values()["source"].get_dict();
115 EXPECT_EQ("com.canonical.libertine.ContainerManager", source["dbus-name"].get_string());
116 EXPECT_EQ(std::string("/Progress/") + c.progress, source["dbus-object"].get_string());
117}
118
119
120TEST_F(CreatePreviewTest, ShowsScopeReadyMessage)
121{
122 ::libertine::scope::Container c;
123 c.status = ::libertine::scope::Container::ContainerStatus::ready;
124 EXPECT_CALL(*service, container_info(QString("palatine"))).WillOnce(testing::Return(c));
125
126 CreatePreview preview(result, metadata, service);
127 preview.run(proxy);
128
129 ASSERT_NE(nullptr, list);
130 ASSERT_EQ(1, list->size());
131
132 auto description = list->front();
133 EXPECT_EQ("info", description.id());
134 EXPECT_EQ("text", description.widget_type());
135 EXPECT_EQ("Scope is ready.", description.attribute_values()["title"].get_string());
136}
137}
0138
=== modified file 'tests/scope/store/test_query.cpp'
--- tests/scope/store/test_query.cpp 2016-08-26 14:22:41 +0000
+++ tests/scope/store/test_query.cpp 2016-10-05 19:26:10 +0000
@@ -28,7 +28,7 @@
2828
29namespace29namespace
30{30{
31using namespace libertine::scope;31using namespace libertine::scope::store;
3232
3333
34class FakeCategory : public unity::scopes::Category34class FakeCategory : public unity::scopes::Category
@@ -56,6 +56,13 @@
56}56}
5757
5858
59MATCHER(ResultCreateMatch, "")
60{
61 return arg.contains("title") && arg["title"] == unity::scopes::Variant(Query::CREATE_CATEGORY_TITLE) &&
62 arg.contains("show_create_preview") && arg["show_create_preview"].get_bool();
63}
64
65
59class TestStoreQuery : public ::testing::Test66class TestStoreQuery : public ::testing::Test
60{67{
61protected:68protected:
@@ -65,13 +72,13 @@
65 , reply_()72 , reply_()
66 , proxy_(&reply_, [](unity::scopes::SearchReply*) {})73 , proxy_(&reply_, [](unity::scopes::SearchReply*) {})
67 , category_(std::make_shared<FakeCategory>("fake-container", "fake-container", "Application", unity::scopes::CategoryRenderer()))74 , category_(std::make_shared<FakeCategory>("fake-container", "fake-container", "Application", unity::scopes::CategoryRenderer()))
68 , service_(new testing::NiceMock<MockServiceManager>())75 , service_(new testing::NiceMock<::libertine::scope::MockServiceManager>())
69 {76 {
70 }77 }
7178
72 Package create_package(std::string const& name, std::string const& summary, std::string const& id)79 ::libertine::scope::Package create_package(std::string const& name, std::string const& summary, std::string const& id)
73 {80 {
74 Package package;81 ::libertine::scope::Package package;
75 package.name = name;82 package.name = name;
76 package.summary = summary;83 package.summary = summary;
77 package.id = id;84 package.id = id;
@@ -84,17 +91,25 @@
84 EXPECT_CALL(reply_, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultPackageMatch(title, subtitle, id)))).WillOnce(testing::Return(result));91 EXPECT_CALL(reply_, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultPackageMatch(title, subtitle, id)))).WillOnce(testing::Return(result));
85 }92 }
8693
94 void set_container_ready(::libertine::scope::Container::ContainerStatus status = ::libertine::scope::Container::ContainerStatus::ready)
95 {
96 ::libertine::scope::Container info;
97 info.status = status;
98 EXPECT_CALL(*service_, container_info(QString("palatine"))).WillOnce(testing::Return(info));
99 }
100
87 unity::scopes::SearchMetadata metadata_;101 unity::scopes::SearchMetadata metadata_;
88 unity::scopes::CannedQuery canned_query_;102 unity::scopes::CannedQuery canned_query_;
89 testing::NiceMock<unity::scopes::testing::MockSearchReply> reply_;103 testing::NiceMock<unity::scopes::testing::MockSearchReply> reply_;
90 unity::scopes::SearchReplyProxy proxy_;104 unity::scopes::SearchReplyProxy proxy_;
91 std::shared_ptr<FakeCategory> category_;105 std::shared_ptr<FakeCategory> category_;
92 std::shared_ptr<testing::NiceMock<MockServiceManager>> service_;106 std::shared_ptr<testing::NiceMock<::libertine::scope::MockServiceManager>> service_;
93};107};
94108
95109
96TEST_F(TestStoreQuery, ShowsSearchHintOnEmptyQuery)110TEST_F(TestStoreQuery, ShowsSearchHintOnEmptyQuery)
97{111{
112 set_container_ready();
98 EXPECT_CALL(reply_, register_category("hint", "", "", testing::_)).WillOnce(testing::Return(category_));113 EXPECT_CALL(reply_, register_category("hint", "", "", testing::_)).WillOnce(testing::Return(category_));
99 EXPECT_CALL(reply_, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultTitleMatch(Query::USE_SEARCH_HINT)))).WillOnce(testing::Return(true));114 EXPECT_CALL(reply_, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultTitleMatch(Query::USE_SEARCH_HINT)))).WillOnce(testing::Return(true));
100115
@@ -105,9 +120,10 @@
105120
106TEST_F(TestStoreQuery, ShowsNoResultsHintOnQueryWithNoResults)121TEST_F(TestStoreQuery, ShowsNoResultsHintOnQueryWithNoResults)
107{122{
123 set_container_ready();
108 EXPECT_CALL(reply_, register_category("hint", "", "", testing::_)).WillOnce(testing::Return(category_));124 EXPECT_CALL(reply_, register_category("hint", "", "", testing::_)).WillOnce(testing::Return(category_));
109 EXPECT_CALL(reply_, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultTitleMatch(Query::NO_SEARCH_RESULTS_HINT)))).WillOnce(testing::Return(true));125 EXPECT_CALL(reply_, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultTitleMatch(Query::NO_SEARCH_RESULTS_HINT)))).WillOnce(testing::Return(true));
110 EXPECT_CALL(*service_, search_cache(testing::_)).WillOnce(testing::Return(QList<Package>{}));126 EXPECT_CALL(*service_, search_cache(testing::_)).WillOnce(testing::Return(QList<::libertine::scope::Package>{}));
111 canned_query_.set_query_string("foobar");127 canned_query_.set_query_string("foobar");
112128
113 Query q(canned_query_, metadata_, service_);129 Query q(canned_query_, metadata_, service_);
@@ -117,12 +133,13 @@
117133
118TEST_F(TestStoreQuery, ShowSingleSearchResult)134TEST_F(TestStoreQuery, ShowSingleSearchResult)
119{135{
136 set_container_ready();
120 EXPECT_CALL(reply_, register_category("aptcache", "1 result found", "Application", testing::_)).WillOnce(testing::Return(category_));137 EXPECT_CALL(reply_, register_category("aptcache", "1 result found", "Application", testing::_)).WillOnce(testing::Return(category_));
121138
122 auto package = create_package("vim", "Writin' stuff", "vim.desktop");139 auto package = create_package("vim", "Writin' stuff", "vim.desktop");
123 expect_push("vim", "Writin' stuff", "vim.desktop");140 expect_push("vim", "Writin' stuff", "vim.desktop");
124141
125 EXPECT_CALL(*service_, search_cache(testing::_)).WillOnce(testing::Return(QList<Package>{package}));142 EXPECT_CALL(*service_, search_cache(testing::_)).WillOnce(testing::Return(QList<::libertine::scope::Package>{package}));
126 canned_query_.set_query_string("vim");143 canned_query_.set_query_string("vim");
127144
128 Query q(canned_query_, metadata_, service_);145 Query q(canned_query_, metadata_, service_);
@@ -132,6 +149,7 @@
132149
133TEST_F(TestStoreQuery, ShowMultipleSearchResults)150TEST_F(TestStoreQuery, ShowMultipleSearchResults)
134{151{
152 set_container_ready();
135 EXPECT_CALL(reply_, register_category("aptcache", "3 results found", "Application", testing::_)).WillOnce(testing::Return(category_));153 EXPECT_CALL(reply_, register_category("aptcache", "3 results found", "Application", testing::_)).WillOnce(testing::Return(category_));
136154
137 auto vim = create_package("vim", "Writin' stuff", "vim.desktop");155 auto vim = create_package("vim", "Writin' stuff", "vim.desktop");
@@ -142,7 +160,7 @@
142 expect_push("gedit", "Writin' gui stuff", "gedit.desktop");160 expect_push("gedit", "Writin' gui stuff", "gedit.desktop");
143 expect_push("ed", "Writin' simple stuff", "ed.desktop");161 expect_push("ed", "Writin' simple stuff", "ed.desktop");
144162
145 EXPECT_CALL(*service_, search_cache(testing::_)).WillOnce(testing::Return(QList<Package>{vim, gedit, ed}));163 EXPECT_CALL(*service_, search_cache(testing::_)).WillOnce(testing::Return(QList<::libertine::scope::Package>{vim, gedit, ed}));
146 canned_query_.set_query_string("vim");164 canned_query_.set_query_string("vim");
147165
148 Query q(canned_query_, metadata_, service_);166 Query q(canned_query_, metadata_, service_);
@@ -152,6 +170,7 @@
152170
153TEST_F(TestStoreQuery, FailureToPushEndsQueryPrematurely)171TEST_F(TestStoreQuery, FailureToPushEndsQueryPrematurely)
154{172{
173 set_container_ready();
155 EXPECT_CALL(reply_, register_category("aptcache", "3 results found", "Application", testing::_)).WillOnce(testing::Return(category_));174 EXPECT_CALL(reply_, register_category("aptcache", "3 results found", "Application", testing::_)).WillOnce(testing::Return(category_));
156175
157 auto vim = create_package("vim", "Writin' stuff", "vim.desktop");176 auto vim = create_package("vim", "Writin' stuff", "vim.desktop");
@@ -161,10 +180,21 @@
161 expect_push("vim", "Writin' stuff", "vim.desktop");180 expect_push("vim", "Writin' stuff", "vim.desktop");
162 expect_push("gedit", "Writin' gui stuff", "gedit.desktop", false);181 expect_push("gedit", "Writin' gui stuff", "gedit.desktop", false);
163182
164 EXPECT_CALL(*service_, search_cache(testing::_)).WillOnce(testing::Return(QList<Package>{vim, gedit, ed}));183 EXPECT_CALL(*service_, search_cache(testing::_)).WillOnce(testing::Return(QList<::libertine::scope::Package>{vim, gedit, ed}));
165 canned_query_.set_query_string("vim");184 canned_query_.set_query_string("vim");
166185
167 Query q(canned_query_, metadata_, service_);186 Query q(canned_query_, metadata_, service_);
168 q.run(proxy_);187 q.run(proxy_);
169}188}
189
190
191TEST_F(TestStoreQuery, ShowsCreateCategoryWhenContainerDoesNotExist)
192{
193 set_container_ready(::libertine::scope::Container::ContainerStatus::none);
194 EXPECT_CALL(reply_, register_category("create", "", "", testing::_)).WillOnce(testing::Return(category_));
195 EXPECT_CALL(reply_, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultCreateMatch()))).WillOnce(testing::Return(true));
196
197 Query q(canned_query_, metadata_, service_);
198 q.run(proxy_);
199}
170}200}

Subscribers

People subscribed via source and target branches

to all changes: