from __future__ import annotations import tempfile import unittest from pathlib import Path from typing import Any from inbox_service import InboxService NANOBOT_REPO_DIR = Path("/home/kacper/nanobot") class InboxServiceTests(unittest.TestCase): def setUp(self) -> None: self._tmpdir = tempfile.TemporaryDirectory() self.inbox_dir = Path(self._tmpdir.name) / "inbox" self.service = InboxService(repo_dir=NANOBOT_REPO_DIR, inbox_dir=self.inbox_dir) def tearDown(self) -> None: self._tmpdir.cleanup() def test_capture_list_and_dismiss_item(self) -> None: captured = self.service.capture_item( title="", text="Pack chargers for Japan", kind="task", source="web-ui", due="2026-04-10", body="Remember the USB-C one too.", session_id="web-123", tags=["travel", "#Japan"], confidence=0.75, ) self.assertEqual(captured["title"], "Pack chargers for Japan") self.assertEqual(captured["kind"], "task") self.assertEqual(captured["source"], "web-ui") self.assertEqual(captured["suggested_due"], "2026-04-10") self.assertEqual(captured["metadata"]["source_session"], "web-123") self.assertIn("## Raw Capture", captured["body"]) self.assertIn("#travel", captured["tags"]) self.assertIn("#japan", captured["tags"]) listed = self.service.list_items( status_filter=None, kind_filter=None, include_closed=False, limit=None, tags=[], ) self.assertEqual(len(listed), 1) self.assertEqual(listed[0]["path"], captured["path"]) dismissed = self.service.dismiss_item(captured["path"]) self.assertEqual(dismissed["status"], "dismissed") self.assertEqual(self.service.open_items(), []) class InboxServiceAcceptTaskTests(unittest.IsolatedAsyncioTestCase): def setUp(self) -> None: self._tmpdir = tempfile.TemporaryDirectory() self.inbox_dir = Path(self._tmpdir.name) / "inbox" self.service = InboxService(repo_dir=NANOBOT_REPO_DIR, inbox_dir=self.inbox_dir) self.item = self.service.capture_item( title="Find a good PWA install guide", text="Find a good PWA install guide", kind="task", source="web-ui", due="", body="Look for something practical, not generic.", session_id="web-456", tags=["research"], confidence=0.9, ) def tearDown(self) -> None: self._tmpdir.cleanup() async def test_accept_item_builds_grooming_prompt_with_hints(self) -> None: captured: dict[str, Any] = {} async def fake_run_nanobot_turn(message: str, **kwargs: Any) -> dict[str, Any]: captured["message"] = message captured["kwargs"] = kwargs return {"status": "ok", "reply": "accepted"} def fake_notification_to_event(payload: dict[str, Any]) -> dict[str, Any] | None: return payload result = await self.service.accept_item_as_task( item=self.item["path"], lane="committed", title="Install the PWA correctly", due="2026-04-12", body_text="Prefer something with screenshots.", tags=["#pwa", "#research"], run_nanobot_turn=fake_run_nanobot_turn, notification_to_event=fake_notification_to_event, ) self.assertEqual(result["status"], "ok") message = captured["message"] self.assertIn("Use the inbox_board tool and the task_helper_card tool.", message) self.assertIn(f"Inbox item path: {self.item['path']}", message) self.assertIn("Title hint from UI: Install the PWA correctly", message) self.assertIn("Description hint from UI: Prefer something with screenshots.", message) self.assertIn("Due hint from UI: 2026-04-12", message) self.assertIn("Tag hint from UI: #pwa, #research", message) self.assertIn("Preferred destination lane: committed", message) kwargs = captured["kwargs"] self.assertEqual(kwargs["chat_id"], "inbox-groomer") self.assertEqual(kwargs["timeout_seconds"], 90.0) self.assertEqual(kwargs["metadata"]["source"], "web-inbox-card") self.assertEqual(kwargs["metadata"]["ui_action"], "accept_task") self.assertEqual(kwargs["metadata"]["inbox_item"], self.item["path"]) self.assertIs(kwargs["notification_to_event"], fake_notification_to_event)