"""Unit tests for scripts/configure_repo.py.""" import http from unittest.mock import MagicMock, patch import click import pytest from gitea_runner_manager.config import BRANCH_PROTECTION_CONFIG, REPO_SETTINGS_CONFIG from gitea_runner_manager.exceptions import APIError from scripts.configure_repo import ( _handle_http_error, main, ) class TestHandleHttpError: def test_handle_http_error_403(self) -> None: err = APIError(http.HTTPStatus.FORBIDDEN, "Forbidden") with pytest.raises(click.ClickException) as exc: _handle_http_error(err) msg = str(exc.value) assert "admin rights" in msg assert "Settings → Branches" in msg def test_handle_http_error_other(self) -> None: err = APIError(http.HTTPStatus.INTERNAL_SERVER_ERROR, "Internal Server Error") with pytest.raises(click.ClickException) as exc: _handle_http_error(err) assert str(http.HTTPStatus.INTERNAL_SERVER_ERROR) in str(exc.value) def test_handle_http_error_json_parse_fails(self) -> None: err = APIError(http.HTTPStatus.BAD_GATEWAY, "bad gateway") with pytest.raises(click.ClickException) as exc: _handle_http_error(err) assert str(http.HTTPStatus.BAD_GATEWAY) in str(exc.value) class TestMain: def test_main_missing_token(self) -> None: with patch.dict("os.environ", {}, clear=True): with pytest.raises(click.ClickException) as exc: main() assert "REPO_TOKEN" in str(exc.value) def test_main_success(self) -> None: with patch.dict("os.environ", {"REPO_TOKEN": "tok"}, clear=True): with patch("scripts.configure_repo.GiteaClient") as mock_client_cls: mock_client = MagicMock() mock_client_cls.return_value = mock_client main() mock_client.ensure_branch_protection.assert_called_once_with("master", BRANCH_PROTECTION_CONFIG) mock_client.ensure_label.assert_called_once() mock_client.update_repo_settings.assert_called_once_with(REPO_SETTINGS_CONFIG) def test_main_label_already_exists(self) -> None: with patch.dict("os.environ", {"REPO_TOKEN": "tok"}, clear=True): with patch("scripts.configure_repo.GiteaClient") as mock_client_cls: mock_client = MagicMock() mock_client.ensure_label.return_value = None mock_client_cls.return_value = mock_client main() mock_client.ensure_branch_protection.assert_called_once_with("master", BRANCH_PROTECTION_CONFIG) mock_client.ensure_label.assert_called_once() mock_client.update_repo_settings.assert_called_once_with(REPO_SETTINGS_CONFIG) def test_main_api_error(self) -> None: with patch.dict("os.environ", {"REPO_TOKEN": "tok"}, clear=True): with patch("scripts.configure_repo.GiteaClient") as mock_client_cls: mock_client = MagicMock() mock_client.ensure_branch_protection.side_effect = APIError(http.HTTPStatus.FORBIDDEN, "Forbidden") mock_client_cls.return_value = mock_client with pytest.raises(click.ClickException) as exc: main() assert "HTTP" in str(exc.value) def test_main_module_block() -> None: with patch.dict("os.environ", {"REPO_TOKEN": "tok"}, clear=True): with patch("scripts.configure_repo.GiteaClient") as mock_client_cls: mock_client = MagicMock() mock_client_cls.return_value = mock_client import scripts.configure_repo as cr with open(cr.__file__) as f: source = f.read() # Remove __main__ block so exec doesn't call main() before we inject the mock source = source.replace('if __name__ == "__main__":\n main()\n', "") namespace = dict(cr.__dict__) exec(compile(source, cr.__file__, "exec"), namespace) namespace["GiteaClient"] = mock_client_cls namespace["main"]() mock_client.ensure_branch_protection.assert_called_once_with("master", BRANCH_PROTECTION_CONFIG) mock_client.update_repo_settings.assert_called_once_with(REPO_SETTINGS_CONFIG)