mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-20 23:21:06 +02:00
90 lines
2.7 KiB
Python
90 lines
2.7 KiB
Python
"""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.SolverUnsupportedError):
|
|
solvers.solve(
|
|
_cfg(solving_site="anticaptcha"),
|
|
challenge_type="v2",
|
|
sitekey="SK",
|
|
page_url="https://t.test",
|
|
)
|
|
assert issubclass(solvers.SolverUnsupportedError, solvers.SolverError)
|
|
|
|
|
|
def test_wired_providers_are_registered():
|
|
supported = solvers.supported_providers()
|
|
assert "2captcha" in supported
|
|
assert "capsolver" in supported
|