# ABOUTME: Tests for power actions — lock, logout, hibernate, reboot, shutdown. # ABOUTME: Uses mocking to avoid actually calling system commands. import subprocess from unittest.mock import patch import pytest from moonset.power import lock, logout, hibernate, reboot, shutdown, POWER_TIMEOUT class TestLock: """Tests for the lock power action.""" @patch("moonset.power.subprocess.run") def test_calls_moonlock(self, mock_run) -> None: lock() mock_run.assert_called_once_with( ["moonlock"], check=True, timeout=POWER_TIMEOUT ) @patch("moonset.power.subprocess.run") def test_raises_on_failure(self, mock_run) -> None: mock_run.side_effect = subprocess.CalledProcessError(1, "loginctl") with pytest.raises(subprocess.CalledProcessError): lock() @patch("moonset.power.subprocess.run") def test_raises_on_timeout(self, mock_run) -> None: mock_run.side_effect = subprocess.TimeoutExpired("loginctl", POWER_TIMEOUT) with pytest.raises(subprocess.TimeoutExpired): lock() class TestLogout: """Tests for the logout power action.""" @patch("moonset.power.subprocess.run") def test_calls_niri_quit(self, mock_run) -> None: logout() mock_run.assert_called_once_with( ["niri", "msg", "action", "quit"], check=True, timeout=POWER_TIMEOUT ) @patch("moonset.power.subprocess.run") def test_raises_on_failure(self, mock_run) -> None: mock_run.side_effect = subprocess.CalledProcessError(1, "niri") with pytest.raises(subprocess.CalledProcessError): logout() @patch("moonset.power.subprocess.run") def test_raises_on_timeout(self, mock_run) -> None: mock_run.side_effect = subprocess.TimeoutExpired("niri", POWER_TIMEOUT) with pytest.raises(subprocess.TimeoutExpired): logout() class TestHibernate: """Tests for the hibernate power action.""" @patch("moonset.power.subprocess.run") def test_calls_systemctl_hibernate(self, mock_run) -> None: hibernate() mock_run.assert_called_once_with( ["systemctl", "hibernate"], check=True, timeout=POWER_TIMEOUT ) @patch("moonset.power.subprocess.run") def test_raises_on_failure(self, mock_run) -> None: mock_run.side_effect = subprocess.CalledProcessError(1, "systemctl") with pytest.raises(subprocess.CalledProcessError): hibernate() @patch("moonset.power.subprocess.run") def test_raises_on_timeout(self, mock_run) -> None: mock_run.side_effect = subprocess.TimeoutExpired("systemctl", POWER_TIMEOUT) with pytest.raises(subprocess.TimeoutExpired): hibernate() class TestReboot: """Tests for the reboot power action.""" @patch("moonset.power.subprocess.run") def test_calls_loginctl_reboot(self, mock_run) -> None: reboot() mock_run.assert_called_once_with( ["loginctl", "reboot"], check=True, timeout=POWER_TIMEOUT ) @patch("moonset.power.subprocess.run") def test_raises_on_failure(self, mock_run) -> None: mock_run.side_effect = subprocess.CalledProcessError(1, "loginctl") with pytest.raises(subprocess.CalledProcessError): reboot() @patch("moonset.power.subprocess.run") def test_raises_on_timeout(self, mock_run) -> None: mock_run.side_effect = subprocess.TimeoutExpired("loginctl", POWER_TIMEOUT) with pytest.raises(subprocess.TimeoutExpired): reboot() class TestShutdown: """Tests for the shutdown power action.""" @patch("moonset.power.subprocess.run") def test_calls_loginctl_poweroff(self, mock_run) -> None: shutdown() mock_run.assert_called_once_with( ["loginctl", "poweroff"], check=True, timeout=POWER_TIMEOUT ) @patch("moonset.power.subprocess.run") def test_raises_on_failure(self, mock_run) -> None: mock_run.side_effect = subprocess.CalledProcessError(1, "loginctl") with pytest.raises(subprocess.CalledProcessError): shutdown() @patch("moonset.power.subprocess.run") def test_raises_on_timeout(self, mock_run) -> None: mock_run.side_effect = subprocess.TimeoutExpired("loginctl", POWER_TIMEOUT) with pytest.raises(subprocess.TimeoutExpired): shutdown()