from pathlib import Path import pytest from app.main import spa_fallback @pytest.fixture def static_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path: static = tmp_path / "static" static.mkdir() (static / "index.html").write_text("index", encoding="utf-8") (static / "app.js").write_text("console.log('app')", encoding="utf-8") secret = tmp_path / "secret.txt" secret.write_text("TOP SECRET", encoding="utf-8") monkeypatch.setattr("app.main.static_dir", static) return static def static_index(static_dir: Path) -> Path: return static_dir / "index.html" def test_returns_existing_file(static_dir: Path) -> None: response = spa_fallback("app.js") assert response.path == static_dir / "app.js" def test_unknown_path_falls_back_to_index(static_dir: Path) -> None: response = spa_fallback("does/not/exist.js") assert response.path == static_index(static_dir) def test_traversal_does_not_leak_outside_static(static_dir: Path) -> None: response = spa_fallback("../secret.txt") assert response.path == static_index(static_dir) response = spa_fallback("%2e%2e/secret.txt") assert response.path == static_index(static_dir) def test_symlink_outside_static_is_blocked(static_dir: Path, tmp_path: Path) -> None: target = tmp_path / "outside.txt" target.write_text("secret", encoding="utf-8") link = static_dir / "leak.txt" link.symlink_to(target) response = spa_fallback("leak.txt") assert response.path == static_index(static_dir)