You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.9 KiB

"""Tests for mounting StaticFiles under APIRouter (issue #10180)."""
from pathlib import Path
import pytest
from fastapi import APIRouter, FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.testclient import TestClient
def test_mount_staticfiles_under_router_with_prefix(tmp_path: Path) -> None:
"""StaticFiles mounted on APIRouter with prefix should be accessible."""
static_file = tmp_path / "hello.txt"
static_file.write_text("hello world")
app = FastAPI()
api_router = APIRouter(prefix="/api")
@api_router.get("/app")
def read_main() -> dict:
return {"message": "Hello World from main app"}
api_router.mount("/static", StaticFiles(directory=tmp_path), name="static")
app.include_router(api_router)
client = TestClient(app)
# Regular route should still work
r = client.get("/api/app")
assert r.status_code == 200
# StaticFiles should be accessible under router prefix
r = client.get("/api/static/hello.txt")
assert r.status_code == 200
assert r.text == "hello world"
def test_mount_staticfiles_under_router_without_prefix(tmp_path: Path) -> None:
"""StaticFiles mounted on APIRouter without prefix should be accessible."""
static_file = tmp_path / "test.txt"
static_file.write_text("test content")
app = FastAPI()
router = APIRouter()
router.mount("/static", StaticFiles(directory=tmp_path), name="static")
app.include_router(router)
client = TestClient(app)
r = client.get("/static/test.txt")
assert r.status_code == 200
assert r.text == "test content"
def test_mount_staticfiles_with_include_router_prefix(tmp_path: Path) -> None:
"""include_router prefix + router prefix + mount path should all combine."""
static_file = tmp_path / "file.txt"
static_file.write_text("combined prefix")
app = FastAPI()
router = APIRouter(prefix="/api")
router.mount("/static", StaticFiles(directory=tmp_path), name="static")
app.include_router(router, prefix="/v1")
client = TestClient(app)
r = client.get("/v1/api/static/file.txt")
assert r.status_code == 200
assert r.text == "combined prefix"
def test_mount_non_staticfiles_app_is_ignored() -> None:
"""Mounting a non-StaticFiles ASGI app on APIRouter should be silently ignored
(not propagated to the main app) to preserve existing behavior."""
app = FastAPI()
api_router = APIRouter(prefix="/api")
subapi = FastAPI()
@subapi.get("/sub")
def read_sub() -> dict:
return {"message": "sub"}
api_router.mount("/subapi", subapi)
app.include_router(api_router)
client = TestClient(app)
# Non-StaticFiles sub-app mount is not propagated — returns 404
r = client.get("/api/subapi/sub")
assert r.status_code == 404
# Regular routes are unaffected
# (no routes defined here, but include_router itself should not crash)
assert app is not None