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