fix(youtube): the scrape search never pins a stale key, and an unknown shape is an error
A failed config fetch or a keyless consent page cached the fallback InnerTube key for the life of the process; once it went stale, search returned nothing with no error. The fallback is now used for that call only. A 200 JSON without a result frame returned an empty page that read as no results; it is a ScrapeError now. Parser, cursor and Shorts-probe tests added.
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
"""youtube/shorts.probe_is_short — three answers, and the third is not the second (E32 S2: 33% covered).
|
||||
|
||||
A Short answers 200 at /shorts/<id>; a regular video redirects to /watch. Anything else — an error
|
||||
page, a network failure — is "undetermined, ask again", never "not a Short": that would file a Short
|
||||
in the normal feed for good.
|
||||
"""
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
from app.youtube import shorts
|
||||
|
||||
|
||||
def _client(respond) -> httpx.Client:
|
||||
return httpx.Client(transport=httpx.MockTransport(respond))
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("status", "expected"),
|
||||
[(200, True), (301, False), (302, False), (303, False), (307, False), (308, False)]
|
||||
+ [(404, None), (429, None), (500, None)],
|
||||
)
|
||||
def test_the_status_decides_short_regular_or_undetermined(status, expected):
|
||||
seen: list[httpx.Request] = []
|
||||
|
||||
def respond(request: httpx.Request) -> httpx.Response:
|
||||
seen.append(request)
|
||||
return httpx.Response(status, headers={"location": "https://www.youtube.com/watch?v=x"})
|
||||
|
||||
assert shorts.probe_is_short(_client(respond), "abc123") is expected
|
||||
assert str(seen[0].url) == "https://www.youtube.com/shorts/abc123"
|
||||
assert len(seen) == 1 # a redirect is the answer, never followed
|
||||
|
||||
|
||||
def test_a_network_failure_is_undetermined_not_regular():
|
||||
def respond(request: httpx.Request) -> httpx.Response:
|
||||
raise httpx.ConnectTimeout("slow", request=request)
|
||||
|
||||
assert shorts.probe_is_short(_client(respond), "abc123") is None
|
||||
|
||||
|
||||
def test_the_client_skips_the_consent_interstitial():
|
||||
with shorts.make_client() as c:
|
||||
assert "SOCS=" in c.headers["cookie"]
|
||||
Reference in New Issue
Block a user