test(webdav): pin encode-once contract + nit cleanups (#891 r3)
Round-3 review on PR #891 (no blockers): - Add test_encode_dav_path_encodes_exactly_once pinning the documented decoded-input precondition ("already%20encoded.pdf" -> "already%2520..."). - format_exception_group: proper singular/plural ("1 sub-exception" vs "N sub-exceptions") instead of "(s)". - oauth_sync: use `if doc_task is not None:` to match processor_task's guard. 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
7b274cd8e2
commit
801bf108fa
@@ -21,7 +21,8 @@ def format_exception_group(exc: BaseException) -> str:
|
|||||||
if not isinstance(exc, BaseExceptionGroup):
|
if not isinstance(exc, BaseExceptionGroup):
|
||||||
return repr(exc)
|
return repr(exc)
|
||||||
leaves = _flatten(exc)
|
leaves = _flatten(exc)
|
||||||
return f"{len(leaves)} sub-exception(s): " + "; ".join(repr(e) for e in leaves)
|
noun = "sub-exception" if len(leaves) == 1 else "sub-exceptions"
|
||||||
|
return f"{len(leaves)} {noun}: " + "; ".join(repr(e) for e in leaves)
|
||||||
|
|
||||||
|
|
||||||
def _flatten(exc: BaseException) -> list[BaseException]:
|
def _flatten(exc: BaseException) -> list[BaseException]:
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ async def multi_user_processor_task(
|
|||||||
break
|
break
|
||||||
|
|
||||||
except NotProvisionedError:
|
except NotProvisionedError:
|
||||||
if doc_task:
|
if doc_task is not None:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"[BasicAuth] User %s not provisioned, skipping %s_%s",
|
"[BasicAuth] User %s not provisioned, skipping %s_%s",
|
||||||
doc_task.user_id,
|
doc_task.user_id,
|
||||||
@@ -342,7 +342,7 @@ async def multi_user_processor_task(
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if doc_task:
|
if doc_task is not None:
|
||||||
logger.error(
|
logger.error(
|
||||||
"[BasicAuth] Processor %s error processing %s_%s: %s",
|
"[BasicAuth] Processor %s error processing %s_%s: %s",
|
||||||
worker_id,
|
worker_id,
|
||||||
|
|||||||
@@ -540,6 +540,15 @@ def test_webdav_path_encoding(path, expected):
|
|||||||
assert client._webdav_path(path) == expected
|
assert client._webdav_path(path) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_encode_dav_path_encodes_exactly_once():
|
||||||
|
"""Pins the decoded-input precondition: a literal '%' becomes '%25', so an
|
||||||
|
already-encoded path passed in error would double-encode (caught here)."""
|
||||||
|
from nextcloud_mcp_server.client.webdav import _encode_dav_path
|
||||||
|
|
||||||
|
assert _encode_dav_path("already%20encoded.pdf") == "already%2520encoded.pdf"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
async def test_read_file_encodes_special_chars(mocker):
|
async def test_read_file_encodes_special_chars(mocker):
|
||||||
"""read_file must percent-encode '#', commas, and spaces in the path (card 309).
|
"""read_file must percent-encode '#', commas, and spaces in the path (card 309).
|
||||||
|
|||||||
@@ -41,4 +41,4 @@ def test_format_nested_exception_group_flattens_all_leaves():
|
|||||||
assert "ValueError" in formatted
|
assert "ValueError" in formatted
|
||||||
assert "ConnectError" in formatted
|
assert "ConnectError" in formatted
|
||||||
assert "RuntimeError" in formatted
|
assert "RuntimeError" in formatted
|
||||||
assert "3 sub-exception(s)" in formatted
|
assert "3 sub-exceptions" in formatted
|
||||||
|
|||||||
Reference in New Issue
Block a user