Files
romm/backend/tests/handler/filesystem/test_assets_handler.py
2025-09-04 11:17:00 -03:00

329 lines
10 KiB
Python

import os
from pathlib import Path
from unittest.mock import Mock
import pytest
from handler.filesystem.assets_handler import ASSETS_BASE_PATH, FSAssetsHandler
from models.user import User
class TestFSAssetsHandler:
"""Test suite for FSAssetsHandler class"""
@pytest.fixture
def handler(self):
return FSAssetsHandler()
def test_init_uses_assets_base_path(self, handler: FSAssetsHandler):
"""Test that FSAssetsHandler initializes with ASSETS_BASE_PATH"""
assert handler.base_path == Path(ASSETS_BASE_PATH).resolve()
def test_user_folder_path(self, handler: FSAssetsHandler, editor_user: User):
"""Test user_folder_path method"""
result = handler.user_folder_path(editor_user)
expected = os.path.join("users", editor_user.fs_safe_folder_name)
assert result == expected
def test_build_avatar_path(self, handler: FSAssetsHandler, editor_user: User):
"""Test build_avatar_path method"""
result = handler.build_avatar_path(editor_user)
expected = os.path.join("users", editor_user.fs_safe_folder_name, "profile")
assert result == expected
def test_build_saves_file_path_without_emulator(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test build_saves_file_path method without emulator"""
platform_fs_slug = "n64"
rom_id = 456
result = handler.build_saves_file_path(
user=editor_user, platform_fs_slug=platform_fs_slug, rom_id=rom_id
)
expected = os.path.join(
"users",
editor_user.fs_safe_folder_name,
"saves",
platform_fs_slug,
str(rom_id),
)
assert result == expected
def test_build_saves_file_path_with_emulator(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test build_saves_file_path method with emulator"""
platform_fs_slug = "n64"
rom_id = 456
emulator = "mupen64plus"
result = handler.build_saves_file_path(
user=editor_user,
platform_fs_slug=platform_fs_slug,
rom_id=rom_id,
emulator=emulator,
)
expected = os.path.join(
"users",
editor_user.fs_safe_folder_name,
"saves",
platform_fs_slug,
str(rom_id),
emulator,
)
assert result == expected
def test_build_states_file_path_without_emulator(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test build_states_file_path method without emulator"""
platform_fs_slug = "snes"
rom_id = 789
result = handler.build_states_file_path(
user=editor_user, platform_fs_slug=platform_fs_slug, rom_id=rom_id
)
expected = os.path.join(
"users",
editor_user.fs_safe_folder_name,
"states",
platform_fs_slug,
str(rom_id),
)
assert result == expected
def test_build_states_file_path_with_emulator(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test build_states_file_path method with emulator"""
platform_fs_slug = "snes"
rom_id = 789
emulator = "snes9x"
result = handler.build_states_file_path(
user=editor_user,
platform_fs_slug=platform_fs_slug,
rom_id=rom_id,
emulator=emulator,
)
expected = os.path.join(
"users",
editor_user.fs_safe_folder_name,
"states",
platform_fs_slug,
str(rom_id),
emulator,
)
assert result == expected
def test_build_screenshots_file_path(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test build_screenshots_file_path method"""
platform_fs_slug = "psx"
rom_id = 101
result = handler.build_screenshots_file_path(
user=editor_user, platform_fs_slug=platform_fs_slug, rom_id=rom_id
)
expected = os.path.join(
"users",
editor_user.fs_safe_folder_name,
"screenshots",
platform_fs_slug,
str(rom_id),
)
assert result == expected
def test_build_asset_file_path_internal_method(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test _build_asset_file_path internal method"""
folder = "custom_folder"
platform_fs_slug = "gba"
rom_id = 999
emulator = "mgba"
result = handler._build_asset_file_path(
user=editor_user,
folder=folder,
platform_fs_slug=platform_fs_slug,
rom_id=rom_id,
emulator=emulator,
)
expected = os.path.join(
"users",
editor_user.fs_safe_folder_name,
folder,
platform_fs_slug,
str(rom_id),
emulator,
)
assert result == expected
def test_build_asset_file_path_without_emulator(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test _build_asset_file_path internal method without emulator"""
folder = "custom_folder"
platform_fs_slug = "gba"
rom_id = 999
result = handler._build_asset_file_path(
user=editor_user,
folder=folder,
platform_fs_slug=platform_fs_slug,
rom_id=rom_id,
)
expected = os.path.join(
"users",
editor_user.fs_safe_folder_name,
folder,
platform_fs_slug,
str(rom_id),
)
assert result == expected
def test_integration_with_real_user_fixture(
self, handler: FSAssetsHandler, admin_user: User
):
"""Test integration with real user fixture from the project"""
platform_fs_slug = "n64"
rom_id = 123
emulator = "mupen64plus"
# Test saves path
saves_path = handler.build_saves_file_path(
user=admin_user,
platform_fs_slug=platform_fs_slug,
rom_id=rom_id,
emulator=emulator,
)
assert saves_path.startswith("users/")
assert platform_fs_slug in saves_path
assert str(rom_id) in saves_path
assert emulator in saves_path
# Test states path
states_path = handler.build_states_file_path(
user=admin_user,
platform_fs_slug=platform_fs_slug,
rom_id=rom_id,
emulator=emulator,
)
assert states_path.startswith("users/")
assert platform_fs_slug in states_path
assert str(rom_id) in states_path
assert emulator in states_path
# Test screenshots path
screenshots_path = handler.build_screenshots_file_path(
user=admin_user, platform_fs_slug=platform_fs_slug, rom_id=rom_id
)
assert screenshots_path.startswith("users/")
assert platform_fs_slug in screenshots_path
assert str(rom_id) in screenshots_path
# Test avatar path
avatar_path = handler.build_avatar_path(admin_user)
assert avatar_path.startswith("users/")
assert "profile" in avatar_path
def test_paths_are_relative_to_base_path(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test that all generated paths are relative to the base path"""
platform_fs_slug = "ps1"
rom_id = 555
emulator = "duckstation"
# Test various path methods
paths = [
handler.user_folder_path(editor_user),
handler.build_avatar_path(editor_user),
handler.build_saves_file_path(editor_user, platform_fs_slug, rom_id),
handler.build_saves_file_path(
editor_user, platform_fs_slug, rom_id, emulator
),
handler.build_states_file_path(editor_user, platform_fs_slug, rom_id),
handler.build_states_file_path(
editor_user, platform_fs_slug, rom_id, emulator
),
handler.build_screenshots_file_path(editor_user, platform_fs_slug, rom_id),
]
for path in paths:
# Ensure paths are relative (don't start with /)
assert not os.path.isabs(path), f"Path should be relative: {path}"
# Ensure paths can be resolved within the base path
full_path = handler.validate_path(path)
assert full_path.is_relative_to(handler.base_path)
def test_different_users_have_different_paths(self, handler: FSAssetsHandler):
"""Test that different users get different folder paths"""
user1 = Mock(spec=User)
user1.id = 1
user1.fs_safe_folder_name = "User:1".encode().hex()
user2 = Mock(spec=User)
user2.id = 2
user2.fs_safe_folder_name = "User:2".encode().hex()
path1 = handler.user_folder_path(user1)
path2 = handler.user_folder_path(user2)
assert path1 != path2
assert user1.fs_safe_folder_name in path1
assert user2.fs_safe_folder_name in path2
def test_rom_id_conversion_to_string(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test that rom_id is properly converted to string in paths"""
platform_fs_slug = "dc"
rom_id = 12345
saves_path = handler.build_saves_file_path(
user=editor_user, platform_fs_slug=platform_fs_slug, rom_id=rom_id
)
assert str(rom_id) in saves_path
assert saves_path.endswith(str(rom_id))
def test_emulator_parameter_handling(
self, handler: FSAssetsHandler, editor_user: User
):
"""Test that emulator parameter is handled consistently"""
platform_fs_slug = "ps2"
rom_id = 777
emulator = "pcsx2"
# Test with emulator
saves_with_emulator = handler.build_saves_file_path(
user=editor_user,
platform_fs_slug=platform_fs_slug,
rom_id=rom_id,
emulator=emulator,
)
# Test without emulator
saves_without_emulator = handler.build_saves_file_path(
user=editor_user, platform_fs_slug=platform_fs_slug, rom_id=rom_id
)
assert emulator in saves_with_emulator
assert emulator not in saves_without_emulator
assert saves_with_emulator.startswith(saves_without_emulator)