Branch data Line data Source code
1 : : /* Unit tests for gdocumentportal
2 : : * GIO - GLib Input, Output and Streaming Library
3 : : *
4 : : * Copyright (C) 2025 Marco Trevisan
5 : : *
6 : : * SPDX-License-Identifier: LGPL-2.1-or-later
7 : : *
8 : : * This library is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU Lesser General Public
10 : : * License as published by the Free Software Foundation; either
11 : : * version 2.1 of the License, or (at your option) any later version.
12 : : *
13 : : * This library is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : : * Lesser General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU Lesser General
19 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 : : *
21 : : * Author: Marco Trevisan <marco.trevisan@canonical.com>
22 : : */
23 : :
24 : : #include <gio/gio.h>
25 : :
26 : : #include "gdbus-sessionbus.h"
27 : : #include "fake-document-portal.h"
28 : : #include "gdocumentportal.h"
29 : :
30 : : /* Returns TRUE and calls g_test_skip() if g_unix_fd_query_path() is not
31 : : * supported on this platform (e.g. Hurd). Tests that depend on the fake
32 : : * document portal being able to resolve fd paths should call this and
33 : : * return early if it returns TRUE. */
34 : : static gboolean
35 : 3 : skip_if_fd_query_path_unsupported (void)
36 : : {
37 : : #ifdef __GNU__
38 : : g_test_skip ("g_unix_fd_query_path() not supported on Hurd");
39 : : return TRUE;
40 : : #else
41 : 3 : return FALSE;
42 : : #endif
43 : : }
44 : :
45 : : static void
46 : 1 : test_document_portal_add_uri (void)
47 : : {
48 : 1 : if (skip_if_fd_query_path_unsupported ())
49 : 0 : return;
50 : :
51 : 1 : GFakeDocumentPortalThread *thread = NULL;
52 : : GFile *file;
53 : 1 : GList *uris = NULL; /* (element-type utf8) */
54 : 1 : GList *portal_uris = NULL; /* (element-type utf8) */
55 : 1 : GFileIOStream *iostream = NULL;
56 : 1 : GError *error = NULL;
57 : : const char *app_id;
58 : : const char *document_portal_mount_point;
59 : : char *basename;
60 : : char *expected_uri;
61 : :
62 : : /* Run a fake-document-portal */
63 : 1 : app_id = "org.gnome.glib.gio";
64 : 1 : thread = g_fake_document_portal_thread_new (session_bus_get_address (), app_id);
65 : 1 : g_fake_document_portal_thread_run (thread);
66 : 1 : document_portal_mount_point = g_fake_document_portal_thread_get_mount_point (thread);
67 : :
68 : 1 : file = g_file_new_tmp ("test_document_portal_add_uri_XXXXXX",
69 : : &iostream, NULL);
70 : 1 : g_assert_no_error (error);
71 : 1 : g_io_stream_close ((GIOStream *) iostream, NULL, &error);
72 : 1 : g_assert_no_error (error);
73 : 1 : g_object_unref (iostream);
74 : :
75 : 1 : uris = g_list_append (uris, g_file_get_uri (file));
76 : 1 : portal_uris = g_document_portal_add_documents (uris, app_id, &error);
77 : 1 : g_assert_no_error (error);
78 : :
79 : 1 : basename = g_file_get_basename (file);
80 : 1 : expected_uri = g_strdup_printf ("file:%s/document-id-0/%s",
81 : : document_portal_mount_point, basename);
82 : :
83 : 1 : g_assert_cmpuint (g_list_length (portal_uris), ==, 1);
84 : 1 : g_assert_cmpstr (g_list_nth_data (portal_uris, 0), ==, expected_uri);
85 : :
86 : 1 : g_fake_document_portal_thread_stop (thread);
87 : 1 : g_clear_object (&thread);
88 : 1 : g_clear_object (&file);
89 : 1 : g_clear_pointer (&expected_uri, g_free);
90 : 1 : g_clear_pointer (&basename, g_free);
91 : 1 : g_clear_list (&uris, g_free);
92 : 1 : g_clear_list (&portal_uris, g_free);
93 : : }
94 : :
95 : : static void
96 : 1 : test_document_portal_add_not_existent_uri (void)
97 : : {
98 : 1 : GFakeDocumentPortalThread *thread = NULL;
99 : 1 : GList *uris = NULL; /* (element-type const char*) */
100 : 1 : GList *portal_uris = NULL; /* (element-type utf8) */
101 : 1 : GError *error = NULL;
102 : : const char *app_id;
103 : : const char *document_portal_mount_point;
104 : : const char *uri;
105 : : char *portal_uri;
106 : :
107 : : /* Run a fake-document-portal */
108 : 1 : app_id = "org.gnome.glib.gio.not-existent-uri";
109 : 1 : thread = g_fake_document_portal_thread_new (session_bus_get_address (), app_id);
110 : 1 : g_fake_document_portal_thread_run (thread);
111 : 1 : document_portal_mount_point = g_fake_document_portal_thread_get_mount_point (thread);
112 : :
113 : 1 : uri = "file:/no-existent-path-really!";
114 : 1 : uris = g_list_append (uris, (char *) uri);
115 : 1 : portal_uris = g_document_portal_add_documents (uris, app_id, &error);
116 : 1 : g_assert_no_error (error);
117 : :
118 : 1 : portal_uri = g_strdup_printf ("file:%s/document-id-0/no-existent-path-really!",
119 : : document_portal_mount_point);
120 : 1 : g_assert_false (g_file_test (portal_uri, G_FILE_TEST_EXISTS));
121 : :
122 : 1 : g_assert_cmpuint (g_list_length (portal_uris), ==, 1);
123 : 1 : g_assert_cmpstr (g_list_nth_data (portal_uris, 0), ==, uri);
124 : :
125 : 1 : g_fake_document_portal_thread_stop (thread);
126 : 1 : g_clear_object (&thread);
127 : 1 : g_clear_pointer (&portal_uri, g_free);
128 : 1 : g_clear_list (&uris, NULL);
129 : 1 : g_clear_list (&portal_uris, g_free);
130 : 1 : }
131 : :
132 : : static void
133 : 1 : test_document_portal_add_existent_and_not_existent_uris (void)
134 : : {
135 : 1 : if (skip_if_fd_query_path_unsupported ())
136 : 0 : return;
137 : :
138 : 1 : GFakeDocumentPortalThread *thread = NULL;
139 : : GFile *file;
140 : : GFile *expected_file0;
141 : : GFile *expected_file1;
142 : 1 : GList *uris = NULL; /* (element-type utf8) */
143 : 1 : GList *portal_uris = NULL; /* (element-type utf8) */
144 : 1 : GFileIOStream *iostream = NULL;
145 : 1 : GError *error = NULL;
146 : : const char *app_id;
147 : : const char *document_portal_mount_point;
148 : : const char *invalid_uri;
149 : : char *basename;
150 : :
151 : : /* Run a fake-document-portal */
152 : 1 : app_id = "org.gnome.glib.gio.mixed-uris";
153 : 1 : thread = g_fake_document_portal_thread_new (session_bus_get_address (), app_id);
154 : 1 : g_fake_document_portal_thread_run (thread);
155 : 1 : document_portal_mount_point = g_fake_document_portal_thread_get_mount_point (thread);
156 : :
157 : 1 : file = g_file_new_tmp ("test_document_portal_add_existent_and_not_existent_uris_XXXXXX",
158 : : &iostream, NULL);
159 : 1 : g_assert_no_error (error);
160 : 1 : g_io_stream_close ((GIOStream *) iostream, NULL, &error);
161 : 1 : g_assert_no_error (error);
162 : 1 : g_object_unref (iostream);
163 : :
164 : 1 : invalid_uri = "file:/no-existent-path-really!";
165 : :
166 : 1 : uris = g_list_append (uris, g_file_get_uri (file));
167 : 1 : uris = g_list_append (uris, g_strdup (invalid_uri));
168 : 1 : uris = g_list_append (uris, g_file_get_uri (file));
169 : 1 : uris = g_list_append (uris, g_strdup (invalid_uri));
170 : :
171 : 1 : portal_uris = g_document_portal_add_documents (uris, app_id, &error);
172 : 1 : g_assert_no_error (error);
173 : :
174 : 1 : basename = g_file_get_basename (file);
175 : 1 : expected_file0 = g_file_new_build_filename (document_portal_mount_point,
176 : : "document-id-0", basename, NULL);
177 : 1 : expected_file1 = g_file_new_build_filename (document_portal_mount_point,
178 : : "document-id-1", basename, NULL);
179 : :
180 : 1 : g_assert_cmpuint (g_list_length (portal_uris), ==, 4);
181 : 1 : g_assert_cmpstr ((char * ) g_list_nth_data (portal_uris, 0) + strlen ("file:"), ==, g_file_peek_path (expected_file0));
182 : 1 : g_assert_cmpstr (g_list_nth_data (portal_uris, 1), ==, invalid_uri);
183 : 1 : g_assert_cmpstr ((char * ) g_list_nth_data (portal_uris, 2) + strlen ("file:"), ==, g_file_peek_path (expected_file1));
184 : 1 : g_assert_cmpstr (g_list_nth_data (portal_uris, 3), ==, invalid_uri);
185 : :
186 : 1 : g_assert_true (g_file_test (g_file_peek_path (expected_file0), G_FILE_TEST_IS_REGULAR));
187 : 1 : g_assert_true (g_file_test (g_file_peek_path (expected_file1), G_FILE_TEST_IS_REGULAR));
188 : :
189 : 1 : g_fake_document_portal_thread_stop (thread);
190 : 1 : g_clear_object (&thread);
191 : 1 : g_clear_object (&file);
192 : 1 : g_clear_object (&expected_file1);
193 : 1 : g_clear_object (&expected_file0);
194 : 1 : g_clear_pointer (&basename, g_free);
195 : 1 : g_clear_list (&uris, g_free);
196 : 1 : g_clear_list (&portal_uris, g_free);
197 : : }
198 : :
199 : : static void
200 : 1 : test_document_portal_add_symlink_uri (void)
201 : : {
202 : 1 : if (skip_if_fd_query_path_unsupported ())
203 : 0 : return;
204 : :
205 : 1 : GFakeDocumentPortalThread *thread = NULL;
206 : : GFile *target;
207 : : GFile *link1;
208 : : GFile *link2;
209 : : GFile *parent_dir;
210 : 1 : GList *uris = NULL; /* (element-type utf8) */
211 : 1 : GList *portal_uris = NULL; /* (element-type utf8) */
212 : 1 : GFileIOStream *iostream = NULL;
213 : 1 : GError *error = NULL;
214 : : const char *app_id;
215 : : const char *document_portal_mount_point;
216 : : char *tmpdir_path;
217 : : char *basename;
218 : : char *expected_uri;
219 : :
220 : : /* Run a fake-document-portal */
221 : 1 : app_id = "org.gnome.glib.gio.symlinks";
222 : 1 : thread = g_fake_document_portal_thread_new (session_bus_get_address (), app_id);
223 : 1 : g_fake_document_portal_thread_run (thread);
224 : 1 : document_portal_mount_point = g_fake_document_portal_thread_get_mount_point (thread);
225 : :
226 : 1 : target = g_file_new_tmp ("test_document_portal_add_symlink_uri_XXXXXX",
227 : : &iostream, NULL);
228 : 1 : g_assert_no_error (error);
229 : 1 : g_io_stream_close ((GIOStream *) iostream, NULL, &error);
230 : 1 : g_assert_no_error (error);
231 : 1 : g_object_unref (iostream);
232 : :
233 : 1 : tmpdir_path = g_dir_make_tmp ("g_file_symlink_XXXXXX", &error);
234 : 1 : g_assert_no_error (error);
235 : :
236 : 1 : parent_dir = g_file_new_for_path (tmpdir_path);
237 : 1 : g_assert_true (g_file_query_exists (parent_dir, NULL));
238 : :
239 : 1 : link1 = g_file_get_child (parent_dir, "symlink");
240 : 1 : g_assert_false (g_file_query_exists (link1, NULL));
241 : :
242 : 1 : g_file_make_symbolic_link (link1, g_file_peek_path (target), NULL, &error);
243 : 1 : g_assert_no_error (error);
244 : 1 : g_assert_true (g_file_query_exists (link1, NULL));
245 : :
246 : 1 : link2 = g_file_get_child (parent_dir, "symlink-of-symlink");
247 : 1 : g_assert_false (g_file_query_exists (link2, NULL));
248 : :
249 : 1 : basename = g_file_get_basename (link1);
250 : 1 : g_file_make_symbolic_link (link2, basename, NULL, &error);
251 : 1 : g_clear_pointer (&basename, g_free);
252 : 1 : g_assert_true (g_file_query_exists (link2, NULL));
253 : 1 : g_assert_no_error (error);
254 : :
255 : 1 : uris = g_list_append (uris, g_file_get_uri (link1));
256 : 1 : uris = g_list_append (uris, g_file_get_uri (link2));
257 : :
258 : 1 : portal_uris = g_document_portal_add_documents (uris, app_id, &error);
259 : 1 : g_assert_no_error (error);
260 : :
261 : 1 : basename = g_file_get_basename (target);
262 : 1 : g_assert_cmpuint (g_list_length (portal_uris), ==, 2);
263 : :
264 : 1 : expected_uri = g_strdup_printf ("file:%s/document-id-0/%s",
265 : : document_portal_mount_point, basename);
266 : 1 : g_assert_cmpstr (g_list_nth_data (portal_uris, 0), ==, expected_uri);
267 : 1 : g_clear_pointer (&expected_uri, g_free);
268 : :
269 : 1 : expected_uri = g_strdup_printf ("file:%s/document-id-1/%s",
270 : : document_portal_mount_point, basename);
271 : 1 : g_assert_cmpstr (g_list_nth_data (portal_uris, 1), ==, expected_uri);
272 : 1 : g_clear_pointer (&expected_uri, g_free);
273 : :
274 : 1 : g_fake_document_portal_thread_stop (thread);
275 : 1 : g_clear_object (&thread);
276 : 1 : g_clear_object (&target);
277 : 1 : g_clear_object (&link1);
278 : 1 : g_clear_object (&link2);
279 : 1 : g_clear_object (&parent_dir);
280 : 1 : g_clear_pointer (&expected_uri, g_free);
281 : 1 : g_clear_pointer (&basename, g_free);
282 : 1 : g_clear_pointer (&tmpdir_path, g_free);
283 : 1 : g_clear_list (&uris, g_free);
284 : 1 : g_clear_list (&portal_uris, g_free);
285 : : }
286 : :
287 : : static void
288 : 1 : test_document_portal_add_uri_with_missing_doc_id_path (void)
289 : : {
290 : 1 : GFakeDocumentPortalThread *thread = NULL;
291 : : GFile *file;
292 : 1 : GList *uris = NULL; /* (element-type utf8) */
293 : 1 : GList *portal_uris = NULL; /* (element-type utf8) */
294 : 1 : GFileIOStream *iostream = NULL;
295 : 1 : GError *error = NULL;
296 : : const char *app_id;
297 : :
298 : : /* Run a fake-document-portal */
299 : 1 : app_id = G_FAKE_DOCUMENT_PORTAL_NO_CREATE_DIR_APP_ID;
300 : 1 : thread = g_fake_document_portal_thread_new (session_bus_get_address (), app_id);
301 : 1 : g_fake_document_portal_thread_run (thread);
302 : :
303 : 1 : file = g_file_new_tmp ("test_document_portal_add_uri_with_missing_doc_id_path_XXXXXX",
304 : : &iostream, NULL);
305 : 1 : g_assert_no_error (error);
306 : 1 : g_io_stream_close ((GIOStream *) iostream, NULL, &error);
307 : 1 : g_assert_no_error (error);
308 : 1 : g_object_unref (iostream);
309 : :
310 : 1 : uris = g_list_append (uris, g_file_get_uri (file));
311 : 1 : portal_uris = g_document_portal_add_documents (uris, app_id, &error);
312 : 1 : g_assert_null (portal_uris);
313 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
314 : :
315 : 1 : g_fake_document_portal_thread_stop (thread);
316 : 1 : g_clear_object (&thread);
317 : 1 : g_clear_object (&file);
318 : 1 : g_clear_list (&uris, g_free);
319 : 1 : g_clear_error (&error);
320 : 1 : g_clear_list (&portal_uris, g_free);
321 : 1 : }
322 : :
323 : : static void
324 : 1 : test_document_portal_add_uri_with_missing_doc_file (void)
325 : : {
326 : 1 : GFakeDocumentPortalThread *thread = NULL;
327 : : GFile *file;
328 : 1 : GList *uris = NULL; /* (element-type utf8) */
329 : 1 : GList *portal_uris = NULL; /* (element-type utf8) */
330 : 1 : GFileIOStream *iostream = NULL;
331 : 1 : GError *error = NULL;
332 : : const char *app_id;
333 : :
334 : : /* Run a fake-document-portal */
335 : 1 : app_id = G_FAKE_DOCUMENT_PORTAL_NO_CREATE_FILE_APP_ID;
336 : 1 : thread = g_fake_document_portal_thread_new (session_bus_get_address (), app_id);
337 : 1 : g_fake_document_portal_thread_run (thread);
338 : :
339 : 1 : file = g_file_new_tmp ("test_document_portal_add_uri_with_missing_doc_file_XXXXXX",
340 : : &iostream, NULL);
341 : 1 : g_assert_no_error (error);
342 : 1 : g_io_stream_close ((GIOStream *) iostream, NULL, &error);
343 : 1 : g_assert_no_error (error);
344 : 1 : g_object_unref (iostream);
345 : :
346 : 1 : uris = g_list_append (uris, g_file_get_uri (file));
347 : 1 : portal_uris = g_document_portal_add_documents (uris, app_id, &error);
348 : 1 : g_assert_null (portal_uris);
349 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
350 : :
351 : 1 : g_fake_document_portal_thread_stop (thread);
352 : 1 : g_clear_object (&thread);
353 : 1 : g_clear_object (&file);
354 : 1 : g_clear_list (&uris, g_free);
355 : 1 : g_clear_error (&error);
356 : 1 : g_clear_list (&portal_uris, g_free);
357 : 1 : }
358 : :
359 : : int
360 : 1 : main (int argc,
361 : : char *argv[])
362 : : {
363 : 1 : g_setenv ("LC_ALL", "C", TRUE);
364 : 1 : g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
365 : :
366 : 1 : g_test_add_func ("/document-portal/add-uri", test_document_portal_add_uri);
367 : 1 : g_test_add_func ("/document-portal/add-not-existent-uri", test_document_portal_add_not_existent_uri);
368 : 1 : g_test_add_func ("/document-portal/add-existent-and-not-existent-uri", test_document_portal_add_existent_and_not_existent_uris);
369 : 1 : g_test_add_func ("/document-portal/add-symlink-uri", test_document_portal_add_symlink_uri);
370 : 1 : g_test_add_func ("/document-portal/add-uri-with-missing-doc-id-path", test_document_portal_add_uri_with_missing_doc_id_path);
371 : 1 : g_test_add_func ("/document-portal/add-uri-with-missing-doc-file", test_document_portal_add_uri_with_missing_doc_file);
372 : :
373 : 1 : return session_bus_run ();
374 : : }
|