import os import time import subprocess import pytest import dbusmock from dbusmock import DBusTestCase from slic.utils.dbusnotify import convert_dbus_strings os.environ['DISPLAY'] = ':0' os.environ['DBUS_FATAL_WARNINGS'] = '0' if 'DBUS_SESSION_BUS_ADDRESS' not in os.environ: os.environ['DBUS_SESSION_BUS_ADDRESS'] = 'unix:path=/tmp/dbusmock.sock' import dbus from dbusmock import DBusTestCase, MOCK_IFACE class _DBusEnv(DBusTestCase): pass @pytest.fixture(scope="session", autouse=True) def _dbus_session_notifications(): # 1) lancer un bus de session _DBusEnv.start_session_bus() # 2) démarrer le service Notifications (ARGUMENTS POSITIONNELS) p_mock = _DBusEnv.spawn_server( 'org.freedesktop.Notifications', '/org/freedesktop/Notifications', 'org.freedesktop.Notifications', False, # system_bus None # stdout ) # 3) récupérer l'objet via le bus bus = _DBusEnv.get_dbus(False) # False => session bus obj = bus.get_object('org.freedesktop.Notifications', '/org/freedesktop/Notifications') mock = dbus.Interface(obj, MOCK_IFACE) # 4) définir les méthodes minimales mock.AddMethod('org.freedesktop.Notifications', 'GetServerInformation', '', 'ssss', ['pytest-notify', 'pytest-vendor', '1.0', '1.2']) mock.AddMethod('org.freedesktop.Notifications', 'GetCapabilities', '', 'as', [['actions', 'body', 'icon', 'sound']]) mock.AddMethod('org.freedesktop.Notifications', 'Notify', 'susssasa{sv}i', 'u', [1]) mock.AddMethod('org.freedesktop.Notifications', 'CloseNotification', 'u', '', []) yield # Pas de teardown nécessaire ici @pytest.fixture def notifier(): """Création de l'objet DBusNotify pour les tests.""" from slic.utils.dbusnotify import DBusNotify return DBusNotify() def test_notify_create(notifier): """Test la création d'une notification.""" notification = notifier.notify("Test Notification", "This is a test notification.") # Vérifie que l'objet Notification est bien créé assert isinstance(notification, Notification) assert notification.summary == "Test Notification" assert notification.body == "This is a test notification." def test_notify_update(notifier): """Test la mise à jour d'une notification.""" notification = notifier.notify("Test Notification", "This is a test notification.") # Mettre à jour la notification notification.update(summary="Updated Test", body="This notification has been updated.") # Vérifie que la notification a bien été mise à jour assert notification.summary == "Updated Test" assert notification.body == "This notification has been updated." def test_get_server_info(notifier): """Test l'obtention des informations du serveur.""" server_info = notifier.get_server_info() assert isinstance(server_info, dict) assert "name" in server_info and server_info["name"], "Server name is empty" assert "vendor" in server_info and server_info["vendor"], "Server vendor is empty" assert "version" in server_info and server_info["version"], "Server version is empty" assert "spec" in server_info and server_info["spec"], "Server spec is empty" def test_get_capabilities(notifier): """Test l'obtention des capacités du serveur.""" capabilities = notifier.get_capabilities() assert isinstance(capabilities, list), "Capabilities should be a list." assert len(capabilities) > 0, "Capabilities list is empty." expected_capabilities = ['actions', 'body', 'icon', 'sound'] for cap in expected_capabilities: assert cap in capabilities, f"Expected capability '{cap}' not found." for cap in capabilities: assert isinstance(cap, str), f"Each capability should be a string, but found {type(cap)}." def test_notify_and_close(notifier): """Test l'envoi d'une notification et sa fermeture.""" notification = notifier.notify("Test Close", "This notification will be closed.") time.sleep(1) notification.close() printed_lines = notification.dbn.interface._prints assert not any(f"Notification {notification.nid} is still visible" in line for line in printed_lines), "Notification was not closed properly." def test_notify_invalid_value(notifier): with pytest.raises(Exception): # On attend une exception si la valeur est incorrecte notifier.notify("Invalid Test", 1234) # Passage d'un type non valide pour `body` def test_convert_dbus_strings(): # Créer une séquence de test avec des éléments dbus.String et des éléments non dbus.String test_sequence = [dbus.String('Test String 1'), 42, dbus.String('Test String 2'), 3.14] # Convertir la séquence avec la fonction convert_dbus_strings converted = convert_dbus_strings(test_sequence) # Vérifie que le type des éléments convertis est maintenant str assert isinstance(converted[0], str), f"Expected str, got {type(converted[0])}" assert isinstance(converted[2], str), f"Expected str, got {type(converted[2])}" # Vérifie que les éléments non dbus.String restent inchangés assert isinstance(converted[1], int), f"Expected int, got {type(converted[1])}" assert isinstance(converted[3], float), f"Expected float, got {type(converted[3])}" # Vérifie que les valeurs des éléments convertis sont correctes assert converted[0] == 'Test String 1', f"Expected 'Test String 1', got {converted[0]}" assert converted[2] == 'Test String 2', f"Expected 'Test String 2', got {converted[2]}"