confluence_web/tests/backend/test_settings.py
Artur Mukhamadiev e65fbf4b67 backend: FastAPI backend track handoff (contract revision 1)
FastAPI app, upstream Confluence/model adapters, authoritative history,
rootless container lifecycle, artifact storage and downloads, fake peers
under backend/dev, tests under tests/backend. Root pytest.ini deselects
the live marker by default; requirements gain the backend dependencies.
2026-09-14 21:57:54 +03:00

70 lines
3.0 KiB
Python

import pytest
from backend.errors import DestinationDeniedError, InvalidInputError
from backend.settings import Settings, canonicalize_url, validate_confluence_url
def test_canonicalize_url_valid():
assert canonicalize_url("https://approved.example.com") == "https://approved.example.com"
assert canonicalize_url("https://approved.example.com/") == "https://approved.example.com"
assert canonicalize_url("https://approved.example.com:443") == "https://approved.example.com"
assert canonicalize_url("http://approved.example.com:80") == "http://approved.example.com"
assert canonicalize_url("https://approved.example.com:8443/wiki/") == "https://approved.example.com:8443/wiki"
assert canonicalize_url("HTTPS://EXAMPLE.COM/Wiki") == "https://example.com/Wiki"
def test_canonicalize_url_rejects_invalids():
with pytest.raises(InvalidInputError, match="userinfo"):
canonicalize_url("https://user:pass@example.com")
with pytest.raises(InvalidInputError, match="fragment"):
canonicalize_url("https://example.com/#frag")
with pytest.raises(InvalidInputError, match="query"):
canonicalize_url("https://example.com/?query=1")
with pytest.raises(InvalidInputError, match="traversal"):
canonicalize_url("https://example.com/foo/../bar")
with pytest.raises(InvalidInputError, match="traversal"):
canonicalize_url("https://example.com/foo/%2e%2e/bar")
with pytest.raises(InvalidInputError, match="traversal"):
canonicalize_url("https://example.com/%2fetc/passwd")
with pytest.raises(InvalidInputError, match="scheme"):
canonicalize_url("ftp://example.com")
with pytest.raises(InvalidInputError, match="empty"):
canonicalize_url(" ")
# 8 KiB limit
with pytest.raises(InvalidInputError, match="limit"):
canonicalize_url("https://example.com/" + "a" * 8200)
def test_validate_confluence_url():
approved = [
"https://approved.example.com",
"https://corp.example.com/wiki",
]
# Exact match
assert validate_confluence_url("https://approved.example.com", approved) == "https://approved.example.com"
assert validate_confluence_url("https://approved.example.com/", approved) == "https://approved.example.com"
assert validate_confluence_url("https://corp.example.com/wiki", approved) == "https://corp.example.com/wiki"
# Context subpath
assert validate_confluence_url("https://corp.example.com/wiki/sub", approved) == "https://corp.example.com/wiki/sub"
# Reject prefix lookalike: /wikileaks must NOT match /wiki
with pytest.raises(DestinationDeniedError, match="denied"):
validate_confluence_url("https://corp.example.com/wikileaks", approved)
# Reject different host
with pytest.raises(DestinationDeniedError, match="denied"):
validate_confluence_url("https://malicious.example.com", approved)
# Reject different scheme
with pytest.raises(DestinationDeniedError, match="denied"):
validate_confluence_url("http://approved.example.com", approved)