mirror of https://github.com/caronc/apprise
dbus/glib testing bulletproofing
parent
90fcc410c8
commit
5cdee8f859
|
@ -43,48 +43,47 @@ logging.disable(logging.CRITICAL)
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def enabled_dbus_environment(mocker):
|
||||
"""Fully mocked D-Bus and GI environment with plugin reloaded and
|
||||
enabled."""
|
||||
def enabled_dbus_environment(monkeypatch):
|
||||
"""
|
||||
Fully mocked DBus and GI environment that works in local and CI environments.
|
||||
"""
|
||||
|
||||
# Step 1: Mock DBus Interface
|
||||
interface_mock = mocker.patch("dbus.Interface", spec=True, Notify=Mock())
|
||||
mocker.patch(
|
||||
"dbus.SessionBus",
|
||||
spec=True,
|
||||
**{"get_object.return_value": interface_mock},
|
||||
)
|
||||
# --- Handle dbus (real or fake) ---
|
||||
try:
|
||||
import dbus
|
||||
except ImportError:
|
||||
dbus = types.ModuleType("dbus")
|
||||
dbus.DBusException = type("DBusException", (Exception,), {})
|
||||
dbus.Interface = Mock()
|
||||
dbus.SessionBus = Mock()
|
||||
|
||||
# Step 2: Inject valid dbus.mainloop.glib and .qt into sys.modules
|
||||
fake_loop = Mock(name="FakeMainLoop")
|
||||
sys.modules["dbus.mainloop.glib"] = types.SimpleNamespace(
|
||||
DBusGMainLoop=lambda: fake_loop
|
||||
)
|
||||
sys.modules["dbus.mainloop.qt"] = types.SimpleNamespace(
|
||||
DBusQtMainLoop=lambda set_as_default=False: fake_loop
|
||||
)
|
||||
sys.modules["dbus"] = dbus
|
||||
|
||||
# Step 3: Mock GI and GdkPixbuf (also covers image handling)
|
||||
# Inject mainloop support if not already present
|
||||
if "dbus.mainloop.glib" not in sys.modules:
|
||||
glib_loop = types.ModuleType("dbus.mainloop.glib")
|
||||
glib_loop.DBusGMainLoop = lambda: Mock(name="FakeLoop")
|
||||
sys.modules["dbus.mainloop.glib"] = glib_loop
|
||||
|
||||
if "dbus.mainloop" not in sys.modules:
|
||||
sys.modules["dbus.mainloop"] = types.ModuleType("dbus.mainloop")
|
||||
|
||||
# Patch specific attributes always, even if real module is present
|
||||
monkeypatch.setattr("dbus.Interface", Mock())
|
||||
monkeypatch.setattr("dbus.SessionBus", Mock())
|
||||
monkeypatch.setattr("dbus.DBusException", type("DBusException", (Exception,), {}))
|
||||
|
||||
# --- Mock GI / GdkPixbuf ---
|
||||
gi = types.ModuleType("gi")
|
||||
gi.repository = types.ModuleType("gi.repository")
|
||||
|
||||
mock_pixbuf = Mock()
|
||||
mock_image = Mock()
|
||||
mock_pixbuf.new_from_file.return_value = mock_image
|
||||
mock_image.get_width.return_value = 100
|
||||
mock_image.get_height.return_value = 100
|
||||
mock_image.get_rowstride.return_value = 1
|
||||
mock_image.get_has_alpha.return_value = 0
|
||||
mock_image.get_bits_per_sample.return_value = 8
|
||||
mock_image.get_n_channels.return_value = 1
|
||||
mock_image.get_pixels.return_value = b""
|
||||
|
||||
gi.repository.GdkPixbuf = types.SimpleNamespace(Pixbuf=mock_pixbuf)
|
||||
gi.require_version = Mock()
|
||||
gi.repository = types.SimpleNamespace(
|
||||
GdkPixbuf=types.SimpleNamespace(Pixbuf=Mock())
|
||||
)
|
||||
|
||||
sys.modules["gi"] = gi
|
||||
sys.modules["gi.repository"] = gi.repository
|
||||
|
||||
# Step 4: Reload plugin after all mocks are in place
|
||||
# --- Reload plugin with controlled env ---
|
||||
reload_plugin("dbus")
|
||||
|
||||
|
||||
|
|
|
@ -41,19 +41,20 @@ logging.disable(logging.CRITICAL)
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def enabled_glib_environment(mocker):
|
||||
"""Mocks a working GI/GLib/Gio environment"""
|
||||
# Patch GLib.Error and Gio
|
||||
def enabled_glib_environment(monkeypatch):
|
||||
"""
|
||||
Fully mocked GI/GLib/Gio/GdkPixbuf environment for local and CI.
|
||||
"""
|
||||
# Step 1: Fake gi and repository
|
||||
gi = types.ModuleType("gi")
|
||||
gi.repository = types.SimpleNamespace()
|
||||
gi.require_version = Mock()
|
||||
|
||||
fake_variant = Mock(name="Variant")
|
||||
fake_error = type("GLibError", (Exception,), {})
|
||||
fake_pixbuf = Mock()
|
||||
fake_image = Mock()
|
||||
|
||||
fake_variant = mocker.MagicMock(name="Variant")
|
||||
fake_error_type = type("GLibError", (Exception,), {})
|
||||
fake_pixbuf = mocker.MagicMock(name="Pixbuf")
|
||||
fake_image = mocker.MagicMock(name="PixbufImage")
|
||||
fake_pixbuf.new_from_file.return_value = fake_image
|
||||
|
||||
# Provide fake return values
|
||||
fake_image.get_width.return_value = 100
|
||||
fake_image.get_height.return_value = 100
|
||||
fake_image.get_rowstride.return_value = 1
|
||||
|
@ -62,16 +63,17 @@ def enabled_glib_environment(mocker):
|
|||
fake_image.get_n_channels.return_value = 1
|
||||
fake_image.get_pixels.return_value = b""
|
||||
|
||||
gi.require_version = Mock()
|
||||
gi.repository.GLib = types.SimpleNamespace(
|
||||
Error=fake_error_type, Variant=fake_variant)
|
||||
gi.repository.Gio = mocker.MagicMock(name="Gio")
|
||||
gi.repository.GdkPixbuf = types.SimpleNamespace(
|
||||
Pixbuf=fake_pixbuf)
|
||||
gi.repository = types.SimpleNamespace(
|
||||
Gio=Mock(),
|
||||
GLib=types.SimpleNamespace(Variant=fake_variant, Error=fake_error),
|
||||
GdkPixbuf=types.SimpleNamespace(Pixbuf=fake_pixbuf),
|
||||
)
|
||||
|
||||
# Step 2: Inject into sys.modules
|
||||
sys.modules["gi"] = gi
|
||||
sys.modules["gi.repository"] = gi.repository
|
||||
|
||||
# Step 3: Reload plugin with all mocks in place
|
||||
reload_plugin("glib")
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue