Forge native integration: PRD + forge library layer #318
@@ -8,6 +8,7 @@ core (`assume_yes` + `headless_prompt_text`) as `start --headless`.
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from typing import Any
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import bot_bottle.cli.resume as resume_mod
|
||||
@@ -40,9 +41,9 @@ class ResumeHeadlessTest(unittest.TestCase):
|
||||
).start()
|
||||
self.addCleanup(patch.stopall)
|
||||
|
||||
def _launch_kwargs(self) -> dict:
|
||||
def _launch_kwargs(self) -> dict[str, Any]:
|
||||
self._launch.assert_called_once()
|
||||
return self._launch.call_args.kwargs
|
||||
return dict(self._launch.call_args.kwargs)
|
||||
|
||||
def test_headless_passes_assume_yes_and_prompt(self):
|
||||
rc = resume_mod.cmd_resume(
|
||||
|
||||
@@ -88,7 +88,7 @@ class TestScopedForgeWrites(unittest.TestCase):
|
||||
|
||||
def test_scope_error_is_permission_error(self):
|
||||
# Sidecars can catch the stdlib base type.
|
||||
self.assertTrue(issubclass(ForgeScopeError, PermissionError))
|
||||
self.assertIn(PermissionError, ForgeScopeError.__mro__)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -20,11 +20,11 @@ def _client() -> GiteaClient:
|
||||
)
|
||||
|
||||
|
||||
def _resp(body, status: int = 200) -> MagicMock:
|
||||
def _resp(body: object, status: int = 200) -> MagicMock:
|
||||
resp = MagicMock()
|
||||
resp.read.return_value = json.dumps(body).encode() if body is not None else b""
|
||||
resp.status = status
|
||||
resp.__enter__ = lambda s: s
|
||||
resp.__enter__ = lambda s: s # type: ignore
|
||||
resp.__exit__ = MagicMock(return_value=False)
|
||||
return resp
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import tempfile
|
||||
import unittest
|
||||
from dataclasses import replace
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
@@ -15,22 +16,21 @@ from bot_bottle.contrib.gitea.forge_state import (
|
||||
)
|
||||
|
||||
|
||||
def _state(**over) -> ForgeState:
|
||||
base = {
|
||||
"owner": "didericis",
|
||||
"repo": "bot-bottle",
|
||||
"issue_number": 17,
|
||||
"slug": "implementer-abc12",
|
||||
"agent_name": "implementer",
|
||||
"bottle_names": ["claude"],
|
||||
"backend_name": "docker",
|
||||
"agent_git_user": "didericis-claude",
|
||||
"pr_number": 42,
|
||||
"status": STATUS_FROZEN,
|
||||
"last_checkin_at": "2026-06-29T12:04:12-04:00",
|
||||
}
|
||||
base.update(over)
|
||||
return ForgeState(**base)
|
||||
def _state(**over: object) -> ForgeState:
|
||||
base = ForgeState(
|
||||
owner="didericis",
|
||||
repo="bot-bottle",
|
||||
issue_number=17,
|
||||
slug="implementer-abc12",
|
||||
agent_name="implementer",
|
||||
bottle_names=["claude"],
|
||||
backend_name="docker",
|
||||
agent_git_user="didericis-claude",
|
||||
pr_number=42,
|
||||
status=STATUS_FROZEN,
|
||||
last_checkin_at="2026-06-29T12:04:12-04:00",
|
||||
)
|
||||
return replace(base, **over)
|
||||
|
||||
|
||||
class ForgeStateTest(unittest.TestCase):
|
||||
|
||||
@@ -7,16 +7,29 @@ import unittest
|
||||
from bot_bottle.contrib.gitea.provenance import build_provenance_footer
|
||||
|
||||
|
||||
def _footer(slug: str = "implementer-abc12", **over) -> str:
|
||||
base = {
|
||||
"agent_name": "implementer",
|
||||
"bottle_names": ("claude",),
|
||||
"started_at": "2026-06-29T12:00:00-04:00",
|
||||
"finished_at": "2026-06-29T12:04:12-04:00",
|
||||
"exit_code": 0,
|
||||
}
|
||||
base.update(over)
|
||||
return build_provenance_footer(slug, **base)
|
||||
def _footer(
|
||||
slug: str = "implementer-abc12",
|
||||
*,
|
||||
agent_name: str = "implementer",
|
||||
bottle_names: tuple[str, ...] = ("claude",),
|
||||
started_at: str = "2026-06-29T12:00:00-04:00",
|
||||
finished_at: str = "2026-06-29T12:04:12-04:00",
|
||||
exit_code: int = 0,
|
||||
watchdog_fired: bool = False,
|
||||
gitleaks_clean: bool | None = None,
|
||||
egress_routes: list[str] | None = None,
|
||||
) -> str:
|
||||
return build_provenance_footer(
|
||||
slug,
|
||||
agent_name=agent_name,
|
||||
bottle_names=bottle_names,
|
||||
started_at=started_at,
|
||||
finished_at=finished_at,
|
||||
exit_code=exit_code,
|
||||
watchdog_fired=watchdog_fired,
|
||||
gitleaks_clean=gitleaks_clean,
|
||||
egress_routes=egress_routes,
|
||||
)
|
||||
|
||||
|
||||
class ProvenanceTest(unittest.TestCase):
|
||||
|
||||
Reference in New Issue
Block a user