1 | #include <glib/gstdio.h> |
2 | #include <gio/gio.h> |
3 | #include <gio/gdesktopappinfo.h> |
4 | |
5 | static gboolean |
6 | strv_equal (gchar **strv, ...) |
7 | { |
8 | gint count; |
9 | va_list list; |
10 | const gchar *str; |
11 | gboolean res; |
12 | |
13 | res = TRUE; |
14 | count = 0; |
15 | va_start (list, strv); |
16 | while (1) |
17 | { |
18 | str = va_arg (list, const gchar *); |
19 | if (str == NULL) |
20 | break; |
21 | if (g_strcmp0 (str1: str, str2: strv[count]) != 0) |
22 | { |
23 | res = FALSE; |
24 | break; |
25 | } |
26 | count++; |
27 | } |
28 | va_end (list); |
29 | |
30 | if (res) |
31 | res = g_strv_length (str_array: strv) == count; |
32 | |
33 | return res; |
34 | } |
35 | |
36 | const gchar *myapp_data = |
37 | "[Desktop Entry]\n" |
38 | "Encoding=UTF-8\n" |
39 | "Version=1.0\n" |
40 | "Type=Application\n" |
41 | "Exec=true %f\n" |
42 | "Name=my app\n" ; |
43 | |
44 | const gchar *myapp2_data = |
45 | "[Desktop Entry]\n" |
46 | "Encoding=UTF-8\n" |
47 | "Version=1.0\n" |
48 | "Type=Application\n" |
49 | "Exec=sleep %f\n" |
50 | "Name=my app 2\n" ; |
51 | |
52 | const gchar *myapp3_data = |
53 | "[Desktop Entry]\n" |
54 | "Encoding=UTF-8\n" |
55 | "Version=1.0\n" |
56 | "Type=Application\n" |
57 | "Exec=sleep 1\n" |
58 | "Name=my app 3\n" |
59 | "MimeType=image/png;" ; |
60 | |
61 | const gchar *myapp4_data = |
62 | "[Desktop Entry]\n" |
63 | "Encoding=UTF-8\n" |
64 | "Version=1.0\n" |
65 | "Type=Application\n" |
66 | "Exec=echo %f\n" |
67 | "Name=my app 4\n" |
68 | "MimeType=image/bmp;" ; |
69 | |
70 | const gchar *myapp5_data = |
71 | "[Desktop Entry]\n" |
72 | "Encoding=UTF-8\n" |
73 | "Version=1.0\n" |
74 | "Type=Application\n" |
75 | "Exec=true %f\n" |
76 | "Name=my app 5\n" |
77 | "MimeType=image/bmp;x-scheme-handler/ftp;" ; |
78 | |
79 | const gchar *nosuchapp_data = |
80 | "[Desktop Entry]\n" |
81 | "Encoding=UTF-8\n" |
82 | "Version=1.0\n" |
83 | "Type=Application\n" |
84 | "Exec=no_such_application %f\n" |
85 | "Name=no such app\n" ; |
86 | |
87 | const gchar *defaults_data = |
88 | "[Default Applications]\n" |
89 | "image/bmp=myapp4.desktop;\n" |
90 | "image/png=myapp3.desktop;\n" |
91 | "x-scheme-handler/ftp=myapp5.desktop;\n" ; |
92 | |
93 | const gchar *mimecache_data = |
94 | "[MIME Cache]\n" |
95 | "image/bmp=myapp4.desktop;myapp5.desktop;\n" |
96 | "image/png=myapp3.desktop;\n" ; |
97 | |
98 | typedef struct |
99 | { |
100 | gchar *mimeapps_list_home; /* (owned) */ |
101 | } Fixture; |
102 | |
103 | /* Set up XDG_DATA_HOME and XDG_DATA_DIRS. |
104 | * XDG_DATA_DIRS/applications will contain mimeapps.list |
105 | * XDG_DATA_HOME/applications will contain myapp.desktop |
106 | * and myapp2.desktop, and no mimeapps.list |
107 | */ |
108 | static void |
109 | setup (Fixture *fixture, |
110 | gconstpointer test_data) |
111 | { |
112 | const gchar *xdgdatahome; |
113 | const gchar * const *xdgdatadirs; |
114 | gchar *appdir; |
115 | gchar *apphome; |
116 | gchar *mimeapps; |
117 | gchar *name; |
118 | gint res; |
119 | GError *error = NULL; |
120 | |
121 | /* These are already set to a temporary directory through our use of |
122 | * %G_TEST_OPTION_ISOLATE_DIRS below. */ |
123 | xdgdatahome = g_get_user_data_dir (); |
124 | xdgdatadirs = g_get_system_data_dirs (); |
125 | |
126 | appdir = g_build_filename (first_element: xdgdatadirs[0], "applications" , NULL); |
127 | g_test_message (format: "creating '%s'" , appdir); |
128 | res = g_mkdir_with_parents (pathname: appdir, mode: 0700); |
129 | g_assert_cmpint (res, ==, 0); |
130 | |
131 | name = g_build_filename (first_element: appdir, "mimeapps.list" , NULL); |
132 | g_test_message (format: "creating '%s'" , name); |
133 | g_file_set_contents (filename: name, contents: defaults_data, length: -1, error: &error); |
134 | g_assert_no_error (error); |
135 | g_free (mem: name); |
136 | |
137 | apphome = g_build_filename (first_element: xdgdatahome, "applications" , NULL); |
138 | g_test_message (format: "creating '%s'" , apphome); |
139 | res = g_mkdir_with_parents (pathname: apphome, mode: 0700); |
140 | g_assert_cmpint (res, ==, 0); |
141 | |
142 | name = g_build_filename (first_element: apphome, "myapp.desktop" , NULL); |
143 | g_test_message (format: "creating '%s'" , name); |
144 | g_file_set_contents (filename: name, contents: myapp_data, length: -1, error: &error); |
145 | g_assert_no_error (error); |
146 | g_free (mem: name); |
147 | |
148 | name = g_build_filename (first_element: apphome, "myapp2.desktop" , NULL); |
149 | g_test_message (format: "creating '%s'" , name); |
150 | g_file_set_contents (filename: name, contents: myapp2_data, length: -1, error: &error); |
151 | g_assert_no_error (error); |
152 | g_free (mem: name); |
153 | |
154 | name = g_build_filename (first_element: apphome, "myapp3.desktop" , NULL); |
155 | g_test_message (format: "creating '%s'" , name); |
156 | g_file_set_contents (filename: name, contents: myapp3_data, length: -1, error: &error); |
157 | g_assert_no_error (error); |
158 | g_free (mem: name); |
159 | |
160 | name = g_build_filename (first_element: apphome, "myapp4.desktop" , NULL); |
161 | g_test_message (format: "creating '%s'" , name); |
162 | g_file_set_contents (filename: name, contents: myapp4_data, length: -1, error: &error); |
163 | g_assert_no_error (error); |
164 | g_free (mem: name); |
165 | |
166 | name = g_build_filename (first_element: apphome, "myapp5.desktop" , NULL); |
167 | g_test_message (format: "creating '%s'" , name); |
168 | g_file_set_contents (filename: name, contents: myapp5_data, length: -1, error: &error); |
169 | g_assert_no_error (error); |
170 | g_free (mem: name); |
171 | |
172 | name = g_build_filename (first_element: apphome, "nosuchapp.desktop" , NULL); |
173 | g_test_message (format: "creating '%s'" , name); |
174 | g_file_set_contents (filename: name, contents: nosuchapp_data, length: -1, error: &error); |
175 | g_assert_no_error (error); |
176 | g_free (mem: name); |
177 | |
178 | mimeapps = g_build_filename (first_element: apphome, "mimeapps.list" , NULL); |
179 | g_test_message (format: "removing '%s'" , mimeapps); |
180 | g_remove (filename: mimeapps); |
181 | |
182 | name = g_build_filename (first_element: apphome, "mimeinfo.cache" , NULL); |
183 | g_test_message (format: "creating '%s'" , name); |
184 | g_file_set_contents (filename: name, contents: mimecache_data, length: -1, error: &error); |
185 | g_assert_no_error (error); |
186 | g_free (mem: name); |
187 | |
188 | g_free (mem: apphome); |
189 | g_free (mem: appdir); |
190 | g_free (mem: mimeapps); |
191 | |
192 | /* Pointer to one of the temporary directories. */ |
193 | fixture->mimeapps_list_home = g_build_filename (first_element: g_get_user_config_dir (), "mimeapps.list" , NULL); |
194 | } |
195 | |
196 | static void |
197 | teardown (Fixture *fixture, |
198 | gconstpointer test_data) |
199 | { |
200 | g_free (mem: fixture->mimeapps_list_home); |
201 | } |
202 | |
203 | static void |
204 | test_mime_api (Fixture *fixture, |
205 | gconstpointer test_data) |
206 | { |
207 | GAppInfo *appinfo; |
208 | GAppInfo *appinfo2; |
209 | GError *error = NULL; |
210 | GAppInfo *def; |
211 | GList *list; |
212 | const gchar *contenttype = "application/pdf" ; |
213 | |
214 | /* clear things out */ |
215 | g_app_info_reset_type_associations (content_type: contenttype); |
216 | |
217 | appinfo = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp.desktop" ); |
218 | appinfo2 = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp2.desktop" ); |
219 | |
220 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
221 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
222 | g_assert_null (def); |
223 | g_assert_null (list); |
224 | |
225 | /* 1. add a non-default association */ |
226 | g_app_info_add_supports_type (appinfo, content_type: contenttype, error: &error); |
227 | g_assert_no_error (error); |
228 | |
229 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
230 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
231 | g_assert_true (g_app_info_equal (def, appinfo)); |
232 | g_assert_cmpint (g_list_length (list), ==, 1); |
233 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); |
234 | g_object_unref (object: def); |
235 | g_list_free_full (list, free_func: g_object_unref); |
236 | |
237 | /* 2. add another non-default association */ |
238 | g_app_info_add_supports_type (appinfo: appinfo2, content_type: contenttype, error: &error); |
239 | g_assert_no_error (error); |
240 | |
241 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
242 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
243 | g_assert_true (g_app_info_equal (def, appinfo)); |
244 | g_assert_cmpint (g_list_length (list), ==, 2); |
245 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); |
246 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2)); |
247 | g_object_unref (object: def); |
248 | g_list_free_full (list, free_func: g_object_unref); |
249 | |
250 | /* 3. make the first app the default */ |
251 | g_app_info_set_as_default_for_type (appinfo, content_type: contenttype, error: &error); |
252 | g_assert_no_error (error); |
253 | |
254 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
255 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
256 | g_assert_true (g_app_info_equal (def, appinfo)); |
257 | g_assert_cmpint (g_list_length (list), ==, 2); |
258 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); |
259 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2)); |
260 | g_object_unref (object: def); |
261 | g_list_free_full (list, free_func: g_object_unref); |
262 | |
263 | /* 4. make the second app the last used one */ |
264 | g_app_info_set_as_last_used_for_type (appinfo: appinfo2, content_type: contenttype, error: &error); |
265 | g_assert_no_error (error); |
266 | |
267 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
268 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
269 | g_assert_true (g_app_info_equal (def, appinfo)); |
270 | g_assert_cmpint (g_list_length (list), ==, 2); |
271 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo2)); |
272 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo)); |
273 | g_object_unref (object: def); |
274 | g_list_free_full (list, free_func: g_object_unref); |
275 | |
276 | /* 5. reset everything */ |
277 | g_app_info_reset_type_associations (content_type: contenttype); |
278 | |
279 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
280 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
281 | g_assert_null (def); |
282 | g_assert_null (list); |
283 | |
284 | g_object_unref (object: appinfo); |
285 | g_object_unref (object: appinfo2); |
286 | } |
287 | |
288 | /* Repeat the same tests, this time checking that we handle |
289 | * mimeapps.list as expected. These tests are different from |
290 | * the ones in test_mime_api() in that we directly parse |
291 | * mimeapps.list to verify the results. |
292 | */ |
293 | static void |
294 | test_mime_file (Fixture *fixture, |
295 | gconstpointer test_data) |
296 | { |
297 | gchar **assoc; |
298 | GAppInfo *appinfo; |
299 | GAppInfo *appinfo2; |
300 | GError *error = NULL; |
301 | GKeyFile *keyfile; |
302 | gchar *str; |
303 | gboolean res; |
304 | GAppInfo *def; |
305 | GList *list; |
306 | const gchar *contenttype = "application/pdf" ; |
307 | |
308 | /* clear things out */ |
309 | g_app_info_reset_type_associations (content_type: contenttype); |
310 | |
311 | appinfo = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp.desktop" ); |
312 | appinfo2 = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp2.desktop" ); |
313 | |
314 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
315 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
316 | g_assert_null (def); |
317 | g_assert_null (list); |
318 | |
319 | /* 1. add a non-default association */ |
320 | g_app_info_add_supports_type (appinfo, content_type: contenttype, error: &error); |
321 | g_assert_no_error (error); |
322 | |
323 | keyfile = g_key_file_new (); |
324 | g_key_file_load_from_file (key_file: keyfile, file: fixture->mimeapps_list_home, flags: G_KEY_FILE_NONE, error: &error); |
325 | g_assert_no_error (error); |
326 | |
327 | assoc = g_key_file_get_string_list (key_file: keyfile, group_name: "Added Associations" , key: contenttype, NULL, error: &error); |
328 | g_assert_no_error (error); |
329 | g_assert_true (strv_equal (assoc, "myapp.desktop" , NULL)); |
330 | g_strfreev (str_array: assoc); |
331 | |
332 | /* we've unset XDG_DATA_DIRS so there should be no default */ |
333 | assoc = g_key_file_get_string_list (key_file: keyfile, group_name: "Default Applications" , key: contenttype, NULL, error: &error); |
334 | g_assert_nonnull (error); |
335 | g_clear_error (err: &error); |
336 | |
337 | g_key_file_free (key_file: keyfile); |
338 | |
339 | /* 2. add another non-default association */ |
340 | g_app_info_add_supports_type (appinfo: appinfo2, content_type: contenttype, error: &error); |
341 | g_assert_no_error (error); |
342 | |
343 | keyfile = g_key_file_new (); |
344 | g_key_file_load_from_file (key_file: keyfile, file: fixture->mimeapps_list_home, flags: G_KEY_FILE_NONE, error: &error); |
345 | g_assert_no_error (error); |
346 | |
347 | assoc = g_key_file_get_string_list (key_file: keyfile, group_name: "Added Associations" , key: contenttype, NULL, error: &error); |
348 | g_assert_no_error (error); |
349 | g_assert_true (strv_equal (assoc, "myapp.desktop" , "myapp2.desktop" , NULL)); |
350 | g_strfreev (str_array: assoc); |
351 | |
352 | assoc = g_key_file_get_string_list (key_file: keyfile, group_name: "Default Applications" , key: contenttype, NULL, error: &error); |
353 | g_assert_nonnull (error); |
354 | g_clear_error (err: &error); |
355 | |
356 | g_key_file_free (key_file: keyfile); |
357 | |
358 | /* 3. make the first app the default */ |
359 | g_app_info_set_as_default_for_type (appinfo, content_type: contenttype, error: &error); |
360 | g_assert_no_error (error); |
361 | |
362 | keyfile = g_key_file_new (); |
363 | g_key_file_load_from_file (key_file: keyfile, file: fixture->mimeapps_list_home, flags: G_KEY_FILE_NONE, error: &error); |
364 | g_assert_no_error (error); |
365 | |
366 | assoc = g_key_file_get_string_list (key_file: keyfile, group_name: "Added Associations" , key: contenttype, NULL, error: &error); |
367 | g_assert_no_error (error); |
368 | g_assert_true (strv_equal (assoc, "myapp.desktop" , "myapp2.desktop" , NULL)); |
369 | g_strfreev (str_array: assoc); |
370 | |
371 | str = g_key_file_get_string (key_file: keyfile, group_name: "Default Applications" , key: contenttype, error: &error); |
372 | g_assert_no_error (error); |
373 | g_assert_cmpstr (str, ==, "myapp.desktop" ); |
374 | g_free (mem: str); |
375 | |
376 | g_key_file_free (key_file: keyfile); |
377 | |
378 | /* 4. make the second app the last used one */ |
379 | g_app_info_set_as_last_used_for_type (appinfo: appinfo2, content_type: contenttype, error: &error); |
380 | g_assert_no_error (error); |
381 | |
382 | keyfile = g_key_file_new (); |
383 | g_key_file_load_from_file (key_file: keyfile, file: fixture->mimeapps_list_home, flags: G_KEY_FILE_NONE, error: &error); |
384 | g_assert_no_error (error); |
385 | |
386 | assoc = g_key_file_get_string_list (key_file: keyfile, group_name: "Added Associations" , key: contenttype, NULL, error: &error); |
387 | g_assert_no_error (error); |
388 | g_assert_true (strv_equal (assoc, "myapp2.desktop" , "myapp.desktop" , NULL)); |
389 | g_strfreev (str_array: assoc); |
390 | |
391 | g_key_file_free (key_file: keyfile); |
392 | |
393 | /* 5. reset everything */ |
394 | g_app_info_reset_type_associations (content_type: contenttype); |
395 | |
396 | keyfile = g_key_file_new (); |
397 | g_key_file_load_from_file (key_file: keyfile, file: fixture->mimeapps_list_home, flags: G_KEY_FILE_NONE, error: &error); |
398 | g_assert_no_error (error); |
399 | |
400 | res = g_key_file_has_key (key_file: keyfile, group_name: "Added Associations" , key: contenttype, NULL); |
401 | g_assert_false (res); |
402 | |
403 | res = g_key_file_has_key (key_file: keyfile, group_name: "Default Applications" , key: contenttype, NULL); |
404 | g_assert_false (res); |
405 | |
406 | g_key_file_free (key_file: keyfile); |
407 | |
408 | g_object_unref (object: appinfo); |
409 | g_object_unref (object: appinfo2); |
410 | } |
411 | |
412 | /* test interaction between mimeapps.list at different levels */ |
413 | static void |
414 | test_mime_default (Fixture *fixture, |
415 | gconstpointer test_data) |
416 | { |
417 | GAppInfo *appinfo; |
418 | GAppInfo *appinfo2; |
419 | GAppInfo *appinfo3; |
420 | GError *error = NULL; |
421 | GAppInfo *def; |
422 | GList *list; |
423 | const gchar *contenttype = "image/png" ; |
424 | |
425 | /* clear things out */ |
426 | g_app_info_reset_type_associations (content_type: contenttype); |
427 | |
428 | appinfo = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp.desktop" ); |
429 | appinfo2 = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp2.desktop" ); |
430 | appinfo3 = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp3.desktop" ); |
431 | |
432 | /* myapp3 is set as the default in defaults.list */ |
433 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
434 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
435 | g_assert_true (g_app_info_equal (def, appinfo3)); |
436 | g_assert_cmpint (g_list_length (list), ==, 1); |
437 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo3)); |
438 | g_object_unref (object: def); |
439 | g_list_free_full (list, free_func: g_object_unref); |
440 | |
441 | /* 1. add a non-default association */ |
442 | g_app_info_add_supports_type (appinfo, content_type: contenttype, error: &error); |
443 | g_assert_no_error (error); |
444 | |
445 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
446 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
447 | g_assert_true (g_app_info_equal (def, appinfo3)); /* default is unaffected */ |
448 | g_assert_cmpint (g_list_length (list), ==, 2); |
449 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); |
450 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo3)); |
451 | g_object_unref (object: def); |
452 | g_list_free_full (list, free_func: g_object_unref); |
453 | |
454 | /* 2. add another non-default association */ |
455 | g_app_info_add_supports_type (appinfo: appinfo2, content_type: contenttype, error: &error); |
456 | g_assert_no_error (error); |
457 | |
458 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
459 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
460 | g_assert_true (g_app_info_equal (def, appinfo3)); |
461 | g_assert_cmpint (g_list_length (list), ==, 3); |
462 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); |
463 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2)); |
464 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->next->data, appinfo3)); |
465 | g_object_unref (object: def); |
466 | g_list_free_full (list, free_func: g_object_unref); |
467 | |
468 | /* 3. make the first app the default */ |
469 | g_app_info_set_as_default_for_type (appinfo, content_type: contenttype, error: &error); |
470 | g_assert_no_error (error); |
471 | |
472 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
473 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
474 | g_assert_true (g_app_info_equal (def, appinfo)); |
475 | g_assert_cmpint (g_list_length (list), ==, 3); |
476 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo)); |
477 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2)); |
478 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->next->data, appinfo3)); |
479 | g_object_unref (object: def); |
480 | g_list_free_full (list, free_func: g_object_unref); |
481 | |
482 | g_object_unref (object: appinfo); |
483 | g_object_unref (object: appinfo2); |
484 | g_object_unref (object: appinfo3); |
485 | } |
486 | |
487 | /* test interaction between mimeinfo.cache, defaults.list and mimeapps.list |
488 | * to ensure g_app_info_set_as_last_used_for_type doesn't incorrectly |
489 | * change the default |
490 | */ |
491 | static void |
492 | test_mime_default_last_used (Fixture *fixture, |
493 | gconstpointer test_data) |
494 | { |
495 | GAppInfo *appinfo4; |
496 | GAppInfo *appinfo5; |
497 | GError *error = NULL; |
498 | GAppInfo *def; |
499 | GList *list; |
500 | const gchar *contenttype = "image/bmp" ; |
501 | |
502 | /* clear things out */ |
503 | g_app_info_reset_type_associations (content_type: contenttype); |
504 | |
505 | appinfo4 = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp4.desktop" ); |
506 | appinfo5 = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp5.desktop" ); |
507 | |
508 | /* myapp4 is set as the default in defaults.list */ |
509 | /* myapp4 and myapp5 can both handle image/bmp */ |
510 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
511 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
512 | g_assert_true (g_app_info_equal (def, appinfo4)); |
513 | g_assert_cmpint (g_list_length (list), ==, 2); |
514 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo4)); |
515 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo5)); |
516 | g_object_unref (object: def); |
517 | g_list_free_full (list, free_func: g_object_unref); |
518 | |
519 | /* 1. set default (myapp4) as last used */ |
520 | g_app_info_set_as_last_used_for_type (appinfo: appinfo4, content_type: contenttype, error: &error); |
521 | g_assert_no_error (error); |
522 | |
523 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
524 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
525 | g_assert_true (g_app_info_equal (def, appinfo4)); /* default is unaffected */ |
526 | g_assert_cmpint (g_list_length (list), ==, 2); |
527 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo4)); |
528 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo5)); |
529 | g_object_unref (object: def); |
530 | g_list_free_full (list, free_func: g_object_unref); |
531 | |
532 | /* 2. set other (myapp5) as last used */ |
533 | g_app_info_set_as_last_used_for_type (appinfo: appinfo5, content_type: contenttype, error: &error); |
534 | g_assert_no_error (error); |
535 | |
536 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
537 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
538 | g_assert_true (g_app_info_equal (def, appinfo4)); |
539 | g_assert_cmpint (g_list_length (list), ==, 2); |
540 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo5)); |
541 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo4)); |
542 | g_object_unref (object: def); |
543 | g_list_free_full (list, free_func: g_object_unref); |
544 | |
545 | /* 3. change the default to myapp5 */ |
546 | g_app_info_set_as_default_for_type (appinfo: appinfo5, content_type: contenttype, error: &error); |
547 | g_assert_no_error (error); |
548 | |
549 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
550 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
551 | g_assert_true (g_app_info_equal (def, appinfo5)); |
552 | g_assert_cmpint (g_list_length (list), ==, 2); |
553 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo5)); |
554 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo4)); |
555 | g_object_unref (object: def); |
556 | g_list_free_full (list, free_func: g_object_unref); |
557 | |
558 | /* 4. set myapp4 as last used */ |
559 | g_app_info_set_as_last_used_for_type (appinfo: appinfo4, content_type: contenttype, error: &error); |
560 | g_assert_no_error (error); |
561 | |
562 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
563 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
564 | g_assert_true (g_app_info_equal (def, appinfo5)); |
565 | g_assert_cmpint (g_list_length (list), ==, 2); |
566 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo4)); |
567 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo5)); |
568 | g_object_unref (object: def); |
569 | g_list_free_full (list, free_func: g_object_unref); |
570 | |
571 | /* 5. set myapp5 as last used again */ |
572 | g_app_info_set_as_last_used_for_type (appinfo: appinfo5, content_type: contenttype, error: &error); |
573 | g_assert_no_error (error); |
574 | |
575 | def = g_app_info_get_default_for_type (content_type: contenttype, FALSE); |
576 | list = g_app_info_get_recommended_for_type (content_type: contenttype); |
577 | g_assert_true (g_app_info_equal (def, appinfo5)); |
578 | g_assert_cmpint (g_list_length (list), ==, 2); |
579 | g_assert_true (g_app_info_equal ((GAppInfo*)list->data, appinfo5)); |
580 | g_assert_true (g_app_info_equal ((GAppInfo*)list->next->data, appinfo4)); |
581 | g_object_unref (object: def); |
582 | g_list_free_full (list, free_func: g_object_unref); |
583 | |
584 | g_object_unref (object: appinfo4); |
585 | g_object_unref (object: appinfo5); |
586 | } |
587 | |
588 | static void |
589 | test_scheme_handler (Fixture *fixture, |
590 | gconstpointer test_data) |
591 | { |
592 | GAppInfo *info, *info5; |
593 | |
594 | info5 = (GAppInfo*)g_desktop_app_info_new (desktop_id: "myapp5.desktop" ); |
595 | info = g_app_info_get_default_for_uri_scheme (uri_scheme: "ftp" ); |
596 | g_assert_true (g_app_info_equal (info, info5)); |
597 | |
598 | g_object_unref (object: info); |
599 | g_object_unref (object: info5); |
600 | } |
601 | |
602 | /* test that g_app_info_* ignores desktop files with nonexisting executables |
603 | */ |
604 | static void |
605 | test_mime_ignore_nonexisting (Fixture *fixture, |
606 | gconstpointer test_data) |
607 | { |
608 | GAppInfo *appinfo; |
609 | |
610 | appinfo = (GAppInfo*)g_desktop_app_info_new (desktop_id: "nosuchapp.desktop" ); |
611 | g_assert_null (appinfo); |
612 | } |
613 | |
614 | static void |
615 | test_all (Fixture *fixture, |
616 | gconstpointer test_data) |
617 | { |
618 | GList *all, *l; |
619 | |
620 | all = g_app_info_get_all (); |
621 | |
622 | for (l = all; l; l = l->next) |
623 | g_assert_true (G_IS_APP_INFO (l->data)); |
624 | |
625 | g_list_free_full (list: all, free_func: g_object_unref); |
626 | } |
627 | |
628 | int |
629 | main (int argc, char *argv[]) |
630 | { |
631 | g_test_init (argc: &argc, argv: &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); |
632 | |
633 | g_test_add ("/appinfo/mime/api" , Fixture, NULL, setup, |
634 | test_mime_api, teardown); |
635 | g_test_add ("/appinfo/mime/default" , Fixture, NULL, setup, |
636 | test_mime_default, teardown); |
637 | g_test_add ("/appinfo/mime/file" , Fixture, NULL, setup, |
638 | test_mime_file, teardown); |
639 | g_test_add ("/appinfo/mime/scheme-handler" , Fixture, NULL, setup, |
640 | test_scheme_handler, teardown); |
641 | g_test_add ("/appinfo/mime/default-last-used" , Fixture, NULL, setup, |
642 | test_mime_default_last_used, teardown); |
643 | g_test_add ("/appinfo/mime/ignore-nonexisting" , Fixture, NULL, setup, |
644 | test_mime_ignore_nonexisting, teardown); |
645 | g_test_add ("/appinfo/all" , Fixture, NULL, setup, test_all, teardown); |
646 | |
647 | return g_test_run (); |
648 | } |
649 | |