Corrections : test Torznab périmé et retries sur erreurs définitives
- test_torznab_search_requires_query attendait un 400 mais le commit
853b4e0 a volontairement fait servir les nouveautés quand q est
absent (RSS sync Sonarr) — le test valide désormais ce comportement.
- fetch() ne retente plus les 4xx définitifs (sauf 408/429) : un
lecteur VoirAnime en échec 422 coûtait 2 requêtes et 3 s de pauses
avant de basculer sur le lecteur suivant.
- 4 nouveaux tests unitaires du client HTTP (fail-fast + retries).
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
"""Tests unitaires : format interne, sanitisation, auth, registres scrapers."""
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
from app import auth
|
||||
from app.scrapers import http as http_module
|
||||
from app.scrapers.base import (
|
||||
ScrapeError,
|
||||
decode_internal_url,
|
||||
encode_internal_url,
|
||||
get_source,
|
||||
@@ -133,3 +136,43 @@ def test_hoster_resolution():
|
||||
assert resolve_hoster("https://vidmoly.to/embed-x.html").name == "vidmoly"
|
||||
assert resolve_hoster("https://sendvid.com/embed/x").name == "sendvid"
|
||||
assert resolve_hoster("https://inconnu.example.com/v/1") is None
|
||||
|
||||
|
||||
# ------------------------------------------------------------ client HTTP
|
||||
|
||||
|
||||
class _StatusClient:
|
||||
"""Fake client HTTP : sert une série de codes statut puis un corps 200."""
|
||||
|
||||
def __init__(self, statuses: list[int]):
|
||||
self._statuses = statuses
|
||||
self.calls = 0
|
||||
|
||||
async def get(self, url, headers=None):
|
||||
self.calls += 1
|
||||
request = httpx.Request("GET", url)
|
||||
status = self._statuses.pop(0) if self._statuses else 200
|
||||
response = httpx.Response(status, request=request, text="ok")
|
||||
response.raise_for_status()
|
||||
return response
|
||||
|
||||
|
||||
async def test_fetch_fails_fast_on_definitive_4xx(monkeypatch):
|
||||
client = _StatusClient([422])
|
||||
monkeypatch.setattr("app.scrapers.http.get_client", lambda: client)
|
||||
with pytest.raises(ScrapeError, match="422"):
|
||||
await http_module.fetch("https://site.example/lecteur/prepare/1?content=2&episode=3")
|
||||
assert client.calls == 1 # aucun retry sur erreur définitive
|
||||
|
||||
|
||||
@pytest.mark.parametrize("status", [429, 500, 503])
|
||||
async def test_fetch_retries_transitory_errors(monkeypatch, status):
|
||||
client = _StatusClient([status, 200])
|
||||
monkeypatch.setattr("app.scrapers.http.get_client", lambda: client)
|
||||
|
||||
async def no_sleep(_delay):
|
||||
return None
|
||||
|
||||
monkeypatch.setattr("app.scrapers.http.asyncio.sleep", no_sleep)
|
||||
assert await http_module.fetch("https://site.example/page", retries=2) == "ok"
|
||||
assert client.calls == 2
|
||||
|
||||
Reference in New Issue
Block a user