""" 测试 cf_session:Cloudflare 限流/人机认证识别与自动重试逻辑 """ import sys import os import pytest from bs4 import BeautifulSoup from loguru import logger # 添加项目路径 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) import cf_session class TestRateLimitDetection: """限流/人机认证页识别(纯函数测试)""" def setup_method(self): logger.remove() logger.add(sys.stderr, level="DEBUG") def test_detects_429_rate_limit_page(self): """429 限流页(Too Many Requests)应被识别""" soup = BeautifulSoup( 'Too Many Requests' '
429
', 'html.parser') assert cf_session.is_rate_limited(soup) is True def test_detects_403_js_challenge_page(self): """403 JS 挑战页(Just a moment)应被识别""" soup = BeautifulSoup( 'Just a moment...' '', 'html.parser') assert cf_session.is_rate_limited(soup) is True def test_detects_403_attention_required_page(self): """403 阻止页(Attention Required)应被识别""" soup = BeautifulSoup( 'Attention Required! | Cloudflarex', 'html.parser') assert cf_session.is_rate_limited(soup) is True def test_normal_page_not_rate_limited(self): """正常页面不应被误判""" soup = BeautifulSoup( '
可下
', 'html.parser') assert cf_session.is_rate_limited(soup) is False def test_none_not_rate_limited(self): """None 页面不应被误判""" assert cf_session.is_rate_limited(None) is False class TestParseCookies: """agent-browser cookies 输出解析""" def test_parse_name_value_lines(self): stdout = ("cf_clearance=abc.def-123\n" "bnState_x=%7B%22a%22%3A1%7D\n" "# comment line\n") cookies = cf_session._parse_cookies(stdout) assert cookies == { "cf_clearance": "abc.def-123", "bnState_x": "%7B%22a%22%3A1%7D", } def test_parse_empty(self): assert cf_session._parse_cookies("") == {} class TestFetchWithRetry: """自动重试的真实请求验证""" def setup_method(self): logger.remove() logger.add(sys.stderr, level="DEBUG") def test_fetch_real_url_ok(self): """真实 URL 正常返回 (soup, 'ok')""" url = "https://freejavbt.com/censored/filter?c=212&page=1" soup, status = cf_session.fetch_with_retry(url, (10, 60), retries=2, retry_delay=2) assert status == "ok" assert soup is not None assert len(soup.find_all("div", {"class": "card-body"})) > 0 def test_fetch_network_error(self): """不可达 URL 返回 (None, 'error')""" soup, status = cf_session.fetch_with_retry( "http://invalid-domain-for-test-12345.invalid", (5, 10), retries=2, retry_delay=1) assert status == "error" assert soup is None def run_tests(): """运行所有测试""" pytest.main([ __file__, "-v", "--tb=short", "--log-cli-level=INFO" ]) if __name__ == "__main__": run_tests()