mirror of
https://github.com/rommapp/romm.git
synced 2026-02-18 23:42:07 +01:00
396 lines
16 KiB
Python
396 lines
16 KiB
Python
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from config.config_manager import LIBRARY_BASE_PATH, Config
|
|
from handler.filesystem.platforms_handler import FSPlatformsHandler, LibraryStructure
|
|
|
|
|
|
class TestFSPlatformsHandler:
|
|
"""Test suite for FSPlatformsHandler class"""
|
|
|
|
@pytest.fixture
|
|
def handler(self):
|
|
return FSPlatformsHandler()
|
|
|
|
@pytest.fixture
|
|
def config(self):
|
|
return Config(
|
|
EXCLUDED_PLATFORMS=["romm", "excluded_platform"],
|
|
EXCLUDED_SINGLE_EXT=["tmp"],
|
|
EXCLUDED_SINGLE_FILES=[],
|
|
EXCLUDED_MULTI_FILES=[],
|
|
EXCLUDED_MULTI_PARTS_EXT=[],
|
|
EXCLUDED_MULTI_PARTS_FILES=[],
|
|
PLATFORMS_BINDING={},
|
|
PLATFORMS_VERSIONS={},
|
|
ROMS_FOLDER_NAME="roms",
|
|
FIRMWARE_FOLDER_NAME="bios",
|
|
)
|
|
|
|
@pytest.fixture
|
|
def config_custom_folder(self):
|
|
return Config(
|
|
EXCLUDED_PLATFORMS=[],
|
|
EXCLUDED_SINGLE_EXT=[],
|
|
EXCLUDED_SINGLE_FILES=[],
|
|
EXCLUDED_MULTI_FILES=[],
|
|
EXCLUDED_MULTI_PARTS_EXT=[],
|
|
EXCLUDED_MULTI_PARTS_FILES=[],
|
|
PLATFORMS_BINDING={},
|
|
PLATFORMS_VERSIONS={},
|
|
ROMS_FOLDER_NAME="ROMS",
|
|
FIRMWARE_FOLDER_NAME="BIOS",
|
|
)
|
|
|
|
def test_init_uses_library_base_path(self, handler: FSPlatformsHandler):
|
|
"""Test that FSPlatformsHandler initializes with LIBRARY_BASE_PATH"""
|
|
assert handler.base_path == Path(LIBRARY_BASE_PATH).resolve()
|
|
|
|
def test_exclude_platforms_filters_excluded_platforms(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test that _exclude_platforms filters out excluded platforms"""
|
|
platforms = ["n64", "psx", "romm", "excluded_platform", "gba"]
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
result = handler._exclude_platforms(platforms)
|
|
|
|
assert "n64" in result
|
|
assert "psx" in result
|
|
assert "gba" in result
|
|
assert "romm" not in result
|
|
assert "excluded_platform" not in result
|
|
|
|
def test_exclude_platforms_empty_list(self, handler: FSPlatformsHandler, config):
|
|
"""Test that _exclude_platforms handles empty list"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
result = handler._exclude_platforms([])
|
|
assert result == []
|
|
|
|
def test_exclude_platforms_no_excluded_config(
|
|
self, handler: FSPlatformsHandler, config_custom_folder
|
|
):
|
|
"""Test that _exclude_platforms works when no platforms are excluded"""
|
|
platforms = ["n64", "psx", "gba"]
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config",
|
|
return_value=config_custom_folder,
|
|
):
|
|
result = handler._exclude_platforms(platforms)
|
|
assert result == platforms
|
|
|
|
def test_get_platforms_directory_high_priority_structure(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test get_platforms_directory with high priority structure"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists", return_value=True):
|
|
result = handler.get_platforms_directory()
|
|
assert result == config.ROMS_FOLDER_NAME
|
|
|
|
def test_get_platforms_directory_normal_structure(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test get_platforms_directory with normal structure"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists", return_value=False):
|
|
result = handler.get_platforms_directory()
|
|
assert result == ""
|
|
|
|
def test_get_platform_fs_structure_high_priority(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test get_platform_fs_structure with high priority structure"""
|
|
fs_slug = "n64"
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists", return_value=True):
|
|
result = handler.get_platform_fs_structure(fs_slug)
|
|
assert result == f"{config.ROMS_FOLDER_NAME}/{fs_slug}"
|
|
|
|
def test_get_platform_fs_structure_normal_structure(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test get_platform_fs_structure with normal structure"""
|
|
fs_slug = "n64"
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
result = handler.get_platform_fs_structure(fs_slug)
|
|
assert result == f"{fs_slug}/{config.ROMS_FOLDER_NAME}"
|
|
|
|
def test_get_platform_fs_structure_custom_folder_name(
|
|
self, handler: FSPlatformsHandler, config_custom_folder
|
|
):
|
|
"""Test get_platform_fs_structure with custom folder name"""
|
|
fs_slug = "psx"
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config",
|
|
return_value=config_custom_folder,
|
|
):
|
|
result = handler.get_platform_fs_structure(fs_slug)
|
|
assert result == f"{fs_slug}/{config_custom_folder.ROMS_FOLDER_NAME}"
|
|
|
|
async def test_add_platform_creates_directory(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test that add_platform creates the correct directory"""
|
|
fs_slug = "gba"
|
|
expected_path = f"{config.ROMS_FOLDER_NAME}/{fs_slug}"
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists", return_value=True):
|
|
with patch.object(handler, "make_directory") as mock_make_directory:
|
|
await handler.add_platform(fs_slug)
|
|
mock_make_directory.assert_called_once_with(expected_path)
|
|
|
|
async def test_add_platform_normal_structure(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test that add_platform creates directory with normal structure"""
|
|
fs_slug = "gba"
|
|
expected_path = f"{fs_slug}/{config.ROMS_FOLDER_NAME}"
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists", return_value=False):
|
|
with patch.object(handler, "make_directory") as mock_make_directory:
|
|
await handler.add_platform(fs_slug)
|
|
mock_make_directory.assert_called_once_with(expected_path)
|
|
|
|
async def test_get_platforms_returns_existing_platforms(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test that get_platforms returns existing platforms"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
result = await handler.get_platforms()
|
|
assert "n64" in result
|
|
assert "psx" in result
|
|
|
|
async def test_get_platforms_excludes_excluded_platforms(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test that get_platforms excludes excluded platforms"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
config.EXCLUDED_PLATFORMS = ["psx"]
|
|
result = await handler.get_platforms()
|
|
|
|
assert "n64" in result
|
|
assert "psx" not in result
|
|
|
|
async def test_get_platforms_calls_list_directories_with_correct_path(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test that get_platforms calls list_directories with correct path"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists", return_value=True):
|
|
with patch.object(
|
|
handler, "list_directories", return_value=[]
|
|
) as mock_list:
|
|
await handler.get_platforms()
|
|
mock_list.assert_called_once_with(path=config.ROMS_FOLDER_NAME)
|
|
|
|
async def test_get_platforms_calls_list_directories_with_empty_path(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test that get_platforms calls list_directories with empty path for normal structure"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch.object(
|
|
handler, "list_directories", return_value=[]
|
|
) as mock_list:
|
|
await handler.get_platforms()
|
|
mock_list.assert_called_once_with(path="")
|
|
|
|
def test_integration_with_base_handler_methods(self, handler: FSPlatformsHandler):
|
|
"""Test that FSPlatformsHandler properly inherits from FSHandler"""
|
|
# Test that handler has base methods
|
|
assert hasattr(handler, "validate_path")
|
|
assert hasattr(handler, "list_directories")
|
|
assert hasattr(handler, "make_directory")
|
|
assert hasattr(handler, "file_exists")
|
|
assert hasattr(handler, "move_file_or_folder")
|
|
assert hasattr(handler, "stream_file")
|
|
|
|
def test_platform_slug_handling_with_special_characters(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test that platform slugs with special characters are handled correctly"""
|
|
fs_slug = "n64"
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
result = handler.get_platform_fs_structure(fs_slug)
|
|
assert result == f"{fs_slug}/{config.ROMS_FOLDER_NAME}"
|
|
|
|
async def test_path_construction_consistency(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test that path construction is consistent across methods"""
|
|
fs_slug = "ps2"
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
# Test both methods return consistent paths
|
|
structure_path = handler.get_platform_fs_structure(fs_slug)
|
|
|
|
with patch.object(handler, "make_directory") as mock_make_directory:
|
|
await handler.add_platform(fs_slug)
|
|
mock_make_directory.assert_called_once_with(structure_path)
|
|
|
|
def test_actual_directory_operations(self, handler: FSPlatformsHandler, config):
|
|
"""Test operations with actual directory structure"""
|
|
# Test with existing platforms
|
|
existing_platforms = ["n64", "psx"]
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
for platform in existing_platforms:
|
|
expected_path = f"{platform}/{config.ROMS_FOLDER_NAME}"
|
|
result = handler.get_platform_fs_structure(platform)
|
|
assert result == expected_path
|
|
|
|
async def test_edge_cases_and_error_handling(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test edge cases and error handling"""
|
|
# Test with empty platform slug
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
result = handler.get_platform_fs_structure("")
|
|
assert result == f"/{config.ROMS_FOLDER_NAME}"
|
|
|
|
# Test adding empty platform
|
|
with patch.object(handler, "make_directory") as mock_make_directory:
|
|
await handler.add_platform("")
|
|
mock_make_directory.assert_called_once_with(
|
|
f"/{config.ROMS_FOLDER_NAME}"
|
|
)
|
|
|
|
def test_multiple_platforms_handling(self, handler: FSPlatformsHandler, config):
|
|
"""Test handling multiple platforms simultaneously"""
|
|
platforms = ["n64", "psx", "gba", "romm", "excluded_platform"]
|
|
expected_filtered = ["n64", "psx", "gba"]
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
filtered = handler._exclude_platforms(platforms)
|
|
assert set(filtered) == set(expected_filtered)
|
|
|
|
# Test that each platform gets correct structure
|
|
for platform in expected_filtered:
|
|
structure = handler.get_platform_fs_structure(platform)
|
|
assert structure == f"{platform}/{config.ROMS_FOLDER_NAME}"
|
|
|
|
def test_detect_library_structure_structure_a(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test detect_library_structure detects Structure A (roms/{platform})"""
|
|
roms_path = f"{LIBRARY_BASE_PATH}/{config.ROMS_FOLDER_NAME}"
|
|
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists") as mock_exists:
|
|
mock_exists.return_value = True
|
|
|
|
result = handler.detect_library_structure()
|
|
assert result == LibraryStructure.A
|
|
mock_exists.assert_called_once_with(roms_path)
|
|
|
|
def test_detect_library_structure_structure_b(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test detect_library_structure detects Structure B ({platform}/roms)"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists") as mock_exists:
|
|
# ROMs folder doesn't exist at base level
|
|
mock_exists.return_value = False
|
|
|
|
with patch("os.listdir") as mock_listdir:
|
|
mock_listdir.return_value = ["n64", "psx", "other_folder"]
|
|
|
|
with patch("os.path.isdir") as mock_isdir:
|
|
# n64 and psx are directories with roms subfolders
|
|
def isdir_side_effect(path):
|
|
return "n64" in path or "psx" in path
|
|
|
|
def exists_side_effect(path):
|
|
# n64/roms and psx/roms exist
|
|
return (
|
|
f"n64/{config.ROMS_FOLDER_NAME}" in path
|
|
or f"psx/{config.ROMS_FOLDER_NAME}" in path
|
|
)
|
|
|
|
mock_isdir.side_effect = isdir_side_effect
|
|
mock_exists.side_effect = exists_side_effect
|
|
|
|
result = handler.detect_library_structure()
|
|
assert result == LibraryStructure.B
|
|
|
|
def test_detect_library_structure_none(self, handler: FSPlatformsHandler, config):
|
|
"""Test detect_library_structure returns None when no structure detected"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists", return_value=False):
|
|
with patch("os.listdir", return_value=[]):
|
|
result = handler.detect_library_structure()
|
|
assert result is None
|
|
|
|
def test_detect_library_structure_handles_os_errors(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test detect_library_structure handles OS errors gracefully"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists", return_value=False):
|
|
with patch("os.listdir", side_effect=OSError("Permission denied")):
|
|
result = handler.detect_library_structure()
|
|
assert result is None
|
|
|
|
def test_detect_library_structure_empty_library(
|
|
self, handler: FSPlatformsHandler, config
|
|
):
|
|
"""Test detect_library_structure with empty library directory"""
|
|
with patch(
|
|
"handler.filesystem.platforms_handler.cm.get_config", return_value=config
|
|
):
|
|
with patch("os.path.exists", return_value=False):
|
|
with patch("os.listdir", return_value=[]):
|
|
result = handler.detect_library_structure()
|
|
assert result is None
|