test(webdav): direct _webdav_path test + double-encode precondition (#891 r2)
Round-2 review on PR #891 (non-blocking): - Add a parametrised test_webdav_path_encoding covering empty path, leading-slash stripping, '#'/comma/space, and a non-ASCII name — the single source of truth for every caller-path builder's encoding, so write_file / delete_resource / create_directory / attachments are covered transitively. - Document the decoded-input precondition on _webdav_path (encode-exactly-once; passing an already-encoded path would double-encode). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a188e9fced
commit
7b274cd8e2
@@ -54,6 +54,11 @@ class WebDAVClient(BaseNextcloudClient):
|
||||
Percent-encodes the caller-supplied portion (see ``_encode_dav_path``)
|
||||
so names with ``#``, commas, or spaces don't truncate/404; the base
|
||||
``/remote.php/dav/files/<user>`` segment is left as-is.
|
||||
|
||||
Precondition: ``path`` is a **decoded** path (the convention everywhere
|
||||
in this client — PROPFIND/REPORT hrefs are ``unquote``d before storage,
|
||||
and MCP-tool inputs are raw). It is encoded exactly once, so passing an
|
||||
already-encoded path would double-encode it (``%20`` → ``%2520``).
|
||||
"""
|
||||
return f"{self._get_webdav_base_path()}/{_encode_dav_path(path.lstrip('/'))}"
|
||||
|
||||
|
||||
@@ -517,6 +517,29 @@ def _request_url(mock_http_client) -> str:
|
||||
return mock_http_client.request.call_args[0][1]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.parametrize(
|
||||
"path, expected",
|
||||
[
|
||||
("", "/remote.php/dav/files/testuser/"),
|
||||
("/Documents/notes.txt", "/remote.php/dav/files/testuser/Documents/notes.txt"),
|
||||
("Documents/notes.txt", "/remote.php/dav/files/testuser/Documents/notes.txt"),
|
||||
("a/b #1.pdf", "/remote.php/dav/files/testuser/a/b%20%231.pdf"),
|
||||
("law/x, y z.pdf", "/remote.php/dav/files/testuser/law/x%2C%20y%20%20z.pdf"),
|
||||
(
|
||||
"学生邮箱/r.pdf",
|
||||
"/remote.php/dav/files/testuser/%E5%AD%A6%E7%94%9F%E9%82%AE%E7%AE%B1/r.pdf",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_webdav_path_encoding(path, expected):
|
||||
"""_webdav_path encodes the decoded caller path once, preserving '/', and
|
||||
strips a leading slash. Every caller-path builder routes through this, so
|
||||
it is the single source of truth for their encoding."""
|
||||
client = WebDAVClient(AsyncMock(), "testuser")
|
||||
assert client._webdav_path(path) == expected
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
async def test_read_file_encodes_special_chars(mocker):
|
||||
"""read_file must percent-encode '#', commas, and spaces in the path (card 309).
|
||||
|
||||
Reference in New Issue
Block a user