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

133 lines
4.8 KiB
Python

"""Example tests demonstrating VCR.py integration.
VCR.py records HTTP interactions to YAML "cassettes" for deterministic replay.
This is useful for:
- Testing against real API responses without hitting rate limits
- Running tests offline or without credentials
- Creating regression tests from actual API behavior
Usage:
# Record mode (requires valid auth):
NOTEBOOKLM_VCR_RECORD=1 pytest tests/integration/test_vcr_example.py -v
# Replay mode (default, uses recorded cassettes):
pytest tests/integration/test_vcr_example.py -v
Note: Cassettes are committed to the repo after security review (see
.gitignore for the policy). Verify sensitive data is scrubbed
(``uv run python tests/scripts/check_cassettes_clean.py``) before
committing a new or re-recorded cassette.
Note: These tests are automatically skipped if cassettes are not available.
"""
import pytest
from tests.integration.conftest import skip_no_cassettes
from tests.vcr_config import notebooklm_vcr
# Skip all tests in this module if cassettes are not available
pytestmark = [pytest.mark.vcr, skip_no_cassettes]
class TestVCRScrubbing:
"""Tests verifying sensitive data scrubbing."""
@pytest.mark.vcr
@notebooklm_vcr.use_cassette("examples/example_scrubbed_cookies.yaml")
@pytest.mark.asyncio
async def test_cookies_are_scrubbed(self):
"""Verify sensitive cookies are scrubbed from cassettes.
The scrubbing happens at record time, so replay should show
scrubbed values. Check the cassette file to verify.
"""
import httpx
async with httpx.AsyncClient() as client:
# Send fake sensitive cookies
response = await client.post(
"https://httpbin.org/post",
headers={
"Cookie": "SID=secret_session; HSID=another_secret",
},
data={"test": "data"},
)
assert response.status_code == 200
# The response from httpbin echoes headers, but cassette should be scrubbed
class TestVCRWithNotebookLMPatterns:
"""Tests demonstrating VCR with notebooklm-py patterns.
These tests show how VCR would integrate with the actual client.
They use the existing pytest-httpx mocks but demonstrate the
cassette structure.
"""
@pytest.mark.vcr
@notebooklm_vcr.use_cassette("examples/example_batchexecute_pattern.yaml")
@pytest.mark.asyncio
async def test_batchexecute_style_request(self):
"""Simulate the batchexecute request pattern used by notebooklm-py.
The actual client sends:
- POST to /batchexecute
- Form-encoded body with f.req= containing nested JSON
- Cookie header with session cookies
- Query params with rpcids and f.sid
"""
import httpx
# Simulate the request format from notebooklm._rpc_executor.RpcExecutor.rpc_call()
fake_rpc_body = (
'f.req=[[["methodId",null,null,[[["notebook_id","data"]]]]]]&at=fake_csrf_token'
)
async with httpx.AsyncClient() as client:
response = await client.post(
"https://httpbin.org/post", # Stand-in for batchexecute endpoint
headers={
"Content-Type": "application/x-www-form-urlencoded",
"Cookie": "SID=test; HSID=test",
},
content=fake_rpc_body,
)
assert response.status_code == 200
# =============================================================================
# Example: How to write a VCR test for real NotebookLM API
# =============================================================================
#
# To create a real VCR test:
#
# 1. Write the test using the actual NotebookLM client:
#
# @pytest.mark.vcr
# @notebooklm_vcr.use_cassette('list_notebooks_real.yaml')
# @pytest.mark.asyncio
# async def test_list_notebooks_vcr(self):
# from notebooklm import NotebookLMClient
# from notebooklm.auth import AuthTokens
#
# # Load real auth (only needed for recording)
# auth = await AuthTokens.from_storage()
#
# async with NotebookLMClient(auth) as client:
# notebooks = await client.notebooks.list()
#
# assert isinstance(notebooks, list)
#
# 2. Record the cassette:
# NOTEBOOKLM_VCR_RECORD=1 pytest tests/integration/test_vcr_example.py::test_list_notebooks_vcr -v
#
# 3. Verify the cassette is properly scrubbed:
# cat tests/cassettes/list_notebooks_real.yaml | grep -E "SID|HSID|SNlM0e"
# # Should show SCRUBBED values, not real tokens
#
# 4. Future runs will replay from cassette (no auth needed):
# pytest tests/integration/test_vcr_example.py::test_list_notebooks_vcr -v
#
# =============================================================================