feat: fold bot-bottle-orchestrator into bot_bottle/orchestrator subpackage
Moves the orchestrator into bot_bottle/orchestrator/ so one install gets everything. Entry point is now `python -m bot_bottle.orchestrator run`. - Add bot_bottle/orchestrator/ with all 14 modules (verbatim move; internal imports were already relative, so no changes inside orchestrator modules) - Rewrite bootstrap.py: remove the lazy bot_bottle import guard, use direct relative imports from ..contrib.* - Add bot_bottle/contrib/forge/base.py: ScopedForge (read-anywhere / write-scoped) - Add bot_bottle/contrib/gitea/client.py: GiteaClient + GiteaForge (urllib.request only) - Add bot_bottle/contrib/gitea/forge_state.py: ForgeState + SqliteForgeStateStore - Add tests/unit/orchestrator/ (82 tests: 63 migrated + 19 new for contrib modules) Closes #321
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
"""Unit: targeting (labels + org membership)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from bot_bottle.orchestrator.model import IssueAssigned
|
||||
from bot_bottle.orchestrator.targeting import parse_labels, resolve_target
|
||||
|
||||
from ._fakes import FakeForge
|
||||
|
||||
|
||||
def _issue(
|
||||
assignees: tuple[str, ...] = ("agent-bot",),
|
||||
labels: tuple[str, ...] = ("bot-bottle:implementer",),
|
||||
) -> IssueAssigned:
|
||||
return IssueAssigned(
|
||||
owner="didericis", repo="bot-bottle", issue_number=17,
|
||||
title="t", body="b", assignees=tuple(assignees), labels=tuple(labels),
|
||||
)
|
||||
|
||||
|
||||
class ParseLabelsTest(unittest.TestCase):
|
||||
def test_agent_label(self):
|
||||
self.assertEqual(("implementer", None), parse_labels(("bot-bottle:implementer",)))
|
||||
|
||||
def test_bottle_override_not_confused_with_agent(self):
|
||||
agent, bottle = parse_labels(("bot-bottle:impl", "bot-bottle-bottle:dev"))
|
||||
self.assertEqual(("impl", "dev"), (agent, bottle))
|
||||
|
||||
def test_no_agent_label(self):
|
||||
self.assertEqual((None, None), parse_labels(("bug", "p1")))
|
||||
|
||||
|
||||
class ResolveTargetTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.forge = FakeForge(members=("agent-bot",))
|
||||
|
||||
def test_targeted(self):
|
||||
target = resolve_target(_issue(), self.forge, "bot-bottle")
|
||||
assert target is not None
|
||||
self.assertEqual("implementer", target.agent_name)
|
||||
self.assertIsNone(target.bottle_override)
|
||||
|
||||
def test_bottle_override(self):
|
||||
ev = _issue(labels=("bot-bottle:impl", "bot-bottle-bottle:dev"))
|
||||
target = resolve_target(ev, self.forge, "bot-bottle")
|
||||
assert target is not None
|
||||
self.assertEqual("dev", target.bottle_override)
|
||||
|
||||
def test_no_label_not_targeted(self):
|
||||
self.assertIsNone(resolve_target(_issue(labels=("bug",)), self.forge, "bot-bottle"))
|
||||
|
||||
def test_non_member_assignee_not_targeted(self):
|
||||
ev = _issue(assignees=("random-user",))
|
||||
self.assertIsNone(resolve_target(ev, self.forge, "bot-bottle"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user