Files
teng-lin--notebooklm-py/tests/unit/test_notebooks_row_adapter.py
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

74 lines
2.8 KiB
Python

"""Tests for the notebook row adapters.
Covers the ``GeneratePromptSuggestions`` (``otmP3b`` / ``SUGGEST_PROMPTS``)
suggestion-list unwrap and per-row reads that back
``NotebooksAPI.suggest_prompts``:
1. **Position-contract pin** — the canary that fails loudly if a position
constant is edited (the wire-shape change signal).
2. **Shape handling** — happy-path reads plus the permissive "absent / short /
non-list → default" degrade (a suggestion list is best-effort UI sugar).
"""
from __future__ import annotations
import pytest
from notebooklm._row_adapters.notebooks import (
PromptSuggestionRow,
unwrap_prompt_suggestions,
)
class TestPromptSuggestionPositionContract:
def test_positions_pinned(self) -> None:
assert (
PromptSuggestionRow._TITLE_POS,
PromptSuggestionRow._PROMPT_POS,
PromptSuggestionRow._MIN_LEN,
) == (0, 1, 2)
class TestPromptSuggestionRow:
"""Permissive position reads for one ``SUGGEST_PROMPTS`` suggestion row."""
def test_well_formed_row(self) -> None:
row = PromptSuggestionRow(["Professional Briefing", "\n- Summarize."])
assert row.is_well_formed
assert row.title == "Professional Briefing"
assert row.prompt == "\n- Summarize."
def test_short_row_degrades_without_raise(self) -> None:
# Missing the prompt slot (< _MIN_LEN): not well-formed; reads degrade to "".
row = PromptSuggestionRow(["Only a title"])
assert not row.is_well_formed
assert row.title == "Only a title"
assert row.prompt == ""
def test_non_string_and_non_list_shapes_degrade(self) -> None:
# Non-string fields and non-list rows degrade to "" / not-well-formed,
# never raising — a suggestion list is best-effort UI sugar.
assert PromptSuggestionRow([None, 7]).title == ""
assert PromptSuggestionRow([None, 7]).prompt == ""
for raw in (None, "x", 7, {"k": 1}):
row = PromptSuggestionRow(raw)
assert not row.is_well_formed
assert (row.title, row.prompt) == ("", "")
class TestUnwrapPromptSuggestions:
"""``result[0]`` envelope-unwrap for ``SUGGEST_PROMPTS`` replies."""
def test_wrapped_envelope_returns_inner_rows(self) -> None:
rows = [["A", "\n- a"], ["B", "\n- b"]]
assert unwrap_prompt_suggestions([rows], source="t") == rows
@pytest.mark.parametrize("payload", [None, [], "unexpected", 7, [None], [[]]])
def test_degenerate_payloads_yield_empty(self, payload: object) -> None:
assert unwrap_prompt_suggestions(payload, source="t") == []
def test_never_raises(self) -> None:
# Best-effort: every shape degrades, never UnknownRPCMethodError.
for raw in (None, "x", 7, {"k": 1}, [7], [[1, 2]]):
unwrap_prompt_suggestions(raw, source="t")