File indexing completed on 2025-04-27 08:22:25
0001 #!/usr/bin/env python3 0002 """ 0003 SPDX-FileCopyrightText: 2023 Fushan Wen <qydwhotmail@gmail.com> 0004 SPDX-License-Identifier: MIT 0005 """ 0006 0007 # For FreeBSD CI which only has python 3.9 0008 from __future__ import annotations 0009 0010 import logging 0011 import os 0012 import subprocess 0013 import sys 0014 import time 0015 import unittest 0016 from typing import Final 0017 0018 from gi.repository import Gio, GLib 0019 0020 KDE_INSTALL_FULL_LIBEXECDIR: Final = os.environ.get("KDE_INSTALL_FULL_LIBEXECDIR", "/usr/libexec") 0021 PORTAL_SERVICE_NAME: Final = "org.freedesktop.impl.portal.desktop.kde" 0022 GROUP: Final = "org.freedesktop.appearance" 0023 KEYS: Final = ("accent-color", "color-scheme") 0024 EXPECTED_SIGNATURES: Final = ("(ddd)", "u") 0025 0026 0027 def name_has_owner(session_bus: Gio.DBusConnection, name: str) -> bool: 0028 """ 0029 Whether the given name is available on session bus 0030 """ 0031 message: Gio.DBusMessage = Gio.DBusMessage.new_method_call("org.freedesktop.DBus", "/", "org.freedesktop.DBus", "NameHasOwner") 0032 message.set_body(GLib.Variant("(s)", [name])) 0033 reply, _ = session_bus.send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE, 1000) 0034 return reply and reply.get_signature() == 'b' and reply.get_body().get_child_value(0).get_boolean() 0035 0036 0037 class OrgFreeDesktopAppearanceTests(unittest.TestCase): 0038 """ 0039 Tests for org.freedesktop.appearance 0040 """ 0041 0042 portal_process: subprocess.Popen | None = None 0043 0044 @classmethod 0045 def setUpClass(cls) -> None: 0046 session_bus: Gio.DBusConnection = Gio.bus_get_sync(Gio.BusType.SESSION) 0047 portal_launched = name_has_owner(session_bus, PORTAL_SERVICE_NAME) 0048 if not portal_launched: 0049 debug_environ = os.environ.copy() 0050 debug_environ["QT_LOGGING_RULES"] = "*.debug=true" 0051 cls.portal_process = subprocess.Popen([os.path.join(KDE_INSTALL_FULL_LIBEXECDIR, "xdg-desktop-portal-kde")], env=debug_environ, stdout=sys.stderr, stderr=sys.stderr) 0052 for _ in range(10): 0053 if name_has_owner(session_bus, PORTAL_SERVICE_NAME): 0054 portal_launched = True 0055 break 0056 logging.info("waiting for portal to appear on the DBus session") 0057 time.sleep(1) 0058 assert portal_launched 0059 0060 @classmethod 0061 def tearDownClass(cls) -> None: 0062 if cls.portal_process is not None: 0063 cls.portal_process.terminate() 0064 0065 def test_bug476592_signature(self) -> None: 0066 """ 0067 Make sure the signature is correct 0068 """ 0069 session_bus: Gio.DBusConnection = Gio.bus_get_sync(Gio.BusType.SESSION) 0070 0071 for key, expected_signature in zip(KEYS, EXPECTED_SIGNATURES): 0072 message: Gio.DBusMessage = Gio.DBusMessage.new_method_call(PORTAL_SERVICE_NAME, "/org/freedesktop/portal/desktop", "org.freedesktop.impl.portal.Settings", "Read") 0073 message.set_body(GLib.Variant("(ss)", [GROUP, key])) 0074 reply, _ = session_bus.send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE, 1000) 0075 self.assertIsNotNone(reply) 0076 self.assertEqual(reply.get_signature(), 'v', f"Wrong signature: {reply.get_signature()}") 0077 self.assertEqual(reply.get_body().get_child_value(0).get_variant().get_type_string(), expected_signature) 0078 0079 0080 if __name__ == '__main__': 0081 logging.getLogger().setLevel(logging.DEBUG) 0082 unittest.main()