/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * vi:set noexpandtab tabstop=8 shiftwidth=8: * * Copyright (C) 2013-2017 Richard Hughes * Copyright (C) 2021 Matthew Leeds * * SPDX-License-Identifier: GPL-2.0+ */ #include "config.h" #include "gnome-software-private.h" #include "gs-test.h" #include "gs-dynamic-launcher-portal-iface.h" #include "gs-epiphany-generated.h" #include /* This is run in a worker thread */ static void epiphany_and_portal_mock_server_cb (GtDBusQueue *queue, gpointer user_data) { { g_autoptr(GDBusMethodInvocation) invocation = NULL; g_autoptr(GVariant) properties_variant = NULL; const char *property_interface; invocation = gt_dbus_queue_assert_pop_message (queue, "/org/gnome/Epiphany/WebAppProvider", "org.freedesktop.DBus.Properties", "GetAll", "(&s)", &property_interface); g_assert_cmpstr (property_interface, ==, "org.gnome.Epiphany.WebAppProvider"); properties_variant = g_variant_new_parsed ("({'Version': <@u 1>},)"); g_dbus_method_invocation_return_value (invocation, g_steal_pointer (&properties_variant)); } { g_autoptr(GDBusMethodInvocation) invocation = NULL; g_autoptr(GVariant) properties_variant = NULL; const char *property_interface, *props_dict; invocation = gt_dbus_queue_assert_pop_message (queue, "/org/freedesktop/portal/desktop", "org.freedesktop.DBus.Properties", "GetAll", "(&s)", &property_interface); g_assert_cmpstr (property_interface, ==, "org.freedesktop.portal.DynamicLauncher"); props_dict = "({'version': <@u 1>,'SupportedLauncherTypes': <@u 3>},)"; properties_variant = g_variant_new_parsed (props_dict); g_dbus_method_invocation_return_value (invocation, g_steal_pointer (&properties_variant)); } { g_autoptr(GDBusMethodInvocation) invocation = NULL; const char *installed_apps[] = {"org.gnome.Epiphany.WebApp_e9d0e1e4b0a10856aa3b38d9eb4375de4070d043.desktop", NULL}; invocation = gt_dbus_queue_assert_pop_message (queue, "/org/gnome/Epiphany/WebAppProvider", "org.gnome.Epiphany.WebAppProvider", "GetInstalledApps", "()", NULL); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(^as)", installed_apps)); } } static GtDBusQueue * bus_set_up (void) { g_autoptr(GError) local_error = NULL; g_autoptr(GtDBusQueue) queue = NULL; queue = gt_dbus_queue_new (); gt_dbus_queue_connect (queue, &local_error); g_assert_no_error (local_error); gt_dbus_queue_own_name (queue, "org.freedesktop.portal.Desktop"); gt_dbus_queue_export_object (queue, "/org/freedesktop/portal/desktop", (GDBusInterfaceInfo *) &org_freedesktop_portal_dynamic_launcher_interface, &local_error); g_assert_no_error (local_error); gt_dbus_queue_own_name (queue, "org.gnome.Epiphany.WebAppProvider"); gt_dbus_queue_export_object (queue, "/org/gnome/Epiphany/WebAppProvider", gs_ephy_web_app_provider_interface_info (), &local_error); g_assert_no_error (local_error); gt_dbus_queue_set_server_func (queue, epiphany_and_portal_mock_server_cb, NULL); return g_steal_pointer (&queue); } static void gs_plugins_epiphany_func (GsPluginLoader *plugin_loader) { g_assert_true (gs_plugin_loader_get_enabled (plugin_loader, "epiphany")); } static char * create_fake_desktop_file (const char *app_id) { g_autofree char *contents = NULL; g_autoptr(GError) error = NULL; g_autofree char *desktop_path = NULL; g_autofree char *icon_path = NULL; /* Use an icon we already have locally */ icon_path = gs_test_get_filename (TESTDATADIR, "icons/hicolor/scalable/org.gnome.Software.svg"); g_assert (icon_path != NULL); /* Use true instead of epiphany in Exec and TryExec; otherwise * g_desktop_app_info_new() in the plugin code will look for an * epiphany binary and fail. */ contents = g_strdup_printf ("[Desktop Entry]\n" "Name=Pinafore\n" "Exec=true --application-mode \"--profile=/home/nobody/.local/share/%s\" https://pinafore.social/\n" "StartupNotify=true\n" "Terminal=false\n" "Type=Application\n" "Categories=GNOME;GTK;\n" "Icon=%s\n" "StartupWMClass=%s\n" "X-Purism-FormFactor=Workstation;Mobile;\n" "TryExec=true\n", app_id, icon_path, app_id); desktop_path = g_strconcat (g_get_user_data_dir (), G_DIR_SEPARATOR_S, "applications", G_DIR_SEPARATOR_S, app_id, ".desktop", NULL); g_debug ("Creating a fake desktop file at path: %s", desktop_path); gs_mkdir_parent (desktop_path, &error); g_assert_no_error (error); g_file_set_contents (desktop_path, contents, -1, &error); g_assert_no_error (error); return g_steal_pointer (&desktop_path); } static void gs_plugins_epiphany_installed_func (GsPluginLoader *plugin_loader) { g_autoptr(GsAppQuery) query = NULL; g_autoptr(GsPluginJob) plugin_job = NULL; g_autoptr(GError) error = NULL; g_autoptr(GIcon) icon = NULL; g_autoptr(GsAppList) list = NULL; GsApp *app; const char *app_id = "org.gnome.Epiphany.WebApp_e9d0e1e4b0a10856aa3b38d9eb4375de4070d043"; const char *metainfo_app_id = "org.gnome.Software.WebApp_e636aa5f2069f6e9c02deccc7b65f43da7985e32.desktop"; const char *launchable_app_id; g_autofree char *app_id_desktop = NULL; g_autofree char *desktop_path = NULL; g_autofree char *origin_ui = NULL; app_id_desktop = g_strdup_printf ("%s.desktop", app_id); desktop_path = create_fake_desktop_file (app_id); query = gs_app_query_new ("is-installed", GS_APP_QUERY_TRISTATE_TRUE, "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN, "dedupe-flags", GS_PLUGIN_JOB_DEDUPE_FLAGS_DEFAULT, NULL); plugin_job = gs_plugin_job_list_apps_new (query, GS_PLUGIN_LIST_APPS_FLAGS_NONE); list = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error); gs_test_flush_main_context (); g_assert_no_error (error); g_assert_nonnull (list); g_assert_cmpint (gs_app_list_length (list), ==, 1); app = gs_app_list_index (list, 0); g_assert_cmpstr (gs_app_get_id (app), ==, metainfo_app_id); launchable_app_id = gs_app_get_launchable (app, AS_LAUNCHABLE_KIND_DESKTOP_ID); g_assert_cmpstr (launchable_app_id, ==, app_id_desktop); g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_WEB_APP); g_assert_cmpint (gs_app_get_scope (app), ==, AS_COMPONENT_SCOPE_USER); g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_INSTALLED); g_assert_cmpstr (gs_app_get_name (app), ==, "Pinafore"); g_assert_cmpstr (gs_app_get_summary (app), ==, "pinafore.social"); g_assert_cmpstr (gs_app_get_origin (app), ==, "gnome-web"); origin_ui = gs_app_dup_origin_ui (app, TRUE); g_assert_cmpstr (origin_ui, ==, "GNOME Web"); icon = gs_app_get_icon_for_size (app, 4096, 1, NULL); g_assert_nonnull (icon); g_clear_object (&icon); gs_utils_unlink (desktop_path, NULL); } int main (int argc, char **argv) { gboolean ret; g_autofree gchar *fn = NULL; g_autofree gchar *xml = NULL; g_autoptr(GError) error = NULL; g_autoptr(GsPluginLoader) plugin_loader = NULL; g_autoptr(GtDBusQueue) queue = NULL; int res; const gchar *allowlist[] = { "epiphany", "icons", NULL }; gs_test_init (&argc, &argv); g_setenv ("GS_XMLB_VERBOSE", "1", TRUE); /* Set up mock D-Bus services for the Epiphany WebAppProvider and the * DynamicLauncher portal */ queue = bus_set_up (); /* we can only load this once per process */ plugin_loader = gs_plugin_loader_new (gt_dbus_queue_get_client_connection (queue), NULL); gs_plugin_loader_add_location (plugin_loader, LOCALPLUGINDIR); gs_plugin_loader_add_location (plugin_loader, LOCALPLUGINDIR_CORE); ret = gs_plugin_loader_setup (plugin_loader, allowlist, NULL, NULL, &error); g_assert_no_error (error); g_assert_true (ret); /* plugin tests go here */ g_test_add_data_func ("/gnome-software/plugins/epiphany/enabled", plugin_loader, (GTestDataFunc) gs_plugins_epiphany_func); g_test_add_data_func ("/gnome-software/plugins/epiphany/installed", plugin_loader, (GTestDataFunc) gs_plugins_epiphany_installed_func); res = g_test_run (); gt_dbus_queue_disconnect (queue, TRUE); return res; }