Files
vault-dash/tests/test_turnstile.py
Bu5hm4nn eb262189cf
Some checks failed
CI / lint (push) Successful in 9s
CI / type-check (push) Successful in 16s
CI / test (push) Failing after 2m7s
test: force Turnstile test mode in CI
2026-04-08 16:47:37 +02:00

169 lines
6.7 KiB
Python

from __future__ import annotations
import requests
from fastapi.testclient import TestClient
from app.main import app
def test_legacy_get_bootstrap_url_redirects_to_welcome_page() -> None:
with TestClient(app) as client:
response = client.get("/workspaces/bootstrap", follow_redirects=False)
assert response.status_code in {302, 303, 307}
assert response.headers["location"] == "/"
def test_bootstrap_workspace_rejects_missing_turnstile_token(monkeypatch, tmp_path) -> None:
from app.models import workspace as workspace_module
from app.models.workspace import WorkspaceRepository
repo = WorkspaceRepository(base_path=tmp_path / "workspaces")
monkeypatch.setattr(workspace_module, "_workspace_repo", repo)
with TestClient(app) as client:
response = client.post("/workspaces/bootstrap", follow_redirects=False)
assert response.status_code == 303
assert response.headers["location"] == "/?captcha_error=1"
def test_bootstrap_workspace_creates_workspace_when_turnstile_verification_succeeds(monkeypatch, tmp_path) -> None:
from app.models import workspace as workspace_module
from app.models.workspace import WorkspaceRepository
from app.services import turnstile as turnstile_module
repo = WorkspaceRepository(base_path=tmp_path / "workspaces")
monkeypatch.setattr(workspace_module, "_workspace_repo", repo)
monkeypatch.setattr(turnstile_module, "verify_turnstile_token", lambda *args, **kwargs: True)
with TestClient(app) as client:
response = client.post(
"/workspaces/bootstrap",
data={"cf-turnstile-response": "token-ok"},
follow_redirects=False,
)
assert response.status_code in {302, 303, 307}
workspace_id = response.headers["location"].strip("/")
assert repo.workspace_exists(workspace_id)
assert response.cookies.get("workspace_id") == workspace_id
def test_bootstrap_workspace_rejects_failed_turnstile_verification(monkeypatch, tmp_path) -> None:
from app.models import workspace as workspace_module
from app.models.workspace import WorkspaceRepository
from app.services import turnstile as turnstile_module
repo = WorkspaceRepository(base_path=tmp_path / "workspaces")
monkeypatch.setattr(workspace_module, "_workspace_repo", repo)
monkeypatch.setattr(turnstile_module, "verify_turnstile_token", lambda *args, **kwargs: False)
with TestClient(app) as client:
response = client.post(
"/workspaces/bootstrap",
data={"cf-turnstile-response": "token-bad"},
follow_redirects=False,
)
assert response.status_code == 303
assert response.headers["location"] == "/?captcha_error=1"
assert not any(repo.base_path.iterdir())
def test_turnstile_settings_use_default_test_keys_when_env_is_missing(monkeypatch) -> None:
from app.services import turnstile as turnstile_module
monkeypatch.setenv("APP_ENV", "test")
monkeypatch.setenv("APP_ENV", "test")
monkeypatch.delenv("TURNSTILE_SITE_KEY", raising=False)
monkeypatch.delenv("TURNSTILE_SECRET_KEY", raising=False)
settings = turnstile_module.load_turnstile_settings()
assert settings.site_key == turnstile_module.DEFAULT_TURNSTILE_TEST_SITE_KEY
assert settings.secret_key == turnstile_module.DEFAULT_TURNSTILE_TEST_SECRET_KEY
assert settings.enabled is True
assert settings.uses_test_keys is True
assert settings.uses_test_keys is True
def test_turnstile_settings_fail_loudly_without_keys_outside_dev(monkeypatch) -> None:
from app.services import turnstile as turnstile_module
monkeypatch.setenv("APP_ENV", "production")
monkeypatch.delenv("TURNSTILE_SITE_KEY", raising=False)
monkeypatch.delenv("TURNSTILE_SECRET_KEY", raising=False)
import pytest
with pytest.raises(RuntimeError, match="Turnstile keys must be configured"):
turnstile_module.load_turnstile_settings()
def test_turnstile_verification_returns_false_on_transport_error(monkeypatch) -> None:
from app.services import turnstile as turnstile_module
monkeypatch.setenv("APP_ENV", "test")
def raise_error(*args, **kwargs):
raise requests.RequestException("boom")
monkeypatch.setattr(turnstile_module.requests, "post", raise_error)
assert turnstile_module.verify_turnstile_token("token") is False
def test_turnstile_settings_ignore_real_credentials_in_test_environment(monkeypatch) -> None:
from app.services import turnstile as turnstile_module
monkeypatch.setenv("APP_ENV", "test")
monkeypatch.setenv("TURNSTILE_SITE_KEY", "real-site-key")
monkeypatch.setenv("TURNSTILE_SECRET_KEY", "real-secret-key")
settings = turnstile_module.load_turnstile_settings()
assert settings.site_key == turnstile_module.DEFAULT_TURNSTILE_TEST_SITE_KEY
assert settings.secret_key == turnstile_module.DEFAULT_TURNSTILE_TEST_SECRET_KEY
assert settings.enabled is True
assert settings.uses_test_keys is True
def test_turnstile_settings_support_always_fail_test_keys(monkeypatch) -> None:
from app.services import turnstile as turnstile_module
monkeypatch.setenv("APP_ENV", "test")
monkeypatch.setenv("TURNSTILE_SITE_KEY", turnstile_module.ALWAYS_FAIL_TURNSTILE_TEST_SITE_KEY)
monkeypatch.setenv("TURNSTILE_SECRET_KEY", turnstile_module.ALWAYS_FAIL_TURNSTILE_TEST_SECRET_KEY)
settings = turnstile_module.load_turnstile_settings()
assert settings.site_key == turnstile_module.ALWAYS_FAIL_TURNSTILE_TEST_SITE_KEY
assert settings.secret_key == turnstile_module.ALWAYS_FAIL_TURNSTILE_TEST_SECRET_KEY
assert settings.enabled is True
assert settings.uses_test_keys is False
def test_bootstrap_stays_blocked_under_always_fail_turnstile_test_keys(monkeypatch, tmp_path) -> None:
from app.models import workspace as workspace_module
from app.models.workspace import WorkspaceRepository
from app.services import turnstile as turnstile_module
repo = WorkspaceRepository(base_path=tmp_path / "workspaces")
monkeypatch.setattr(workspace_module, "_workspace_repo", repo)
monkeypatch.setenv("APP_ENV", "test")
monkeypatch.setenv("TURNSTILE_SITE_KEY", turnstile_module.ALWAYS_FAIL_TURNSTILE_TEST_SITE_KEY)
monkeypatch.setenv("TURNSTILE_SECRET_KEY", turnstile_module.ALWAYS_FAIL_TURNSTILE_TEST_SECRET_KEY)
monkeypatch.setattr(turnstile_module, "verify_turnstile_token", lambda *args, **kwargs: False)
with TestClient(app) as client:
response = client.post(
"/workspaces/bootstrap",
data={"cf-turnstile-response": "blocked-token"},
follow_redirects=False,
)
assert response.status_code == 303
assert response.headers["location"] == "/?captcha_error=1"
assert not any(repo.base_path.iterdir())