Remove g_type_init() calls
[platform/upstream/glib.git] / gio / tests / mimeapps.c
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 (str, 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 (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=my_app %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=my_app2 %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=my_app3 %f\n"
58   "Name=my app 3\n";
59
60 const gchar *myapp4_data =
61   "[Desktop Entry]\n"
62   "Encoding=UTF-8\n"
63   "Version=1.0\n"
64   "Type=Application\n"
65   "Exec=my_app4 %f\n"
66   "Name=my app 4\n"
67   "MimeType=image/bmp;";
68
69 const gchar *myapp5_data =
70   "[Desktop Entry]\n"
71   "Encoding=UTF-8\n"
72   "Version=1.0\n"
73   "Type=Application\n"
74   "Exec=my_app5 %f\n"
75   "Name=my app 5\n"
76   "MimeType=image/bmp;x-scheme-handler/ftp;";
77
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";
83
84 const gchar *mimecache_data =
85   "[MIME Cache]\n"
86   "image/bmp=myapp4.desktop;myapp5.desktop;\n";
87
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
92  */
93 static void
94 setup (void)
95 {
96   gchar *dir;
97   gchar *xdgdatahome;
98   gchar *xdgdatadir;
99   gchar *appdir;
100   gchar *apphome;
101   gchar *mimeapps;
102   gchar *name;
103   gboolean res;
104   GError *error = NULL;
105
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);
113
114   appdir = g_build_filename (xdgdatadir, "applications", NULL);
115   g_test_message ("creating '%s'\n", appdir);
116   res = g_mkdir_with_parents (appdir, 0700);
117   g_assert (res == 0);
118
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);
123   g_free (name);
124
125   apphome = g_build_filename (xdgdatahome, "applications", NULL);
126   g_test_message ("creating '%s'\n", apphome);
127   res = g_mkdir_with_parents (apphome, 0700);
128   g_assert (res == 0);
129
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);
134   g_free (name);
135
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);
140   g_free (name);
141
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);
146   g_free (name);
147
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);
152   g_free (name);
153
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);
158   g_free (name);
159
160   mimeapps = g_build_filename (apphome, "mimeapps.list", NULL);
161   g_test_message ("removing '%s'\n", mimeapps);
162   g_remove (mimeapps);
163
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);
168   g_free (name);
169
170   g_free (dir);
171   g_free (xdgdatahome);
172   g_free (xdgdatadir);
173   g_free (apphome);
174   g_free (appdir);
175   g_free (mimeapps);
176 }
177
178 static void
179 test_mime_api (void)
180 {
181   GAppInfo *appinfo;
182   GAppInfo *appinfo2;
183   GError *error = NULL;
184   GAppInfo *def;
185   GList *list;
186   const gchar *contenttype = "application/pdf";
187
188   /* clear things out */
189   g_app_info_reset_type_associations (contenttype);
190
191   appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop");
192   appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop");
193
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);
198
199   /* 1. add a non-default association */
200   g_app_info_add_supports_type (appinfo, contenttype, &error);
201   g_assert_no_error (error);
202
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);
210
211   /* 2. add another non-default association */
212   g_app_info_add_supports_type (appinfo2, contenttype, &error);
213   g_assert_no_error (error);
214
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);
223
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);
227
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);
236
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);
240
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);
249
250   /* 5. reset everything */
251   g_app_info_reset_type_associations (contenttype);
252
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);
257
258   g_object_unref (appinfo);
259   g_object_unref (appinfo2);
260 }
261
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.
266  */
267 static void
268 test_mime_file (void)
269 {
270   gchar **assoc;
271   GAppInfo *appinfo;
272   GAppInfo *appinfo2;
273   GError *error = NULL;
274   GKeyFile *keyfile;
275   gchar *str;
276   gboolean res;
277   GAppInfo *def;
278   GList *list;
279   gchar *mimeapps;
280   gchar *dir;
281   const gchar *contenttype = "application/pdf";
282
283   dir = g_get_current_dir ();
284   mimeapps = g_build_filename (dir, "xdgdatahome", "applications", "mimeapps.list", NULL);
285
286   /* clear things out */
287   g_app_info_reset_type_associations (contenttype);
288
289   appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop");
290   appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop");
291
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);
296
297   /* 1. add a non-default association */
298   g_app_info_add_supports_type (appinfo, contenttype, &error);
299   g_assert_no_error (error);
300
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);
304
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));
308   g_strfreev (assoc);
309
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);
314
315   g_key_file_free (keyfile);
316
317   /* 2. add another non-default association */
318   g_app_info_add_supports_type (appinfo2, contenttype, &error);
319   g_assert_no_error (error);
320
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);
324
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));
328   g_strfreev (assoc);
329
330   assoc = g_key_file_get_string_list (keyfile, "Default Applications", contenttype, NULL, &error);
331   g_assert (error != NULL);
332   g_clear_error (&error);
333
334   g_key_file_free (keyfile);
335
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);
339
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);
343
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));
347   g_strfreev (assoc);
348
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");
352   g_free (str);
353
354   g_key_file_free (keyfile);
355
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);
359
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);
363
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));
367   g_strfreev (assoc);
368
369   g_key_file_free (keyfile);
370
371   /* 5. reset everything */
372   g_app_info_reset_type_associations (contenttype);
373
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);
377
378   res = g_key_file_has_key (keyfile, "Added Associations", contenttype, NULL);
379   g_assert (!res);
380
381   res = g_key_file_has_key (keyfile, "Default Applications", contenttype, NULL);
382   g_assert (!res);
383
384   g_key_file_free (keyfile);
385
386   g_object_unref (appinfo);
387   g_object_unref (appinfo2);
388
389   g_free (mimeapps);
390   g_free (dir);
391 }
392
393 /* test interaction between defaults.list and mimeapps.list */
394 static void
395 test_mime_default (void)
396 {
397   GAppInfo *appinfo;
398   GAppInfo *appinfo2;
399   GAppInfo *appinfo3;
400   GError *error = NULL;
401   GAppInfo *def;
402   GList *list;
403   const gchar *contenttype = "image/png";
404
405   /* clear things out */
406   g_app_info_reset_type_associations (contenttype);
407
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");
411
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);
420
421   /* 1. add a non-default association */
422   g_app_info_add_supports_type (appinfo, contenttype, &error);
423   g_assert_no_error (error);
424
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);
433
434   /* 2. add another non-default association */
435   g_app_info_add_supports_type (appinfo2, contenttype, &error);
436   g_assert_no_error (error);
437
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);
447
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);
451
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);
461
462   g_object_unref (appinfo);
463   g_object_unref (appinfo2);
464   g_object_unref (appinfo3);
465 }
466
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
469  * change the default
470  */
471 static void
472 test_mime_default_last_used (void)
473 {
474   GAppInfo *appinfo4;
475   GAppInfo *appinfo5;
476   GError *error = NULL;
477   GAppInfo *def;
478   GList *list;
479   const gchar *contenttype = "image/bmp";
480
481   /* clear things out */
482   g_app_info_reset_type_associations (contenttype);
483
484   appinfo4 = (GAppInfo*)g_desktop_app_info_new ("myapp4.desktop");
485   appinfo5 = (GAppInfo*)g_desktop_app_info_new ("myapp5.desktop");
486
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);
497
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);
501
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);
510
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);
514
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);
523
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);
527
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);
536
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);
540
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);
549
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);
553
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);
562
563   g_object_unref (appinfo4);
564   g_object_unref (appinfo5);
565 }
566
567 static void
568 test_scheme_handler (void)
569 {
570   GAppInfo *info, *info5;
571
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));
575
576   g_object_unref (info);
577   g_object_unref (info5);
578 }
579
580 int
581 main (int argc, char *argv[])
582 {
583   g_test_init (&argc, &argv, NULL);
584
585   setup ();
586
587   g_test_add_func ("/appinfo/mime/api", test_mime_api);
588   g_test_add_func ("/appinfo/mime/default", test_mime_default);
589   g_test_add_func ("/appinfo/mime/file", test_mime_file);
590   g_test_add_func ("/appinfo/mime/scheme-handler", test_scheme_handler);
591   g_test_add_func ("/appinfo/mime/default-last-used", test_mime_default_last_used);
592
593   return g_test_run ();
594 }