/
liquid-g
/
liquid-code
Обзор
Документация
Войти
/
liquid-g
/
liquid-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop-0.4
tests/unit/middleware/test_static.py
395 строк
12 KB
User
0.4.4 - унифицирована загрузка middleware в application.py; дописаны тесты: - Всего тестов: 341 - Общее покрытие: 64%
05 июл 2026, 14:02
05 июл 2026, 14:02
27abc28
Код
Авторство
О чём код?
"""Unit-тесты для StaticFilesMiddleware.""" import pytest import tempfile import os from unittest.mock import Mock from liquidcode.middleware.static import StaticFilesMiddleware from liquidcode.http import HttpRequest, HttpResponse class TestStaticFilesMiddleware: """Тесты раздачи статических файлов.""" def test_serve_static_file(self, tmp_path): """Отдача существующего файла.""" # Создаем временный файл static_dir = tmp_path / "static" static_dir.mkdir() test_file = static_dir / "test.css" test_file.write_text("body { color: red; }") middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="GET", path="/static/test.css", headers={}, body=b"" ) def call_next(req): return HttpResponse({"fallback": True}, 200) response = middleware(request, call_next) assert response.get_status() == 200 assert b"body { color: red; }" in response.get_content() assert "text/css" in response.get_headers().get("Content-Type", "") def test_prefix_not_matched(self, tmp_path): """Путь не соответствует префиксу.""" static_dir = tmp_path / "static" static_dir.mkdir() middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="GET", path="/api/test", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({"api": "response"}, 200)) response = middleware(request, call_next) assert response.get_content() == {"api": "response"} call_next.assert_called_once() def test_directory_traversal_prevented(self, tmp_path): """Предотвращение directory traversal.""" static_dir = tmp_path / "static" static_dir.mkdir() # Создаем файл за пределами статики outside_file = tmp_path / "secret.txt" outside_file.write_text("secret") middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) # Попытка доступа через ../ request = HttpRequest( method="GET", path="/static/../secret.txt", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({"fallback": True}, 200)) response = middleware(request, call_next) # Должен вернуть fallback, а не файл assert response.get_content() == {"fallback": True} call_next.assert_called_once() def test_missing_file(self, tmp_path): """Файл не существует.""" static_dir = tmp_path / "static" static_dir.mkdir() middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="GET", path="/static/missing.txt", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({"fallback": True}, 200)) response = middleware(request, call_next) assert response.get_content() == {"fallback": True} call_next.assert_called_once() def test_directory_request(self, tmp_path): """Запрос на директорию.""" static_dir = tmp_path / "static" static_dir.mkdir() middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="GET", path="/static/", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({"fallback": True}, 200)) response = middleware(request, call_next) # Должен пропустить (пустой relative_path) assert response.get_content() == {"fallback": True} call_next.assert_called_once() def test_default_prefix_and_directory(self, tmp_path): """Дефолтные значения prefix и directory.""" # Используем временную директорию как public static_dir = tmp_path / "public" static_dir.mkdir() test_file = static_dir / "test.js" test_file.write_text("console.log('test');") middleware = StaticFilesMiddleware(directory=str(static_dir)) request = HttpRequest( method="GET", path="/static/test.js", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({}, 200)) response = middleware(request, call_next) # Статика должна отдаваться assert response.get_status() == 200 assert b"console.log" in response.get_content() def test_no_trailing_slash_in_prefix(self, tmp_path): """Префикс без trailing slash.""" static_dir = tmp_path / "static" static_dir.mkdir() test_file = static_dir / "test.png" test_file.write_bytes(b"\x89PNG") middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="GET", path="/static/test.png", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({}, 200)) response = middleware(request, call_next) assert response.get_status() == 200 assert b"\x89PNG" in response.get_content() # PNG mime type assert "png" in response.get_headers().get("Content-Type", "") def test_nested_path(self, tmp_path): """Вложенный путь.""" static_dir = tmp_path / "static" static_dir.mkdir() # Создаем вложенную директорию nested_dir = static_dir / "js" nested_dir.mkdir() test_file = nested_dir / "app.js" test_file.write_text("var app = {};") middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="GET", path="/static/js/app.js", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({}, 200)) response = middleware(request, call_next) assert response.get_status() == 200 assert b"var app = {}" in response.get_content() def test_unknown_file_type(self, tmp_path): """Неизвестный тип файла.""" static_dir = tmp_path / "static" static_dir.mkdir() test_file = static_dir / "unknown.xyz" test_file.write_text("unknown") middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="GET", path="/static/unknown.xyz", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({}, 200)) response = middleware(request, call_next) assert response.get_status() == 200 assert "application/octet-stream" in response.get_headers().get("Content-Type", "") def test_empty_directory(self, tmp_path): """Пустая директория.""" static_dir = tmp_path / "static" static_dir.mkdir() middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="GET", path="/static/anything.txt", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({"fallback": True}, 200)) response = middleware(request, call_next) assert response.get_content() == {"fallback": True} def test_prefix_normalization(self, tmp_path): """Нормализация префикса (без trailing slash).""" static_dir = tmp_path / "static" static_dir.mkdir() test_file = static_dir / "test.txt" test_file.write_text("content") middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static/" # С trailing slash ) request = HttpRequest( method="GET", path="/static/test.txt", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({}, 200)) response = middleware(request, call_next) assert response.get_status() == 200 assert b"content" in response.get_content() def test_read_error(self, tmp_path, monkeypatch): """Ошибка чтения файла.""" static_dir = tmp_path / "static" static_dir.mkdir() test_file = static_dir / "test.txt" test_file.write_text("content") middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) # Подменяем open чтобы вызвать ошибку original_open = open def mock_open(*args, **kwargs): raise IOError("Permission denied") monkeypatch.setattr("builtins.open", mock_open) request = HttpRequest( method="GET", path="/static/test.txt", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({"fallback": True}, 200)) response = middleware(request, call_next) # Должен вернуть fallback при ошибке чтения assert response.get_content() == {"fallback": True} def test_post_request(self, tmp_path): """POST запрос к статике.""" static_dir = tmp_path / "static" static_dir.mkdir() test_file = static_dir / "test.txt" test_file.write_text("content") middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="POST", path="/static/test.txt", headers={}, body=b"" ) # Для POST файл все равно отдастся, если он есть call_next = Mock(return_value=HttpResponse({"fallback": True}, 200)) response = middleware(request, call_next) assert response.get_status() == 200 assert b"content" in response.get_content() def test_file_inside_directory(self, tmp_path): """Файл внутри статической директории.""" static_dir = tmp_path / "static" static_dir.mkdir() # Создаем поддиректорию sub_dir = static_dir / "sub" sub_dir.mkdir() test_file = sub_dir / "test.txt" test_file.write_text("sub content") middleware = StaticFilesMiddleware( directory=str(static_dir), prefix="/static" ) request = HttpRequest( method="GET", path="/static/sub/test.txt", headers={}, body=b"" ) call_next = Mock(return_value=HttpResponse({}, 200)) response = middleware(request, call_next) assert response.get_status() == 200 assert b"sub content" in response.get_content()