2
* Copyright 2014 Canonical Ltd.
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.
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.
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/>.
17
* Charles Kerr <charles.kerr@canonical.com>
20
#include "glib-fixture.h"
21
#include "controller-mock.h"
22
#include "world-mock.h"
24
#include <transfer/dbus-shared.h>
25
#include <transfer/view-gmenu.h>
28
using namespace unity::indicator::transfer;
30
class GMenuViewFixture: public GlibFixture
33
typedef GlibFixture super;
37
GTestDBus* bus = nullptr;
38
std::shared_ptr<MockWorld> m_world;
39
std::shared_ptr<MutableModel> m_model;
40
std::shared_ptr<MockController> m_controller;
41
std::shared_ptr<GMenuView> m_view;
47
// bring up the test bus
48
bus = g_test_dbus_new(G_TEST_DBUS_NONE);
50
const auto address = g_test_dbus_get_bus_address(bus);
51
g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, true);
52
g_setenv("DBUS_SESSION_BUS_ADDRESS", address, true);
55
m_world.reset(new MockWorld);
56
m_model.reset(new MutableModel);
57
std::shared_ptr<Transfer> t;
58
t.reset(new Transfer);
60
t->state = Transfer::RUNNING;
62
t.reset(new Transfer);
64
t->state = Transfer::PAUSED;
66
t.reset(new Transfer);
68
t->state = Transfer::FINISHED;
70
m_controller.reset(new MockController(m_model, m_world));
71
m_view.reset(new GMenuView(m_model, m_controller));
83
GError * error = nullptr;
84
GDBusConnection* connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, &error);
85
if(!g_dbus_connection_is_closed(connection))
86
g_dbus_connection_close_sync(connection, nullptr, &error);
87
g_assert_no_error(error);
88
g_clear_object(&connection);
89
g_test_dbus_down(bus);
101
* These two are more about testing the scaffolding.
102
* If the objects listening to the bus don't all get
103
* torn down correctly, the second time we setup the
104
* fixture we'll see glib errors
107
TEST_F(GMenuViewFixture, CanFixtureSetupOnce)
109
g_timeout_add_seconds(1, [](gpointer g){
110
g_main_loop_quit(static_cast<GMainLoop*>(g));
111
return G_SOURCE_REMOVE;
113
g_main_loop_run(loop);
116
TEST_F(GMenuViewFixture, CanFixtureSetupTwice)
118
g_timeout_add_seconds(1, [](gpointer g){
119
g_main_loop_quit(static_cast<GMainLoop*>(g));
120
return G_SOURCE_REMOVE;
122
g_main_loop_run(loop);
131
/* Make sure all the actions we expect are there */
132
TEST_F(GMenuViewFixture, ExportedActions)
136
// these are the actions we expect to find
137
const std::set<std::string> expected_actions {
151
auto connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
152
auto exported = g_dbus_action_group_get(connection, BUS_NAME, BUS_PATH);
153
auto names_strv = g_action_group_list_actions(G_ACTION_GROUP(exported));
155
// wait for the exported ActionGroup to be populated
156
if (g_strv_length(names_strv) == 0)
158
g_strfreev(names_strv);
159
wait_for_signal(exported, "action-added");
160
names_strv = g_action_group_list_actions(G_ACTION_GROUP(exported));
163
// convert it to a std::set for easy prodding
164
std::set<std::string> actions;
165
for(int i=0; names_strv && names_strv[i]; i++)
166
actions.insert(names_strv[i]);
168
EXPECT_EQ(expected_actions, actions);
170
// try closing the connection prematurely
171
// to test Exporter's name-lost signal
172
bool name_lost = false;
173
m_view->name_lost().connect([this,&name_lost](){
175
g_main_loop_quit(loop);
177
g_dbus_connection_close_sync(connection, nullptr, nullptr);
178
g_main_loop_run(loop);
179
EXPECT_TRUE(name_lost);
182
g_strfreev(names_strv);
183
g_clear_object(&exported);
184
g_clear_object(&connection);
187
TEST_F(GMenuViewFixture, InvokedGActionsCallTheController)
190
auto connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
191
auto dbus_action_group = g_dbus_action_group_get(connection, BUS_NAME, BUS_PATH);
192
auto action_group = G_ACTION_GROUP(dbus_action_group);
194
// wait for the exported ActionGroup to be populated
195
auto names_strv = g_action_group_list_actions(action_group);
196
if (g_strv_length(names_strv) == 0)
198
g_strfreev(names_strv);
199
wait_for_signal(dbus_action_group, "action-added");
200
names_strv = g_action_group_list_actions(action_group);
202
g_strfreev(names_strv);
204
// try tapping a transfer that can be resumed
205
const char* id = "b";
206
EXPECT_TRUE(m_model->get(id)->can_resume());
207
EXPECT_CALL(*m_controller, tap(id)).Times(1);
208
g_action_group_activate_action(action_group, "activate-transfer", g_variant_new_string(id));
211
// try tapping a transfer that CAN'T be resumed
213
EXPECT_TRUE(!m_model->get(id)->can_resume());
214
EXPECT_CALL(*m_controller, tap(id)).Times(1);
215
g_action_group_activate_action(action_group, "activate-transfer", g_variant_new_string(id));
218
// try cancelling a transfer
220
EXPECT_CALL(*m_controller, cancel(id)).Times(1);
221
g_action_group_activate_action(action_group, "cancel-transfer", g_variant_new_string(id));
224
// try opening a transfer
226
EXPECT_CALL(*m_controller, open(id)).Times(1);
227
g_action_group_activate_action(action_group, "open-transfer", g_variant_new_string(id));
230
// try opening a transfer's recipient's app
232
EXPECT_CALL(*m_controller, open_app(id)).Times(1);
233
g_action_group_activate_action(action_group, "open-app-transfer", g_variant_new_string(id));
236
// try calling clear-all
237
EXPECT_CALL(*m_controller, clear_all()).Times(1);
238
g_action_group_activate_action(action_group, "clear-all", nullptr);
241
// try pausing a transfer
243
EXPECT_CALL(*m_controller, pause(id)).Times(1);
244
g_action_group_activate_action(action_group, "pause-transfer", g_variant_new_string(id));
247
// try calling pause-all
248
EXPECT_CALL(*m_controller, pause_all()).Times(1);
249
g_action_group_activate_action(action_group, "pause-all", nullptr);
252
// try calling resume-all
253
EXPECT_CALL(*m_controller, resume_all()).Times(1);
254
g_action_group_activate_action(action_group, "resume-all", nullptr);
257
// try resuming a transfer
259
EXPECT_CALL(*m_controller, resume(id)).Times(1);
260
g_action_group_activate_action(action_group, "resume-transfer", g_variant_new_string(id));
264
g_clear_object(&dbus_action_group);
265
g_clear_object(&connection);
274
TEST_F(GMenuViewFixture, DoesExportMenu)
278
auto connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
279
auto dbus_menu_model = g_dbus_menu_model_get(connection, BUS_NAME, BUS_PATH"/phone");
280
auto menu_model = G_MENU_MODEL(dbus_menu_model);
282
// query the GDBusMenuModel for information to activate it
283
int n = g_menu_model_get_n_items(menu_model);
286
// give the model a moment to populate its info
288
n = g_menu_model_get_n_items(menu_model);
291
EXPECT_TRUE(menu_model != nullptr);
295
g_clear_object(&dbus_menu_model);
296
g_clear_object(&connection);