1
2 #include <locale.h>
3 #include <string.h>
4
5 #include <glib/gstdio.h>
6 #include <gio/gio.h>
7 #include <gio/gdesktopappinfo.h>
8
9 static void
10 test_launch_for_app_info (GAppInfo *appinfo)
11 {
12 GError *error = NULL;
13 gboolean success;
14 GFile *file;
15 GList *l;
16 const gchar *path;
17 gchar *uri;
18
19 success = g_app_info_launch (appinfo, NULL, NULL, &error);
20 g_assert_no_error (error);
21 g_assert_true (success);
22
23 success = g_app_info_launch_uris (appinfo, NULL, NULL, &error);
24 g_assert_no_error (error);
25 g_assert_true (success);
26
27 path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
28 file = g_file_new_for_path (path);
29 l = NULL;
30 l = g_list_append (l, file);
31
32 success = g_app_info_launch (appinfo, l, NULL, &error);
33 g_assert_no_error (error);
34 g_assert_true (success);
35 g_list_free (l);
36 g_object_unref (file);
37
38 l = NULL;
39 uri = g_strconcat ("file://", g_test_get_dir (G_TEST_BUILT), "/appinfo-test.desktop", NULL);
40 l = g_list_append (l, uri);
41 l = g_list_append (l, "file:///etc/group#adm");
42
43 success = g_app_info_launch_uris (appinfo, l, NULL, &error);
44 g_assert_no_error (error);
45 g_assert_true (success);
46
47 g_list_free (l);
48 g_free (uri);
49 }
50
51 static void
52 test_launch (void)
53 {
54 GAppInfo *appinfo;
55 const gchar *path;
56
57 path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
58 appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
59 g_assert_true (G_IS_APP_INFO (appinfo));
60
61 test_launch_for_app_info (appinfo);
62 g_object_unref (appinfo);
63 }
64
65 static void
66 test_launch_no_app_id (void)
67 {
68 const gchar desktop_file_base_contents[] =
69 "[Desktop Entry]\n"
70 "Type=Application\n"
71 "GenericName=generic-appinfo-test\n"
72 "Name=appinfo-test\n"
73 "Name[de]=appinfo-test-de\n"
74 "X-GNOME-FullName=example\n"
75 "X-GNOME-FullName[de]=Beispiel\n"
76 "Comment=GAppInfo example\n"
77 "Comment[de]=GAppInfo Beispiel\n"
78 "Icon=testicon.svg\n"
79 "Terminal=false\n"
80 "StartupNotify=true\n"
81 "StartupWMClass=appinfo-class\n"
82 "MimeType=image/png;image/jpeg;\n"
83 "Keywords=keyword1;test keyword;\n"
84 "Categories=GNOME;GTK;\n";
85
86 gchar *exec_line_variants[2];
87 gsize i;
88
89 exec_line_variants[0] = g_strdup_printf (
90 "Exec=%s/appinfo-test --option %%U %%i --name %%c --filename %%k %%m %%%%",
91 g_test_get_dir (G_TEST_BUILT));
92 exec_line_variants[1] = g_strdup_printf (
93 "Exec=%s/appinfo-test --option %%u %%i --name %%c --filename %%k %%m %%%%",
94 g_test_get_dir (G_TEST_BUILT));
95
96 g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=791337");
97
98 for (i = 0; i < G_N_ELEMENTS (exec_line_variants); i++)
99 {
100 gchar *desktop_file_contents;
101 GKeyFile *fake_desktop_file;
102 GAppInfo *appinfo;
103 gboolean loaded;
104
105 g_test_message ("Exec line variant #%" G_GSIZE_FORMAT, i);
106
107 desktop_file_contents = g_strdup_printf ("%s\n%s",
108 desktop_file_base_contents,
109 exec_line_variants[i]);
110
111 /* We load a desktop file from memory to force the app not
112 * to have an app ID, which would check different codepaths.
113 */
114 fake_desktop_file = g_key_file_new ();
115 loaded = g_key_file_load_from_data (fake_desktop_file, desktop_file_contents, -1, G_KEY_FILE_NONE, NULL);
116 g_assert_true (loaded);
117
118 appinfo = (GAppInfo*)g_desktop_app_info_new_from_keyfile (fake_desktop_file);
119 g_assert_nonnull (appinfo);
120
121 test_launch_for_app_info (appinfo);
122
123 g_free (desktop_file_contents);
124 g_object_unref (appinfo);
125 g_key_file_unref (fake_desktop_file);
126 }
127
128 g_free (exec_line_variants[1]);
129 g_free (exec_line_variants[0]);
130 }
131
132 static void
133 test_locale (const char *locale)
134 {
135 GAppInfo *appinfo;
136 gchar *orig = NULL;
137 const gchar *path;
138
139 orig = g_strdup (setlocale (LC_ALL, NULL));
140 g_setenv ("LANGUAGE", locale, TRUE);
141 setlocale (LC_ALL, "");
142
143 path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
144 appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
145
146 if (g_strcmp0 (locale, "C") == 0)
147 {
148 g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test");
149 g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo example");
150 g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "example");
151 }
152 else if (g_str_has_prefix (locale, "en"))
153 {
154 g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test");
155 g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo example");
156 g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "example");
157 }
158 else if (g_str_has_prefix (locale, "de"))
159 {
160 g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test-de");
161 g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo Beispiel");
162 g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "Beispiel");
163 }
164
165 g_object_unref (appinfo);
166
167 g_setenv ("LANGUAGE", orig, TRUE);
168 setlocale (LC_ALL, "");
169 g_free (orig);
170 }
171
172 static void
173 test_text (void)
174 {
175 test_locale ("C");
176 test_locale ("en_US");
177 test_locale ("de");
178 test_locale ("de_DE.UTF-8");
179 }
180
181 static void
182 test_basic (void)
183 {
184 GAppInfo *appinfo;
185 GAppInfo *appinfo2;
186 GIcon *icon, *icon2;
187 const gchar *path;
188
189 path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
190 appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
191 g_assert_nonnull (appinfo);
192
193 g_assert_cmpstr (g_app_info_get_id (appinfo), ==, "appinfo-test-static.desktop");
194 g_assert_nonnull (strstr (g_app_info_get_executable (appinfo), "true"));
195
196 icon = g_app_info_get_icon (appinfo);
197 g_assert_true (G_IS_THEMED_ICON (icon));
198 icon2 = g_themed_icon_new ("testicon");
199 g_assert_true (g_icon_equal (icon, icon2));
200 g_object_unref (icon2);
201
202 appinfo2 = g_app_info_dup (appinfo);
203 g_assert_cmpstr (g_app_info_get_id (appinfo), ==, g_app_info_get_id (appinfo2));
204 g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
205
206 g_object_unref (appinfo);
207 g_object_unref (appinfo2);
208 }
209
210 static void
211 test_show_in (void)
212 {
213 GAppInfo *appinfo;
214 const gchar *path;
215
216 path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
217 appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
218 g_assert_true (G_IS_APP_INFO (appinfo));
219
220 g_assert_true (g_app_info_should_show (appinfo));
221 g_object_unref (appinfo);
222
223 path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-gnome.desktop", NULL);
224 appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
225 g_assert_true (g_app_info_should_show (appinfo));
226 g_object_unref (appinfo);
227
228 path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-notgnome.desktop", NULL);
229 appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
230 g_assert_false (g_app_info_should_show (appinfo));
231 g_object_unref (appinfo);
232 }
233
234 static void
235 test_commandline (void)
236 {
237 GAppInfo *appinfo;
238 GError *error;
239 gchar *cmdline;
240 gchar *cmdline_out;
241
242 cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
243 cmdline_out = g_strconcat (cmdline, " %u", NULL);
244
245 error = NULL;
246 appinfo = g_app_info_create_from_commandline (cmdline,
247 "cmdline-app-test",
248 G_APP_INFO_CREATE_SUPPORTS_URIS,
249 &error);
250 g_assert_no_error (error);
251 g_assert_nonnull (appinfo);
252 g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "cmdline-app-test");
253 g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, cmdline_out);
254 g_assert_true (g_app_info_supports_uris (appinfo));
255 g_assert_false (g_app_info_supports_files (appinfo));
256
257 g_object_unref (appinfo);
258
259 g_free (cmdline_out);
260 cmdline_out = g_strconcat (cmdline, " %f", NULL);
261
262 error = NULL;
263 appinfo = g_app_info_create_from_commandline (cmdline,
264 "cmdline-app-test",
265 G_APP_INFO_CREATE_NONE,
266 &error);
267 g_assert_no_error (error);
268 g_assert_nonnull (appinfo);
269 g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "cmdline-app-test");
270 g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, cmdline_out);
271 g_assert_false (g_app_info_supports_uris (appinfo));
272 g_assert_true (g_app_info_supports_files (appinfo));
273
274 g_object_unref (appinfo);
275
276 g_free (cmdline);
277 g_free (cmdline_out);
278 }
279
280 static void
281 test_launch_context (void)
282 {
283 GAppLaunchContext *context;
284 GAppInfo *appinfo;
285 gchar *str;
286 gchar *cmdline;
287
288 cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
289
290 context = g_app_launch_context_new ();
291 appinfo = g_app_info_create_from_commandline (cmdline,
292 "cmdline-app-test",
293 G_APP_INFO_CREATE_SUPPORTS_URIS,
294 NULL);
295
296 str = g_app_launch_context_get_display (context, appinfo, NULL);
297 g_assert_null (str);
298
299 str = g_app_launch_context_get_startup_notify_id (context, appinfo, NULL);
300 g_assert_null (str);
301
302 g_object_unref (appinfo);
303 g_object_unref (context);
304
305 g_free (cmdline);
306 }
307
308 static gboolean launched_reached;
309
310 static void
311 launched (GAppLaunchContext *context,
312 GAppInfo *info,
313 GVariant *platform_data,
314 gpointer user_data)
315 {
316 gint pid;
317
318 pid = 0;
319 g_assert_true (g_variant_lookup (platform_data, "pid", "i", &pid));
320 g_assert_cmpint (pid, !=, 0);
321
322 launched_reached = TRUE;
323 }
324
325 static void
326 launch_failed (GAppLaunchContext *context,
327 const gchar *startup_notify_id)
328 {
329 g_assert_not_reached ();
330 }
331
332 static void
333 test_launch_context_signals (void)
334 {
335 GAppLaunchContext *context;
336 GAppInfo *appinfo;
337 GError *error = NULL;
338 gboolean success;
339 gchar *cmdline;
340
341 cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
342
343 context = g_app_launch_context_new ();
344 g_signal_connect (context, "launched", G_CALLBACK (launched), NULL);
345 g_signal_connect (context, "launch_failed", G_CALLBACK (launch_failed), NULL);
346 appinfo = g_app_info_create_from_commandline (cmdline,
347 "cmdline-app-test",
348 G_APP_INFO_CREATE_SUPPORTS_URIS,
349 NULL);
350
351 success = g_app_info_launch (appinfo, NULL, context, &error);
352 g_assert_no_error (error);
353 g_assert_true (success);
354
355 g_assert_true (launched_reached);
356
357 g_object_unref (appinfo);
358 g_object_unref (context);
359
360 g_free (cmdline);
361 }
362
363 static void
364 test_tryexec (void)
365 {
366 GAppInfo *appinfo;
367 const gchar *path;
368
369 path = g_test_get_filename (G_TEST_BUILT, "appinfo-test2.desktop", NULL);
370 appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
371
372 g_assert_null (appinfo);
373 }
374
375 /* Test that we can set an appinfo as default for a mime type or
376 * file extension, and also add and remove handled mime types.
377 */
378 static void
379 test_associations (void)
380 {
381 GAppInfo *appinfo;
382 GAppInfo *appinfo2;
383 GError *error = NULL;
384 gboolean result;
385 GList *list;
386 gchar *cmdline;
387 gchar *update_desktop_database = NULL, *update_mime_database = NULL;
388
389 update_desktop_database = g_find_program_in_path ("update-desktop-database");
390 update_mime_database = g_find_program_in_path ("update-mime-database");
391
392 if (update_desktop_database == NULL || update_mime_database == NULL)
393 {
394 g_test_skip ("update-desktop-database and update-mime-database are needed to change file associations");
395 g_free (update_desktop_database);
396 g_free (update_mime_database);
397 return;
398 }
399
400 g_free (update_desktop_database);
401 g_free (update_mime_database);
402
403 cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
404 appinfo = g_app_info_create_from_commandline (cmdline,
405 "cmdline-app-test",
406 G_APP_INFO_CREATE_SUPPORTS_URIS,
407 NULL);
408 g_free (cmdline);
409
410 result = g_app_info_set_as_default_for_type (appinfo, "application/x-glib-test", &error);
411 g_assert_no_error (error);
412 g_assert_true (result);
413
414 appinfo2 = g_app_info_get_default_for_type ("application/x-glib-test", FALSE);
415
416 g_assert_nonnull (appinfo2);
417 g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
418
419 g_object_unref (appinfo2);
420
421 result = g_app_info_set_as_default_for_extension (appinfo, "gio-tests", &error);
422 g_assert_no_error (error);
423 g_assert_true (result);
424
425 appinfo2 = g_app_info_get_default_for_type ("application/x-extension-gio-tests", FALSE);
426
427 g_assert_nonnull (appinfo2);
428 g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
429
430 g_object_unref (appinfo2);
431
432 result = g_app_info_add_supports_type (appinfo, "application/x-gio-test", &error);
433 g_assert_no_error (error);
434 g_assert_true (result);
435
436 list = g_app_info_get_all_for_type ("application/x-gio-test");
437 g_assert_cmpint (g_list_length (list), ==, 1);
438 appinfo2 = list->data;
439 g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
440 g_object_unref (appinfo2);
441 g_list_free (list);
442
443 g_assert_true (g_app_info_can_remove_supports_type (appinfo));
444 result = g_app_info_remove_supports_type (appinfo, "application/x-gio-test", &error);
445 g_assert_no_error (error);
446 g_assert_true (result);
447
448 g_assert_true (g_app_info_can_delete (appinfo));
449 g_assert_true (g_app_info_delete (appinfo));
450 g_object_unref (appinfo);
451 }
452
453 static void
454 test_environment (void)
455 {
456 GAppLaunchContext *ctx;
457 gchar **env;
458 const gchar *path;
459
460 g_unsetenv ("FOO");
461 g_unsetenv ("BLA");
462 path = g_getenv ("PATH");
463
464 ctx = g_app_launch_context_new ();
465
466 env = g_app_launch_context_get_environment (ctx);
467
468 g_assert_null (g_environ_getenv (env, "FOO"));
469 g_assert_null (g_environ_getenv (env, "BLA"));
470 g_assert_cmpstr (g_environ_getenv (env, "PATH"), ==, path);
471
472 g_strfreev (env);
473
474 g_app_launch_context_setenv (ctx, "FOO", "bar");
475 g_app_launch_context_setenv (ctx, "BLA", "bla");
476
477 env = g_app_launch_context_get_environment (ctx);
478
479 g_assert_cmpstr (g_environ_getenv (env, "FOO"), ==, "bar");
480 g_assert_cmpstr (g_environ_getenv (env, "BLA"), ==, "bla");
481 g_assert_cmpstr (g_environ_getenv (env, "PATH"), ==, path);
482
483 g_strfreev (env);
484
485 g_app_launch_context_setenv (ctx, "FOO", "baz");
486 g_app_launch_context_unsetenv (ctx, "BLA");
487
488 env = g_app_launch_context_get_environment (ctx);
489
490 g_assert_cmpstr (g_environ_getenv (env, "FOO"), ==, "baz");
491 g_assert_null (g_environ_getenv (env, "BLA"));
492
493 g_strfreev (env);
494
495 g_object_unref (ctx);
496 }
497
498 static void
499 test_startup_wm_class (void)
500 {
501 GDesktopAppInfo *appinfo;
502 const char *wm_class;
503 const gchar *path;
504
505 path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
506 appinfo = g_desktop_app_info_new_from_filename (path);
507 wm_class = g_desktop_app_info_get_startup_wm_class (appinfo);
508
509 g_assert_cmpstr (wm_class, ==, "appinfo-class");
510
511 g_object_unref (appinfo);
512 }
513
514 static void
515 test_supported_types (void)
516 {
517 GAppInfo *appinfo;
518 const char * const *content_types;
519 const gchar *path;
520
521 path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
522 appinfo = G_APP_INFO (g_desktop_app_info_new_from_filename (path));
523 content_types = g_app_info_get_supported_types (appinfo);
524
525 g_assert_cmpint (g_strv_length ((char**)content_types), ==, 2);
526 g_assert_cmpstr (content_types[0], ==, "image/png");
527
528 g_object_unref (appinfo);
529 }
530
531 static void
532 test_from_keyfile (void)
533 {
534 GDesktopAppInfo *info;
535 GKeyFile *kf;
536 GError *error = NULL;
537 const gchar *categories;
538 gchar **categories_list;
539 gsize categories_count;
540 gchar **keywords;
541 const gchar *file;
542 const gchar *name;
543 const gchar *path;
544
545 path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
546 kf = g_key_file_new ();
547 g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, &error);
548 g_assert_no_error (error);
549 info = g_desktop_app_info_new_from_keyfile (kf);
550 g_key_file_unref (kf);
551 g_assert_nonnull (info);
552
553 g_object_get (info, "filename", &file, NULL);
554 g_assert_null (file);
555
556 file = g_desktop_app_info_get_filename (info);
557 g_assert_null (file);
558 categories = g_desktop_app_info_get_categories (info);
559 g_assert_cmpstr (categories, ==, "GNOME;GTK;");
560 categories_list = g_desktop_app_info_get_string_list (info, "Categories", &categories_count);
561 g_assert_cmpint (categories_count, ==, 2);
562 g_assert_cmpint (g_strv_length (categories_list), ==, 2);
563 g_assert_cmpstr (categories_list[0], ==, "GNOME");
564 g_assert_cmpstr (categories_list[1], ==, "GTK");
565 keywords = (gchar **)g_desktop_app_info_get_keywords (info);
566 g_assert_cmpint (g_strv_length (keywords), ==, 2);
567 g_assert_cmpstr (keywords[0], ==, "keyword1");
568 g_assert_cmpstr (keywords[1], ==, "test keyword");
569 name = g_desktop_app_info_get_generic_name (info);
570 g_assert_cmpstr (name, ==, "generic-appinfo-test");
571 g_assert_false (g_desktop_app_info_get_nodisplay (info));
572
573 g_strfreev (categories_list);
574 g_object_unref (info);
575 }
576
577 int
578 main (int argc, char *argv[])
579 {
580 g_setenv ("XDG_CURRENT_DESKTOP", "GNOME", TRUE);
581
582 g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
583
584 g_test_add_func ("/appinfo/basic", test_basic);
585 g_test_add_func ("/appinfo/text", test_text);
586 g_test_add_func ("/appinfo/launch", test_launch);
587 g_test_add_func ("/appinfo/launch/no-appid", test_launch_no_app_id);
588 g_test_add_func ("/appinfo/show-in", test_show_in);
589 g_test_add_func ("/appinfo/commandline", test_commandline);
590 g_test_add_func ("/appinfo/launch-context", test_launch_context);
591 g_test_add_func ("/appinfo/launch-context-signals", test_launch_context_signals);
592 g_test_add_func ("/appinfo/tryexec", test_tryexec);
593 g_test_add_func ("/appinfo/associations", test_associations);
594 g_test_add_func ("/appinfo/environment", test_environment);
595 g_test_add_func ("/appinfo/startup-wm-class", test_startup_wm_class);
596 g_test_add_func ("/appinfo/supported-types", test_supported_types);
597 g_test_add_func ("/appinfo/from-keyfile", test_from_keyfile);
598
599 return g_test_run ();
600 }