mirror of
https://github.com/rommapp/romm.git
synced 2026-06-27 22:35:57 +00:00
Merge pull request #3473 from Spinnich/fix/rom-content-404-on-stale-file-ids
fix(roms): return 404 when content file_ids match no files
This commit is contained in:
@@ -868,6 +868,12 @@ async def head_rom_content(
|
||||
files = [f for f in files if f.id in file_id_values]
|
||||
files.sort(key=lambda x: x.file_name)
|
||||
|
||||
if not files:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"No files found for ROM {id}",
|
||||
)
|
||||
|
||||
# Serve the file directly in development mode for emulatorjs
|
||||
if DEV_MODE:
|
||||
if len(files) == 1:
|
||||
@@ -945,6 +951,12 @@ async def get_rom_content(
|
||||
files = [f for f in files if f.id in file_id_values]
|
||||
files.sort(key=lambda x: x.file_name)
|
||||
|
||||
if not files:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"No files found for ROM {id}",
|
||||
)
|
||||
|
||||
log.info(
|
||||
f"User {hl(current_username, color=BLUE)} is downloading {hl(rom.fs_name)}"
|
||||
)
|
||||
|
||||
@@ -89,6 +89,18 @@ def rom(admin_user: User, platform: Platform):
|
||||
return rom
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rom_file(rom: Rom):
|
||||
"""A single content file attached to the `rom` fixture."""
|
||||
rom_file = RomFile(
|
||||
rom_id=rom.id,
|
||||
file_name="test_rom.zip",
|
||||
file_path=rom.fs_path,
|
||||
file_size_bytes=1000,
|
||||
)
|
||||
return db_rom_handler.add_rom_file(rom_file)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def multi_file_rom(admin_user: User, platform: Platform):
|
||||
"""A ROM stored as a game folder with multiple files (e.g. multi-disc).
|
||||
|
||||
@@ -82,6 +82,62 @@ def test_get_all_roms(
|
||||
assert items[0]["id"] == rom.id
|
||||
|
||||
|
||||
def test_get_rom_content_requires_auth(client: TestClient, rom: Rom, rom_file):
|
||||
response = client.get(f"/api/roms/{rom.id}/content/test_rom.zip")
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
|
||||
|
||||
def test_get_rom_content_single_file(
|
||||
client: TestClient, access_token: str, rom: Rom, rom_file
|
||||
):
|
||||
response = client.get(
|
||||
f"/api/roms/{rom.id}/content/test_rom.zip",
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
follow_redirects=False,
|
||||
)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
# Single-file roms are proxied through nginx via X-Accel-Redirect.
|
||||
assert "X-Accel-Redirect" in response.headers
|
||||
|
||||
|
||||
def test_get_rom_content_valid_file_id(
|
||||
client: TestClient, access_token: str, rom: Rom, rom_file
|
||||
):
|
||||
response = client.get(
|
||||
f"/api/roms/{rom.id}/content/test_rom.zip",
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
params={"file_ids": str(rom_file.id)},
|
||||
follow_redirects=False,
|
||||
)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert "X-Accel-Redirect" in response.headers
|
||||
|
||||
|
||||
def test_get_rom_content_stale_file_id_returns_404(
|
||||
client: TestClient, access_token: str, rom: Rom, rom_file
|
||||
):
|
||||
# Regression test for #3470: a remembered file id that no longer exists
|
||||
# (e.g. after a rename gave the file a new id) must return a clean 404
|
||||
# instead of an empty-.m3u ZIP that nginx aborts as a 0-byte response.
|
||||
stale_file_id = rom_file.id + 999
|
||||
response = client.get(
|
||||
f"/api/roms/{rom.id}/content/test_rom.zip",
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
params={"file_ids": str(stale_file_id)},
|
||||
follow_redirects=False,
|
||||
)
|
||||
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||
|
||||
|
||||
def test_get_rom_content_missing_rom_returns_404(client: TestClient, access_token: str):
|
||||
response = client.get(
|
||||
"/api/roms/999999/content/missing.zip",
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
follow_redirects=False,
|
||||
)
|
||||
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||
|
||||
|
||||
@patch.object(FSRomsHandler, "rename_fs_rom")
|
||||
@patch.object(IGDBHandler, "get_rom_by_id", return_value=IGDBRom(igdb_id=None))
|
||||
def test_update_rom(
|
||||
|
||||
Reference in New Issue
Block a user