tests: mock the libnotify backend so the suite raises no real notifications
The desktop_notifications tests called the real init/alert/show, which reach the libnotify daemon — every test run popped real GNOME notifications titled "MockDevice" and "unknown". Add an autouse conftest fixture that swaps Notify for a mock in both desktop_notifications modules (solaar.ui and logitech_receiver). The tests still exercise the real init/alert/show code paths, but Notification.show() never reaches the daemon. The fixture returns the mock; the notification tests now assert show() was actually dispatched against it, so they verify the path instead of just "didn't crash".
This commit is contained in:
parent
eefa37d83f
commit
4c709ecb73
|
|
@ -1,3 +1,7 @@
|
||||||
|
import importlib
|
||||||
|
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -16,3 +20,24 @@ def isolate_solaar_configuration(tmp_path, monkeypatch):
|
||||||
monkeypatch.setattr(configuration, "_yaml_file_path", str(tmp_path / "config.yaml"))
|
monkeypatch.setattr(configuration, "_yaml_file_path", str(tmp_path / "config.yaml"))
|
||||||
monkeypatch.setattr(configuration, "_json_file_path", str(tmp_path / "config.json"))
|
monkeypatch.setattr(configuration, "_json_file_path", str(tmp_path / "config.json"))
|
||||||
monkeypatch.setattr(configuration, "_config", [])
|
monkeypatch.setattr(configuration, "_config", [])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def mock_desktop_notifications(monkeypatch):
|
||||||
|
"""Swap the libnotify backend for a mock in both desktop_notifications
|
||||||
|
modules. Tests still exercise the real init/alert/show code paths, but
|
||||||
|
Notification.show() never reaches the daemon — without this the suite
|
||||||
|
raises real 'MockDevice' / 'unknown' notifications on every run.
|
||||||
|
|
||||||
|
Returns the Notify mock so notification tests can assert against it."""
|
||||||
|
notify = mock.MagicMock(name="Notify")
|
||||||
|
notify.is_initted.return_value = True
|
||||||
|
notify.init.return_value = True
|
||||||
|
for modname in ("solaar.ui.desktop_notifications", "logitech_receiver.desktop_notifications"):
|
||||||
|
try:
|
||||||
|
module = importlib.import_module(modname)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
monkeypatch.setattr(module, "Notify", notify, raising=False)
|
||||||
|
monkeypatch.setattr(module, "_notifications", {}, raising=False)
|
||||||
|
return notify
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ from unittest import mock
|
||||||
|
|
||||||
from logitech_receiver import desktop_notifications
|
from logitech_receiver import desktop_notifications
|
||||||
|
|
||||||
# depends on external environment, so make some tests dependent on availability
|
# The mock_desktop_notifications autouse fixture (tests/conftest.py) swaps the
|
||||||
|
# libnotify backend for a mock, so these exercise the real code paths without
|
||||||
|
# raising real desktop notifications.
|
||||||
|
|
||||||
|
|
||||||
def test_init():
|
def test_init():
|
||||||
|
|
@ -22,8 +24,11 @@ class MockDevice(mock.Mock):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def test_show():
|
def test_show(mock_desktop_notifications):
|
||||||
dev = MockDevice()
|
result = desktop_notifications.show(MockDevice(), "unknown")
|
||||||
reason = "unknown"
|
|
||||||
result = desktop_notifications.show(dev, reason)
|
if desktop_notifications.available:
|
||||||
assert result is not None if desktop_notifications.available else result is None
|
assert result is not None
|
||||||
|
mock_desktop_notifications.Notification.return_value.show.assert_called()
|
||||||
|
else:
|
||||||
|
assert result is None
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ from unittest import mock
|
||||||
|
|
||||||
from solaar.ui import desktop_notifications
|
from solaar.ui import desktop_notifications
|
||||||
|
|
||||||
# depends on external environment, so make some tests dependent on availability
|
# The mock_desktop_notifications autouse fixture (tests/conftest.py) swaps the
|
||||||
|
# libnotify backend for a mock, so these exercise the real code paths without
|
||||||
|
# raising real desktop notifications.
|
||||||
|
|
||||||
|
|
||||||
def test_init():
|
def test_init():
|
||||||
|
|
@ -15,9 +17,11 @@ def test_uninit():
|
||||||
assert desktop_notifications.uninit() is None
|
assert desktop_notifications.uninit() is None
|
||||||
|
|
||||||
|
|
||||||
def test_alert():
|
def test_alert(mock_desktop_notifications):
|
||||||
reason = "unknown"
|
assert desktop_notifications.alert("unknown") is None
|
||||||
assert desktop_notifications.alert(reason) is None
|
|
||||||
|
if desktop_notifications.available:
|
||||||
|
mock_desktop_notifications.Notification.return_value.show.assert_called()
|
||||||
|
|
||||||
|
|
||||||
class MockDevice(mock.Mock):
|
class MockDevice(mock.Mock):
|
||||||
|
|
@ -27,13 +31,11 @@ class MockDevice(mock.Mock):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def test_show():
|
def test_show(mock_desktop_notifications):
|
||||||
dev = MockDevice()
|
result = desktop_notifications.show(MockDevice(), "unknown")
|
||||||
reason = "unknown"
|
|
||||||
available = desktop_notifications.init()
|
|
||||||
|
|
||||||
result = desktop_notifications.show(dev, reason)
|
if desktop_notifications.available:
|
||||||
if available:
|
|
||||||
assert result is not None
|
assert result is not None
|
||||||
|
mock_desktop_notifications.Notification.return_value.show.assert_called()
|
||||||
else:
|
else:
|
||||||
assert result is None
|
assert result is None
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue