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