Files
DocsGPT/tests/test_notes_tool.py
Alex 81b6ee5daa Pg 4 (#2390)
* feat: postgres tests

* feat: mongo cutoff

* feat: mongo cutoff

* feat: adjust docs and compose files

* fix: mini code mongo removals

* fix: tests and k8s mongo stuff

* feat: test fixes

* fix: ruff

* fix: vale

* Potential fix for pull request finding 'CodeQL / Clear-text logging of sensitive information'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix: mini suggestions

* vale lint fix 2

* fix: codeql columns thing

* fix: test mongo

* fix: tests coverage

* feat: better tests 4

* feat: more tests

* feat: decent coverage

* fix: ruff fixes

* fix: remove mongo mock

* feat: enhance workflow engine and API routes; add document retrieval and source handling

* feat: e2e tests

* fix: mcp, mongo and more

* fix: mini codeql warning

* fix: agent chunk view

* fix: mini issues

* fix: more pg fixes

* feat: postgres prep on start

* feat: qa tests

* fix: mini improvements

* fix: tests

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Siddhant Rai <siddhant.rai.5686@gmail.com>
2026-04-18 13:13:57 +01:00

181 lines
5.6 KiB
Python

"""Unit tests for NotesTool.
Same approach as ``test_todo_tool.py``: patch ``NotesRepository`` with
an in-memory fake and replace ``db_session`` / ``db_readonly`` with a
no-op context manager.
"""
from __future__ import annotations
import uuid
from contextlib import contextmanager
import pytest
from application.agents.tools.notes import NotesTool
class _FakeNotesRepo:
_store: dict[tuple[str, str], dict] = {}
def __init__(self, conn=None) -> None:
self._conn = conn
@classmethod
def reset(cls) -> None:
cls._store = {}
def upsert(self, user_id, tool_id, title, content):
key = (user_id, tool_id)
if key in self._store:
self._store[key].update({"title": title, "content": content})
else:
self._store[key] = {
"id": str(uuid.uuid4()),
"user_id": user_id,
"tool_id": tool_id,
"title": title,
"content": content,
}
return self._store[key]
def get_for_user_tool(self, user_id, tool_id):
return self._store.get((user_id, tool_id))
def delete(self, user_id, tool_id):
return self._store.pop((user_id, tool_id), None) is not None
@contextmanager
def _noop_conn():
yield None
@pytest.fixture
def notes_tool(monkeypatch):
_FakeNotesRepo.reset()
monkeypatch.setattr(
"application.agents.tools.notes.NotesRepository", _FakeNotesRepo
)
monkeypatch.setattr(
"application.agents.tools.notes.db_session", _noop_conn
)
monkeypatch.setattr(
"application.agents.tools.notes.db_readonly", _noop_conn
)
return NotesTool({"tool_id": str(uuid.uuid4())}, user_id="test_user")
@pytest.mark.unit
def test_overwrite_and_view(notes_tool):
assert "saved" in notes_tool.execute_action("overwrite", text="first").lower()
assert "first" in notes_tool.execute_action("view")
assert "saved" in notes_tool.execute_action("overwrite", text="second").lower()
assert "second" in notes_tool.execute_action("view")
@pytest.mark.unit
def test_delete_note(notes_tool):
notes_tool.execute_action("overwrite", text="hello")
assert "deleted" in notes_tool.execute_action("delete").lower()
assert "no note" in notes_tool.execute_action("view").lower()
@pytest.mark.unit
def test_view_not_found(notes_tool):
result = notes_tool.execute_action("view")
assert "no note found" in result.lower()
@pytest.mark.unit
def test_str_replace(notes_tool):
notes_tool.execute_action("overwrite", text="Hello world, hello universe")
result = notes_tool.execute_action("str_replace", old_str="hello", new_str="hi")
assert "updated" in result.lower()
note = notes_tool.execute_action("view")
assert "hi world, hi universe" in note.lower()
@pytest.mark.unit
def test_str_replace_not_found(notes_tool):
notes_tool.execute_action("overwrite", text="Hello world")
result = notes_tool.execute_action("str_replace", old_str="goodbye", new_str="hi")
assert "not found" in result.lower()
@pytest.mark.unit
def test_insert_line(notes_tool):
notes_tool.execute_action("overwrite", text="Line 1\nLine 2\nLine 3")
result = notes_tool.execute_action("insert", line_number=2, text="Inserted line")
assert "inserted" in result.lower()
note = notes_tool.execute_action("view")
lines = note.split("\n")
assert lines[1] == "Inserted line"
assert lines[2] == "Line 2"
@pytest.mark.unit
def test_delete_nonexistent_note(notes_tool):
result = notes_tool.execute_action("delete")
assert "no note found" in result.lower()
@pytest.mark.unit
def test_isolation_per_tool_id(monkeypatch):
_FakeNotesRepo.reset()
monkeypatch.setattr(
"application.agents.tools.notes.NotesRepository", _FakeNotesRepo
)
monkeypatch.setattr(
"application.agents.tools.notes.db_session", _noop_conn
)
monkeypatch.setattr(
"application.agents.tools.notes.db_readonly", _noop_conn
)
tool1 = NotesTool({"tool_id": str(uuid.uuid4())}, user_id="test_user")
tool2 = NotesTool({"tool_id": str(uuid.uuid4())}, user_id="test_user")
tool1.execute_action("overwrite", text="Content from tool 1")
tool2.execute_action("overwrite", text="Content from tool 2")
assert "Content from tool 1" in tool1.execute_action("view")
assert "Content from tool 2" not in tool1.execute_action("view")
assert "Content from tool 2" in tool2.execute_action("view")
assert "Content from tool 1" not in tool2.execute_action("view")
@pytest.mark.unit
def test_init_without_user_id():
"""Should fail gracefully if no user_id is provided."""
notes_tool = NotesTool(tool_config={})
result = notes_tool.execute_action("view")
assert "user_id" in str(result).lower()
@pytest.mark.unit
def test_sentinel_tool_id_short_circuits():
"""A ``default_{user_id}`` tool_id must no-op with a polite error."""
tool = NotesTool({}, user_id="test_user")
assert tool.tool_id == "default_test_user"
result = tool.execute_action("view")
assert "Error" in result
assert "not configured" in result.lower() or "unavailable" in result.lower()
@pytest.mark.unit
def test_notes_tool_auto_generates_default_tool_id():
"""Without ``tool_id``, tool_id defaults to ``default_{user_id}``."""
tool1 = NotesTool({}, user_id="test_user")
tool2 = NotesTool({}, user_id="test_user")
assert tool1.tool_id == "default_test_user"
assert tool2.tool_id == "default_test_user"
tool3 = NotesTool({}, user_id="another_user")
assert tool3.tool_id == "default_another_user"
assert tool3.tool_id != tool1.tool_id