1 /*
2 * Copyright © 2013 Lars Uebernickel
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors: Lars Uebernickel <lars@uebernic.de>
20 */
21
22 #include <glib.h>
23
24 #include "gnotification-server.h"
25 #include "gdbus-sessionbus.h"
26
27 static void
28 activate_app (GApplication *application,
29 gpointer user_data)
30 {
31 GNotification *notification;
32 GIcon *icon;
33
34 notification = g_notification_new ("Test");
35
36 g_application_send_notification (application, "test1", notification);
37 g_application_send_notification (application, "test2", notification);
38 g_application_withdraw_notification (application, "test1");
39 g_application_send_notification (application, "test3", notification);
40
41 icon = g_themed_icon_new ("i-c-o-n");
42 g_notification_set_icon (notification, icon);
43 g_object_unref (icon);
44
45 g_notification_set_body (notification, "body");
46 g_notification_set_priority (notification, G_NOTIFICATION_PRIORITY_URGENT);
47 g_notification_set_default_action_and_target (notification, "app.action", "i", 42);
48 g_notification_add_button_with_target (notification, "label", "app.action2", "s", "bla");
49
50 g_application_send_notification (application, "test4", notification);
51 g_application_send_notification (application, NULL, notification);
52
53 g_dbus_connection_flush_sync (g_application_get_dbus_connection (application), NULL, NULL);
54
55 g_object_unref (notification);
56 }
57
58 static void
59 notification_received (GNotificationServer *server,
60 const gchar *app_id,
61 const gchar *notification_id,
62 GVariant *notification,
63 gpointer user_data)
64 {
65 gint *count = user_data;
66 const gchar *title;
67
68 g_assert_cmpstr (app_id, ==, "org.gtk.TestApplication");
69
70 switch (*count)
71 {
72 case 0:
73 g_assert_cmpstr (notification_id, ==, "test1");
74 g_assert (g_variant_lookup (notification, "title", "&s", &title));
75 g_assert_cmpstr (title, ==, "Test");
76 break;
77
78 case 1:
79 g_assert_cmpstr (notification_id, ==, "test2");
80 break;
81
82 case 2:
83 g_assert_cmpstr (notification_id, ==, "test3");
84 break;
85
86 case 3:
87 g_assert_cmpstr (notification_id, ==, "test4");
88 break;
89
90 case 4:
91 g_assert (g_dbus_is_guid (notification_id));
92
93 g_notification_server_stop (server);
94 break;
95 }
96
97 (*count)++;
98 }
99
100 static void
101 notification_removed (GNotificationServer *server,
102 const gchar *app_id,
103 const gchar *notification_id,
104 gpointer user_data)
105 {
106 gint *count = user_data;
107
108 g_assert_cmpstr (app_id, ==, "org.gtk.TestApplication");
109 g_assert_cmpstr (notification_id, ==, "test1");
110
111 (*count)++;
112 }
113
114 static void
115 server_notify_is_running (GObject *object,
116 GParamSpec *pspec,
117 gpointer user_data)
118 {
119 GMainLoop *loop = user_data;
120 GNotificationServer *server = G_NOTIFICATION_SERVER (object);
121
122 if (g_notification_server_get_is_running (server))
123 {
124 GApplication *app;
125
126 app = g_application_new ("org.gtk.TestApplication", G_APPLICATION_DEFAULT_FLAGS);
127 g_signal_connect (app, "activate", G_CALLBACK (activate_app), NULL);
128
129 g_application_run (app, 0, NULL);
130
131 g_object_unref (app);
132 }
133 else
134 {
135 g_main_loop_quit (loop);
136 }
137 }
138
139 static void
140 basic (void)
141 {
142 GNotificationServer *server;
143 GMainLoop *loop;
144 gint received_count = 0;
145 gint removed_count = 0;
146
147 session_bus_up ();
148
149 loop = g_main_loop_new (NULL, FALSE);
150
151 server = g_notification_server_new ();
152 g_signal_connect (server, "notification-received", G_CALLBACK (notification_received), &received_count);
153 g_signal_connect (server, "notification-removed", G_CALLBACK (notification_removed), &removed_count);
154 g_signal_connect (server, "notify::is-running", G_CALLBACK (server_notify_is_running), loop);
155
156 g_main_loop_run (loop);
157
158 g_assert_cmpint (received_count, ==, 5);
159 g_assert_cmpint (removed_count, ==, 1);
160
161 g_object_unref (server);
162 g_main_loop_unref (loop);
163 session_bus_stop ();
164 }
165
166 struct _GNotification
167 {
168 GObject parent;
169
170 gchar *title;
171 gchar *body;
172 GIcon *icon;
173 GNotificationPriority priority;
174 gchar *category;
175 GPtrArray *buttons;
176 gchar *default_action;
177 GVariant *default_action_target;
178 };
179
180 typedef struct
181 {
182 gchar *label;
183 gchar *action_name;
184 GVariant *target;
185 } Button;
186
187 static void
188 test_properties (void)
189 {
190 GNotification *n;
191 struct _GNotification *rn;
192 GIcon *icon;
193 const gchar * const *names;
194 Button *b;
195
196 n = g_notification_new ("Test");
197
198 g_notification_set_title (n, "title");
199 g_notification_set_body (n, "body");
200 g_notification_set_category (n, "cate.gory");
201 icon = g_themed_icon_new ("i-c-o-n");
202 g_notification_set_icon (n, icon);
203 g_object_unref (icon);
204 g_notification_set_priority (n, G_NOTIFICATION_PRIORITY_HIGH);
205 g_notification_set_category (n, "cate.gory");
206 g_notification_add_button (n, "label1", "app.action1::target1");
207 g_notification_set_default_action (n, "app.action2::target2");
208
209 rn = (struct _GNotification *)n;
210
211 g_assert_cmpstr (rn->title, ==, "title");
212 g_assert_cmpstr (rn->body, ==, "body");
213 g_assert (G_IS_THEMED_ICON (rn->icon));
214 names = g_themed_icon_get_names (G_THEMED_ICON (rn->icon));
215 g_assert_cmpstr (names[0], ==, "i-c-o-n");
216 g_assert_cmpstr (names[1], ==, "i-c-o-n-symbolic");
217 g_assert_null (names[2]);
218 g_assert (rn->priority == G_NOTIFICATION_PRIORITY_HIGH);
219 g_assert_cmpstr (rn->category, ==, "cate.gory");
220
221 g_assert_cmpint (rn->buttons->len, ==, 1);
222 b = (Button*)rn->buttons->pdata[0];
223 g_assert_cmpstr (b->label, ==, "label1");
224 g_assert_cmpstr (b->action_name, ==, "app.action1");
225 g_assert_cmpstr (g_variant_get_string (b->target, NULL), ==, "target1");
226
227 g_assert_cmpstr (rn->default_action, ==, "app.action2");
228 g_assert_cmpstr (g_variant_get_string (rn->default_action_target, NULL), ==, "target2");
229
230 g_object_unref (n);
231 }
232
233 int main (int argc, char *argv[])
234 {
235 g_test_init (&argc, &argv, NULL);
236
237 g_test_add_func ("/gnotification/basic", basic);
238 g_test_add_func ("/gnotification/properties", test_properties);
239
240 return g_test_run ();
241 }