test_login_manager.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # systemctl-mqtt - MQTT client triggering & reporting shutdown on systemd-based systems
  2. #
  3. # Copyright (C) 2024 Fabian Peter Hammerle <fabian@hammerle.me>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. import contextlib
  18. import datetime
  19. import typing
  20. import unittest.mock
  21. import pytest
  22. from jeepney.low_level import HeaderFields, Message
  23. import systemctl_mqtt._dbus
  24. # pylint: disable=protected-access
  25. @contextlib.contextmanager
  26. def mock_open_dbus_connection() -> typing.Iterator[unittest.mock.MagicMock]:
  27. with unittest.mock.patch("jeepney.io.blocking.open_dbus_connection") as mock:
  28. yield mock.return_value
  29. @pytest.mark.parametrize(
  30. ("member", "signature", "kwargs", "body"),
  31. [
  32. ("ListInhibitors", None, {}, ()),
  33. ("LockSessions", None, {}, ()),
  34. ("CanPowerOff", None, {}, ()),
  35. (
  36. "ScheduleShutdown",
  37. "st",
  38. {
  39. "action": "poweroff",
  40. "time": datetime.datetime(
  41. 1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc
  42. ),
  43. },
  44. ("poweroff", 0),
  45. ),
  46. ("Suspend", "b", {"interactive": True}, (True,)),
  47. (
  48. "Inhibit",
  49. "ssss",
  50. {"what": "poweroff", "who": "me", "why": "fixing bugs", "mode": "block"},
  51. ("poweroff", "me", "fixing bugs", "block"),
  52. ),
  53. ],
  54. )
  55. def test_method(
  56. member: str,
  57. signature: typing.Optional[str],
  58. kwargs: typing.Dict[str, typing.Any],
  59. body: typing.Tuple[typing.Any],
  60. ) -> None:
  61. with mock_open_dbus_connection() as dbus_connection_mock:
  62. proxy = systemctl_mqtt._dbus.get_login_manager_proxy()
  63. getattr(proxy, member)(**kwargs)
  64. dbus_connection_mock.send_and_get_reply.assert_called_once()
  65. message: Message = dbus_connection_mock.send_and_get_reply.call_args[0][0]
  66. if signature:
  67. assert message.header.fields.pop(HeaderFields.signature) == signature
  68. assert message.header.fields == {
  69. HeaderFields.path: "/org/freedesktop/login1",
  70. HeaderFields.destination: "org.freedesktop.login1",
  71. HeaderFields.interface: "org.freedesktop.login1.Manager",
  72. HeaderFields.member: member,
  73. }
  74. assert message.body == body
  75. @pytest.mark.parametrize("property_name", ["HandlePowerKey", "Docked"])
  76. def test_get(property_name: str) -> None:
  77. with mock_open_dbus_connection() as dbus_connection_mock:
  78. proxy = systemctl_mqtt._dbus.get_login_manager_proxy()
  79. proxy.Get(property_name=property_name)
  80. dbus_connection_mock.send_and_get_reply.assert_called_once()
  81. message: Message = dbus_connection_mock.send_and_get_reply.call_args[0][0]
  82. assert message.header.fields == {
  83. HeaderFields.path: "/org/freedesktop/login1",
  84. HeaderFields.destination: "org.freedesktop.login1",
  85. HeaderFields.interface: "org.freedesktop.DBus.Properties",
  86. HeaderFields.member: "Get",
  87. HeaderFields.signature: "ss",
  88. }
  89. assert message.body == ("org.freedesktop.login1.Manager", property_name)