diff options
author | Lars Uebernickel <lars.uebernickel@canonical.com> | 2013-06-07 22:15:28 +0000 |
---|---|---|
committer | Tarmac <Unknown> | 2013-06-07 22:15:28 +0000 |
commit | e5a4ba5371000d1075d18205ecdd25fafbde3c38 (patch) | |
tree | ee8934012f52d77f67be4181b11d193016bd2639 | |
parent | b38a660213950fa1aa46d1fd73901eafcd7b8a75 (diff) | |
parent | 014158fd7f63b25840bbcecc92e9ec3f42a7002c (diff) | |
download | ayatana-indicator-messages-e5a4ba5371000d1075d18205ecdd25fafbde3c38.tar.gz ayatana-indicator-messages-e5a4ba5371000d1075d18205ecdd25fafbde3c38.tar.bz2 ayatana-indicator-messages-e5a4ba5371000d1075d18205ecdd25fafbde3c38.zip |
Notify the service when an app unrefs its MessagingMenuApp. Fixes: https://bugs.launchpad.net/bugs/1154099.
Approved by PS Jenkins bot, Ted Gould.
-rw-r--r-- | configure.ac | 18 | ||||
-rw-r--r-- | debian/control | 1 | ||||
-rw-r--r-- | libmessaging-menu/messaging-menu.c | 4 | ||||
-rw-r--r-- | m4/ax_python_module.m4 | 49 | ||||
-rw-r--r-- | src/messages-service.c | 25 | ||||
-rw-r--r-- | src/messages-service.xml | 4 | ||||
-rw-r--r-- | test/Makefile.am | 11 | ||||
-rw-r--r-- | test/applications/test.desktop | 2 | ||||
-rwxr-xr-x | test/test-client.py | 75 |
9 files changed, 183 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac index bcd7b20..08ac680 100644 --- a/configure.ac +++ b/configure.ac @@ -75,7 +75,7 @@ AC_SUBST(COVERAGE_CXXFLAGS) AC_SUBST(COVERAGE_LDFLAGS) ########################### -# Google Test framework +# Tests ########################### AC_ARG_ENABLE([tests], @@ -85,10 +85,16 @@ AC_ARG_ENABLE([tests], if test "x$enable_tests" != "xno"; then m4_include([m4/gtest.m4]) CHECK_GTEST - if test "x$enable_tests" = "xauto"; then - enable_tests=${have_gtest} - elif test "x$enable_tests" = "xyes" && test "x$have_gtest" != "xyes"; then - AC_MSG_ERROR([tests were requested but gtest is not installed.]) + AM_PATH_PYTHON(3.0,, [:]) + AC_PYTHON_MODULE(dbusmock) + if test "x$have_gtest" = "xyes" -a "x$HAVE_PYMOD_DBUSMOCK" = "xyes"; then + enable_tests="yes" + else + if test "x$enable_tests" = "xyes"; then + AC_MSG_ERROR([tests were requested but gtest or dbusmock are not installed.]) + else + enable_tests="no" + fi fi fi AM_CONDITIONAL([BUILD_TESTS],[test "x$enable_tests" = "xyes"]) @@ -193,7 +199,7 @@ Messaging Indicator Configuration: Prefix: $prefix Indicator Dir: $INDICATORDIR - gtest: $enable_tests + tests: $enable_tests gcov: $use_gcov introspecion: $enable_introspection documentation: $enable_gtk_doc diff --git a/debian/control b/debian/control index e44b405..7773476 100644 --- a/debian/control +++ b/debian/control @@ -19,6 +19,7 @@ Build-Depends: debhelper (>= 9), libgirepository1.0-dev (>= 0.9.12), gtk-doc-tools, libgtest-dev, + python3-dbusmock, Standards-Version: 3.9.3 Homepage: https://launchpad.net/indicator-messages # If you aren't a member of ~indicator-applet-developers but need to upload diff --git a/libmessaging-menu/messaging-menu.c b/libmessaging-menu/messaging-menu.c index acf3d90..467a67a 100644 --- a/libmessaging-menu/messaging-menu.c +++ b/libmessaging-menu/messaging-menu.c @@ -277,6 +277,10 @@ messaging_menu_app_dispose (GObject *object) if (app->messages_service) { + indicator_messages_service_call_application_stopped_running (app->messages_service, + g_app_info_get_id (G_APP_INFO (app->appinfo)), + NULL, NULL, NULL); + g_signal_handlers_disconnect_by_func (app->messages_service, global_status_changed, app); diff --git a/m4/ax_python_module.m4 b/m4/ax_python_module.m4 new file mode 100644 index 0000000..bd70a06 --- /dev/null +++ b/m4/ax_python_module.m4 @@ -0,0 +1,49 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_python_module.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PYTHON_MODULE(modname[, fatal]) +# +# DESCRIPTION +# +# Checks for Python module. +# +# If fatal is non-empty then absence of a module will trigger an error. +# +# LICENSE +# +# Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 5 + +AU_ALIAS([AC_PYTHON_MODULE], [AX_PYTHON_MODULE]) +AC_DEFUN([AX_PYTHON_MODULE],[ + if test -z $PYTHON; + then + PYTHON="python" + fi + PYTHON_NAME=`basename $PYTHON` + AC_MSG_CHECKING($PYTHON_NAME module: $1) + $PYTHON -c "import $1" 2>/dev/null + if test $? -eq 0; + then + AC_MSG_RESULT(yes) + eval AS_TR_CPP(HAVE_PYMOD_$1)=yes + else + AC_MSG_RESULT(no) + eval AS_TR_CPP(HAVE_PYMOD_$1)=no + # + if test -n "$2" + then + AC_MSG_ERROR(failed to find required module $1) + exit 1 + fi + fi +]) diff --git a/src/messages-service.c b/src/messages-service.c index f93cf68..25a19b9 100644 --- a/src/messages-service.c +++ b/src/messages-service.c @@ -474,6 +474,29 @@ unregister_application (IndicatorMessagesService *service, } static void +application_stopped_running (IndicatorMessagesService *service, + GDBusMethodInvocation *invocation, + const gchar *desktop_id, + gpointer user_data) +{ + GDesktopAppInfo *appinfo; + gchar *id; + AppSection *section; + + indicator_messages_service_complete_application_stopped_running (service, invocation); + + if (!(appinfo = g_desktop_app_info_new (desktop_id))) + return; + + id = g_app_info_get_simple_id (G_APP_INFO (appinfo)); + section = g_hash_table_lookup (applications, id); + app_section_unset_object_path (section); + + g_free (id); + g_object_unref (appinfo); +} + +static void set_status (IndicatorMessagesService *service, GDBusMethodInvocation *invocation, const gchar *desktop_id, @@ -650,6 +673,8 @@ main (int argc, char ** argv) G_CALLBACK (register_application), NULL); g_signal_connect (messages_service, "handle-unregister-application", G_CALLBACK (unregister_application), NULL); + g_signal_connect (messages_service, "handle-application-stopped-running", + G_CALLBACK (application_stopped_running), NULL); g_signal_connect (messages_service, "handle-set-status", G_CALLBACK (set_status), NULL); diff --git a/src/messages-service.xml b/src/messages-service.xml index 00ae154..3c3c779 100644 --- a/src/messages-service.xml +++ b/src/messages-service.xml @@ -11,6 +11,10 @@ <arg type="s" name="desktop_id" direction="in" /> </method> + <method name="ApplicationStoppedRunning"> + <arg type="s" name="desktop_id" direction="in" /> + </method> + <method name="SetStatus"> <arg type="s" name="desktop_id" direction="in" /> <arg type="s" name="status" direction="in" /> diff --git a/test/Makefile.am b/test/Makefile.am index 4671446..4f1a163 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -65,3 +65,14 @@ libindicator_messages_service_la_LIBADD = \ libindicator_messages_service_la_LDFLAGS = \ $(COVERAGE_LDFLAGS) + +###################################### +# Test client with dbusmock +###################################### + +TESTS_ENVIRONMENT = \ + export LD_LIBRARY_PATH=$(top_builddir)/libmessaging-menu/.libs; \ + export GI_TYPELIB_PATH=$(top_builddir)/libmessaging-menu; \ + export XDG_DATA_DIRS=$(abs_srcdir); + +TESTS += test-client.py diff --git a/test/applications/test.desktop b/test/applications/test.desktop new file mode 100644 index 0000000..c2332b9 --- /dev/null +++ b/test/applications/test.desktop @@ -0,0 +1,2 @@ +[Desktop Entry] +Type=Application diff --git a/test/test-client.py b/test/test-client.py new file mode 100755 index 0000000..a1d503f --- /dev/null +++ b/test/test-client.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +import unittest +import dbus +from dbus.mainloop.glib import DBusGMainLoop +import dbusmock +import subprocess +from gi.repository import GLib, Gio, MessagingMenu + +DBusGMainLoop(set_as_default=True) + +class MessagingMenuTest(dbusmock.DBusTestCase): + @classmethod + def setUpClass(klass): + klass.start_session_bus() + klass.bus = klass.get_dbus(False) + + def setUp(self): + name = 'com.canonical.indicator.messages' + obj_path = '/com/canonical/indicator/messages/service' + iface = 'com.canonical.indicator.messages.service' + + self.messaging_service = self.spawn_server(name, obj_path, iface, stdout=subprocess.PIPE) + self.mock = dbus.Interface(self.bus.get_object(name, obj_path), dbusmock.MOCK_IFACE) + self.mock.AddMethod('', 'RegisterApplication', 'so', '', '') + self.mock.AddMethod('', 'UnregisterApplication', 's', '', '') + self.mock.AddMethod('', 'ApplicationStoppedRunning', 's', '', '') + self.mock.AddMethod('', 'SetStatus', 'ss', '', '') + + self.loop = GLib.MainLoop() + + def tearDown(self): + self.messaging_service.terminate() + self.messaging_service.wait() + + def assertArgumentsEqual(self, args, *expected_args): + self.assertEqual(len(args), len(expected_args)) + for i in range(len(args)): + if expected_args[i]: + self.assertEqual(args[i], expected_args[i]) + + def assertMethodCalled(self, name, *expected_args): + # set a flag on timeout, assertions don't get bubbled up through c functions + self.timed_out = False + def timeout(): self.timed_out = True + timeout_id = GLib.timeout_add_seconds(10, timeout) + while 1: + calls = self.mock.GetMethodCalls(name) + if len(calls) > 0: + GLib.source_remove(timeout_id) + self.assertArgumentsEqual(calls[0][1], *expected_args) + break + GLib.MainContext.default().iteration(True) + if self.timed_out: + raise self.failureException('method %s was not called after 10 seconds' % name) + + def test_registration(self): + mmapp = MessagingMenu.App.new('test.desktop') + mmapp.register() + self.assertMethodCalled('RegisterApplication', 'test.desktop', None) + + mmapp.unregister() + self.assertMethodCalled('UnregisterApplication', 'test.desktop') + + # ApplicationStoppedRunning is called when the last ref on mmapp is dropped + del mmapp + self.assertMethodCalled('ApplicationStoppedRunning', 'test.desktop') + + def test_status(self): + mmapp = MessagingMenu.App.new('test.desktop') + mmapp.register() + mmapp.set_status(MessagingMenu.Status.AWAY) + self.assertMethodCalled('SetStatus', 'test.desktop', 'away') + +unittest.main(testRunner=unittest.TextTestRunner()) |