314dc03b0d
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
61 lines
2.0 KiB
Python
61 lines
2.0 KiB
Python
"""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()
|