"""Unit tests for web-based Login Flow v2 provisioning routes. Tests validation, HTML escaping, URL rewriting, and route handlers. """ import time from unittest.mock import AsyncMock, MagicMock, patch import pytest from nextcloud_mcp_server.auth.provision_routes import ( _provision_sessions, _render_error, _validate_redirect_uri, provision_page, provision_status, ) pytestmark = pytest.mark.unit # ── _validate_redirect_uri tests ───────────────────────────────────────── async def test_validate_redirect_uri_accepts_https(): """Valid HTTPS URL is accepted.""" assert _validate_redirect_uri("https://app.example.com/callback") is True async def test_validate_redirect_uri_accepts_http_localhost(): """Valid HTTP localhost URL is accepted.""" assert _validate_redirect_uri("http://localhost:3000/callback") is True async def test_validate_redirect_uri_rejects_javascript(): """javascript: URIs are rejected.""" assert _validate_redirect_uri("javascript:alert(1)") is False async def test_validate_redirect_uri_rejects_relative_url(): """Relative URLs are rejected (no scheme/netloc).""" assert _validate_redirect_uri("/relative/path") is False async def test_validate_redirect_uri_rejects_bare_hostname(): """Bare hostnames without scheme are rejected.""" assert _validate_redirect_uri("example.com") is False async def test_validate_redirect_uri_rejects_data_uri(): """data: URIs are rejected.""" assert _validate_redirect_uri("data:text/html,

hi

") is False async def test_validate_redirect_uri_rejects_empty(): """Empty string is rejected.""" assert _validate_redirect_uri("") is False # ── _render_error tests ────────────────────────────────────────────────── async def test_render_error_escapes_html(): """XSS regression: HTML in error messages must be escaped.""" html_output = _render_error("") assert "