aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Uebernickel <lars.uebernickel@canonical.com>2013-06-07 22:15:28 +0000
committerTarmac <Unknown>2013-06-07 22:15:28 +0000
commite5a4ba5371000d1075d18205ecdd25fafbde3c38 (patch)
treeee8934012f52d77f67be4181b11d193016bd2639
parentb38a660213950fa1aa46d1fd73901eafcd7b8a75 (diff)
parent014158fd7f63b25840bbcecc92e9ec3f42a7002c (diff)
downloadayatana-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.ac18
-rw-r--r--debian/control1
-rw-r--r--libmessaging-menu/messaging-menu.c4
-rw-r--r--m4/ax_python_module.m449
-rw-r--r--src/messages-service.c25
-rw-r--r--src/messages-service.xml4
-rw-r--r--test/Makefile.am11
-rw-r--r--test/applications/test.desktop2
-rwxr-xr-xtest/test-client.py75
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())