1 #include <glib/gstdio.h>
3 #include <gio/gdesktopappinfo.h>
6 strv_equal (gchar **strv, ...)
15 va_start (list, strv);
18 str = va_arg (list, const gchar *);
21 if (g_strcmp0 (str, strv[count]) != 0)
31 res = g_strv_length (strv) == count;
36 const gchar *myapp_data =
44 const gchar *myapp2_data =
52 const gchar *myapp3_data =
60 const gchar *myapp4_data =
67 "MimeType=image/bmp;";
69 const gchar *myapp5_data =
76 "MimeType=image/bmp;x-scheme-handler/ftp;";
78 const gchar *defaults_data =
79 "[Default Applications]\n"
80 "image/bmp=myapp4.desktop;\n"
81 "image/png=myapp3.desktop;\n"
82 "x-scheme-handler/ftp=myapp5.desktop;\n";
84 const gchar *mimecache_data =
86 "image/bmp=myapp4.desktop;myapp5.desktop;\n";
88 /* Set up XDG_DATA_HOME and XDG_DATA_DIRS.
89 * XDG_DATA_DIRS/applications will contain defaults.list
90 * XDG_DATA_HOME/applications will contain myapp.desktop
91 * and myapp2.desktop, and no mimeapps.list
104 GError *error = NULL;
106 dir = g_get_current_dir ();
107 xdgdatahome = g_build_filename (dir, "xdgdatahome", NULL);
108 xdgdatadir = g_build_filename (dir, "xdgdatadir", NULL);
109 g_test_message ("setting XDG_DATA_HOME to '%s'\n", xdgdatahome);
110 g_setenv ("XDG_DATA_HOME", xdgdatahome, TRUE);
111 g_test_message ("setting XDG_DATA_DIRS to '%s'\n", xdgdatadir);
112 g_setenv ("XDG_DATA_DIRS", xdgdatadir, TRUE);
114 appdir = g_build_filename (xdgdatadir, "applications", NULL);
115 g_test_message ("creating '%s'\n", appdir);
116 res = g_mkdir_with_parents (appdir, 0700);
119 name = g_build_filename (appdir, "defaults.list", NULL);
120 g_test_message ("creating '%s'\n", name);
121 g_file_set_contents (name, defaults_data, -1, &error);
122 g_assert_no_error (error);
125 apphome = g_build_filename (xdgdatahome, "applications", NULL);
126 g_test_message ("creating '%s'\n", apphome);
127 res = g_mkdir_with_parents (apphome, 0700);
130 name = g_build_filename (apphome, "myapp.desktop", NULL);
131 g_test_message ("creating '%s'\n", name);
132 g_file_set_contents (name, myapp_data, -1, &error);
133 g_assert_no_error (error);
136 name = g_build_filename (apphome, "myapp2.desktop", NULL);
137 g_test_message ("creating '%s'\n", name);
138 g_file_set_contents (name, myapp2_data, -1, &error);
139 g_assert_no_error (error);
142 name = g_build_filename (apphome, "myapp3.desktop", NULL);
143 g_test_message ("creating '%s'\n", name);
144 g_file_set_contents (name, myapp3_data, -1, &error);
145 g_assert_no_error (error);
148 name = g_build_filename (apphome, "myapp4.desktop", NULL);
149 g_test_message ("creating '%s'\n", name);
150 g_file_set_contents (name, myapp4_data, -1, &error);
151 g_assert_no_error (error);
154 name = g_build_filename (apphome, "myapp5.desktop", NULL);
155 g_test_message ("creating '%s'\n", name);
156 g_file_set_contents (name, myapp5_data, -1, &error);
157 g_assert_no_error (error);
160 mimeapps = g_build_filename (apphome, "mimeapps.list", NULL);
161 g_test_message ("removing '%s'\n", mimeapps);
164 name = g_build_filename (apphome, "mimeinfo.cache", NULL);
165 g_test_message ("creating '%s'\n", name);
166 g_file_set_contents (name, mimecache_data, -1, &error);
167 g_assert_no_error (error);
171 g_free (xdgdatahome);
183 GError *error = NULL;
186 const gchar *contenttype = "application/pdf";
188 /* clear things out */
189 g_app_info_reset_type_associations (contenttype);
191 appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop");
192 appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop");
194 def = g_app_info_get_default_for_type (contenttype, FALSE);
195 list = g_app_info_get_recommended_for_type (contenttype);
196 g_assert (def == NULL);
197 g_assert (list == NULL);
199 /* 1. add a non-default association */
200 g_app_info_add_supports_type (appinfo, contenttype, &error);
201 g_assert_no_error (error);
203 def = g_app_info_get_default_for_type (contenttype, FALSE);
204 list = g_app_info_get_recommended_for_type (contenttype);
205 g_assert (g_app_info_equal (def, appinfo));
206 g_assert_cmpint (g_list_length (list), ==, 1);
207 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
208 g_object_unref (def);
209 g_list_free_full (list, g_object_unref);
211 /* 2. add another non-default association */
212 g_app_info_add_supports_type (appinfo2, contenttype, &error);
213 g_assert_no_error (error);
215 def = g_app_info_get_default_for_type (contenttype, FALSE);
216 list = g_app_info_get_recommended_for_type (contenttype);
217 g_assert (g_app_info_equal (def, appinfo));
218 g_assert_cmpint (g_list_length (list), ==, 2);
219 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
220 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2));
221 g_object_unref (def);
222 g_list_free_full (list, g_object_unref);
224 /* 3. make the first app the default */
225 g_app_info_set_as_default_for_type (appinfo, contenttype, &error);
226 g_assert_no_error (error);
228 def = g_app_info_get_default_for_type (contenttype, FALSE);
229 list = g_app_info_get_recommended_for_type (contenttype);
230 g_assert (g_app_info_equal (def, appinfo));
231 g_assert_cmpint (g_list_length (list), ==, 2);
232 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
233 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2));
234 g_object_unref (def);
235 g_list_free_full (list, g_object_unref);
237 /* 4. make the second app the last used one */
238 g_app_info_set_as_last_used_for_type (appinfo2, contenttype, &error);
239 g_assert_no_error (error);
241 def = g_app_info_get_default_for_type (contenttype, FALSE);
242 list = g_app_info_get_recommended_for_type (contenttype);
243 g_assert (g_app_info_equal (def, appinfo));
244 g_assert_cmpint (g_list_length (list), ==, 2);
245 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo2));
246 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo));
247 g_object_unref (def);
248 g_list_free_full (list, g_object_unref);
250 /* 5. reset everything */
251 g_app_info_reset_type_associations (contenttype);
253 def = g_app_info_get_default_for_type (contenttype, FALSE);
254 list = g_app_info_get_recommended_for_type (contenttype);
255 g_assert (def == NULL);
256 g_assert (list == NULL);
258 g_object_unref (appinfo);
259 g_object_unref (appinfo2);
262 /* Repeat the same tests, this time checking that we handle
263 * mimeapps.list as expected. These tests are different from
264 * the ones in test_mime_api() in that we directly parse
265 * mimeapps.list to verify the results.
268 test_mime_file (void)
273 GError *error = NULL;
281 const gchar *contenttype = "application/pdf";
283 dir = g_get_current_dir ();
284 mimeapps = g_build_filename (dir, "xdgdatahome", "applications", "mimeapps.list", NULL);
286 /* clear things out */
287 g_app_info_reset_type_associations (contenttype);
289 appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop");
290 appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop");
292 def = g_app_info_get_default_for_type (contenttype, FALSE);
293 list = g_app_info_get_recommended_for_type (contenttype);
294 g_assert (def == NULL);
295 g_assert (list == NULL);
297 /* 1. add a non-default association */
298 g_app_info_add_supports_type (appinfo, contenttype, &error);
299 g_assert_no_error (error);
301 keyfile = g_key_file_new ();
302 g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
303 g_assert_no_error (error);
305 assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error);
306 g_assert_no_error (error);
307 g_assert (strv_equal (assoc, "myapp.desktop", NULL));
310 /* we've unset XDG_DATA_DIRS so there should be no default */
311 assoc = g_key_file_get_string_list (keyfile, "Default Applications", contenttype, NULL, &error);
312 g_assert (error != NULL);
313 g_clear_error (&error);
315 g_key_file_free (keyfile);
317 /* 2. add another non-default association */
318 g_app_info_add_supports_type (appinfo2, contenttype, &error);
319 g_assert_no_error (error);
321 keyfile = g_key_file_new ();
322 g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
323 g_assert_no_error (error);
325 assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error);
326 g_assert_no_error (error);
327 g_assert (strv_equal (assoc, "myapp.desktop", "myapp2.desktop", NULL));
330 assoc = g_key_file_get_string_list (keyfile, "Default Applications", contenttype, NULL, &error);
331 g_assert (error != NULL);
332 g_clear_error (&error);
334 g_key_file_free (keyfile);
336 /* 3. make the first app the default */
337 g_app_info_set_as_default_for_type (appinfo, contenttype, &error);
338 g_assert_no_error (error);
340 keyfile = g_key_file_new ();
341 g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
342 g_assert_no_error (error);
344 assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error);
345 g_assert_no_error (error);
346 g_assert (strv_equal (assoc, "myapp.desktop", "myapp2.desktop", NULL));
349 str = g_key_file_get_string (keyfile, "Default Applications", contenttype, &error);
350 g_assert_no_error (error);
351 g_assert_cmpstr (str, ==, "myapp.desktop");
354 g_key_file_free (keyfile);
356 /* 4. make the second app the last used one */
357 g_app_info_set_as_last_used_for_type (appinfo2, contenttype, &error);
358 g_assert_no_error (error);
360 keyfile = g_key_file_new ();
361 g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
362 g_assert_no_error (error);
364 assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error);
365 g_assert_no_error (error);
366 g_assert (strv_equal (assoc, "myapp2.desktop", "myapp.desktop", NULL));
369 g_key_file_free (keyfile);
371 /* 5. reset everything */
372 g_app_info_reset_type_associations (contenttype);
374 keyfile = g_key_file_new ();
375 g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
376 g_assert_no_error (error);
378 res = g_key_file_has_key (keyfile, "Added Associations", contenttype, NULL);
381 res = g_key_file_has_key (keyfile, "Default Applications", contenttype, NULL);
384 g_key_file_free (keyfile);
386 g_object_unref (appinfo);
387 g_object_unref (appinfo2);
393 /* test interaction between defaults.list and mimeapps.list */
395 test_mime_default (void)
400 GError *error = NULL;
403 const gchar *contenttype = "image/png";
405 /* clear things out */
406 g_app_info_reset_type_associations (contenttype);
408 appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop");
409 appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop");
410 appinfo3 = (GAppInfo*)g_desktop_app_info_new ("myapp3.desktop");
412 /* myapp3 is set as the default in defaults.list */
413 def = g_app_info_get_default_for_type (contenttype, FALSE);
414 list = g_app_info_get_recommended_for_type (contenttype);
415 g_assert (g_app_info_equal (def, appinfo3));
416 g_assert_cmpint (g_list_length (list), ==, 1);
417 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo3));
418 g_object_unref (def);
419 g_list_free_full (list, g_object_unref);
421 /* 1. add a non-default association */
422 g_app_info_add_supports_type (appinfo, contenttype, &error);
423 g_assert_no_error (error);
425 def = g_app_info_get_default_for_type (contenttype, FALSE);
426 list = g_app_info_get_recommended_for_type (contenttype);
427 g_assert (g_app_info_equal (def, appinfo3)); /* default is unaffected */
428 g_assert_cmpint (g_list_length (list), ==, 2);
429 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
430 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo3));
431 g_object_unref (def);
432 g_list_free_full (list, g_object_unref);
434 /* 2. add another non-default association */
435 g_app_info_add_supports_type (appinfo2, contenttype, &error);
436 g_assert_no_error (error);
438 def = g_app_info_get_default_for_type (contenttype, FALSE);
439 list = g_app_info_get_recommended_for_type (contenttype);
440 g_assert (g_app_info_equal (def, appinfo3));
441 g_assert_cmpint (g_list_length (list), ==, 3);
442 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
443 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2));
444 g_assert (g_app_info_equal ((GAppInfo*)list->next->next->data, appinfo3));
445 g_object_unref (def);
446 g_list_free_full (list, g_object_unref);
448 /* 3. make the first app the default */
449 g_app_info_set_as_default_for_type (appinfo, contenttype, &error);
450 g_assert_no_error (error);
452 def = g_app_info_get_default_for_type (contenttype, FALSE);
453 list = g_app_info_get_recommended_for_type (contenttype);
454 g_assert (g_app_info_equal (def, appinfo));
455 g_assert_cmpint (g_list_length (list), ==, 3);
456 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
457 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2));
458 g_assert (g_app_info_equal ((GAppInfo*)list->next->next->data, appinfo3));
459 g_object_unref (def);
460 g_list_free_full (list, g_object_unref);
462 g_object_unref (appinfo);
463 g_object_unref (appinfo2);
464 g_object_unref (appinfo3);
467 /* test interaction between mimeinfo.cache, defaults.list and mimeapps.list
468 * to ensure g_app_info_set_as_last_used_for_type doesn't incorrectly
472 test_mime_default_last_used (void)
476 GError *error = NULL;
479 const gchar *contenttype = "image/bmp";
481 /* clear things out */
482 g_app_info_reset_type_associations (contenttype);
484 appinfo4 = (GAppInfo*)g_desktop_app_info_new ("myapp4.desktop");
485 appinfo5 = (GAppInfo*)g_desktop_app_info_new ("myapp5.desktop");
487 /* myapp4 is set as the default in defaults.list */
488 /* myapp4 and myapp5 can both handle image/bmp */
489 def = g_app_info_get_default_for_type (contenttype, FALSE);
490 list = g_app_info_get_recommended_for_type (contenttype);
491 g_assert (g_app_info_equal (def, appinfo4));
492 g_assert_cmpint (g_list_length (list), ==, 2);
493 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo4));
494 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo5));
495 g_object_unref (def);
496 g_list_free_full (list, g_object_unref);
498 /* 1. set default (myapp4) as last used */
499 g_app_info_set_as_last_used_for_type (appinfo4, contenttype, &error);
500 g_assert_no_error (error);
502 def = g_app_info_get_default_for_type (contenttype, FALSE);
503 list = g_app_info_get_recommended_for_type (contenttype);
504 g_assert (g_app_info_equal (def, appinfo4)); /* default is unaffected */
505 g_assert_cmpint (g_list_length (list), ==, 2);
506 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo4));
507 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo5));
508 g_object_unref (def);
509 g_list_free_full (list, g_object_unref);
511 /* 2. set other (myapp5) as last used */
512 g_app_info_set_as_last_used_for_type (appinfo5, contenttype, &error);
513 g_assert_no_error (error);
515 def = g_app_info_get_default_for_type (contenttype, FALSE);
516 list = g_app_info_get_recommended_for_type (contenttype);
517 g_assert (g_app_info_equal (def, appinfo4));
518 g_assert_cmpint (g_list_length (list), ==, 2);
519 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo5));
520 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo4));
521 g_object_unref (def);
522 g_list_free_full (list, g_object_unref);
524 /* 3. change the default to myapp5 */
525 g_app_info_set_as_default_for_type (appinfo5, contenttype, &error);
526 g_assert_no_error (error);
528 def = g_app_info_get_default_for_type (contenttype, FALSE);
529 list = g_app_info_get_recommended_for_type (contenttype);
530 g_assert (g_app_info_equal (def, appinfo5));
531 g_assert_cmpint (g_list_length (list), ==, 2);
532 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo5));
533 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo4));
534 g_object_unref (def);
535 g_list_free_full (list, g_object_unref);
537 /* 4. set myapp4 as last used */
538 g_app_info_set_as_last_used_for_type (appinfo4, contenttype, &error);
539 g_assert_no_error (error);
541 def = g_app_info_get_default_for_type (contenttype, FALSE);
542 list = g_app_info_get_recommended_for_type (contenttype);
543 g_assert (g_app_info_equal (def, appinfo5));
544 g_assert_cmpint (g_list_length (list), ==, 2);
545 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo4));
546 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo5));
547 g_object_unref (def);
548 g_list_free_full (list, g_object_unref);
550 /* 5. set myapp5 as last used again */
551 g_app_info_set_as_last_used_for_type (appinfo5, contenttype, &error);
552 g_assert_no_error (error);
554 def = g_app_info_get_default_for_type (contenttype, FALSE);
555 list = g_app_info_get_recommended_for_type (contenttype);
556 g_assert (g_app_info_equal (def, appinfo5));
557 g_assert_cmpint (g_list_length (list), ==, 2);
558 g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo5));
559 g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo4));
560 g_object_unref (def);
561 g_list_free_full (list, g_object_unref);
563 g_object_unref (appinfo4);
564 g_object_unref (appinfo5);
568 test_scheme_handler (void)
570 GAppInfo *info, *info5;
572 info5 = (GAppInfo*)g_desktop_app_info_new ("myapp5.desktop");
573 info = g_app_info_get_default_for_uri_scheme ("ftp");
574 g_assert (g_app_info_equal (info, info5));
576 g_object_unref (info);
577 g_object_unref (info5);
581 main (int argc, char *argv[])
584 g_test_init (&argc, &argv, NULL);
588 g_test_add_func ("/appinfo/mime/api", test_mime_api);
589 g_test_add_func ("/appinfo/mime/default", test_mime_default);
590 g_test_add_func ("/appinfo/mime/file", test_mime_file);
591 g_test_add_func ("/appinfo/mime/scheme-handler", test_scheme_handler);
592 g_test_add_func ("/appinfo/mime/default-last-used", test_mime_default_last_used);
594 return g_test_run ();