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
|
@pytest.fixture
|
||||||
def enabled_dbus_environment(mocker):
|
def enabled_dbus_environment(monkeypatch):
|
||||||
"""Fully mocked D-Bus and GI environment with plugin reloaded and
|
"""
|
||||||
enabled."""
|
Fully mocked DBus and GI environment that works in local and CI environments.
|
||||||
|
"""
|
||||||
|
|
||||||
# Step 1: Mock DBus Interface
|
# --- Handle dbus (real or fake) ---
|
||||||
interface_mock = mocker.patch("dbus.Interface", spec=True, Notify=Mock())
|
try:
|
||||||
mocker.patch(
|
import dbus
|
||||||
"dbus.SessionBus",
|
except ImportError:
|
||||||
spec=True,
|
dbus = types.ModuleType("dbus")
|
||||||
**{"get_object.return_value": interface_mock},
|
dbus.DBusException = type("DBusException", (Exception,), {})
|
||||||
)
|
dbus.Interface = Mock()
|
||||||
|
dbus.SessionBus = Mock()
|
||||||
|
|
||||||
# Step 2: Inject valid dbus.mainloop.glib and .qt into sys.modules
|
sys.modules["dbus"] = dbus
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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 = 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.require_version = Mock()
|
||||||
|
gi.repository = types.SimpleNamespace(
|
||||||
|
GdkPixbuf=types.SimpleNamespace(Pixbuf=Mock())
|
||||||
|
)
|
||||||
|
|
||||||
sys.modules["gi"] = gi
|
sys.modules["gi"] = gi
|
||||||
sys.modules["gi.repository"] = gi.repository
|
sys.modules["gi.repository"] = gi.repository
|
||||||
|
|
||||||
# Step 4: Reload plugin after all mocks are in place
|
# --- Reload plugin with controlled env ---
|
||||||
reload_plugin("dbus")
|
reload_plugin("dbus")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,19 +41,20 @@ logging.disable(logging.CRITICAL)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def enabled_glib_environment(mocker):
|
def enabled_glib_environment(monkeypatch):
|
||||||
"""Mocks a working GI/GLib/Gio environment"""
|
"""
|
||||||
# Patch GLib.Error and Gio
|
Fully mocked GI/GLib/Gio/GdkPixbuf environment for local and CI.
|
||||||
|
"""
|
||||||
|
# Step 1: Fake gi and repository
|
||||||
gi = types.ModuleType("gi")
|
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
|
fake_pixbuf.new_from_file.return_value = fake_image
|
||||||
|
|
||||||
# Provide fake return values
|
|
||||||
fake_image.get_width.return_value = 100
|
fake_image.get_width.return_value = 100
|
||||||
fake_image.get_height.return_value = 100
|
fake_image.get_height.return_value = 100
|
||||||
fake_image.get_rowstride.return_value = 1
|
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_n_channels.return_value = 1
|
||||||
fake_image.get_pixels.return_value = b""
|
fake_image.get_pixels.return_value = b""
|
||||||
|
|
||||||
gi.require_version = Mock()
|
gi.repository = types.SimpleNamespace(
|
||||||
gi.repository.GLib = types.SimpleNamespace(
|
Gio=Mock(),
|
||||||
Error=fake_error_type, Variant=fake_variant)
|
GLib=types.SimpleNamespace(Variant=fake_variant, Error=fake_error),
|
||||||
gi.repository.Gio = mocker.MagicMock(name="Gio")
|
GdkPixbuf=types.SimpleNamespace(Pixbuf=fake_pixbuf),
|
||||||
gi.repository.GdkPixbuf = types.SimpleNamespace(
|
)
|
||||||
Pixbuf=fake_pixbuf)
|
|
||||||
|
|
||||||
|
# Step 2: Inject into sys.modules
|
||||||
sys.modules["gi"] = gi
|
sys.modules["gi"] = gi
|
||||||
sys.modules["gi.repository"] = gi.repository
|
sys.modules["gi.repository"] = gi.repository
|
||||||
|
|
||||||
|
# Step 3: Reload plugin with all mocks in place
|
||||||
reload_plugin("glib")
|
reload_plugin("glib")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue