|
1 | 1 | """Tests for delete_note MCP tool.""" |
2 | 2 |
|
| 3 | +from unittest.mock import patch |
| 4 | + |
3 | 5 | import pytest |
4 | 6 |
|
5 | 7 | from basic_memory.mcp.tools.delete_note import delete_note, _format_delete_error_response |
@@ -120,3 +122,56 @@ async def test_delete_note_rejects_fuzzy_match(client, test_project): |
120 | 122 | # Verify the existing note was NOT deleted |
121 | 123 | content = await read_note("Delete Target Note", project=test_project.name) |
122 | 124 | assert "Should not be deleted" in content |
| 125 | + |
| 126 | + |
| 127 | +@pytest.mark.asyncio |
| 128 | +async def test_delete_note_detects_project_from_memory_url(client, test_project): |
| 129 | + """delete_note should detect project from memory:// URL prefix when project=None.""" |
| 130 | + # Create a note to delete |
| 131 | + await write_note( |
| 132 | + project=test_project.name, |
| 133 | + title="Delete URL Note", |
| 134 | + directory="test", |
| 135 | + content="# Delete URL Note\nContent to delete.", |
| 136 | + ) |
| 137 | + |
| 138 | + # Delete using memory:// URL with project=None — should auto-detect project |
| 139 | + # The note may or may not be found (depends on URL resolution), but the key |
| 140 | + # assertion is that routing goes to the correct project |
| 141 | + result = await delete_note( |
| 142 | + identifier=f"memory://{test_project.name}/test/delete-url-note", |
| 143 | + project=None, |
| 144 | + ) |
| 145 | + |
| 146 | + # Result is True (deleted) or False (not found by that URL) — either is acceptable. |
| 147 | + # The important thing is it didn't error and routed to the correct project. |
| 148 | + assert isinstance(result, bool) |
| 149 | + |
| 150 | + |
| 151 | +@pytest.mark.asyncio |
| 152 | +async def test_delete_note_skips_detection_for_plain_path(client, test_project): |
| 153 | + """delete_note should NOT call detect_project_from_url_prefix for plain path identifiers. |
| 154 | +
|
| 155 | + A plain path like 'research/note' should not be misrouted to a project |
| 156 | + named 'research' — the 'research' segment is a directory, not a project. |
| 157 | + """ |
| 158 | + with patch("basic_memory.mcp.tools.delete_note.detect_project_from_url_prefix") as mock_detect: |
| 159 | + # Use a plain path (no memory:// prefix) — detection should not be called |
| 160 | + await delete_note( |
| 161 | + identifier="test/nonexistent-note", |
| 162 | + project=None, |
| 163 | + ) |
| 164 | + |
| 165 | + mock_detect.assert_not_called() |
| 166 | + |
| 167 | + |
| 168 | +@pytest.mark.asyncio |
| 169 | +async def test_delete_note_skips_detection_when_project_provided(client, test_project): |
| 170 | + """delete_note should skip URL detection when project is explicitly provided.""" |
| 171 | + with patch("basic_memory.mcp.tools.delete_note.detect_project_from_url_prefix") as mock_detect: |
| 172 | + await delete_note( |
| 173 | + identifier=f"memory://{test_project.name}/test/some-note", |
| 174 | + project=test_project.name, |
| 175 | + ) |
| 176 | + |
| 177 | + mock_detect.assert_not_called() |
0 commit comments