mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-22 23:31:12 +02:00
refactor: enhance Google search scraping capabilities with warm sticky-IP pool and improved captcha handling
This commit is contained in:
parent
4b97e9a54e
commit
68d1832f10
20 changed files with 1900 additions and 175 deletions
84
surfsense_backend/tests/unit/utils/captcha/test_solvers.py
Normal file
84
surfsense_backend/tests/unit/utils/captcha/test_solvers.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
"""Offline checks for the in-house captcha-solver seam.
|
||||
|
||||
The network solve can't be unit-tested, but the boundary logic can: a wrong
|
||||
proxy reformat (2captcha's ``ERROR_PROXY_FORMAT``) or dispatching to a provider
|
||||
we haven't wired silently burns paid solves / leaks the key to the wrong vendor.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from app.utils.captcha import solvers
|
||||
from app.utils.captcha.config import CaptchaConfig
|
||||
|
||||
pytestmark = pytest.mark.unit
|
||||
|
||||
|
||||
def _cfg(**overrides) -> CaptchaConfig:
|
||||
base = {
|
||||
"enabled": True,
|
||||
"solving_site": "2captcha",
|
||||
"api_key": "key-123",
|
||||
"max_attempts_per_url": 1,
|
||||
"timeout_s": 30,
|
||||
"captcha_type_default": "v2",
|
||||
"v3_min_score": 0.7,
|
||||
"v3_action": "verify",
|
||||
}
|
||||
base.update(overrides)
|
||||
return CaptchaConfig(**base)
|
||||
|
||||
|
||||
# --- proxy reformat (2captcha wants login:pass@host:port, NO scheme) --------
|
||||
|
||||
|
||||
def test_proxy_login_form_strips_scheme():
|
||||
got = solvers.proxy_login_form("http://user:pass@gw.dataimpulse.com:15673")
|
||||
assert got == "user:pass@gw.dataimpulse.com:15673"
|
||||
|
||||
|
||||
def test_proxy_login_form_without_credentials():
|
||||
assert solvers.proxy_login_form("http://gw.dataimpulse.com:823") == "gw.dataimpulse.com:823"
|
||||
|
||||
|
||||
def test_proxy_login_form_none_on_missing_or_bad():
|
||||
assert solvers.proxy_login_form(None) is None
|
||||
assert solvers.proxy_login_form("not a url") is None
|
||||
|
||||
|
||||
# --- capsolver proxy reformat (colon-delimited scheme:host:port:user:pass) --
|
||||
|
||||
|
||||
def test_capsolver_proxy_colon_delimited_with_creds():
|
||||
got = solvers.capsolver_proxy("http://user:pass@gw.dataimpulse.com:823")
|
||||
assert got == "http:gw.dataimpulse.com:823:user:pass"
|
||||
|
||||
|
||||
def test_capsolver_proxy_without_credentials():
|
||||
assert solvers.capsolver_proxy("http://gw.dataimpulse.com:823") == "http:gw.dataimpulse.com:823"
|
||||
|
||||
|
||||
def test_capsolver_proxy_none_on_missing_or_bad():
|
||||
assert solvers.capsolver_proxy(None) is None
|
||||
assert solvers.capsolver_proxy("not a url") is None
|
||||
|
||||
|
||||
# --- dispatch --------------------------------------------------------------
|
||||
|
||||
|
||||
def test_unsupported_provider_raises_solvererror():
|
||||
# An unconfigured provider must fail loudly (latch) rather than POST the key
|
||||
# to a wired vendor's endpoint under the wrong account.
|
||||
with pytest.raises(solvers.SolverUnsupported):
|
||||
solvers.solve(
|
||||
_cfg(solving_site="anticaptcha"),
|
||||
challenge_type="v2",
|
||||
sitekey="SK",
|
||||
page_url="https://t.test",
|
||||
)
|
||||
assert issubclass(solvers.SolverUnsupported, solvers.SolverError)
|
||||
|
||||
|
||||
def test_wired_providers_are_registered():
|
||||
supported = solvers.supported_providers()
|
||||
assert "2captcha" in supported
|
||||
assert "capsolver" in supported
|
||||
Loading…
Add table
Add a link
Reference in a new issue