Download tests/test_validators.py from ItsBounvy/bot_host: direct link, hf CLI and curl.
- Browser
- Download file 6.11 kB
-
https://huggingface.co/spaces/ItsBounvy/bot_host/resolve/main/tests/test_validators.py
- Command line
-
hf download hf://spaces/ItsBounvy/bot_host/tests/test_validators.py
-
curl -L -o test_validators.py https://huggingface.co/spaces/ItsBounvy/bot_host/resolve/main/tests/test_validators.py
6.11 kB
| """Unit tests for hosting_panel.validators.""" | |
| from __future__ import annotations | |
| import os | |
| os.environ.setdefault("PANEL_SECRET_KEY", "x" * 64) | |
| os.environ.setdefault("PANEL_ENCRYPTION_KEY", | |
| "90mbg1KLmFKBpoSs5nstm7Ew-p3Q-J3ya3Zbuhwbtho=") | |
| import pytest | |
| from fastapi import HTTPException | |
| from hosting_panel import validators as v | |
| # ---- slug ----------------------------------------------------------------- | |
| def test_slug_accepts_normal(): | |
| assert v.validate_slug("my-bot") == "my-bot" | |
| def test_slug_lowercases_and_strips(): | |
| assert v.validate_slug(" My-Bot ") == "my-bot" | |
| def test_slug_rejects_invalid(bad): | |
| with pytest.raises(HTTPException): | |
| v.validate_slug(bad) | |
| # ---- bot token (Telegram format: <bot_id>:<secret>) ---------------------- | |
| def test_bot_token_accepts(ok): | |
| assert v.validate_bot_token(ok) == ok | |
| def test_bot_token_rejects(bad): | |
| with pytest.raises(HTTPException): | |
| v.validate_bot_token(bad) | |
| def test_bot_token_with_colon_35_chars_works(): | |
| # bot_id:secret, total length 35 | |
| tok = "1234:" + "A" * 30 # 5 + 30 = 35 | |
| assert v.validate_bot_token(tok) == tok | |
| # ---- hf token (hf_... length 30-60) -------------------------------------- | |
| def test_hf_token_30_chars_works(): | |
| tok = "hf_" + "x" * 27 # 3 + 27 = 30 | |
| assert v.validate_hf_token(tok) == tok | |
| def test_hf_token_60_chars_works(): | |
| tok = "hf_" + "x" * 57 | |
| assert v.validate_hf_token(tok) == tok | |
| def test_hf_token_rejects_short(): | |
| with pytest.raises(HTTPException): | |
| v.validate_hf_token("hf_" + "x" * 5) # 8 chars | |
| def test_hf_token_rejects_long(): | |
| with pytest.raises(HTTPException): | |
| v.validate_hf_token("hf_" + "x" * 60) | |
| # ---- proxy token ---------------------------------------------------------- | |
| def test_proxy_token_accepts(): | |
| assert v.validate_proxy_token("proxy-token-long-enough-1234567890") == "proxy-token-long-enough-1234567890" | |
| # ---- source repo ---------------------------------------------------------- | |
| def test_source_repo_hf_format(): | |
| assert v.validate_source_repo("owner/name") == "owner/name" | |
| assert v.validate_source_repo("owner-name/repo-name") == "owner-name/repo-name" | |
| def test_source_repo_hf_rejects_no_slash(): | |
| with pytest.raises(HTTPException): | |
| v.validate_source_repo("noslash") | |
| def test_source_repo_github_format(): | |
| assert v.validate_source_repo( | |
| "https://github.com/owner/repo.git", | |
| source_type="github", | |
| ) == "https://github.com/owner/repo.git" | |
| def test_source_repo_github_rejects_bare_name(): | |
| with pytest.raises(HTTPException): | |
| v.validate_source_repo("owner/repo", source_type="github") | |
| # ---- source type ---------------------------------------------------------- | |
| def test_source_type_accepts_hf_default(): | |
| # Empty -> "hf" | |
| assert v.validate_source_type("") == "hf" | |
| assert v.validate_source_type("hf") == "hf" | |
| assert v.validate_source_type("github") == "github" | |
| def test_source_type_rejects(bad): | |
| with pytest.raises(HTTPException): | |
| v.validate_source_type(bad) | |
| # ---- framework ------------------------------------------------------------ | |
| def test_framework_default_is_docker(): | |
| assert v.validate_framework("") == "docker" | |
| def test_framework_accepts(): | |
| assert v.validate_framework("python") == "python" | |
| assert v.validate_framework("node") == "node" | |
| assert v.validate_framework("fastapi/aiogram") == "fastapi/aiogram" | |
| def test_framework_lowercases(): | |
| """Validator lowercases; this is intentional -- reject via special chars only.""" | |
| assert v.validate_framework("Python") == "python" | |
| def test_framework_rejects_special_chars(): | |
| with pytest.raises(HTTPException): | |
| v.validate_framework("python@3.11") | |
| # ---- branch --------------------------------------------------------------- | |
| def test_branch_default_is_main(): | |
| assert v.validate_branch("") == "main" | |
| def test_branch_accepts(): | |
| assert v.validate_branch("feature/auth") == "feature/auth" | |
| assert v.validate_branch("main") == "main" | |
| def test_branch_rejects_special_chars(): | |
| with pytest.raises(HTTPException): | |
| v.validate_branch("feature; rm -rf /") | |
| # ---- nvidia api key ------------------------------------------------------- | |
| def test_nvidia_key_accepts_60_chars(): | |
| key = "nvapi-" + "x" * 54 # 60 chars | |
| assert v.validate_nvidia_api_key(key) == key | |
| def test_nvidia_key_rejects_short(): | |
| with pytest.raises(HTTPException): | |
| v.validate_nvidia_api_key("nvapi-x") | |
| # ---- url ------------------------------------------------------------------ | |
| def test_url_optional_empty(): | |
| assert v.validate_optional_url("", "render_url") == "" | |
| def test_url_accepts_https(): | |
| assert v.validate_optional_url("https://example.com", "url") == "https://example.com" | |
| def test_url_rejects_no_scheme(): | |
| with pytest.raises(HTTPException): | |
| v.validate_optional_url("example.com", "url") | |
| # ---- model ---------------------------------------------------------------- | |
| def test_model_default(): | |
| assert v.validate_optional_nvidia_model("") == "minimaxai/minimax-m3" | |
| def test_model_accepts_custom(): | |
| assert v.validate_optional_nvidia_model("openai/gpt-4") == "openai/gpt-4" | |
| def test_model_rejects_special_chars(): | |
| with pytest.raises(HTTPException): | |
| v.validate_optional_nvidia_model("model@name") |