pyobject availability does not impact glib testing

pull/1384/head
Chris Caron 2025-08-03 10:12:10 -04:00
parent 808497b58a
commit 57b04e4d0a
1 changed files with 33 additions and 1 deletions

View File

@ -152,11 +152,43 @@ def test_plugin_glib_send_raises_glib_error(mocker, enabled_glib_environment):
def test_plugin_glib_send_raises_generic(mocker, enabled_glib_environment):
"""Simulate generic error in gio_iface.Notify()"""
# Re: https://github.com/caronc/apprise/issues/1383
# This test validates that the NotifyGLib plugin correctly handles a
# generic exception raised by the `Notify()` method call on a mocked
# DBus interface. However, it is only meaningful in environments that:
#
# 1. Do NOT have PyGObject (`gi`) installed, OR
# 2. Have `gi`, but without introspection or live bindings activated.
#
# When PyGObject is installed and active, the `gi.repository` namespace
# becomes populated by introspected C-based objects that do not behave
# like regular Python functions. This causes mock patching via
# `mocker.patch("gi.repository.Gio.DBusProxy.new_for_bus_sync")` to
# silently fail or be ignored, as Python's mocking machinery cannot
# reliably override these introspected symbols.
#
# This test exists to ensure coverage of legacy or minimal environments
# where Apprise's GLib support can still be used through soft mocks,
# such as CI/CD pipelines or headless test setups where PyGObject is
# absent or stubbed (as done via `enabled_glib_environment`).
#
# Note: In production environments with active PyGObject, exception
# handling is already tested via `GLib.Error` branches or during actual
# usage of `NotifyGLib.send()`. This test supplements that by simulating
# the rare fallback case of a non-GLib-related exception during Notify().
import gi
if hasattr(gi, "repository"):
pytest.skip(
"pygobject introspection active, test won't behave as expected")
fake_iface = Mock()
fake_iface.Notify.side_effect = RuntimeError("boom")
mocker.patch(
"gi.repository.Gio.DBusProxy.new_for_bus_sync",
return_value=fake_iface)
return_value=fake_iface,
)
obj = apprise.Apprise.instantiate("glib://", suppress_exceptions=False)
logger = mocker.spy(obj, "logger")
assert obj.notify("boom", title="fail") is False