"""Unit tests for scripts/notify_failure.py.""" from unittest.mock import MagicMock, patch from click.testing import CliRunner from gitea_runner_manager.exceptions import APIError from scripts.notify_failure import main class TestNotifyFailure: @patch.dict("os.environ", {"REPO_TOKEN": "tok"}) @patch("scripts.notify_failure.GiteaClient") def test_creates_issue_with_labels(self, mock_client_cls: MagicMock) -> None: mock_client = MagicMock() mock_client.list_labels.return_value = [{"id": 5, "name": "bug"}] mock_client.create_issue.return_value = {"id": 42} mock_client_cls.return_value = mock_client runner = CliRunner() result = runner.invoke( main, [ "--repo", "owner/repo", "--run-id", "123", "--workflow", "release", "--commit", "abc123def456", ], ) assert result.exit_code == 0 assert "issue #42" in result.output mock_client.create_issue.assert_called_once() call_kwargs = mock_client.create_issue.call_args assert call_kwargs.kwargs["labels"] == [5] @patch.dict("os.environ", {"REPO_TOKEN": "tok"}) @patch("scripts.notify_failure.GiteaClient") def test_creates_issue_without_bug_label(self, mock_client_cls: MagicMock) -> None: """When 'bug' label doesn't exist, create issue without labels.""" mock_client = MagicMock() mock_client.list_labels.return_value = [{"id": 1, "name": "enhancement"}] mock_client.create_issue.return_value = {"id": 43} mock_client_cls.return_value = mock_client runner = CliRunner() result = runner.invoke( main, [ "--repo", "owner/repo", "--run-id", "124", "--workflow", "publish", "--commit", "def789", ], ) assert result.exit_code == 0 assert "issue #43" in result.output mock_client.create_issue.assert_called_once() call_kwargs = mock_client.create_issue.call_args assert call_kwargs.kwargs.get("labels") is None @patch.dict("os.environ", {"REPO_TOKEN": "tok"}) @patch("scripts.notify_failure.GiteaClient") def test_api_error_raises(self, mock_client_cls: MagicMock) -> None: mock_client = MagicMock() mock_client.list_labels.return_value = [] mock_client.create_issue.side_effect = APIError(403, "forbidden") mock_client_cls.return_value = mock_client runner = CliRunner() result = runner.invoke( main, [ "--repo", "owner/repo", "--run-id", "125", "--workflow", "release", "--commit", "abc", ], ) assert result.exit_code == 1 assert "403" in result.output @patch.dict("os.environ", {"REPO_TOKEN": ""}, clear=True) def test_missing_token_exits(self) -> None: runner = CliRunner() result = runner.invoke( main, ["--repo", "owner/repo", "--run-id", "1", "--workflow", "release", "--commit", "abc"], ) assert result.exit_code == 1 assert "REPO_TOKEN" in result.output