Expand mimeapps test
[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 *defaults_data =
61   "[Default Applications]\n"
62   "image/png=myapp3.desktop;\n";
63
64 /* Set up XDG_DATA_HOME and XDG_DATA_DIRS.
65  * XDG_DATA_DIRS/applications will contain defaults.list
66  * XDG_DATA_HOME/applications will contain myapp.desktop
67  * and myapp2.desktop, and no mimeapps.list
68  */
69 static void
70 setup (void)
71 {
72   gchar *dir;
73   gchar *xdgdatahome;
74   gchar *xdgdatadir;
75   gchar *appdir;
76   gchar *apphome;
77   gchar *mimeapps;
78   gchar *name;
79   gboolean res;
80   GError *error = NULL;
81
82   dir = g_get_current_dir ();
83   xdgdatahome = g_build_filename (dir, "xdgdatahome", NULL);
84   xdgdatadir = g_build_filename (dir, "xdgdatadir", NULL);
85   g_test_message ("setting XDG_DATA_HOME to '%s'\n", xdgdatahome);
86   g_setenv ("XDG_DATA_HOME", xdgdatahome, TRUE);
87   g_test_message ("setting XDG_DATA_DIRS to '%s'\n", xdgdatadir);
88   g_setenv ("XDG_DATA_DIRS", xdgdatadir, TRUE);
89
90   appdir = g_build_filename (xdgdatadir, "applications", NULL);
91   g_test_message ("creating '%s'\n", appdir);
92   res = g_mkdir_with_parents (appdir, 0700);
93   g_assert (res == 0);
94
95   name = g_build_filename (appdir, "defaults.list", NULL);
96   g_test_message ("creating '%s'\n", name);
97   g_file_set_contents (name, defaults_data, -1, &error);
98   g_assert_no_error (error);
99   g_free (name);
100
101   apphome = g_build_filename (xdgdatahome, "applications", NULL);
102   g_test_message ("creating '%s'\n", apphome);
103   res = g_mkdir_with_parents (apphome, 0700);
104   g_assert (res == 0);
105
106   name = g_build_filename (apphome, "myapp.desktop", NULL);
107   g_test_message ("creating '%s'\n", name);
108   g_file_set_contents (name, myapp_data, -1, &error);
109   g_assert_no_error (error);
110   g_free (name);
111
112   name = g_build_filename (apphome, "myapp2.desktop", NULL);
113   g_test_message ("creating '%s'\n", name);
114   g_file_set_contents (name, myapp2_data, -1, &error);
115   g_assert_no_error (error);
116   g_free (name);
117
118   name = g_build_filename (apphome, "myapp3.desktop", NULL);
119   g_test_message ("creating '%s'\n", name);
120   g_file_set_contents (name, myapp3_data, -1, &error);
121   g_assert_no_error (error);
122   g_free (name);
123
124   mimeapps = g_build_filename (apphome, "mimeapps.list", NULL);
125   g_test_message ("removing '%s'\n", mimeapps);
126   g_remove (mimeapps);
127
128   g_free (dir);
129   g_free (xdgdatahome);
130   g_free (xdgdatadir);
131   g_free (apphome);
132   g_free (appdir);
133   g_free (mimeapps);
134 }
135
136 static void
137 test_mime_api (void)
138 {
139   GAppInfo *appinfo;
140   GAppInfo *appinfo2;
141   GError *error = NULL;
142   GAppInfo *def;
143   GList *list;
144   const gchar *contenttype = "application/pdf";
145
146   /* clear things out */
147   g_app_info_reset_type_associations (contenttype);
148
149   appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop");
150   appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop");
151
152   def = g_app_info_get_default_for_type (contenttype, FALSE);
153   list = g_app_info_get_recommended_for_type (contenttype);
154   g_assert (def == NULL);
155   g_assert (list == NULL);
156
157   /* 1. add a non-default association */
158   g_app_info_add_supports_type (appinfo, contenttype, &error);
159   g_assert_no_error (error);
160
161   def = g_app_info_get_default_for_type (contenttype, FALSE);
162   list = g_app_info_get_recommended_for_type (contenttype);
163   g_assert (g_app_info_equal (def, appinfo));
164   g_assert_cmpint (g_list_length (list), ==, 1);
165   g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
166   g_object_unref (def);
167   g_list_free_full (list, g_object_unref);
168
169   /* 2. add another non-default association */
170   g_app_info_add_supports_type (appinfo2, contenttype, &error);
171   g_assert_no_error (error);
172
173   def = g_app_info_get_default_for_type (contenttype, FALSE);
174   list = g_app_info_get_recommended_for_type (contenttype);
175   g_assert (g_app_info_equal (def, appinfo));
176   g_assert_cmpint (g_list_length (list), ==, 2);
177   g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
178   g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2));
179   g_object_unref (def);
180   g_list_free_full (list, g_object_unref);
181
182   /* 3. make the first app the default */
183   g_app_info_set_as_default_for_type (appinfo, contenttype, &error);
184   g_assert_no_error (error);
185
186   def = g_app_info_get_default_for_type (contenttype, FALSE);
187   list = g_app_info_get_recommended_for_type (contenttype);
188   g_assert (g_app_info_equal (def, appinfo));
189   g_assert_cmpint (g_list_length (list), ==, 2);
190   g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
191   g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2));
192   g_object_unref (def);
193   g_list_free_full (list, g_object_unref);
194
195   /* 4. make the second app the last used one */
196   g_app_info_set_as_last_used_for_type (appinfo2, contenttype, &error);
197   g_assert_no_error (error);
198
199   def = g_app_info_get_default_for_type (contenttype, FALSE);
200   list = g_app_info_get_recommended_for_type (contenttype);
201   g_assert (g_app_info_equal (def, appinfo));
202   g_assert_cmpint (g_list_length (list), ==, 2);
203   g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo2));
204   g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo));
205   g_object_unref (def);
206   g_list_free_full (list, g_object_unref);
207
208   /* 5. reset everything */
209   g_app_info_reset_type_associations (contenttype);
210
211   def = g_app_info_get_default_for_type (contenttype, FALSE);
212   list = g_app_info_get_recommended_for_type (contenttype);
213   g_assert (def == NULL);
214   g_assert (list == NULL);
215
216   g_object_unref (appinfo);
217   g_object_unref (appinfo2);
218 }
219
220 /* Repeat the same tests, this time checking that we handle
221  * mimeapps.list as expected. These tests are different from
222  * the ones in test_mime_api() in that we directly parse
223  * mimeapps.list to verify the results.
224  */
225 static void
226 test_mime_file (void)
227 {
228   gchar **assoc;
229   GAppInfo *appinfo;
230   GAppInfo *appinfo2;
231   GError *error = NULL;
232   GKeyFile *keyfile;
233   gchar *str;
234   gboolean res;
235   GAppInfo *def;
236   GList *list;
237   gchar *mimeapps;
238   gchar *dir;
239   const gchar *contenttype = "application/pdf";
240
241   dir = g_get_current_dir ();
242   mimeapps = g_build_filename (dir, "xdgdatahome", "applications", "mimeapps.list", NULL);
243
244   /* clear things out */
245   g_app_info_reset_type_associations (contenttype);
246
247   appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop");
248   appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop");
249
250   def = g_app_info_get_default_for_type (contenttype, FALSE);
251   list = g_app_info_get_recommended_for_type (contenttype);
252   g_assert (def == NULL);
253   g_assert (list == NULL);
254
255   /* 1. add a non-default association */
256   g_app_info_add_supports_type (appinfo, contenttype, &error);
257   g_assert_no_error (error);
258
259   keyfile = g_key_file_new ();
260   g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
261   g_assert_no_error (error);
262
263   assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error);
264   g_assert_no_error (error);
265   g_assert (strv_equal (assoc, "myapp.desktop", NULL));
266   g_strfreev (assoc);
267
268   /* we've unset XDG_DATA_DIRS so there should be no default */
269   assoc = g_key_file_get_string_list (keyfile, "Default Applications", contenttype, NULL, &error);
270   g_assert (error != NULL);
271   g_clear_error (&error);
272
273   g_key_file_free (keyfile);
274
275   /* 2. add another non-default association */
276   g_app_info_add_supports_type (appinfo2, contenttype, &error);
277   g_assert_no_error (error);
278
279   keyfile = g_key_file_new ();
280   g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
281   g_assert_no_error (error);
282
283   assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error);
284   g_assert_no_error (error);
285   g_assert (strv_equal (assoc, "myapp.desktop", "myapp2.desktop", NULL));
286   g_strfreev (assoc);
287
288   assoc = g_key_file_get_string_list (keyfile, "Default Applications", contenttype, NULL, &error);
289   g_assert (error != NULL);
290   g_clear_error (&error);
291
292   g_key_file_free (keyfile);
293
294   /* 3. make the first app the default */
295   g_app_info_set_as_default_for_type (appinfo, contenttype, &error);
296   g_assert_no_error (error);
297
298   keyfile = g_key_file_new ();
299   g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
300   g_assert_no_error (error);
301
302   assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error);
303   g_assert_no_error (error);
304   g_assert (strv_equal (assoc, "myapp.desktop", "myapp2.desktop", NULL));
305   g_strfreev (assoc);
306
307   str = g_key_file_get_string (keyfile, "Default Applications", contenttype, &error);
308   g_assert_no_error (error);
309   g_assert_cmpstr (str, ==, "myapp.desktop");
310
311   g_key_file_free (keyfile);
312
313   /* 4. make the second app the last used one */
314   g_app_info_set_as_last_used_for_type (appinfo2, contenttype, &error);
315   g_assert_no_error (error);
316
317   keyfile = g_key_file_new ();
318   g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
319   g_assert_no_error (error);
320
321   assoc = g_key_file_get_string_list (keyfile, "Added Associations", contenttype, NULL, &error);
322   g_assert_no_error (error);
323   g_assert (strv_equal (assoc, "myapp2.desktop", "myapp.desktop", NULL));
324   g_strfreev (assoc);
325
326   g_key_file_free (keyfile);
327
328   /* 5. reset everything */
329   g_app_info_reset_type_associations (contenttype);
330
331   keyfile = g_key_file_new ();
332   g_key_file_load_from_file (keyfile, mimeapps, G_KEY_FILE_NONE, &error);
333   g_assert_no_error (error);
334
335   res = g_key_file_has_key (keyfile, "Added Associations", contenttype, NULL);
336   g_assert (!res);
337
338   res = g_key_file_has_key (keyfile, "Default Applications", contenttype, NULL);
339   g_assert (!res);
340
341   g_key_file_free (keyfile);
342
343   g_object_unref (appinfo);
344   g_object_unref (appinfo2);
345
346   g_free (mimeapps);
347   g_free (dir);
348 }
349
350 /* test interaction between defaults.list and mimeapps.list */
351 static void
352 test_mime_default (void)
353 {
354   GAppInfo *appinfo;
355   GAppInfo *appinfo2;
356   GAppInfo *appinfo3;
357   GError *error = NULL;
358   GAppInfo *def;
359   GList *list;
360   const gchar *contenttype = "image/png";
361
362   /* clear things out */
363   g_app_info_reset_type_associations (contenttype);
364
365   appinfo = (GAppInfo*)g_desktop_app_info_new ("myapp.desktop");
366   appinfo2 = (GAppInfo*)g_desktop_app_info_new ("myapp2.desktop");
367   appinfo3 = (GAppInfo*)g_desktop_app_info_new ("myapp3.desktop");
368
369   /* myapp3 is set as the default in defaults.list */
370   def = g_app_info_get_default_for_type (contenttype, FALSE);
371   list = g_app_info_get_recommended_for_type (contenttype);
372   g_assert (g_app_info_equal (def, appinfo3));
373   g_assert_cmpint (g_list_length (list), ==, 1);
374   g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo3));
375   g_object_unref (def);
376   g_list_free_full (list, g_object_unref);
377
378   /* 1. add a non-default association */
379   g_app_info_add_supports_type (appinfo, contenttype, &error);
380   g_assert_no_error (error);
381
382   def = g_app_info_get_default_for_type (contenttype, FALSE);
383   list = g_app_info_get_recommended_for_type (contenttype);
384   g_assert (g_app_info_equal (def, appinfo3)); /* default is unaffected */
385   g_assert_cmpint (g_list_length (list), ==, 2);
386   g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
387   g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo3));
388   g_object_unref (def);
389   g_list_free_full (list, g_object_unref);
390
391   /* 2. add another non-default association */
392   g_app_info_add_supports_type (appinfo2, contenttype, &error);
393   g_assert_no_error (error);
394
395   def = g_app_info_get_default_for_type (contenttype, FALSE);
396   list = g_app_info_get_recommended_for_type (contenttype);
397   g_assert (g_app_info_equal (def, appinfo3));
398   g_assert_cmpint (g_list_length (list), ==, 3);
399   g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
400   g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2));
401   g_assert (g_app_info_equal ((GAppInfo*)list->next->next->data, appinfo3));
402   g_object_unref (def);
403   g_list_free_full (list, g_object_unref);
404
405   /* 3. make the first app the default */
406   g_app_info_set_as_default_for_type (appinfo, contenttype, &error);
407   g_assert_no_error (error);
408
409   def = g_app_info_get_default_for_type (contenttype, FALSE);
410   list = g_app_info_get_recommended_for_type (contenttype);
411   g_assert (g_app_info_equal (def, appinfo));
412   g_assert_cmpint (g_list_length (list), ==, 3);
413   g_assert (g_app_info_equal ((GAppInfo*)list->data, appinfo));
414   g_assert (g_app_info_equal ((GAppInfo*)list->next->data, appinfo2));
415   g_assert (g_app_info_equal ((GAppInfo*)list->next->next->data, appinfo3));
416   g_object_unref (def);
417   g_list_free_full (list, g_object_unref);
418
419   g_object_unref (appinfo);
420   g_object_unref (appinfo2);
421   g_object_unref (appinfo3);
422 }
423
424 int
425 main (int argc, char *argv[])
426 {
427   g_type_init ();
428   g_test_init (&argc, &argv, NULL);
429
430   setup ();
431
432   g_test_add_func ("/appinfo/mime/api", test_mime_api);
433   g_test_add_func ("/appinfo/mime/default", test_mime_default);
434   g_test_add_func ("/appinfo/mime/file", test_mime_file);
435
436   return g_test_run ();
437 }