1 /*
2  * Copyright (C) 2020 Purism SPC
3  * SPDX-License-Identifier: GPL-3.0+
4  * Author: Guido Günther <agx@sigxcpu.org>
5  */
6 
7 #include "libfeedback.h"
8 #include <gio/gio.h>
9 
10 typedef struct {
11   GTestDBus *dbus;
12 
13 } TestFixture;
14 
15 GMainLoop *mainloop;
16 
17 static void
fixture_setup(TestFixture * fixture,gconstpointer unused)18 fixture_setup (TestFixture *fixture, gconstpointer unused)
19 {
20   g_autoptr (GError) err = NULL;
21   gchar *relative, *servicesdir;
22   gint success;
23 
24   fixture->dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
25   relative = g_test_build_filename (G_TEST_BUILT, "services", NULL);
26   servicesdir = g_canonicalize_filename (relative, NULL);
27   g_free (relative);
28 
29   g_test_dbus_add_service_dir (fixture->dbus, servicesdir);
30   g_free (servicesdir);
31   g_setenv ("FEEDBACK_THEME", TEST_DATA_DIR "/test.json", TRUE);
32   g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
33   g_test_dbus_up (fixture->dbus);
34 
35   g_assert_null (mainloop);
36   mainloop = g_main_loop_new (NULL, FALSE);
37 
38   success = lfb_init (TEST_APP_ID, &err);
39   g_assert_no_error (err);
40   g_assert_true (success);
41 }
42 
43 static void
fixture_teardown(TestFixture * fixture,gconstpointer unused)44 fixture_teardown (TestFixture *fixture, gconstpointer unused)
45 {
46   g_clear_pointer (&mainloop, g_main_loop_unref);
47   lfb_uninit ();
48 
49   g_test_dbus_down (fixture->dbus);
50   g_object_unref (fixture->dbus);
51 }
52 
53 static void
on_feedback_ended(LfbEvent * event,LfbEvent ** cmp)54 on_feedback_ended (LfbEvent *event, LfbEvent **cmp)
55 {
56   g_assert_true (LFB_IS_EVENT (event));
57   g_assert_null (*cmp);
58 
59   g_debug ("Feedback ended for %s: %d",
60 	   lfb_event_get_event (event),
61 	   lfb_event_get_end_reason (event));
62 
63   /* "Return" event */
64   *cmp = event;
65 }
66 
67 static void
test_lfb_integration_event_sync(void)68 test_lfb_integration_event_sync (void)
69 {
70   g_autoptr(LfbEvent) event0 = NULL;
71   g_autoptr(LfbEvent) event1 = NULL;
72   g_autoptr(LfbEvent) event10 = NULL;
73   g_autofree gchar *evname = NULL;
74   g_autoptr (GError) err = NULL;
75   LfbEvent *cmp = NULL;
76   gboolean success;
77 
78   event0 = lfb_event_new ("test-dummy-0");
79   success = lfb_event_trigger_feedback (event0, &err);
80   g_assert_no_error (err);
81   g_assert_true (success);
82 
83   event10 = lfb_event_new ("test-dummy-10");
84   g_signal_connect (event10, "feedback-ended", (GCallback)on_feedback_ended, &cmp);
85   g_signal_connect_swapped (event10, "feedback-ended", (GCallback)g_main_loop_quit, mainloop);
86   success = lfb_event_trigger_feedback (event10, &err);
87   g_assert_no_error (err);
88   g_assert_true (success);
89 
90   success = lfb_event_end_feedback (event10, &err);
91   g_assert_no_error (err);
92   g_assert_true (success);
93 
94   g_main_loop_run (mainloop);
95 
96   /* If the signal fired cmp will match event */
97   g_assert_true (event10 == cmp);
98   g_assert_cmpint (lfb_event_get_state (event10), ==, LFB_EVENT_STATE_ENDED);
99   g_assert_cmpint (lfb_event_get_end_reason (event10), ==, LFB_EVENT_END_REASON_EXPLICIT);
100 }
101 
102 static void
test_lfb_integration_event_not_found(void)103 test_lfb_integration_event_not_found (void)
104 {
105   g_autoptr(LfbEvent) event0 = NULL;
106   g_autofree gchar *evname = NULL;
107   g_autoptr (GError) err = NULL;
108   LfbEvent *cmp = NULL;
109   gboolean success;
110 
111   event0 = lfb_event_new ("test-does-not-exist");
112   g_signal_connect (event0, "feedback-ended", (GCallback)on_feedback_ended, &cmp);
113   g_signal_connect_swapped (event0, "feedback-ended", (GCallback)g_main_loop_quit, mainloop);
114   success = lfb_event_trigger_feedback (event0, &err);
115   g_assert_no_error (err);
116   g_assert_true (success);
117 
118   g_main_loop_run (mainloop);
119 
120   /* If the signal fired cmp will match event */
121   g_assert_true (event0 == cmp);
122   g_assert_cmpint (lfb_event_get_state (event0), ==, LFB_EVENT_STATE_ENDED);
123   g_assert_cmpint (lfb_event_get_end_reason (event0), ==, LFB_EVENT_END_REASON_NOT_FOUND);
124 }
125 
126 static void
on_event_triggered(LfbEvent * event,GAsyncResult * res,LfbEvent ** cmp)127 on_event_triggered (LfbEvent      *event,
128 		    GAsyncResult  *res,
129 		    LfbEvent     **cmp)
130 {
131   g_autoptr (GError) err = NULL;
132   gboolean success;
133 
134   g_assert_true (LFB_IS_EVENT (event));
135   g_assert_null (*cmp);
136 
137   g_debug ("%s: %p, %s", __func__, event, lfb_event_get_event (event));
138   success = lfb_event_trigger_feedback_finish (event, res, &err);
139   g_assert_no_error (err);
140   g_assert_true (success);
141 
142   /* "Return" event */
143   *cmp = event;
144   g_main_loop_quit (mainloop);
145 }
146 
147 static void
on_event_end_finished(LfbEvent * event,GAsyncResult * res,LfbEvent ** cmp)148 on_event_end_finished (LfbEvent      *event,
149                        GAsyncResult  *res,
150                        LfbEvent     **cmp)
151 {
152   g_autoptr (GError) err = NULL;
153   gboolean success;
154 
155   g_debug ("%s: %p, %s", __func__, event, lfb_event_get_event (event));
156   g_assert_true (LFB_IS_EVENT (event));
157   g_assert_null (*cmp);
158 
159   success = lfb_event_end_feedback_finish (event, res, &err);
160   g_assert_no_error (err);
161   g_assert_true (success);
162 
163   /* "Return" event */
164   *cmp = event;
165   g_main_loop_quit (mainloop);
166 }
167 
168 static void
test_lfb_integration_event_async(void)169 test_lfb_integration_event_async (void)
170 {
171   g_autoptr(LfbEvent) event0 = NULL;
172   g_autoptr(LfbEvent) event10 = NULL;
173   g_autofree gchar *evname = NULL;
174   g_autoptr (GError) err = NULL;
175   LfbEvent *cmp1 = NULL, *cmp2 = NULL, *cmp3 = NULL;
176 
177   event0 = lfb_event_new ("test-dummy-0");
178   lfb_event_trigger_feedback_async (event0,
179 				    NULL,
180 				    (GAsyncReadyCallback)on_event_triggered,
181 				    &cmp1);
182   g_main_loop_run (mainloop);
183   /* The async finish callback saw the right event */
184   g_assert_true (event0 == cmp1);
185   cmp1 = NULL;
186 
187   event10 = lfb_event_new ("test-dummy-10");
188   lfb_event_set_timeout (event10, 1);
189   g_assert_cmpint (lfb_event_get_timeout (event10), ==, 1);
190   lfb_event_set_feedback_profile (event10, "quiet");
191   g_signal_connect (event10, "feedback-ended", (GCallback)on_feedback_ended, &cmp1);
192 
193   /* The async callback ends the main loop */
194   lfb_event_trigger_feedback_async (event10,
195 				    NULL,
196 				    (GAsyncReadyCallback)on_event_triggered,
197 				    &cmp2);
198   g_main_loop_run (mainloop);
199 
200   /* The async callback ends the main loop */
201   lfb_event_end_feedback_async (event10,
202 				NULL,
203 				(GAsyncReadyCallback)on_event_end_finished,
204 				&cmp3);
205   g_main_loop_run (mainloop);
206 
207   /* Check if callbacks saw the right event */
208   g_assert_true (event10 == cmp1);
209   g_assert_true (event10 == cmp2);
210   g_assert_true (event10 == cmp3);
211   g_assert_cmpint (lfb_event_get_state (event10), ==, LFB_EVENT_STATE_ENDED);
212   g_assert_cmpint (lfb_event_get_end_reason (event10), ==, LFB_EVENT_END_REASON_EXPLICIT);
213 }
214 
215 
216 static void
on_event_with_error_triggered(LfbEvent * event,GAsyncResult * res,LfbEvent ** cmp)217 on_event_with_error_triggered (LfbEvent      *event,
218 			       GAsyncResult  *res,
219 			       LfbEvent     **cmp)
220 {
221   g_autoptr (GError) err = NULL;
222   gboolean success;
223 
224   g_debug ("%s: %p, %s", __func__, event, lfb_event_get_event (event));
225   g_assert_true (LFB_IS_EVENT (event));
226   g_assert_null (*cmp);
227 
228   success = lfb_event_end_feedback_finish (event, res, &err);
229   g_assert_false (success);
230   g_assert_error (err, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS);
231 
232   /* "Return" event */
233   *cmp = event;
234   g_main_loop_quit (mainloop);
235 }
236 
237 
238 static void
test_lfb_integration_event_async_error(void)239 test_lfb_integration_event_async_error (void)
240 {
241   g_autoptr(LfbEvent) event0 = NULL;
242   LfbEvent *cmp1 = NULL;
243 
244   /* Empty event names are invalid */
245   event0 = lfb_event_new ("");
246   lfb_event_trigger_feedback_async (event0,
247 				    NULL,
248 				    (GAsyncReadyCallback)on_event_with_error_triggered,
249 				    &cmp1);
250   g_main_loop_run (mainloop);
251   /* The async finish callback saw the right event */
252   g_assert_true (event0 == cmp1);
253 }
254 
255 
256 static void
on_profile_changed(LfbGdbusFeedback * proxy,GParamSpec * psepc,const gchar ** profile)257 on_profile_changed (LfbGdbusFeedback *proxy, GParamSpec *psepc, const gchar **profile)
258 {
259   g_assert_null (*profile);
260   *profile = lfb_get_feedback_profile();
261   g_debug("Set feedback profile to: '%s'", *profile);
262 
263   g_main_loop_quit (mainloop);
264 }
265 
266 static void
test_lfb_integration_profile(void)267 test_lfb_integration_profile (void)
268 {
269   g_autoptr (GError) err = NULL;
270   LfbGdbusFeedback *proxy;
271   gchar *cmp = NULL;
272 
273   g_assert_cmpstr (lfb_get_feedback_profile (), ==, "full");
274   proxy = lfb_get_proxy ();
275   g_assert_nonnull (proxy);
276 
277   lfb_set_feedback_profile ("quiet");
278   g_signal_connect (proxy, "notify::profile", (GCallback)on_profile_changed, &cmp);
279   g_main_loop_run (mainloop);
280   g_assert_cmpstr (lfb_get_feedback_profile (), ==, "quiet");
281   g_assert_cmpstr (cmp, ==, "quiet");
282 }
283 
284 gint
main(gint argc,gchar * argv[])285 main (gint argc, gchar *argv[])
286 {
287   g_test_init (&argc, &argv, NULL);
288 
289   g_test_add("/feedbackd/lfb-integration/event_sync", TestFixture, NULL,
290 	     (gpointer)fixture_setup,
291 	     (gpointer)test_lfb_integration_event_sync,
292 	     (gpointer)fixture_teardown);
293 
294   g_test_add("/feedbackd/lfb-integration/event_async/success", TestFixture, NULL,
295 	     (gpointer)fixture_setup,
296 	     (gpointer)test_lfb_integration_event_async,
297 	     (gpointer)fixture_teardown);
298 
299   g_test_add("/feedbackd/lfb-integration/event_async/error", TestFixture, NULL,
300 	     (gpointer)fixture_setup,
301 	     (gpointer)test_lfb_integration_event_async_error,
302 	     (gpointer)fixture_teardown);
303 
304   g_test_add("/feedbackd/lfb-integration/event_not_found", TestFixture, NULL,
305 	     (gpointer)fixture_setup,
306 	     (gpointer)test_lfb_integration_event_not_found,
307 	     (gpointer)fixture_teardown);
308 
309   g_test_add("/feedbackd/lfb-integration/profile", TestFixture, NULL,
310 	     (gpointer)fixture_setup,
311 	     (gpointer)test_lfb_integration_profile,
312 	     (gpointer)fixture_teardown);
313 
314   return g_test_run();
315 }
316