From a54b4721039857179b8d7837f3be540d68e2a1e3 Mon Sep 17 00:00:00 2001 From: Amin Alaee Date: Mon, 12 Dec 2022 10:14:53 +0100 Subject: [PATCH] fix naming in tests --- tests/test_staticfiles.py | 821 +++++++++++++++++++------------------- 1 file changed, 418 insertions(+), 403 deletions(-) diff --git a/tests/test_staticfiles.py b/tests/test_staticfiles.py index cdc119fbab..1b5235835b 100644 --- a/tests/test_staticfiles.py +++ b/tests/test_staticfiles.py @@ -1,7 +1,5 @@ import os -import pathlib -import stat -import time +import tempfile import anyio import pytest @@ -14,478 +12,495 @@ from starlette.routing import Mount from starlette.staticfiles import StaticFiles +# def test_staticfiles(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") -def test_staticfiles(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") +# app = StaticFiles(directory=tmpdir) +# client = test_client_factory(app) +# response = client.get("/example.txt") +# assert response.status_code == 200 +# assert response.text == "" - app = StaticFiles(directory=tmpdir) - client = test_client_factory(app) - response = client.get("/example.txt") - assert response.status_code == 200 - assert response.text == "" - - -def test_staticfiles_with_pathlib(tmpdir, test_client_factory): - base_dir = pathlib.Path(tmpdir) - path = base_dir / "example.txt" - with open(path, "w") as file: - file.write("") - - app = StaticFiles(directory=base_dir) - client = test_client_factory(app) - response = client.get("/example.txt") - assert response.status_code == 200 - assert response.text == "" - - -def test_staticfiles_head_with_middleware(tmpdir, test_client_factory): - """ - see https://github.com/encode/starlette/pull/935 - """ - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("x" * 100) - - async def does_nothing_middleware(request: Request, call_next): - response = await call_next(request) - return response - - routes = [Mount("/static", app=StaticFiles(directory=tmpdir), name="static")] - middleware = [Middleware(BaseHTTPMiddleware, dispatch=does_nothing_middleware)] - app = Starlette(routes=routes, middleware=middleware) - - client = test_client_factory(app) - response = client.head("/static/example.txt") - assert response.status_code == 200 - assert response.headers.get("content-length") == "100" - - -def test_staticfiles_with_package(test_client_factory): - app = StaticFiles(packages=["tests"]) - client = test_client_factory(app) - response = client.get("/example.txt") - assert response.status_code == 200 - assert response.text == "123\n" - - app = StaticFiles(packages=[("tests", "statics")]) - client = test_client_factory(app) - response = client.get("/example.txt") - assert response.status_code == 200 - assert response.text == "123\n" - - -def test_staticfiles_post(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") - - routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] - app = Starlette(routes=routes) - client = test_client_factory(app) - - response = client.post("/example.txt") - assert response.status_code == 405 - assert response.text == "Method Not Allowed" +# def test_staticfiles_with_pathlib(tmpdir, test_client_factory): +# base_dir = pathlib.Path(tmpdir) +# path = base_dir / "example.txt" +# with open(path, "w") as file: +# file.write("") -def test_staticfiles_with_directory_returns_404(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") +# app = StaticFiles(directory=base_dir) +# client = test_client_factory(app) +# response = client.get("/example.txt") +# assert response.status_code == 200 +# assert response.text == "" - routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] - app = Starlette(routes=routes) - client = test_client_factory(app) - response = client.get("/") - assert response.status_code == 404 - assert response.text == "Not Found" +# def test_staticfiles_head_with_middleware(tmpdir, test_client_factory): +# """ +# see https://github.com/encode/starlette/pull/935 +# """ +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("x" * 100) +# async def does_nothing_middleware(request: Request, call_next): +# response = await call_next(request) +# return response -def test_staticfiles_with_missing_file_returns_404(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") +# routes = [Mount("/static", app=StaticFiles(directory=tmpdir), name="static")] +# middleware = [Middleware(BaseHTTPMiddleware, dispatch=does_nothing_middleware)] +# app = Starlette(routes=routes, middleware=middleware) - routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] - app = Starlette(routes=routes) - client = test_client_factory(app) +# client = test_client_factory(app) +# response = client.head("/static/example.txt") +# assert response.status_code == 200 +# assert response.headers.get("content-length") == "100" - response = client.get("/404.txt") - assert response.status_code == 404 - assert response.text == "Not Found" +# def test_staticfiles_with_package(test_client_factory): +# app = StaticFiles(packages=["tests"]) +# client = test_client_factory(app) +# response = client.get("/example.txt") +# assert response.status_code == 200 +# assert response.text == "123\n" -def test_staticfiles_instantiated_with_missing_directory(tmpdir): - with pytest.raises(RuntimeError) as exc_info: - path = os.path.join(tmpdir, "no_such_directory") - StaticFiles(directory=path) - assert "does not exist" in str(exc_info.value) +# app = StaticFiles(packages=[("tests", "statics")]) +# client = test_client_factory(app) +# response = client.get("/example.txt") +# assert response.status_code == 200 +# assert response.text == "123\n" -def test_staticfiles_configured_with_missing_directory(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "no_such_directory") - app = StaticFiles(directory=path, check_dir=False) - client = test_client_factory(app) - with pytest.raises(RuntimeError) as exc_info: - client.get("/example.txt") - assert "does not exist" in str(exc_info.value) +# def test_staticfiles_post(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") +# routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] +# app = Starlette(routes=routes) +# client = test_client_factory(app) -def test_staticfiles_configured_with_file_instead_of_directory( - tmpdir, test_client_factory -): - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") +# response = client.post("/example.txt") +# assert response.status_code == 405 +# assert response.text == "Method Not Allowed" - app = StaticFiles(directory=path, check_dir=False) - client = test_client_factory(app) - with pytest.raises(RuntimeError) as exc_info: - client.get("/example.txt") - assert "is not a directory" in str(exc_info.value) - - -def test_staticfiles_config_check_occurs_only_once(tmpdir, test_client_factory): - app = StaticFiles(directory=tmpdir) - client = test_client_factory(app) - assert not app.config_checked - with pytest.raises(HTTPException): - client.get("/") +# def test_staticfiles_with_directory_returns_404(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") - assert app.config_checked +# routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] +# app = Starlette(routes=routes) +# client = test_client_factory(app) - with pytest.raises(HTTPException): - client.get("/") +# response = client.get("/") +# assert response.status_code == 404 +# assert response.text == "Not Found" -def test_staticfiles_prevents_breaking_out_of_directory(tmpdir): - directory = os.path.join(tmpdir, "foo") - os.mkdir(directory) - - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("outside root dir") - - app = StaticFiles(directory=directory) - # We can't test this with 'requests', so we test the app directly here. - path = app.get_path({"path": "/../example.txt"}) - scope = {"method": "GET"} - - with pytest.raises(HTTPException) as exc_info: - anyio.run(app.get_response, path, scope) +# def test_staticfiles_with_missing_file_returns_404(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") - assert exc_info.value.status_code == 404 - assert exc_info.value.detail == "Not Found" +# routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] +# app = Starlette(routes=routes) +# client = test_client_factory(app) +# response = client.get("/404.txt") +# assert response.status_code == 404 +# assert response.text == "Not Found" -def test_staticfiles_never_read_file_for_head_method(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") - app = StaticFiles(directory=tmpdir) - client = test_client_factory(app) - response = client.head("/example.txt") - assert response.status_code == 200 - assert response.content == b"" - assert response.headers["content-length"] == "14" +# def test_staticfiles_instantiated_with_missing_directory(tmpdir): +# with pytest.raises(RuntimeError) as exc_info: +# path = os.path.join(tmpdir, "no_such_directory") +# StaticFiles(directory=path) +# assert "does not exist" in str(exc_info.value) -def test_staticfiles_304_with_etag_match(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") +# def test_staticfiles_configured_with_missing_directory(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "no_such_directory") +# app = StaticFiles(directory=path, check_dir=False) +# client = test_client_factory(app) +# with pytest.raises(RuntimeError) as exc_info: +# client.get("/example.txt") +# assert "does not exist" in str(exc_info.value) + + +# def test_staticfiles_configured_with_file_instead_of_directory( +# tmpdir, test_client_factory +# ): +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") + +# app = StaticFiles(directory=path, check_dir=False) +# client = test_client_factory(app) +# with pytest.raises(RuntimeError) as exc_info: +# client.get("/example.txt") +# assert "is not a directory" in str(exc_info.value) + + +# def test_staticfiles_config_check_occurs_only_once(tmpdir, test_client_factory): +# app = StaticFiles(directory=tmpdir) +# client = test_client_factory(app) +# assert not app.config_checked + +# with pytest.raises(HTTPException): +# client.get("/") + +# assert app.config_checked + +# with pytest.raises(HTTPException): +# client.get("/") + + +# def test_staticfiles_prevents_breaking_out_of_directory(tmpdir): +# directory = os.path.join(tmpdir, "foo") +# os.mkdir(directory) + +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("outside root dir") + +# app = StaticFiles(directory=directory) +# # We can't test this with 'requests', so we test the app directly here. +# path = app.get_path({"path": "/../example.txt"}) +# scope = {"method": "GET"} + +# with pytest.raises(HTTPException) as exc_info: +# anyio.run(app.get_response, path, scope) + +# assert exc_info.value.status_code == 404 +# assert exc_info.value.detail == "Not Found" + + +# def test_staticfiles_never_read_file_for_head_method(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") + +# app = StaticFiles(directory=tmpdir) +# client = test_client_factory(app) +# response = client.head("/example.txt") +# assert response.status_code == 200 +# assert response.content == b"" +# assert response.headers["content-length"] == "14" + + +# def test_staticfiles_304_with_etag_match(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") + +# app = StaticFiles(directory=tmpdir) +# client = test_client_factory(app) +# first_resp = client.get("/example.txt") +# assert first_resp.status_code == 200 +# last_etag = first_resp.headers["etag"] +# second_resp = client.get("/example.txt", headers={"if-none-match": last_etag}) +# assert second_resp.status_code == 304 +# assert second_resp.content == b"" + + +# def test_staticfiles_304_with_last_modified_compare_last_req( +# tmpdir, test_client_factory +# ): +# path = os.path.join(tmpdir, "example.txt") +# file_last_modified_time = time.mktime( +# time.strptime("2013-10-10 23:40:00", "%Y-%m-%d %H:%M:%S") +# ) +# with open(path, "w") as file: +# file.write("") +# os.utime(path, (file_last_modified_time, file_last_modified_time)) + +# app = StaticFiles(directory=tmpdir) +# client = test_client_factory(app) +# # last modified less than last request, 304 +# response = client.get( +# "/example.txt", headers={"If-Modified-Since": "Thu, 11 Oct 2013 15:30:19 GMT"} +# ) +# assert response.status_code == 304 +# assert response.content == b"" +# # last modified greater than last request, 200 with content +# response = client.get( +# "/example.txt", headers={"If-Modified-Since": "Thu, 20 Feb 2012 15:30:19 GMT"} +# ) +# assert response.status_code == 200 +# assert response.content == b"" + + +# def test_staticfiles_html_normal(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "404.html") +# with open(path, "w") as file: +# file.write("

Custom not found page

") +# path = os.path.join(tmpdir, "dir") +# os.mkdir(path) +# path = os.path.join(path, "index.html") +# with open(path, "w") as file: +# file.write("

Hello

") + +# app = StaticFiles(directory=tmpdir, html=True) +# client = test_client_factory(app) + +# response = client.get("/dir/") +# assert response.url == "http://testserver/dir/" +# assert response.status_code == 200 +# assert response.text == "

Hello

" + +# response = client.get("/dir") +# assert response.url == "http://testserver/dir/" +# assert response.status_code == 200 +# assert response.text == "

Hello

" + +# response = client.get("/dir/index.html") +# assert response.url == "http://testserver/dir/index.html" +# assert response.status_code == 200 +# assert response.text == "

Hello

" + +# response = client.get("/missing") +# assert response.status_code == 404 +# assert response.text == "

Custom not found page

" + + +# def test_staticfiles_html_without_index(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "404.html") +# with open(path, "w") as file: +# file.write("

Custom not found page

") +# path = os.path.join(tmpdir, "dir") +# os.mkdir(path) + +# app = StaticFiles(directory=tmpdir, html=True) +# client = test_client_factory(app) + +# response = client.get("/dir/") +# assert response.url == "http://testserver/dir/" +# assert response.status_code == 404 +# assert response.text == "

Custom not found page

" + +# response = client.get("/dir") +# assert response.url == "http://testserver/dir" +# assert response.status_code == 404 +# assert response.text == "

Custom not found page

" + +# response = client.get("/missing") +# assert response.status_code == 404 +# assert response.text == "

Custom not found page

" + + +# def test_staticfiles_html_without_404(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "dir") +# os.mkdir(path) +# path = os.path.join(path, "index.html") +# with open(path, "w") as file: +# file.write("

Hello

") + +# app = StaticFiles(directory=tmpdir, html=True) +# client = test_client_factory(app) + +# response = client.get("/dir/") +# assert response.url == "http://testserver/dir/" +# assert response.status_code == 200 +# assert response.text == "

Hello

" + +# response = client.get("/dir") +# assert response.url == "http://testserver/dir/" +# assert response.status_code == 200 +# assert response.text == "

Hello

" + +# with pytest.raises(HTTPException) as exc_info: +# response = client.get("/missing") +# assert exc_info.value.status_code == 404 + + +# def test_staticfiles_html_only_files(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "hello.html") +# with open(path, "w") as file: +# file.write("

Hello

") + +# app = StaticFiles(directory=tmpdir, html=True) +# client = test_client_factory(app) + +# with pytest.raises(HTTPException) as exc_info: +# response = client.get("/") +# assert exc_info.value.status_code == 404 + +# response = client.get("/hello.html") +# assert response.status_code == 200 +# assert response.text == "

Hello

" + + +# def test_staticfiles_cache_invalidation_for_deleted_file_html_mode( +# tmpdir, test_client_factory +# ): +# path_404 = os.path.join(tmpdir, "404.html") +# with open(path_404, "w") as file: +# file.write("

404 file

") +# path_some = os.path.join(tmpdir, "some.html") +# with open(path_some, "w") as file: +# file.write("

some file

") + +# common_modified_time = time.mktime( +# time.strptime("2013-10-10 23:40:00", "%Y-%m-%d %H:%M:%S") +# ) +# os.utime(path_404, (common_modified_time, common_modified_time)) +# os.utime(path_some, (common_modified_time, common_modified_time)) + +# app = StaticFiles(directory=tmpdir, html=True) +# client = test_client_factory(app) + +# resp_exists = client.get("/some.html") +# assert resp_exists.status_code == 200 +# assert resp_exists.text == "

some file

" - app = StaticFiles(directory=tmpdir) - client = test_client_factory(app) - first_resp = client.get("/example.txt") - assert first_resp.status_code == 200 - last_etag = first_resp.headers["etag"] - second_resp = client.get("/example.txt", headers={"if-none-match": last_etag}) - assert second_resp.status_code == 304 - assert second_resp.content == b"" - - -def test_staticfiles_304_with_last_modified_compare_last_req( - tmpdir, test_client_factory -): - path = os.path.join(tmpdir, "example.txt") - file_last_modified_time = time.mktime( - time.strptime("2013-10-10 23:40:00", "%Y-%m-%d %H:%M:%S") - ) - with open(path, "w") as file: - file.write("") - os.utime(path, (file_last_modified_time, file_last_modified_time)) - - app = StaticFiles(directory=tmpdir) - client = test_client_factory(app) - # last modified less than last request, 304 - response = client.get( - "/example.txt", headers={"If-Modified-Since": "Thu, 11 Oct 2013 15:30:19 GMT"} - ) - assert response.status_code == 304 - assert response.content == b"" - # last modified greater than last request, 200 with content - response = client.get( - "/example.txt", headers={"If-Modified-Since": "Thu, 20 Feb 2012 15:30:19 GMT"} - ) - assert response.status_code == 200 - assert response.content == b"" +# resp_cached = client.get( +# "/some.html", +# headers={"If-Modified-Since": resp_exists.headers["last-modified"]}, +# ) +# assert resp_cached.status_code == 304 + +# os.remove(path_some) + +# resp_deleted = client.get( +# "/some.html", +# headers={"If-Modified-Since": resp_exists.headers["last-modified"]}, +# ) +# assert resp_deleted.status_code == 404 +# assert resp_deleted.text == "

404 file

" -def test_staticfiles_html_normal(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "404.html") - with open(path, "w") as file: - file.write("

Custom not found page

") - path = os.path.join(tmpdir, "dir") - os.mkdir(path) - path = os.path.join(path, "index.html") - with open(path, "w") as file: - file.write("

Hello

") +# def test_staticfiles_with_invalid_dir_permissions_returns_401( +# tmp_path, test_client_factory +# ): +# (tmp_path / "example.txt").write_bytes(b"") + +# original_mode = tmp_path.stat().st_mode +# tmp_path.chmod(stat.S_IRWXO) +# try: +# routes = [ +# Mount( +# "/", +# app=StaticFiles(directory=os.fsdecode(tmp_path)), +# name="static", +# ) +# ] +# app = Starlette(routes=routes) +# client = test_client_factory(app) - app = StaticFiles(directory=tmpdir, html=True) - client = test_client_factory(app) +# response = client.get("/example.txt") +# assert response.status_code == 401 +# assert response.text == "Unauthorized" +# finally: +# tmp_path.chmod(original_mode) - response = client.get("/dir/") - assert response.url == "http://testserver/dir/" - assert response.status_code == 200 - assert response.text == "

Hello

" - response = client.get("/dir") - assert response.url == "http://testserver/dir/" - assert response.status_code == 200 - assert response.text == "

Hello

" +# def test_staticfiles_with_missing_dir_returns_404(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") + +# routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] +# app = Starlette(routes=routes) +# client = test_client_factory(app) - response = client.get("/dir/index.html") - assert response.url == "http://testserver/dir/index.html" - assert response.status_code == 200 - assert response.text == "

Hello

" +# response = client.get("/foo/example.txt") +# assert response.status_code == 404 +# assert response.text == "Not Found" - response = client.get("/missing") - assert response.status_code == 404 - assert response.text == "

Custom not found page

" +# def test_staticfiles_access_file_as_dir_returns_404(tmpdir, test_client_factory): +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") -def test_staticfiles_html_without_index(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "404.html") - with open(path, "w") as file: - file.write("

Custom not found page

") - path = os.path.join(tmpdir, "dir") - os.mkdir(path) +# routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] +# app = Starlette(routes=routes) +# client = test_client_factory(app) - app = StaticFiles(directory=tmpdir, html=True) - client = test_client_factory(app) +# response = client.get("/example.txt/foo") +# assert response.status_code == 404 +# assert response.text == "Not Found" - response = client.get("/dir/") - assert response.url == "http://testserver/dir/" - assert response.status_code == 404 - assert response.text == "

Custom not found page

" - response = client.get("/dir") - assert response.url == "http://testserver/dir" - assert response.status_code == 404 - assert response.text == "

Custom not found page

" +# def test_staticfiles_unhandled_os_error_returns_500( +# tmpdir, test_client_factory, monkeypatch +# ): +# def mock_timeout(*args, **kwargs): +# raise TimeoutError + +# path = os.path.join(tmpdir, "example.txt") +# with open(path, "w") as file: +# file.write("") + +# routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] +# app = Starlette(routes=routes) +# client = test_client_factory(app, raise_server_exceptions=False) + +# monkeypatch.setattr("starlette.staticfiles.StaticFiles.lookup_path", mock_timeout) + +# response = client.get("/example.txt") +# assert response.status_code == 500 +# assert response.text == "Internal Server Error" - response = client.get("/missing") - assert response.status_code == 404 - assert response.text == "

Custom not found page

" +def test_staticfiles_follows_symlinks(tmpdir, test_client_factory): + statics_path = os.path.join(tmpdir, "statics") + os.mkdir(statics_path) -def test_staticfiles_html_without_404(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "dir") - os.mkdir(path) - path = os.path.join(path, "index.html") - with open(path, "w") as file: + source_path = tempfile.mkdtemp() + source_file_path = os.path.join(source_path, "page.html") + with open(source_file_path, "w") as file: file.write("

Hello

") - app = StaticFiles(directory=tmpdir, html=True) - client = test_client_factory(app) - - response = client.get("/dir/") - assert response.url == "http://testserver/dir/" - assert response.status_code == 200 - assert response.text == "

Hello

" - - response = client.get("/dir") - assert response.url == "http://testserver/dir/" - assert response.status_code == 200 - assert response.text == "

Hello

" - - with pytest.raises(HTTPException) as exc_info: - response = client.get("/missing") - assert exc_info.value.status_code == 404 - - -def test_staticfiles_html_only_files(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "hello.html") - with open(path, "w") as file: - file.write("

Hello

") + statics_file_path = os.path.join(statics_path, "index.html") + os.symlink(source_file_path, statics_file_path) - app = StaticFiles(directory=tmpdir, html=True) + app = StaticFiles(directory=statics_path) client = test_client_factory(app) - with pytest.raises(HTTPException) as exc_info: - response = client.get("/") - assert exc_info.value.status_code == 404 - - response = client.get("/hello.html") + response = client.get("/index.html") + assert response.url == "http://testserver/index.html" assert response.status_code == 200 assert response.text == "

Hello

" -def test_staticfiles_cache_invalidation_for_deleted_file_html_mode( - tmpdir, test_client_factory -): - path_404 = os.path.join(tmpdir, "404.html") - with open(path_404, "w") as file: - file.write("

404 file

") - path_some = os.path.join(tmpdir, "some.html") - with open(path_some, "w") as file: - file.write("

some file

") - - common_modified_time = time.mktime( - time.strptime("2013-10-10 23:40:00", "%Y-%m-%d %H:%M:%S") - ) - os.utime(path_404, (common_modified_time, common_modified_time)) - os.utime(path_some, (common_modified_time, common_modified_time)) - - app = StaticFiles(directory=tmpdir, html=True) - client = test_client_factory(app) - - resp_exists = client.get("/some.html") - assert resp_exists.status_code == 200 - assert resp_exists.text == "

some file

" - - resp_cached = client.get( - "/some.html", - headers={"If-Modified-Since": resp_exists.headers["last-modified"]}, - ) - assert resp_cached.status_code == 304 - - os.remove(path_some) - - resp_deleted = client.get( - "/some.html", - headers={"If-Modified-Since": resp_exists.headers["last-modified"]}, - ) - assert resp_deleted.status_code == 404 - assert resp_deleted.text == "

404 file

" - - -def test_staticfiles_with_invalid_dir_permissions_returns_401( - tmp_path, test_client_factory -): - (tmp_path / "example.txt").write_bytes(b"") - - original_mode = tmp_path.stat().st_mode - tmp_path.chmod(stat.S_IRWXO) - try: - routes = [ - Mount( - "/", - app=StaticFiles(directory=os.fsdecode(tmp_path)), - name="static", - ) - ] - app = Starlette(routes=routes) - client = test_client_factory(app) - - response = client.get("/example.txt") - assert response.status_code == 401 - assert response.text == "Unauthorized" - finally: - tmp_path.chmod(original_mode) - - -def test_staticfiles_with_missing_dir_returns_404(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") - - routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] - app = Starlette(routes=routes) - client = test_client_factory(app) - - response = client.get("/foo/example.txt") - assert response.status_code == 404 - assert response.text == "Not Found" - - -def test_staticfiles_access_file_as_dir_returns_404(tmpdir, test_client_factory): - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") - - routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] - app = Starlette(routes=routes) - client = test_client_factory(app) - - response = client.get("/example.txt/foo") - assert response.status_code == 404 - assert response.text == "Not Found" - - -def test_staticfiles_unhandled_os_error_returns_500( - tmpdir, test_client_factory, monkeypatch -): - def mock_timeout(*args, **kwargs): - raise TimeoutError - - path = os.path.join(tmpdir, "example.txt") - with open(path, "w") as file: - file.write("") - - routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] - app = Starlette(routes=routes) - client = test_client_factory(app, raise_server_exceptions=False) - - monkeypatch.setattr("starlette.staticfiles.StaticFiles.lookup_path", mock_timeout) - - response = client.get("/example.txt") - assert response.status_code == 500 - assert response.text == "Internal Server Error" - - -def test_staticfiles_follows_symlinks(tmpdir, test_client_factory): +def test_staticfiles_follows_symlink_directories(tmpdir, test_client_factory): statics_path = os.path.join(tmpdir, "statics") + statics_html_path = os.path.join(statics_path, "html") os.mkdir(statics_path) - symlink_path = os.path.join(tmpdir, "symlink") - os.mkdir(symlink_path) - - symlink_file_path = os.path.join(symlink_path, "index.html") - with open(symlink_file_path, "w") as file: + source_path = tempfile.mkdtemp() + source_file_path = os.path.join(source_path, "page.html") + with open(source_file_path, "w") as file: file.write("

Hello

") - statics_file_path = os.path.join(statics_path, "index.html") - os.symlink(symlink_file_path, statics_file_path) + os.symlink(source_path, statics_html_path) app = StaticFiles(directory=statics_path) client = test_client_factory(app) - response = client.get("/index.html") - assert response.url == "http://testserver/index.html" + response = client.get("/html/page.html") + assert response.url == "http://testserver/html/page.html" assert response.status_code == 200 assert response.text == "

Hello

" def test_staticfiles_disallows_path_traversal_with_symlinks(tmpdir): statics_path = os.path.join(tmpdir, "statics") - os.mkdir(statics_path) - symlink_path = os.path.join(tmpdir, "symlink") - os.mkdir(symlink_path) + root_source_path = tempfile.mkdtemp() + source_path = os.path.join(root_source_path, "statics") + os.mkdir(source_path) - symlink_file_path = os.path.join(symlink_path, "index.html") - with open(symlink_file_path, "w") as file: + source_file_path = os.path.join(root_source_path, "index.html") + with open(source_file_path, "w") as file: file.write("

Hello

") - temp_path = os.path.join(tmpdir, "index.html") - os.symlink(symlink_file_path, temp_path) + os.symlink(source_path, statics_path) app = StaticFiles(directory=statics_path) # We can't test this with 'requests', so we test the app directly here.