"""Unit tests for cli module.""" from unittest.mock import MagicMock, patch from click.testing import CliRunner from gitea_runner_manager.cli import cli class TestCLI: def test_cli_version(self) -> None: runner = CliRunner() result = runner.invoke(cli, ["--version"]) assert result.exit_code == 0 assert "0.1.0" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_install(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com", "GITEA_ADMIN_TOKEN": ""}) result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu", "--token", "tok"]) assert result.exit_code == 0 mock_manager.install.assert_called_once_with( host="host1", user="ubuntu", key=None, name=None, token="tok", gitea_url="https://git.example.com", mode="docker", admin_token="", integration_retries=3, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_install_no_ask_become_pass(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com", "GITEA_ADMIN_TOKEN": ""}) result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu", "--token", "tok", "--no-ask-become-pass"]) assert result.exit_code == 0 mock_manager.install.assert_called_once_with( host="host1", user="ubuntu", key=None, name=None, token="tok", gitea_url="https://git.example.com", mode="docker", admin_token="", integration_retries=3, ask_become_pass=False, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_install_missing_url(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.install.side_effect = AnsibleError("GITEA_URL must be set (or pass --url)") mock_manager_class.return_value = mock_manager with patch.dict("os.environ", {"GITEA_REGISTRATION_TOKEN": "tok"}, clear=True): runner = CliRunner() result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu", "--token", "tok"]) assert result.exit_code != 0 assert "GITEA_URL must be set" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_install_with_url_flag(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager with patch.dict("os.environ", {"GITEA_REGISTRATION_TOKEN": "tok"}, clear=True): runner = CliRunner() result = runner.invoke( cli, ["install", "host1", "--user", "ubuntu", "--token", "tok", "--url", "https://git.example.com"], ) assert result.exit_code == 0 mock_manager.install.assert_called_once_with( host="host1", user="ubuntu", key=None, name=None, token="tok", gitea_url="https://git.example.com", mode="docker", admin_token=None, integration_retries=3, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_install_missing_token(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.install.side_effect = AnsibleError("GITEA_REGISTRATION_TOKEN must be set (or pass --token)") mock_manager_class.return_value = mock_manager with patch.dict("os.environ", {"GITEA_URL": "https://git.example.com"}, clear=True): runner = CliRunner() result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu"]) assert result.exit_code != 0 assert "GITEA_REGISTRATION_TOKEN must be set" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_install_with_options(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com", "GITEA_ADMIN_TOKEN": ""}) result = runner.invoke( cli, [ "install", "host1", "--user", "ubuntu", "--key", "/key", "--name", "r1", "--token", "tok", ], ) assert result.exit_code == 0 mock_manager.install.assert_called_once_with( host="host1", user="ubuntu", key="/key", name="r1", token="tok", gitea_url="https://git.example.com", mode="docker", admin_token="", integration_retries=3, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_install_ask_become_pass(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com", "GITEA_ADMIN_TOKEN": ""}) result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu", "--token", "tok", "--ask-become-pass"]) assert result.exit_code == 0 mock_manager.install.assert_called_once_with( host="host1", user="ubuntu", key=None, name=None, token="tok", gitea_url="https://git.example.com", mode="docker", admin_token="", integration_retries=3, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_install_binary_mode(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com", "GITEA_ADMIN_TOKEN": ""}) result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu", "--token", "tok", "--mode", "binary"]) assert result.exit_code == 0 mock_manager.install.assert_called_once_with( host="host1", user="ubuntu", key=None, name=None, token="tok", gitea_url="https://git.example.com", mode="binary", admin_token="", integration_retries=3, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_install_error(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.install.side_effect = AnsibleError("fail") mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com"}) result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu", "--token", "tok"]) assert result.exit_code != 0 assert "fail" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_update(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke( cli, [ "update", "host1", "--user", "ubuntu", "--key", "/key", "--version", "v0.2.0", ], ) assert result.exit_code == 0 mock_manager.update.assert_called_once_with( host="host1", user="ubuntu", key="/key", version="v0.2.0", mode="docker", ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_update_ask_become_pass(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["update", "host1", "--user", "ubuntu", "--ask-become-pass"]) assert result.exit_code == 0 mock_manager.update.assert_called_once_with( host="host1", user="ubuntu", key=None, version=None, mode="docker", ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_update_binary_mode(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["update", "host1", "--user", "ubuntu", "--mode", "binary"]) assert result.exit_code == 0 mock_manager.update.assert_called_once_with( host="host1", user="ubuntu", key=None, version=None, mode="binary", ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_update_error(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.update.side_effect = AnsibleError("fail") mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["update", "host1", "--user", "ubuntu"]) assert result.exit_code != 0 assert "fail" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_start(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["start", "r1"]) assert result.exit_code == 0 mock_manager.start.assert_called_once_with( name="r1", host=None, user=None, key=None, mode=None, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_start_with_override(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["start", "r1", "--host", "newhost", "--user", "newuser", "--mode", "binary"]) assert result.exit_code == 0 mock_manager.start.assert_called_once_with( name="r1", host="newhost", user="newuser", key=None, mode="binary", ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_stop(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["stop", "r1"]) assert result.exit_code == 0 mock_manager.stop.assert_called_once_with( name="r1", host=None, user=None, key=None, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_enable(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["enable", "r1"]) assert result.exit_code == 0 mock_manager.enable.assert_called_once_with( name="r1", host=None, user=None, key=None, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_disable(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com"}) result = runner.invoke(cli, ["disable", "r1", "--token", "tok"]) assert result.exit_code == 0 mock_manager.disable.assert_called_once_with( name="r1", host=None, user=None, key=None, token="tok", gitea_url="https://git.example.com", mode=None, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_disable_missing_url(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.disable.side_effect = AnsibleError("GITEA_URL must be set (or pass --url)") mock_manager_class.return_value = mock_manager with patch.dict("os.environ", {"GITEA_REGISTRATION_TOKEN": "tok"}, clear=True): runner = CliRunner() result = runner.invoke(cli, ["disable", "r1", "--token", "tok"]) assert result.exit_code != 0 assert "GITEA_URL must be set" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_disable_with_url_flag(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager with patch.dict("os.environ", {"GITEA_REGISTRATION_TOKEN": "tok"}, clear=True): runner = CliRunner() result = runner.invoke(cli, ["disable", "r1", "--token", "tok", "--url", "https://git.example.com"]) assert result.exit_code == 0 mock_manager.disable.assert_called_once_with( name="r1", host=None, user=None, key=None, token="tok", gitea_url="https://git.example.com", mode=None, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_disable_error(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.disable.side_effect = AnsibleError("fail") mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com"}) result = runner.invoke(cli, ["disable", "r1", "--token", "tok"]) assert result.exit_code != 0 assert "fail" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_status(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["status", "r1"]) assert result.exit_code == 0 mock_manager.status.assert_called_once_with( name="r1", host=None, user=None, key=None, mode=None, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_remove(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com"}) result = runner.invoke(cli, ["remove", "r1", "--token", "tok"]) assert result.exit_code == 0 mock_manager.remove.assert_called_once_with( name="r1", host=None, user=None, key=None, token="tok", gitea_url="https://git.example.com", mode=None, force=False, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_remove_force_flag(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com"}) result = runner.invoke(cli, ["remove", "r1", "--token", "tok", "--force"]) assert result.exit_code == 0 mock_manager.remove.assert_called_once_with( name="r1", host=None, user=None, key=None, token="tok", gitea_url="https://git.example.com", mode=None, force=True, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_start_error(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.start.side_effect = AnsibleError("fail") mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["start", "r1"]) assert result.exit_code != 0 assert "fail" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_stop_error(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.stop.side_effect = AnsibleError("fail") mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["stop", "r1"]) assert result.exit_code != 0 assert "fail" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_enable_error(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.enable.side_effect = AnsibleError("fail") mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["enable", "r1"]) assert result.exit_code != 0 assert "fail" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_status_error(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.status.side_effect = AnsibleError("fail") mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["status", "r1"]) assert result.exit_code != 0 assert "fail" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_remove_missing_url(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.remove.side_effect = AnsibleError("GITEA_URL must be set (or pass --url)") mock_manager_class.return_value = mock_manager with patch.dict("os.environ", {"GITEA_REGISTRATION_TOKEN": "tok"}, clear=True): runner = CliRunner() result = runner.invoke(cli, ["remove", "r1", "--token", "tok"]) assert result.exit_code != 0 assert "GITEA_URL must be set" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_remove_with_url_flag(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager_class.return_value = mock_manager with patch.dict("os.environ", {"GITEA_REGISTRATION_TOKEN": "tok"}, clear=True): runner = CliRunner() result = runner.invoke(cli, ["remove", "r1", "--token", "tok", "--url", "https://git.example.com"]) assert result.exit_code == 0 mock_manager.remove.assert_called_once_with( name="r1", host=None, user=None, key=None, token="tok", gitea_url="https://git.example.com", mode=None, force=False, ask_become_pass=True, ) @patch("gitea_runner_manager.cli.RunnerManager") def test_remove_error(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.remove.side_effect = AnsibleError("fail") mock_manager_class.return_value = mock_manager runner = CliRunner(env={"GITEA_URL": "https://git.example.com"}) result = runner.invoke(cli, ["remove", "r1", "--token", "tok"]) assert result.exit_code != 0 assert "fail" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_list(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager.list_runners.return_value = [ {"name": "r1", "host": "10.0.0.1", "user": "ubuntu", "mode": "docker", "status": "active"}, ] mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["list"]) assert result.exit_code == 0 assert "r1" in result.output assert "10.0.0.1" in result.output assert "active" in result.output mock_manager.list_runners.assert_called_once() @patch("gitea_runner_manager.cli.RunnerManager") def test_list_empty(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() mock_manager.list_runners.return_value = [] mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["list"]) assert result.exit_code == 0 assert "No runners registered" in result.output @patch("gitea_runner_manager.cli.RunnerManager") def test_list_error(self, mock_manager_class: MagicMock) -> None: mock_manager = MagicMock() from gitea_runner_manager.exceptions import AnsibleError mock_manager.list_runners.side_effect = AnsibleError("fail") mock_manager_class.return_value = mock_manager runner = CliRunner() result = runner.invoke(cli, ["list"]) assert result.exit_code != 0 assert "fail" in result.output