feat: replace Aider with secure mini-SWE-agent worker
Some checks failed
CI / test (push) Has been cancelled
CI / test (pull_request) Has been cancelled

This commit is contained in:
Christian Meyer
2026-08-31 02:46:58 +02:00
parent 582db3a654
commit 25ed6a8439
30 changed files with 4215 additions and 2148 deletions

View File

@@ -1,27 +1,130 @@
from __future__ import annotations
from unittest.mock import Mock
import pytest
from test_config import settings
from lai_automation.gitea import GiteaClient
from lai_automation.models import Issue, Label
def test_create_pull_request_requires_url() -> None:
client = GiteaClient(settings(gitea_token="token"))
response = Mock()
response.json.return_value = {"number": 12}
client.session.post = Mock(return_value=response)
with pytest.raises(ValueError, match="pull request URL"):
client.create_pull_request("ai/failure-1", "Fix", "Body")
def response(payload, status: int = 200) -> Mock:
result = Mock()
result.json.return_value = payload
result.status_code = status
result.text = ""
result.raise_for_status.return_value = None
return result
def test_create_pull_request_returns_html_url() -> None:
client = GiteaClient(settings(gitea_token="token"))
response = Mock()
response.json.return_value = {"html_url": "https://example.test/owner/lai/pulls/12"}
client.session.post = Mock(return_value=response)
def test_list_queued_issues_filters_pull_requests(settings) -> None:
client = GiteaClient(settings)
client.session.request = Mock(
return_value=response(
[
{
"number": 7,
"title": "Wrong answer",
"body": "Details",
"html_url": "https://gitea.example.test/owner/lai/issues/7",
"labels": [{"id": 1, "name": "ai:queued"}],
},
{
"number": 8,
"title": "A pull request",
"body": "",
"html_url": "https://gitea.example.test/owner/lai/pulls/8",
"labels": [{"id": 1, "name": "ai:queued"}],
"pull_request": {"merged": False},
},
]
)
)
result = client.create_pull_request("ai/failure-1", "Fix", "Body")
issues = client.list_queued_issues()
assert result.endswith("/pulls/12")
assert [issue.number for issue in issues] == [7]
assert client.session.request.call_args.kwargs["params"]["labels"] == "ai:queued"
def test_ensure_automation_labels_creates_only_missing_labels(settings) -> None:
client = GiteaClient(settings)
existing = [{"id": 1, "name": "ai:queued"}]
created = iter(
[
{"id": 2, "name": "ai:running"},
{"id": 3, "name": "ai:ready"},
{"id": 4, "name": "ai:failed"},
]
)
def request(method, _url, **kwargs):
if method == "GET":
return response(existing)
return response(next(created))
client.session.request = Mock(side_effect=request)
labels = client.ensure_automation_labels()
assert set(labels) == {"ai:queued", "ai:running", "ai:ready", "ai:failed"}
assert client.session.request.call_count == 4
def test_state_transition_preserves_manual_labels(settings) -> None:
client = GiteaClient(settings)
client.session.request = Mock(
side_effect=[
response(
[
{"id": 9, "name": "bug"},
{"id": 2, "name": "ai:running"},
]
),
response(
{
"number": 5,
"title": "Issue",
"body": "Body",
"html_url": "https://gitea.example.test/owner/lai/issues/5",
"labels": [
{"id": 9, "name": "bug"},
{"id": 2, "name": "ai:running"},
],
}
),
]
)
issue = Issue(
number=5,
title="Issue",
body="Body",
html_url="https://gitea.example.test/owner/lai/issues/5",
labels=(Label(9, "bug"), Label(1, "ai:queued")),
)
known = {
"ai:queued": Label(1, "ai:queued"),
"ai:running": Label(2, "ai:running"),
}
updated = client.set_automation_state(issue, "ai:running", known)
assert updated.has_label("ai:running")
replace_call = client.session.request.call_args_list[0]
assert replace_call.args[0] == "PUT"
assert replace_call.args[1].endswith("/issues/5/labels")
assert replace_call.kwargs["json"] == {"labels": [9, 2]}
assert client.session.request.call_args_list[1].args[0] == "GET"
def test_create_pull_request_returns_number_and_url(settings) -> None:
client = GiteaClient(settings)
client.session.request = Mock(
return_value=response(
{"number": 17, "html_url": "https://gitea.example.test/owner/lai/pulls/17"}
)
)
pull_request = client.create_pull_request("ai/issue-5", "Fix", "Fixes #5")
assert pull_request.number == 17
assert pull_request.html_url.endswith("/pulls/17")
assert client.session.request.call_args.kwargs["json"]["base"] == "main"