feat(rulebook): service layer — Topic CRUD
This commit is contained in:
@@ -101,3 +101,58 @@ async def test_delete_rulebook_calls_delete():
|
||||
from fabledassistant.services.rulebooks import delete_rulebook
|
||||
await delete_rulebook(rulebook_id=1, user_id=7)
|
||||
assert mock_session.delete.called
|
||||
|
||||
|
||||
# ── Topic CRUD ───────────────────────────────────────────────────────────
|
||||
|
||||
def _fake_topic(id=1, rulebook_id=1, title="git-workflow", description="", order_index=0):
|
||||
t = MagicMock()
|
||||
t.id = id
|
||||
t.rulebook_id = rulebook_id
|
||||
t.title = title
|
||||
t.description = description
|
||||
t.order_index = order_index
|
||||
t.created_at = datetime.now(timezone.utc)
|
||||
t.updated_at = datetime.now(timezone.utc)
|
||||
t.to_dict.return_value = {
|
||||
"id": id, "rulebook_id": rulebook_id, "title": title,
|
||||
"description": description or "", "order_index": order_index,
|
||||
}
|
||||
return t
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_topic_requires_owned_rulebook():
|
||||
"""create_topic raises ValueError if the rulebook isn't owned by user."""
|
||||
mock_session = _make_mock_session()
|
||||
mock_result = MagicMock()
|
||||
mock_result.scalar_one_or_none.return_value = None
|
||||
mock_session.execute = AsyncMock(return_value=mock_result)
|
||||
with patch("fabledassistant.services.rulebooks.async_session") as mock_cls:
|
||||
mock_cls.return_value = mock_session
|
||||
from fabledassistant.services.rulebooks import create_topic
|
||||
with pytest.raises(ValueError, match="not found"):
|
||||
await create_topic(
|
||||
rulebook_id=999, user_id=7, title="git-workflow",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_topics_returns_topics_for_owned_rulebook():
|
||||
rb = _fake_rulebook(id=1)
|
||||
topic = _fake_topic(id=10, rulebook_id=1, title="git-workflow")
|
||||
|
||||
# Two execute calls: ownership check, then topic select.
|
||||
mock_session = _make_mock_session()
|
||||
rb_result = MagicMock()
|
||||
rb_result.scalar_one_or_none.return_value = rb
|
||||
topic_result = MagicMock()
|
||||
topic_result.scalars.return_value.all.return_value = [topic]
|
||||
mock_session.execute = AsyncMock(side_effect=[rb_result, topic_result])
|
||||
|
||||
with patch("fabledassistant.services.rulebooks.async_session") as mock_cls:
|
||||
mock_cls.return_value = mock_session
|
||||
from fabledassistant.services.rulebooks import list_topics
|
||||
results = await list_topics(rulebook_id=1, user_id=7)
|
||||
assert len(results) == 1
|
||||
assert results[0].title == "git-workflow"
|
||||
|
||||
Reference in New Issue
Block a user