3
* Copyright © 2012 Canonical Ltd.
5
* This program is free software: you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 3, as
7
* published by the Free Software Foundation.
9
* This program is distributed in the hope that it will be useful, but
10
* WITHOUT ANY WARRANTY; without even the implied warranties of
11
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12
* PURPOSE. See the GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License along
15
* with this program. If not, see <http://www.gnu.org/licenses/>.
18
#define G_LOG_DOMAIN "test-hudappindicatorsource"
19
#define _POSIX_SOURCE 1
24
#include "application-list.h"
25
#include "test-utils.h"
27
#include <glib-object.h>
29
#include <libdbustest/dbus-test.h>
32
/* hardcode some parameters for reasons of determinism.
34
HudSettings hud_settings = {
35
.indicator_penalty = 50,
38
.end_drop_penalty = 1,
43
static const gchar *BAMF_BUS_NAME = "org.ayatana.bamf";
44
static const gchar *MATCHER_OBJECT_PATH = "/org/ayatana/bamf/matcher";
45
static const gchar *APPLICATION_INTERFACE_NAME = "org.ayatana.bamf.application";
46
static const gchar *MATCHER_INTERFACE_NAME = "org.ayatana.bamf.matcher";
47
static const gchar *VIEW_INTERFACE_NAME = "org.ayatana.bamf.view";
48
static const gchar *WINDOW_INTERFACE_NAME = "org.ayatana.bamf.window";
49
static const gchar* REGISTRAR_BUS_NAME = "com.canonical.AppMenu.Registrar";
50
static const gchar* REGISTRAR_OBJECT_PATH = "/com/canonical/AppMenu/Registrar";
51
static const gchar* REGISTRAR_INTERFACE_NAME = "com.canonical.AppMenu.Registrar";
53
static void name_appeared(GDBusConnection *connection, const gchar *name,
54
const gchar *name_owner, gpointer user_data) {
55
g_debug("name appeared: %s, %s", name, name_owner);
56
g_main_loop_quit((GMainLoop *) user_data);
60
timeout_error_func (gpointer user_data)
62
GMainLoop * loop = (GMainLoop *)user_data;
63
g_main_loop_quit(loop);
64
g_error("Failed to get service");
69
test_window_source_add_view_properties (GDBusConnection* connection,
70
const gchar *object_path)
72
dbus_mock_add_property(connection, BAMF_BUS_NAME, object_path,
73
VIEW_INTERFACE_NAME, "Name", g_variant_new_string("name"));
74
dbus_mock_add_property(connection, BAMF_BUS_NAME, object_path,
75
VIEW_INTERFACE_NAME, "Icon", g_variant_new_string("icon.png"));
79
test_window_source_add_view_methods (GDBusConnection* connection,
80
const gchar *object_path)
82
dbus_mock_add_method (connection, BAMF_BUS_NAME, object_path,
83
VIEW_INTERFACE_NAME, "Children", "", "as", "ret = []");
85
/* As of 13.10 the methods below are deprecated and these all handled with
86
* properties above. Once we stop supporting (or at least testing) older
87
* releases these can be removed.
89
dbus_mock_add_method (connection, BAMF_BUS_NAME, object_path,
90
VIEW_INTERFACE_NAME, "Name", "", "s", "ret = 'name'");
91
dbus_mock_add_method (connection, BAMF_BUS_NAME, object_path,
92
VIEW_INTERFACE_NAME, "Icon", "", "s", "ret = 'icon.png'");
96
test_window_source_menu_model ()
98
const gchar *app_dbus_name = "app.dbus.name";
99
const gchar *app_dbus_menu_path = "/app/dbus/menu/path";
101
DbusTestService *service = dbus_test_service_new (NULL);
102
hud_test_utils_dbus_mock_start (service, BAMF_BUS_NAME,
103
MATCHER_OBJECT_PATH, MATCHER_INTERFACE_NAME);
104
hud_test_utils_dbus_mock_start (service, REGISTRAR_BUS_NAME,
105
REGISTRAR_OBJECT_PATH, REGISTRAR_INTERFACE_NAME);
106
hud_test_utils_start_menu_model_full (service,
107
MODEL_SIMPLE, app_dbus_name, app_dbus_menu_path,
109
hud_test_utils_json_loader_start_full(service, "app.dbus.name.two", "/menu", JSON_SHORTCUTS);
110
GDBusConnection *connection = hud_test_utils_mock_dbus_connection_new (service,
111
BAMF_BUS_NAME, REGISTRAR_BUS_NAME, app_dbus_name, "app.dbus.name.two", NULL );
112
hud_test_utils_process_mainloop (300);
114
/* Define the mock window */
116
DBusMockProperties* properties = dbus_mock_new_properties ();
117
DBusMockMethods* methods = dbus_mock_new_methods ();
118
dbus_mock_methods_append (methods, "GetXid", "", "u", "ret = 1");
119
dbus_mock_methods_append (methods, "Monitor", "", "i", "ret = 0");
120
dbus_mock_methods_append (methods, "Maximized", "", "i", "ret = 1");
121
dbus_mock_methods_append (methods, "WindowType", "", "u", "ret = 0");
122
dbus_mock_methods_append (methods, "Xprop", "s", "s", ""
123
"dict = {'_GTK_UNIQUE_BUS_NAME': 'app.dbus.name',\n"
124
" '_GTK_APP_MENU_OBJECT_PATH': '/app/dbus/menu/path',\n"
125
" '_GTK_MENUBAR_OBJECT_PATH': '',\n"
126
" '_GTK_APPLICATION_OBJECT_PATH': '/app/dbus/menu/path',\n"
127
" '_GTK_WINDOW_OBJECT_PATH': '',\n"
128
" '_UNITY_OBJECT_PATH': '',\n"
129
" 'WM_NAME': 'name'\n"
131
"ret = dict[args[0]]");
132
dbus_mock_add_object (connection, BAMF_BUS_NAME, MATCHER_OBJECT_PATH,
133
"/org/ayatana/bamf/window00000001", WINDOW_INTERFACE_NAME, properties,
135
test_window_source_add_view_methods (connection,
136
"/org/ayatana/bamf/window00000001");
137
test_window_source_add_view_properties (connection,
138
"/org/ayatana/bamf/window00000001");
139
dbus_mock_add_method (connection, BAMF_BUS_NAME, "/org/ayatana/bamf/window00000001",
140
VIEW_INTERFACE_NAME, "Parents", "", "as", "ret = ['/org/ayatana/bamf/application00000001']");
143
/* Define the mock application */
145
DBusMockProperties* properties = dbus_mock_new_properties ();
146
DBusMockMethods* methods = dbus_mock_new_methods ();
147
dbus_mock_methods_append (methods, "DesktopFile", "", "s",
148
"ret = '/usr/share/applications/name.desktop'");
150
dbus_mock_add_object (connection, BAMF_BUS_NAME, MATCHER_OBJECT_PATH,
151
"/org/ayatana/bamf/application00000001", APPLICATION_INTERFACE_NAME,
152
properties, methods);
153
test_window_source_add_view_methods (connection,
154
"/org/ayatana/bamf/application00000001");
155
test_window_source_add_view_properties (connection,
156
"/org/ayatana/bamf/application00000001");
159
/* Set up the BAMF matcher */
161
dbus_mock_add_method (connection,
162
BAMF_BUS_NAME, MATCHER_OBJECT_PATH,
163
MATCHER_INTERFACE_NAME, "ActiveWindow", "", "s",
164
"ret = '/org/ayatana/bamf/window00000001'");
165
dbus_mock_add_method (connection,
166
BAMF_BUS_NAME, MATCHER_OBJECT_PATH,
167
MATCHER_INTERFACE_NAME, "ApplicationForXid", "u", "s",
169
" ret = '/org/ayatana/bamf/application00000001'\n"
172
dbus_mock_add_method (connection,
173
BAMF_BUS_NAME, MATCHER_OBJECT_PATH,
174
MATCHER_INTERFACE_NAME, "ApplicationPaths", "", "as",
175
"ret = ['/org/ayatana/bamf/application00000001']");
176
dbus_mock_add_method (connection,
177
BAMF_BUS_NAME, MATCHER_OBJECT_PATH,
178
MATCHER_INTERFACE_NAME, "WindowStackForMonitor", "i", "as",
179
"if args[0] == -1:\n"
180
" ret = ['/org/ayatana/bamf/window00000001']\n"
183
dbus_mock_add_method (connection,
184
BAMF_BUS_NAME, MATCHER_OBJECT_PATH,
185
MATCHER_INTERFACE_NAME, "WindowPaths", "", "as",
186
"ret = ['/org/ayatana/bamf/window00000001']");
187
dbus_mock_add_method (connection,
188
BAMF_BUS_NAME, MATCHER_OBJECT_PATH,
189
MATCHER_INTERFACE_NAME, "ActiveApplication", "", "s",
190
"ret = '/org/ayatana/bamf/application00000001'");
193
/* Set up the app registrar */
195
dbus_mock_add_method (connection,
196
REGISTRAR_BUS_NAME, REGISTRAR_OBJECT_PATH,
197
REGISTRAR_INTERFACE_NAME, "GetMenus", "", "a(uso)",
198
"ret = [(1, 'app.dbus.name.two', '/menu')]");
201
hud_test_utils_process_mainloop (100);
205
GError *error = NULL;
207
const gchar *argv[] = { BAMF_BRIDGE, NULL };
208
g_spawn_async(NULL, (gchar **) argv,
209
NULL, G_SPAWN_DEFAULT,
214
GMainLoop *temploop = g_main_loop_new (NULL, FALSE);
215
g_timeout_add (1000, timeout_error_func, temploop);
216
g_bus_watch_name(G_BUS_TYPE_SESSION, "com.canonical.Unity.WindowStack",
217
G_BUS_NAME_WATCHER_FLAGS_NONE, name_appeared, NULL, temploop,
219
g_main_loop_run (temploop);
220
g_main_loop_unref (temploop);
223
HudApplicationList* source = hud_application_list_new();
224
g_assert(source != NULL);
225
g_assert(HUD_IS_APPLICATION_LIST(source));
227
hud_test_utils_process_mainloop (100);
231
DBusMockSignalArgs* args = dbus_mock_new_signal_args ();
232
dbus_mock_signal_args_append(args, g_variant_new("s", ""));
233
dbus_mock_signal_args_append(args, g_variant_new("s", "/org/ayatana/bamf/window00000001"));
234
dbus_mock_emit_signal (connection, BAMF_BUS_NAME, MATCHER_OBJECT_PATH,
235
MATCHER_INTERFACE_NAME, "ActiveWindowChanged", "ss", args);
238
hud_test_utils_process_mainloop (100);
240
hud_source_use(HUD_SOURCE(source));
242
HudTokenList *search = hud_token_list_new_from_string ("simple");
244
GPtrArray *results = g_ptr_array_new_with_free_func(g_object_unref);
245
hud_source_search(HUD_SOURCE(source), search, hud_test_utils_results_append_func, results);
246
g_assert_cmpuint(results->len, ==, 1);
247
hud_test_utils_source_assert_result (results, 0, "Simple");
248
g_ptr_array_free(results, TRUE);
251
HudTokenList *search_two = hud_token_list_new_from_string ("save");
253
GPtrArray *results = g_ptr_array_new_with_free_func(g_object_unref);
254
hud_source_search(HUD_SOURCE(source), search_two, hud_test_utils_results_append_func, results);
255
g_assert_cmpuint(results->len, ==, 1);
256
hud_test_utils_source_assert_result (results, 0, "Save");
257
g_ptr_array_free(results, TRUE);
261
GList* apps = hud_application_list_get_apps (source);
262
g_assert_cmpuint(g_list_length(apps), ==, 1);
263
HudApplicationSource * app =
264
HUD_APPLICATION_SOURCE(g_list_nth_data(apps, 0));
265
g_assert(HUD_IS_APPLICATION_SOURCE(app));
266
g_assert_cmpstr(hud_application_source_get_id (app), ==, "1");
267
g_assert_cmpstr(hud_application_source_get_path (app), ==,
268
"/com/canonical/hud/applications/1");
273
HudApplicationSource * app = hud_application_list_get_source (source,
275
g_assert(HUD_IS_APPLICATION_SOURCE(app));
276
g_assert_cmpstr(hud_application_source_get_id (app), ==, "1");
277
g_assert_cmpstr(hud_application_source_get_path (app), ==,
278
"/com/canonical/hud/applications/1");
281
g_debug("Unusing Source");
282
hud_source_unuse(HUD_SOURCE(source));
284
g_debug("Freeing Token lists");
285
hud_token_list_free(search);
286
hud_token_list_free(search_two);
288
g_debug("Unreferencing the source");
289
g_object_unref (source);
291
g_debug("Waiting for things to settle");
292
hud_test_utils_process_mainloop (100);
296
g_debug("Taking down the connection");
297
g_object_unref (connection);
298
g_debug("Taking down the dbus service");
299
g_object_unref (service);
300
/* FIXME: We would like to do this here, but dbus makes us exit with a non-zero code
301
hud_test_utils_wait_for_connection_close(connection);
306
main (int argc, char **argv)
308
#ifndef GLIB_VERSION_2_36
312
g_test_init (&argc, &argv, NULL);
313
g_test_add_func ("/hud/windowsource/menu_model", test_window_source_menu_model);
315
return g_test_run ();