screen-locker/screen_locker/tests/test_web_server_part2.py
Krzysztof kuhy Rudnicki 4a36b6b264 Fix mechanical pylint findings in tests
Booleaness asserts, hoisted imports, fixture(name=...) instead of
shadowing arguments, explicit encodings, snake_case names, comparison
of bound methods, dead protected-access disables.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWYdwRAtMg7ki6TKxuU
2026-11-01 21:11:34 +01:00

82 lines
3.1 KiB
Python

"""Tests for _web_server static serving: SPA fallback and traversal guard.
Split out of test_web_server.py for the 250-line cap; the server harness and
the real_loopback fixture stay in that module and are imported here.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from unittest.mock import patch
import pytest
from screen_locker.tests.test_web_server import (
_PKG,
_get,
_make_dist,
_running,
real_loopback_fixture,
)
if TYPE_CHECKING:
from pathlib import Path
__all__ = ["real_loopback_fixture"]
class TestStaticServing:
"""The built bundle is served with an SPA fallback and a traversal guard."""
@pytest.fixture(autouse=True)
def _network(self, real_loopback: None) -> None:
"""Every test in this class talks to the server over real HTTP."""
def test_index_is_served_at_the_root(self, tmp_path: Path) -> None:
"""/ serves index.html."""
with patch(f"{_PKG}.WEB_DIST", _make_dist(tmp_path)), _running() as port:
status, body, ctype = _get(port, "/")
assert status == 200
assert b"INDEX" in body
assert ctype.startswith("text/html")
def test_an_asset_is_served_with_its_own_type(self, tmp_path: Path) -> None:
"""A real file is served rather than the SPA fallback."""
with patch(f"{_PKG}.WEB_DIST", _make_dist(tmp_path)), _running() as port:
status, body, ctype = _get(port, "/app.css")
assert status == 200
assert body == b"body{}"
assert ctype.startswith("text/css")
def test_a_binary_asset_gets_no_charset(self, tmp_path: Path) -> None:
"""A charset on image/png would be wrong; only text types get one."""
with patch(f"{_PKG}.WEB_DIST", _make_dist(tmp_path)), _running() as port:
status, body, ctype = _get(port, "/icon.png")
assert status == 200
assert body.startswith(b"\x89PNG")
assert ctype == "image/png"
def test_an_unknown_route_falls_back_to_index(self, tmp_path: Path) -> None:
"""SPA routes are handled by the bundle, not by the server."""
with patch(f"{_PKG}.WEB_DIST", _make_dist(tmp_path)), _running() as port:
status, body, _ = _get(port, "/why/2026-08-29")
assert status == 200
assert b"INDEX" in body
def test_traversal_never_escapes_the_bundle(self, tmp_path: Path) -> None:
"""A ../ path is refused, not resolved against the filesystem."""
secret = tmp_path / "secret.txt"
secret.write_text("do not serve me", encoding="utf-8")
with patch(f"{_PKG}.WEB_DIST", _make_dist(tmp_path)), _running() as port:
status, body, _ = _get(port, "/../secret.txt")
assert status == 200
assert b"do not serve me" not in body
def test_missing_bundle_says_how_to_build_it(self, tmp_path: Path) -> None:
"""404 carries the build command instead of an empty page."""
dist = _make_dist(tmp_path, with_index=False)
with patch(f"{_PKG}.WEB_DIST", dist), _running() as port:
status, body, _ = _get(port, "/")
assert status == 404
assert b"npm --prefix web run build" in body