~xavi-garcia-mena/indicator-sound/icon-volume-zero

« back to all changes in this revision

Viewing changes to tests/notifications-test.cc

  • Committer: CI Train Bot
  • Author(s): Ted Gould
  • Date: 2015-02-19 16:27:24 UTC
  • mfrom: (473.2.46 notification-mock)
  • Revision ID: ci-train-bot@canonical.com-20150219162724-yzhx9ev7503vwqow
Add notifications mock and tests
Approved by: Jussi Pakkanen, PS Jenkins bot

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2015 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 as published by
 
6
 * the Free Software Foundation; version 3.
 
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
 * Authors:
 
17
 *      Ted Gould <ted@canonical.com>
 
18
 */
 
19
 
 
20
#include <memory>
 
21
 
 
22
#include <gtest/gtest.h>
 
23
#include <gio/gio.h>
 
24
#include <libdbustest/dbus-test.h>
 
25
#include <libnotify/notify.h>
 
26
 
 
27
#include "notifications-mock.h"
 
28
#include "gtest-gvariant.h"
 
29
 
 
30
extern "C" {
 
31
#include "indicator-sound-service.h"
 
32
#include "vala-mocks.h"
 
33
}
 
34
 
 
35
class NotificationsTest : public ::testing::Test
 
36
{
 
37
        protected:
 
38
                DbusTestService * service = NULL;
 
39
 
 
40
                GDBusConnection * session = NULL;
 
41
                std::shared_ptr<NotificationsMock> notifications;
 
42
 
 
43
                virtual void SetUp() {
 
44
                        g_setenv("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, TRUE);
 
45
                        g_setenv("GSETTINGS_BACKEND", "memory", TRUE);
 
46
 
 
47
                        service = dbus_test_service_new(NULL);
 
48
                        dbus_test_service_set_bus(service, DBUS_TEST_SERVICE_BUS_SESSION);
 
49
 
 
50
                        /* Useful for debugging test failures, not needed all the time (until it fails) */
 
51
                        #if 0
 
52
                        auto bustle = std::shared_ptr<DbusTestTask>([]() {
 
53
                                DbusTestTask * bustle = DBUS_TEST_TASK(dbus_test_bustle_new("notifications-test.bustle"));
 
54
                                dbus_test_task_set_name(bustle, "Bustle");
 
55
                                dbus_test_task_set_bus(bustle, DBUS_TEST_SERVICE_BUS_SESSION);
 
56
                                return bustle;
 
57
                        }(), [](DbusTestTask * bustle) {
 
58
                                g_clear_object(&bustle);
 
59
                        });
 
60
                        dbus_test_service_add_task(service, bustle.get());
 
61
                        #endif
 
62
 
 
63
                        notifications = std::make_shared<NotificationsMock>();
 
64
 
 
65
                        dbus_test_service_add_task(service, (DbusTestTask*)*notifications);
 
66
                        dbus_test_service_start_tasks(service);
 
67
 
 
68
                        session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
 
69
                        ASSERT_NE(nullptr, session);
 
70
                        g_dbus_connection_set_exit_on_close(session, FALSE);
 
71
                        g_object_add_weak_pointer(G_OBJECT(session), (gpointer *)&session);
 
72
 
 
73
                        /* This is done in main.c */
 
74
                        notify_init("indicator-sound");
 
75
                }
 
76
 
 
77
                virtual void TearDown() {
 
78
                        if (notify_is_initted())
 
79
                                notify_uninit();
 
80
 
 
81
                        notifications.reset();
 
82
                        g_clear_object(&service);
 
83
 
 
84
                        g_object_unref(session);
 
85
 
 
86
                        unsigned int cleartry = 0;
 
87
                        while (session != NULL && cleartry < 100) {
 
88
                                loop(100);
 
89
                                cleartry++;
 
90
                        }
 
91
 
 
92
                        ASSERT_EQ(nullptr, session);
 
93
                }
 
94
 
 
95
                static gboolean timeout_cb (gpointer user_data) {
 
96
                        GMainLoop * loop = static_cast<GMainLoop *>(user_data);
 
97
                        g_main_loop_quit(loop);
 
98
                        return G_SOURCE_REMOVE;
 
99
                }
 
100
 
 
101
                void loop (unsigned int ms) {
 
102
                        GMainLoop * loop = g_main_loop_new(NULL, FALSE);
 
103
                        g_timeout_add(ms, timeout_cb, loop);
 
104
                        g_main_loop_run(loop);
 
105
                        g_main_loop_unref(loop);
 
106
                }
 
107
 
 
108
                static int unref_idle (gpointer user_data) {
 
109
                        g_variant_unref(static_cast<GVariant *>(user_data));
 
110
                        return G_SOURCE_REMOVE;
 
111
                }
 
112
 
 
113
                std::shared_ptr<MediaPlayerList> playerListMock () {
 
114
                        auto playerList = std::shared_ptr<MediaPlayerList>(
 
115
                                MEDIA_PLAYER_LIST(media_player_list_mock_new()),
 
116
                                [](MediaPlayerList * list) {
 
117
                                        g_clear_object(&list);
 
118
                                });
 
119
                        return playerList;
 
120
                }
 
121
 
 
122
                std::shared_ptr<VolumeControl> volumeControlMock () {
 
123
                        auto volumeControl = std::shared_ptr<VolumeControl>(
 
124
                                VOLUME_CONTROL(volume_control_mock_new()),
 
125
                                [](VolumeControl * control){
 
126
                                        g_clear_object(&control);
 
127
                                });
 
128
                        return volumeControl;
 
129
                }
 
130
 
 
131
                std::shared_ptr<IndicatorSoundService> standardService (std::shared_ptr<VolumeControl> volumeControl, std::shared_ptr<MediaPlayerList> playerList) {
 
132
                        auto soundService = std::shared_ptr<IndicatorSoundService>(
 
133
                                indicator_sound_service_new(playerList.get(), volumeControl.get(), nullptr),
 
134
                                [](IndicatorSoundService * service){
 
135
                                        g_clear_object(&service);
 
136
                                });
 
137
 
 
138
                        return soundService;
 
139
                }
 
140
};
 
141
 
 
142
TEST_F(NotificationsTest, BasicObject) {
 
143
        auto soundService = standardService(volumeControlMock(), playerListMock());
 
144
 
 
145
        /* Give some time settle */
 
146
        loop(50);
 
147
 
 
148
        /* Auto free */
 
149
}
 
150
 
 
151
TEST_F(NotificationsTest, VolumeChanges) {
 
152
        auto volumeControl = volumeControlMock();
 
153
        auto soundService = standardService(volumeControl, playerListMock());
 
154
 
 
155
        /* Set a volume */
 
156
        notifications->clearNotifications();
 
157
        volume_control_set_volume(volumeControl.get(), 0.50);
 
158
        loop(50);
 
159
        auto notev = notifications->getNotifications();
 
160
        ASSERT_EQ(1, notev.size());
 
161
        EXPECT_EQ("indicator-sound", notev[0].app_name);
 
162
        EXPECT_EQ("Volume", notev[0].summary);
 
163
        EXPECT_EQ(0, notev[0].actions.size());
 
164
        EXPECT_GVARIANT_EQ("@s 'true'", notev[0].hints["x-canonical-private-synchronous"]);
 
165
        EXPECT_GVARIANT_EQ("@i 50", notev[0].hints["value"]);
 
166
 
 
167
        /* Set a different volume */
 
168
        notifications->clearNotifications();
 
169
        volume_control_set_volume(volumeControl.get(), 0.60);
 
170
        loop(50);
 
171
        notev = notifications->getNotifications();
 
172
        ASSERT_EQ(1, notev.size());
 
173
        EXPECT_GVARIANT_EQ("@i 60", notev[0].hints["value"]);
 
174
 
 
175
        /* Set the same volume */
 
176
        notifications->clearNotifications();
 
177
        volume_control_set_volume(volumeControl.get(), 0.60);
 
178
        loop(50);
 
179
        notev = notifications->getNotifications();
 
180
        ASSERT_EQ(0, notev.size());
 
181
 
 
182
        /* Change just a little */
 
183
        notifications->clearNotifications();
 
184
        volume_control_set_volume(volumeControl.get(), 0.60001);
 
185
        loop(50);
 
186
        notev = notifications->getNotifications();
 
187
        ASSERT_EQ(0, notev.size());
 
188
}
 
189
 
 
190
TEST_F(NotificationsTest, StreamChanges) {
 
191
        auto volumeControl = volumeControlMock();
 
192
        auto soundService = standardService(volumeControl, playerListMock());
 
193
 
 
194
        /* Set a volume */
 
195
        notifications->clearNotifications();
 
196
        volume_control_set_volume(volumeControl.get(), 0.5);
 
197
        loop(50);
 
198
        auto notev = notifications->getNotifications();
 
199
        ASSERT_EQ(1, notev.size());
 
200
 
 
201
        /* Change Streams, no volume change */
 
202
        notifications->clearNotifications();
 
203
        volume_control_mock_set_mock_stream(VOLUME_CONTROL_MOCK(volumeControl.get()), "alarm");
 
204
        volume_control_set_volume(volumeControl.get(), 0.5);
 
205
        loop(50);
 
206
        notev = notifications->getNotifications();
 
207
        EXPECT_EQ(0, notev.size());
 
208
 
 
209
        /* Change Streams, volume change */
 
210
        notifications->clearNotifications();
 
211
        volume_control_mock_set_mock_stream(VOLUME_CONTROL_MOCK(volumeControl.get()), "alert");
 
212
        volume_control_set_volume(volumeControl.get(), 0.60);
 
213
        loop(50);
 
214
        notev = notifications->getNotifications();
 
215
        EXPECT_EQ(0, notev.size());
 
216
 
 
217
        /* Change Streams, no volume change, volume up */
 
218
        notifications->clearNotifications();
 
219
        volume_control_mock_set_mock_stream(VOLUME_CONTROL_MOCK(volumeControl.get()), "multimedia");
 
220
        volume_control_set_volume(volumeControl.get(), 0.60);
 
221
        loop(50);
 
222
        volume_control_set_volume(volumeControl.get(), 0.65);
 
223
        notev = notifications->getNotifications();
 
224
        EXPECT_EQ(1, notev.size());
 
225
        EXPECT_GVARIANT_EQ("@i 65", notev[0].hints["value"]);
 
226
}
 
227
 
 
228
TEST_F(NotificationsTest, IconTesting) {
 
229
        auto volumeControl = volumeControlMock();
 
230
        auto soundService = standardService(volumeControl, playerListMock());
 
231
 
 
232
        /* Set an initial volume */
 
233
        notifications->clearNotifications();
 
234
        volume_control_set_volume(volumeControl.get(), 0.5);
 
235
        loop(50);
 
236
        auto notev = notifications->getNotifications();
 
237
        ASSERT_EQ(1, notev.size());
 
238
 
 
239
        /* Generate a set of notifications */
 
240
        notifications->clearNotifications();
 
241
        for (float i = 0.0; i < 1.01; i += 0.1) {
 
242
                volume_control_set_volume(volumeControl.get(), i);
 
243
        }
 
244
 
 
245
        loop(50);
 
246
        notev = notifications->getNotifications();
 
247
        ASSERT_EQ(11, notev.size());
 
248
 
 
249
        EXPECT_EQ("audio-volume-muted",  notev[0].app_icon);
 
250
        EXPECT_EQ("audio-volume-low",    notev[1].app_icon);
 
251
        EXPECT_EQ("audio-volume-low",    notev[2].app_icon);
 
252
        EXPECT_EQ("audio-volume-medium", notev[3].app_icon);
 
253
        EXPECT_EQ("audio-volume-medium", notev[4].app_icon);
 
254
        EXPECT_EQ("audio-volume-medium", notev[5].app_icon);
 
255
        EXPECT_EQ("audio-volume-medium", notev[6].app_icon);
 
256
        EXPECT_EQ("audio-volume-high",   notev[7].app_icon);
 
257
        EXPECT_EQ("audio-volume-high",   notev[8].app_icon);
 
258
        EXPECT_EQ("audio-volume-high",   notev[9].app_icon);
 
259
        EXPECT_EQ("audio-volume-high",   notev[10].app_icon);
 
260
}
 
261
 
 
262
TEST_F(NotificationsTest, ServerRestart) {
 
263
        auto volumeControl = volumeControlMock();
 
264
        auto soundService = standardService(volumeControl, playerListMock());
 
265
 
 
266
        /* Set a volume */
 
267
        notifications->clearNotifications();
 
268
        volume_control_set_volume(volumeControl.get(), 0.50);
 
269
        loop(50);
 
270
        auto notev = notifications->getNotifications();
 
271
        ASSERT_EQ(1, notev.size());
 
272
 
 
273
        /* Restart server without sync notifications */
 
274
        notifications->clearNotifications();
 
275
        dbus_test_service_remove_task(service, (DbusTestTask*)*notifications);
 
276
        notifications.reset();
 
277
 
 
278
        loop(50);
 
279
 
 
280
        notifications = std::make_shared<NotificationsMock>(std::vector<std::string>({"body", "body-markup", "icon-static"}));
 
281
        dbus_test_service_add_task(service, (DbusTestTask*)*notifications);
 
282
        dbus_test_task_run((DbusTestTask*)*notifications);
 
283
 
 
284
        /* Change the volume */
 
285
        notifications->clearNotifications();
 
286
        volume_control_set_volume(volumeControl.get(), 0.60);
 
287
        loop(50);
 
288
        notev = notifications->getNotifications();
 
289
        ASSERT_EQ(0, notev.size());
 
290
 
 
291
        /* Put a good server back */
 
292
        dbus_test_service_remove_task(service, (DbusTestTask*)*notifications);
 
293
        notifications.reset();
 
294
 
 
295
        loop(50);
 
296
 
 
297
        notifications = std::make_shared<NotificationsMock>();
 
298
        dbus_test_service_add_task(service, (DbusTestTask*)*notifications);
 
299
        dbus_test_task_run((DbusTestTask*)*notifications);
 
300
 
 
301
        /* Change the volume again */
 
302
        notifications->clearNotifications();
 
303
        volume_control_set_volume(volumeControl.get(), 0.70);
 
304
        loop(50);
 
305
        notev = notifications->getNotifications();
 
306
        ASSERT_EQ(1, notev.size());
 
307
}
 
308
 
 
309
TEST_F(NotificationsTest, HighVolume) {
 
310
        auto volumeControl = volumeControlMock();
 
311
        auto soundService = standardService(volumeControl, playerListMock());
 
312
 
 
313
        /* Set a volume */
 
314
        notifications->clearNotifications();
 
315
        volume_control_set_volume(volumeControl.get(), 0.50);
 
316
        loop(50);
 
317
        auto notev = notifications->getNotifications();
 
318
        ASSERT_EQ(1, notev.size());
 
319
        EXPECT_EQ("Volume", notev[0].summary);
 
320
        EXPECT_EQ("", notev[0].body);
 
321
        EXPECT_GVARIANT_EQ("@s 'false'", notev[0].hints["x-canonical-value-bar-tint"]);
 
322
 
 
323
        /* Set high volume with volume change */
 
324
        notifications->clearNotifications();
 
325
        volume_control_mock_set_mock_high_volume(VOLUME_CONTROL_MOCK(volumeControl.get()), TRUE);
 
326
        volume_control_set_volume(volumeControl.get(), 0.90);
 
327
        loop(50);
 
328
        notev = notifications->getNotifications();
 
329
        ASSERT_LT(0, notev.size()); /* This passes with one or two since it would just be an update to the first if a second was sent */
 
330
        EXPECT_EQ("Volume", notev[0].summary);
 
331
        EXPECT_EQ("High volume", notev[0].body);
 
332
        EXPECT_GVARIANT_EQ("@s 'true'", notev[0].hints["x-canonical-value-bar-tint"]);
 
333
 
 
334
        /* Move it back */
 
335
        volume_control_mock_set_mock_high_volume(VOLUME_CONTROL_MOCK(volumeControl.get()), FALSE);
 
336
        volume_control_set_volume(volumeControl.get(), 0.50);
 
337
        loop(50);
 
338
 
 
339
        /* Set high volume without level change */
 
340
        /* NOTE: This can happen if headphones are plugged in */
 
341
        notifications->clearNotifications();
 
342
        volume_control_mock_set_mock_high_volume(VOLUME_CONTROL_MOCK(volumeControl.get()), TRUE);
 
343
        loop(50);
 
344
        notev = notifications->getNotifications();
 
345
        ASSERT_EQ(1, notev.size());
 
346
        EXPECT_EQ("Volume", notev[0].summary);
 
347
        EXPECT_EQ("High volume", notev[0].body);
 
348
        EXPECT_GVARIANT_EQ("@s 'true'", notev[0].hints["x-canonical-value-bar-tint"]);
 
349
}