Files
wehub-resource-sync 09e9f3545f
Test / Code Quality (push) Has been cancelled
Test / Test (macos-latest, Python 3.10) (push) Has been cancelled
Test / Test (macos-latest, Python 3.11) (push) Has been cancelled
Test / Test (macos-latest, Python 3.12) (push) Has been cancelled
Test / Test (macos-latest, Python 3.13) (push) Has been cancelled
Test / Test (macos-latest, Python 3.14) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.10) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.11) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.12) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.13) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.14) (push) Has been cancelled
Test / Test (windows-latest, Python 3.10) (push) Has been cancelled
Test / Test (windows-latest, Python 3.11) (push) Has been cancelled
Test / Test (windows-latest, Python 3.12) (push) Has been cancelled
Test / Test (windows-latest, Python 3.13) (push) Has been cancelled
Test / Test (windows-latest, Python 3.14) (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
dependency-audit / pip-audit (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:30:13 +08:00

98 lines
4.2 KiB
Python

"""Tests for the response-preview truncation helper used in RPC errors.
The library truncates raw RPC response bodies in error contexts so they are
safe to display in logs / CLI output. ``NOTEBOOKLM_DEBUG=1`` is the opt-in to
preserve the full body for deep debugging.
"""
from __future__ import annotations
import pytest
from notebooklm.exceptions import RPCError, _truncate_response_preview
class TestTruncateResponsePreview:
"""Behavior of the ``_truncate_response_preview`` helper."""
def test_long_body_default_truncates_to_80_plus_ellipsis(
self, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Long body with no NOTEBOOKLM_DEBUG env returns 80 chars + '...'."""
monkeypatch.delenv("NOTEBOOKLM_DEBUG", raising=False)
body = "x" * 200
result = _truncate_response_preview(body)
assert result is not None
assert result.endswith("...")
# Exactly 80 chars before the "..." suffix.
assert result[:-3] == "x" * 80
assert len(result) == 83
def test_debug_env_one_returns_full_body(self, monkeypatch: pytest.MonkeyPatch) -> None:
"""NOTEBOOKLM_DEBUG=1 disables truncation entirely."""
monkeypatch.setenv("NOTEBOOKLM_DEBUG", "1")
body = "y" * 500
result = _truncate_response_preview(body)
assert result == body
assert len(result) == 500 # type: ignore[arg-type]
def test_debug_env_zero_still_truncates(self, monkeypatch: pytest.MonkeyPatch) -> None:
"""NOTEBOOKLM_DEBUG=0 (explicit zero) must NOT disable truncation.
Common env-var footgun: users sometimes set ``=0`` expecting it to mean
"off", but the contract is strictly ``=1`` to opt-in. Guard against
regression where any truthy-looking string disables truncation.
"""
monkeypatch.setenv("NOTEBOOKLM_DEBUG", "0")
body = "z" * 200
result = _truncate_response_preview(body)
assert result is not None
assert result == "z" * 80 + "..."
def test_short_body_unchanged_default(self, monkeypatch: pytest.MonkeyPatch) -> None:
"""Bodies <= 80 chars are returned unchanged when env is unset."""
monkeypatch.delenv("NOTEBOOKLM_DEBUG", raising=False)
body = "short body"
assert _truncate_response_preview(body) == body
def test_short_body_unchanged_with_debug(self, monkeypatch: pytest.MonkeyPatch) -> None:
"""Bodies <= 80 chars are returned unchanged even with debug enabled."""
monkeypatch.setenv("NOTEBOOKLM_DEBUG", "1")
body = "short body"
assert _truncate_response_preview(body) == body
def test_exactly_80_chars_unchanged(self, monkeypatch: pytest.MonkeyPatch) -> None:
"""Boundary: a body of exactly 80 chars is not truncated."""
monkeypatch.delenv("NOTEBOOKLM_DEBUG", raising=False)
body = "a" * 80
assert _truncate_response_preview(body) == body
def test_none_input_returns_none(self, monkeypatch: pytest.MonkeyPatch) -> None:
"""None input short-circuits to None regardless of env."""
monkeypatch.delenv("NOTEBOOKLM_DEBUG", raising=False)
assert _truncate_response_preview(None) is None
monkeypatch.setenv("NOTEBOOKLM_DEBUG", "1")
assert _truncate_response_preview(None) is None
class TestRPCErrorIntegration:
"""End-to-end: constructing an RPCError truncates the stored body."""
def test_rpc_error_truncates_raw_response(self, monkeypatch: pytest.MonkeyPatch) -> None:
"""RPCError.raw_response is truncated to 80 chars + '...' by default."""
monkeypatch.delenv("NOTEBOOKLM_DEBUG", raising=False)
long_body = "Q" * 300
err = RPCError("boom", raw_response=long_body)
assert err.raw_response is not None
assert len(err.raw_response) == 83
assert err.raw_response.endswith("...")
assert err.raw_response[:-3] == "Q" * 80
def test_rpc_error_full_body_with_debug(self, monkeypatch: pytest.MonkeyPatch) -> None:
"""NOTEBOOKLM_DEBUG=1 preserves the full body on RPCError."""
monkeypatch.setenv("NOTEBOOKLM_DEBUG", "1")
long_body = "Q" * 300
err = RPCError("boom", raw_response=long_body)
assert err.raw_response == long_body