Post-merge / detect-type (push) Successful in 55s
Post-merge / release (push) Successful in 1m19s
Post-merge / validate-commit-msg (push) Successful in 1m19s
Post-merge / badges (push) Successful in 1m33s
Post-merge / vikunja (push) Successful in 1m13s
Post-merge / configure-repo (push) Successful in 1m13s
Post-merge / sync-wiki (push) Successful in 1m54s
Post-merge / publish (push) Successful in 55s
121 lines
5.0 KiB
Python
121 lines
5.0 KiB
Python
"""Unit tests for gitea_client module."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from gitea_runner_manager.gitea_client import GiteaAPIError, GiteaWorkflowClient
|
|
|
|
|
|
class TestGiteaWorkflowClient:
|
|
def _client(self) -> GiteaWorkflowClient:
|
|
return GiteaWorkflowClient("https://git.example.com", "test-token")
|
|
|
|
def test_list_workflows(self) -> None:
|
|
client = self._client()
|
|
mock_response = {"workflows": [{"id": 1, "name": "CI", "path": "ci.yml", "state": "active"}]}
|
|
with patch.object(client, "_request", return_value=mock_response) as mock_req:
|
|
result = client.list_workflows("oblachno-oss", "grm")
|
|
assert len(result) == 1
|
|
assert result[0]["name"] == "CI"
|
|
mock_req.assert_called_once_with("GET", "/repos/oblachno-oss/grm/actions/workflows")
|
|
|
|
def test_list_workflows_empty(self) -> None:
|
|
client = self._client()
|
|
with patch.object(client, "_request", return_value=None):
|
|
result = client.list_workflows("oblachno-oss", "grm")
|
|
assert result == []
|
|
|
|
def test_dispatch_workflow(self) -> None:
|
|
client = self._client()
|
|
mock_response = {"id": 42, "html_url": "https://git.example.com/oblachno-oss/grm/actions/runs/42"}
|
|
with patch.object(client, "_request", return_value=mock_response) as mock_req:
|
|
result = client.dispatch_workflow("oblachno-oss", "grm", "ci.yml", ref="master")
|
|
assert result is not None
|
|
assert result["id"] == 42
|
|
mock_req.assert_called_once_with(
|
|
"POST",
|
|
"/repos/oblachno-oss/grm/actions/workflows/ci.yml/dispatches?return_run_details=true",
|
|
{"ref": "master"},
|
|
)
|
|
|
|
def test_dispatch_workflow_with_inputs(self) -> None:
|
|
client = self._client()
|
|
with patch.object(client, "_request", return_value=None) as mock_req:
|
|
client.dispatch_workflow("oblachno-oss", "grm", "build.yml", ref="master", inputs={"env": "prod"})
|
|
mock_req.assert_called_once_with(
|
|
"POST",
|
|
"/repos/oblachno-oss/grm/actions/workflows/build.yml/dispatches?return_run_details=true",
|
|
{"ref": "master", "inputs": {"env": "prod"}},
|
|
)
|
|
|
|
def test_dispatch_workflow_api_error(self) -> None:
|
|
client = self._client()
|
|
with patch.object(client, "_request", side_effect=GiteaAPIError(404, "workflow not found")):
|
|
with pytest.raises(GiteaAPIError) as exc_info:
|
|
client.dispatch_workflow("oblachno-oss", "grm", "nonexistent.yml")
|
|
assert exc_info.value.status == 404
|
|
|
|
|
|
class TestGiteaWorkflowClientRequest:
|
|
"""Test the underlying _request method with mocked urllib."""
|
|
|
|
def test_request_success(self) -> None:
|
|
client = GiteaWorkflowClient("https://git.example.com/", "tok")
|
|
mock_resp = MagicMock()
|
|
mock_resp.status = 200
|
|
mock_resp.read.return_value = json.dumps({"ok": True}).encode()
|
|
mock_resp.__enter__ = MagicMock(return_value=mock_resp)
|
|
mock_resp.__exit__ = MagicMock(return_value=False)
|
|
with patch("urllib.request.urlopen", return_value=mock_resp) as mock_urlopen:
|
|
result = client._request("GET", "/test")
|
|
assert result == {"ok": True}
|
|
mock_urlopen.assert_called_once()
|
|
|
|
def test_request_204_no_content(self) -> None:
|
|
client = GiteaWorkflowClient("https://git.example.com", "tok")
|
|
mock_resp = MagicMock()
|
|
mock_resp.status = 204
|
|
mock_resp.__enter__ = MagicMock(return_value=mock_resp)
|
|
mock_resp.__exit__ = MagicMock(return_value=False)
|
|
with patch("urllib.request.urlopen", return_value=mock_resp):
|
|
result = client._request("POST", "/test", {"ref": "master"})
|
|
assert result is None
|
|
|
|
def test_request_http_error(self) -> None:
|
|
import urllib.error
|
|
|
|
client = GiteaWorkflowClient("https://git.example.com", "tok")
|
|
err = urllib.error.HTTPError(
|
|
"https://git.example.com/api/v1/test",
|
|
404,
|
|
"Not Found",
|
|
{},
|
|
__import__("io").BytesIO(b'{"message": "resource not found"}'),
|
|
)
|
|
with patch("urllib.request.urlopen", side_effect=err):
|
|
with pytest.raises(GiteaAPIError) as exc_info:
|
|
client._request("GET", "/test")
|
|
assert exc_info.value.status == 404
|
|
assert "resource not found" in exc_info.value.message
|
|
|
|
def test_request_http_error_non_json(self) -> None:
|
|
import urllib.error
|
|
|
|
client = GiteaWorkflowClient("https://git.example.com", "tok")
|
|
err = urllib.error.HTTPError(
|
|
"https://git.example.com/api/v1/test",
|
|
500,
|
|
"Internal Server Error",
|
|
{},
|
|
__import__("io").BytesIO(b"plain text error"),
|
|
)
|
|
with patch("urllib.request.urlopen", side_effect=err):
|
|
with pytest.raises(GiteaAPIError) as exc_info:
|
|
client._request("GET", "/test")
|
|
assert exc_info.value.status == 500
|
|
assert "plain text error" in exc_info.value.message
|