Make lr/desktop_notifications testable
Introduce unit tests. Related #2273
This commit is contained in:
parent
0f8ab61ddf
commit
912afff173
|
@ -14,29 +14,46 @@
|
||||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""Implements the desktop notification service."""
|
||||||
|
|
||||||
|
import importlib
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
try:
|
|
||||||
import gi
|
|
||||||
|
|
||||||
gi.require_version("Notify", "0.7")
|
def notifications_available():
|
||||||
gi.require_version("Gtk", "3.0")
|
"""Checks if notification service is available."""
|
||||||
from gi.repository import GLib # this import is allowed to fail making the entire feature unavailable
|
notifications_supported = False
|
||||||
from gi.repository import Gtk # this import is allowed to fail making the entire feature unavailable
|
try:
|
||||||
from gi.repository import Notify # this import is allowed to fail making the entire feature unavailable
|
import gi
|
||||||
|
|
||||||
available = True
|
gi.require_version("Notify", "0.7")
|
||||||
except (ValueError, ImportError):
|
gi.require_version("Gtk", "3.0")
|
||||||
available = False
|
|
||||||
|
importlib.util.find_spec("gi.repository.GLib")
|
||||||
|
importlib.util.find_spec("gi.repository.Gtk")
|
||||||
|
importlib.util.find_spec("gi.repository.Notify")
|
||||||
|
|
||||||
|
notifications_supported = True
|
||||||
|
except ValueError as e:
|
||||||
|
logger.warning(f"Notification service is not available: {e}")
|
||||||
|
return notifications_supported
|
||||||
|
|
||||||
|
|
||||||
|
available = notifications_available()
|
||||||
|
|
||||||
if available:
|
if available:
|
||||||
|
from gi.repository import GLib
|
||||||
|
from gi.repository import Gtk
|
||||||
|
from gi.repository import Notify
|
||||||
|
|
||||||
# cache references to shown notifications here to allow reuse
|
# cache references to shown notifications here to allow reuse
|
||||||
_notifications = {}
|
_notifications = {}
|
||||||
|
_ICON_LISTS = {}
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
"""Init the notifications system."""
|
"""Initialize desktop notifications."""
|
||||||
global available
|
global available
|
||||||
if available:
|
if available:
|
||||||
if not Notify.is_initted():
|
if not Notify.is_initted():
|
||||||
|
@ -50,13 +67,14 @@ if available:
|
||||||
return available and Notify.is_initted()
|
return available and Notify.is_initted()
|
||||||
|
|
||||||
def uninit():
|
def uninit():
|
||||||
|
"""Stop desktop notifications."""
|
||||||
if available and Notify.is_initted():
|
if available and Notify.is_initted():
|
||||||
if logger.isEnabledFor(logging.INFO):
|
if logger.isEnabledFor(logging.INFO):
|
||||||
logger.info("stopping desktop notifications")
|
logger.info("stopping desktop notifications")
|
||||||
_notifications.clear()
|
_notifications.clear()
|
||||||
Notify.uninit()
|
Notify.uninit()
|
||||||
|
|
||||||
def show(dev, message, icon=None):
|
def show(dev, message: str, icon=None):
|
||||||
"""Show a notification with title and text."""
|
"""Show a notification with title and text."""
|
||||||
if available and (Notify.is_initted() or init()):
|
if available and (Notify.is_initted() or init()):
|
||||||
summary = dev.name
|
summary = dev.name
|
||||||
|
@ -68,13 +86,9 @@ if available:
|
||||||
n.set_urgency(Notify.Urgency.NORMAL)
|
n.set_urgency(Notify.Urgency.NORMAL)
|
||||||
n.set_hint("desktop-entry", GLib.Variant("s", "solaar")) # replace with better name late
|
n.set_hint("desktop-entry", GLib.Variant("s", "solaar")) # replace with better name late
|
||||||
try:
|
try:
|
||||||
# if logger.isEnabledFor(logging.DEBUG):
|
|
||||||
# logger.debug("showing %s", n)
|
|
||||||
n.show()
|
n.show()
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("showing %s", n)
|
logger.exception(f"showing {n}")
|
||||||
|
|
||||||
_ICON_LISTS = {}
|
|
||||||
|
|
||||||
def device_icon_list(name="_", kind=None):
|
def device_icon_list(name="_", kind=None):
|
||||||
icon_list = _ICON_LISTS.get(name)
|
icon_list = _ICON_LISTS.get(name)
|
||||||
|
@ -82,16 +96,17 @@ if available:
|
||||||
# names of possible icons, in reverse order of likelihood
|
# names of possible icons, in reverse order of likelihood
|
||||||
# the theme will hopefully pick up the most appropriate
|
# the theme will hopefully pick up the most appropriate
|
||||||
icon_list = ["preferences-desktop-peripherals"]
|
icon_list = ["preferences-desktop-peripherals"]
|
||||||
|
kind = str(kind)
|
||||||
if kind:
|
if kind:
|
||||||
if str(kind) == "numpad":
|
if kind == "numpad":
|
||||||
icon_list += ("input-keyboard", "input-dialpad")
|
icon_list += ("input-keyboard", "input-dialpad")
|
||||||
elif str(kind) == "touchpad":
|
elif kind == "touchpad":
|
||||||
icon_list += ("input-mouse", "input-tablet")
|
icon_list += ("input-mouse", "input-tablet")
|
||||||
elif str(kind) == "trackball":
|
elif kind == "trackball":
|
||||||
icon_list += ("input-mouse",)
|
icon_list += ("input-mouse",)
|
||||||
elif str(kind) == "headset":
|
elif kind == "headset":
|
||||||
icon_list += ("audio-headphones", "audio-headset")
|
icon_list += ("audio-headphones", "audio-headset")
|
||||||
icon_list += ("input-" + str(kind),)
|
icon_list += (f"input-{kind}",)
|
||||||
_ICON_LISTS[name] = icon_list
|
_ICON_LISTS[name] = icon_list
|
||||||
return icon_list
|
return icon_list
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from logitech_receiver import desktop_notifications
|
||||||
|
|
||||||
|
|
||||||
|
def test_notifications_available():
|
||||||
|
result = desktop_notifications.notifications_available()
|
||||||
|
|
||||||
|
assert not result
|
||||||
|
|
||||||
|
|
||||||
|
def test_init():
|
||||||
|
assert not desktop_notifications.init()
|
||||||
|
|
||||||
|
|
||||||
|
def test_uninit():
|
||||||
|
assert desktop_notifications.uninit() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_show():
|
||||||
|
dev = mock.MagicMock()
|
||||||
|
reason = "unknown"
|
||||||
|
assert desktop_notifications.show(dev, reason) is None
|
Loading…
Reference in New Issue