mirror of
https://github.com/rommapp/romm.git
synced 2026-06-28 14:56:01 +00:00
make the tests real
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
from unittest.mock import Mock, patch
|
||||
from pathlib import Path
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
from handler.filesystem.assets_handler import FSAssetsHandler
|
||||
from handler.filesystem.assets_handler import ASSETS_BASE_PATH, FSAssetsHandler
|
||||
from models.user import User
|
||||
|
||||
|
||||
@@ -12,40 +11,28 @@ class TestFSAssetsHandler:
|
||||
"""Test suite for FSAssetsHandler class"""
|
||||
|
||||
@pytest.fixture
|
||||
def temp_dir(self):
|
||||
"""Create a temporary directory for testing"""
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
yield temp_dir
|
||||
shutil.rmtree(temp_dir, ignore_errors=True)
|
||||
def handler(self):
|
||||
return FSAssetsHandler()
|
||||
|
||||
@pytest.fixture
|
||||
def handler(self, temp_dir):
|
||||
"""Create FSAssetsHandler instance for testing"""
|
||||
with patch("handler.filesystem.assets_handler.ASSETS_BASE_PATH", temp_dir):
|
||||
return FSAssetsHandler()
|
||||
|
||||
def test_init_uses_assets_base_path(self, temp_dir):
|
||||
def test_init_uses_assets_base_path(self, handler: FSAssetsHandler):
|
||||
"""Test that FSAssetsHandler initializes with ASSETS_BASE_PATH"""
|
||||
from pathlib import Path
|
||||
assert handler.base_path == Path(ASSETS_BASE_PATH).resolve()
|
||||
|
||||
with patch("handler.filesystem.assets_handler.ASSETS_BASE_PATH", temp_dir):
|
||||
handler = FSAssetsHandler()
|
||||
# Use resolve() to handle macOS path resolution consistently
|
||||
assert handler.base_path == Path(temp_dir).resolve()
|
||||
|
||||
def test_user_folder_path(self, handler, editor_user):
|
||||
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, editor_user):
|
||||
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, editor_user):
|
||||
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
|
||||
@@ -63,7 +50,9 @@ class TestFSAssetsHandler:
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
def test_build_saves_file_path_with_emulator(self, handler, editor_user):
|
||||
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
|
||||
@@ -86,7 +75,9 @@ class TestFSAssetsHandler:
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
def test_build_states_file_path_without_emulator(self, handler, editor_user):
|
||||
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
|
||||
@@ -104,7 +95,9 @@ class TestFSAssetsHandler:
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
def test_build_states_file_path_with_emulator(self, handler, editor_user):
|
||||
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
|
||||
@@ -127,7 +120,9 @@ class TestFSAssetsHandler:
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
def test_build_screenshots_file_path(self, handler, editor_user):
|
||||
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
|
||||
@@ -145,7 +140,9 @@ class TestFSAssetsHandler:
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
def test_build_asset_file_path_internal_method(self, handler, editor_user):
|
||||
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"
|
||||
@@ -170,7 +167,9 @@ class TestFSAssetsHandler:
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
def test_build_asset_file_path_without_emulator(self, handler, editor_user):
|
||||
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"
|
||||
@@ -192,7 +191,9 @@ class TestFSAssetsHandler:
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
def test_integration_with_real_user_fixture(self, handler, admin_user):
|
||||
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
|
||||
@@ -238,7 +239,9 @@ class TestFSAssetsHandler:
|
||||
assert avatar_path.startswith("users/")
|
||||
assert "profile" in avatar_path
|
||||
|
||||
def test_paths_are_relative_to_base_path(self, handler, editor_user):
|
||||
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
|
||||
@@ -267,7 +270,7 @@ class TestFSAssetsHandler:
|
||||
full_path = handler.validate_path(path)
|
||||
assert full_path.is_relative_to(handler.base_path)
|
||||
|
||||
def test_different_users_have_different_paths(self, handler):
|
||||
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
|
||||
@@ -284,7 +287,9 @@ class TestFSAssetsHandler:
|
||||
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, editor_user):
|
||||
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
|
||||
@@ -296,7 +301,9 @@ class TestFSAssetsHandler:
|
||||
assert str(rom_id) in saves_path
|
||||
assert saves_path.endswith(str(rom_id))
|
||||
|
||||
def test_emulator_parameter_handling(self, handler, editor_user):
|
||||
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
|
||||
|
||||
@@ -1,35 +1,26 @@
|
||||
import binascii
|
||||
import hashlib
|
||||
import shutil
|
||||
import tempfile
|
||||
from unittest.mock import Mock, patch
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from config.config_manager import Config
|
||||
from exceptions.fs_exceptions import FirmwareAlreadyExistsException
|
||||
from config.config_manager import LIBRARY_BASE_PATH, Config
|
||||
from handler.filesystem.firmware_handler import FSFirmwareHandler
|
||||
from utils.hashing import crc32_to_hex
|
||||
|
||||
|
||||
class TestFSFirmwareHandler:
|
||||
"""Test suite for FSFirmwareHandler class"""
|
||||
|
||||
@pytest.fixture
|
||||
def temp_dir(self):
|
||||
"""Create a temporary directory for testing"""
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
yield temp_dir
|
||||
shutil.rmtree(temp_dir, ignore_errors=True)
|
||||
|
||||
@pytest.fixture
|
||||
def handler(self, temp_dir):
|
||||
"""Create FSFirmwareHandler instance for testing"""
|
||||
with patch("handler.filesystem.firmware_handler.LIBRARY_BASE_PATH", temp_dir):
|
||||
return FSFirmwareHandler()
|
||||
def handler(self):
|
||||
return FSFirmwareHandler()
|
||||
|
||||
@pytest.fixture
|
||||
def config(self):
|
||||
return Config(
|
||||
EXCLUDED_PLATFORMS=[],
|
||||
EXCLUDED_SINGLE_EXT=[],
|
||||
EXCLUDED_SINGLE_EXT=["tmp"],
|
||||
EXCLUDED_SINGLE_FILES=[],
|
||||
EXCLUDED_MULTI_FILES=[],
|
||||
EXCLUDED_MULTI_PARTS_EXT=[],
|
||||
@@ -40,196 +31,99 @@ class TestFSFirmwareHandler:
|
||||
FIRMWARE_FOLDER_NAME="bios",
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def sample_firmware_content(self):
|
||||
"""Sample firmware content for testing"""
|
||||
return b"This is test firmware content for hashing and file operations"
|
||||
|
||||
def test_init_uses_library_base_path(self, temp_dir):
|
||||
def test_init_uses_library_base_path(self, handler: FSFirmwareHandler):
|
||||
"""Test that FSFirmwareHandler initializes with LIBRARY_BASE_PATH"""
|
||||
from pathlib import Path
|
||||
assert handler.base_path == Path(LIBRARY_BASE_PATH).resolve()
|
||||
|
||||
with patch("handler.filesystem.firmware_handler.LIBRARY_BASE_PATH", temp_dir):
|
||||
handler = FSFirmwareHandler()
|
||||
assert handler.base_path == Path(temp_dir).resolve()
|
||||
|
||||
def test_get_firmware_fs_structure_high_prio_exists(self, handler, config):
|
||||
"""Test get_firmware_fs_structure when high priority structure exists"""
|
||||
fs_slug = "ps2"
|
||||
|
||||
with patch(
|
||||
"handler.filesystem.firmware_handler.cm.get_config", return_value=config
|
||||
):
|
||||
with patch("os.path.exists", return_value=True):
|
||||
result = handler.get_firmware_fs_structure(fs_slug)
|
||||
expected = f"{config.FIRMWARE_FOLDER_NAME}/{fs_slug}"
|
||||
assert result == expected
|
||||
|
||||
def test_get_firmware_fs_structure_high_prio_not_exists(self, handler, config):
|
||||
"""Test get_firmware_fs_structure when high priority structure doesn't exist"""
|
||||
fs_slug = "ps2"
|
||||
|
||||
with patch(
|
||||
"handler.filesystem.firmware_handler.cm.get_config", return_value=config
|
||||
):
|
||||
with patch("os.path.exists", return_value=False):
|
||||
result = handler.get_firmware_fs_structure(fs_slug)
|
||||
expected = f"{fs_slug}/{config.FIRMWARE_FOLDER_NAME}"
|
||||
assert result == expected
|
||||
|
||||
def test_get_firmware_success(self, handler, config):
|
||||
"""Test get_firmware method with successful file listing"""
|
||||
def test_get_firmware(self, handler, config):
|
||||
"""Test get_firmware method"""
|
||||
platform_fs_slug = "n64"
|
||||
firmware_files = ["bios1.bin", "bios2.bin", "excluded.tmp"]
|
||||
filtered_files = ["bios1.bin", "bios2.bin"]
|
||||
|
||||
with patch(
|
||||
"handler.filesystem.firmware_handler.cm.get_config", return_value=config
|
||||
):
|
||||
with patch("os.path.exists", return_value=True):
|
||||
with patch.object(handler, "list_files", return_value=firmware_files):
|
||||
with patch.object(
|
||||
handler, "exclude_single_files", return_value=filtered_files
|
||||
):
|
||||
result = handler.get_firmware(platform_fs_slug)
|
||||
assert result == filtered_files
|
||||
result = handler.get_firmware(platform_fs_slug)
|
||||
assert "bios1.bin" in result
|
||||
assert "bios2.bin" in result
|
||||
assert "temp.tmp" not in result
|
||||
|
||||
def test_get_firmware_calls_correct_methods(self, handler, config):
|
||||
"""Test that get_firmware calls the correct methods in sequence"""
|
||||
platform_fs_slug = "psx"
|
||||
firmware_files = ["bios.bin"]
|
||||
|
||||
with patch(
|
||||
"handler.filesystem.firmware_handler.cm.get_config", return_value=config
|
||||
):
|
||||
with patch("os.path.exists", return_value=True):
|
||||
with patch.object(
|
||||
handler, "list_files", return_value=firmware_files
|
||||
) as mock_list:
|
||||
with patch.object(
|
||||
handler, "exclude_single_files", return_value=firmware_files
|
||||
) as mock_exclude:
|
||||
result = handler.get_firmware(platform_fs_slug)
|
||||
result = handler.get_firmware(platform_fs_slug)
|
||||
assert "scph1001.bin" in result
|
||||
|
||||
# Verify the correct path was used
|
||||
expected_path = (
|
||||
f"{config.FIRMWARE_FOLDER_NAME}/{platform_fs_slug}"
|
||||
)
|
||||
mock_list.assert_called_once_with(path=expected_path)
|
||||
mock_exclude.assert_called_once_with(firmware_files)
|
||||
assert result == firmware_files
|
||||
def test_get_firmware_nonexistent_platform(self, handler, config):
|
||||
"""Test get_firmware method with nonexistent platform"""
|
||||
platform_fs_slug = "nonexistent"
|
||||
|
||||
def test_calculate_file_hashes(self, handler, sample_firmware_content):
|
||||
"""Test calculate_file_hashes method"""
|
||||
firmware_path = "test_platform/bios"
|
||||
file_name = "test_bios.bin"
|
||||
with patch(
|
||||
"handler.filesystem.firmware_handler.cm.get_config", return_value=config
|
||||
):
|
||||
with pytest.raises(FileNotFoundError):
|
||||
handler.get_firmware(platform_fs_slug)
|
||||
|
||||
# Create a mock file stream that supports context manager protocol
|
||||
mock_stream = Mock()
|
||||
mock_stream.read.side_effect = [
|
||||
sample_firmware_content,
|
||||
b"",
|
||||
] # First read returns content, second returns empty
|
||||
mock_stream.__enter__ = Mock(return_value=mock_stream)
|
||||
mock_stream.__exit__ = Mock(return_value=None)
|
||||
def test_calculate_file_hashes(self, handler: FSFirmwareHandler):
|
||||
"""Test calculate_file_hashes method with actual file"""
|
||||
firmware_path = "n64/bios"
|
||||
file_name = "bios1.bin"
|
||||
|
||||
with patch.object(handler, "stream_file", return_value=mock_stream):
|
||||
result = handler.calculate_file_hashes(firmware_path, file_name)
|
||||
result = handler.calculate_file_hashes(firmware_path, file_name)
|
||||
|
||||
# Verify the structure of the result
|
||||
assert isinstance(result, dict)
|
||||
assert "crc_hash" in result
|
||||
assert "md5_hash" in result
|
||||
assert "sha1_hash" in result
|
||||
assert isinstance(result, dict)
|
||||
assert "crc_hash" in result
|
||||
assert "md5_hash" in result
|
||||
assert "sha1_hash" in result
|
||||
|
||||
# Verify hash values are strings
|
||||
assert isinstance(result["crc_hash"], str)
|
||||
assert isinstance(result["md5_hash"], str)
|
||||
assert isinstance(result["sha1_hash"], str)
|
||||
assert isinstance(result["crc_hash"], str)
|
||||
assert isinstance(result["md5_hash"], str)
|
||||
assert isinstance(result["sha1_hash"], str)
|
||||
|
||||
def test_calculate_file_hashes_actual_values(
|
||||
self, handler, sample_firmware_content
|
||||
):
|
||||
"""Test calculate_file_hashes with actual hash verification"""
|
||||
firmware_path = "test_platform/bios"
|
||||
file_name = "test_bios.bin"
|
||||
assert len(result["crc_hash"]) > 0
|
||||
assert len(result["md5_hash"]) > 0
|
||||
assert len(result["sha1_hash"]) > 0
|
||||
|
||||
# Calculate expected values
|
||||
import binascii
|
||||
file_path = handler.base_path / firmware_path / file_name
|
||||
with open(file_path, "rb") as f:
|
||||
content = f.read()
|
||||
|
||||
from utils.hashing import crc32_to_hex
|
||||
crc_expected = crc32_to_hex(binascii.crc32(content))
|
||||
md5_expected = hashlib.md5(content, usedforsecurity=False).hexdigest()
|
||||
sha1_expected = hashlib.sha1(content, usedforsecurity=False).hexdigest()
|
||||
|
||||
crc_expected = crc32_to_hex(binascii.crc32(sample_firmware_content))
|
||||
md5_expected = hashlib.md5(
|
||||
sample_firmware_content, usedforsecurity=False
|
||||
).hexdigest()
|
||||
sha1_expected = hashlib.sha1(
|
||||
sample_firmware_content, usedforsecurity=False
|
||||
).hexdigest()
|
||||
result = handler.calculate_file_hashes(firmware_path, file_name)
|
||||
|
||||
# Create a mock file stream that supports context manager protocol
|
||||
mock_stream = Mock()
|
||||
mock_stream.read.side_effect = [sample_firmware_content, b""]
|
||||
mock_stream.__enter__ = Mock(return_value=mock_stream)
|
||||
mock_stream.__exit__ = Mock(return_value=None)
|
||||
assert result["crc_hash"] == crc_expected
|
||||
assert result["md5_hash"] == md5_expected
|
||||
assert result["sha1_hash"] == sha1_expected
|
||||
|
||||
with patch.object(handler, "stream_file", return_value=mock_stream):
|
||||
result = handler.calculate_file_hashes(firmware_path, file_name)
|
||||
def test_calculate_file_hashes_different_files(self, handler: FSFirmwareHandler):
|
||||
"""Test calculate_file_hashes with different files have different hashes"""
|
||||
firmware_path = "n64/bios"
|
||||
|
||||
assert result["crc_hash"] == crc_expected
|
||||
assert result["md5_hash"] == md5_expected
|
||||
assert result["sha1_hash"] == sha1_expected
|
||||
result1 = handler.calculate_file_hashes(firmware_path, "bios1.bin")
|
||||
result2 = handler.calculate_file_hashes(firmware_path, "bios2.bin")
|
||||
|
||||
def test_calculate_file_hashes_chunked_reading(self, handler):
|
||||
"""Test calculate_file_hashes with chunked reading"""
|
||||
firmware_path = "test_platform/bios"
|
||||
file_name = "test_bios.bin"
|
||||
# Different files should have different hashes
|
||||
assert result1["crc_hash"] != result2["crc_hash"]
|
||||
assert result1["md5_hash"] != result2["md5_hash"]
|
||||
assert result1["sha1_hash"] != result2["sha1_hash"]
|
||||
|
||||
# Create test data larger than chunk size
|
||||
chunk1 = b"A" * 4096
|
||||
chunk2 = b"B" * 4096
|
||||
chunk3 = b"C" * 1000
|
||||
def test_calculate_file_hashes_nonexistent_file(self, handler: FSFirmwareHandler):
|
||||
"""Test calculate_file_hashes with nonexistent file"""
|
||||
firmware_path = "n64/bios"
|
||||
file_name = "nonexistent.bin"
|
||||
|
||||
# Create a mock file stream that returns chunks and supports context manager protocol
|
||||
mock_stream = Mock()
|
||||
mock_stream.read.side_effect = [chunk1, chunk2, chunk3, b""]
|
||||
mock_stream.__enter__ = Mock(return_value=mock_stream)
|
||||
mock_stream.__exit__ = Mock(return_value=None)
|
||||
|
||||
with patch.object(handler, "stream_file", return_value=mock_stream):
|
||||
result = handler.calculate_file_hashes(firmware_path, file_name)
|
||||
|
||||
# Verify that multiple reads were made
|
||||
assert mock_stream.read.call_count == 4
|
||||
|
||||
# Verify results are still strings
|
||||
assert isinstance(result["crc_hash"], str)
|
||||
assert isinstance(result["md5_hash"], str)
|
||||
assert isinstance(result["sha1_hash"], str)
|
||||
|
||||
def test_calculate_file_hashes_stream_file_called_correctly(self, handler):
|
||||
"""Test that calculate_file_hashes calls stream_file with correct parameters"""
|
||||
firmware_path = "test_platform/bios"
|
||||
file_name = "test_bios.bin"
|
||||
|
||||
mock_stream = Mock()
|
||||
mock_stream.read.side_effect = [b"test", b""]
|
||||
mock_stream.__enter__ = Mock(return_value=mock_stream)
|
||||
mock_stream.__exit__ = Mock(return_value=None)
|
||||
|
||||
with patch.object(
|
||||
handler, "stream_file", return_value=mock_stream
|
||||
) as mock_stream_method:
|
||||
with pytest.raises(FileNotFoundError):
|
||||
handler.calculate_file_hashes(firmware_path, file_name)
|
||||
|
||||
expected_file_path = f"{firmware_path}/{file_name}"
|
||||
mock_stream_method.assert_called_once_with(file_path=expected_file_path)
|
||||
|
||||
def test_rename_file_same_name(self, handler):
|
||||
def test_rename_file_same_name(self, handler: FSFirmwareHandler):
|
||||
"""Test rename_file when old and new names are the same"""
|
||||
old_name = "bios.bin"
|
||||
new_name = "bios.bin"
|
||||
file_path = "ps2/bios"
|
||||
old_name = "bios1.bin"
|
||||
new_name = "bios1.bin"
|
||||
file_path = "n64/bios"
|
||||
|
||||
# Should not call any file operations
|
||||
with patch.object(handler, "file_exists") as mock_exists:
|
||||
@@ -239,52 +133,7 @@ class TestFSFirmwareHandler:
|
||||
mock_exists.assert_not_called()
|
||||
mock_move.assert_not_called()
|
||||
|
||||
def test_rename_file_different_name_success(self, handler):
|
||||
"""Test rename_file when names are different and target doesn't exist"""
|
||||
old_name = "old_bios.bin"
|
||||
new_name = "new_bios.bin"
|
||||
file_path = "ps2/bios"
|
||||
|
||||
with patch.object(handler, "file_exists", return_value=False):
|
||||
with patch.object(handler, "move_file") as mock_move:
|
||||
handler.rename_file(old_name, new_name, file_path)
|
||||
|
||||
# The method reassigns file_path to include new_name
|
||||
modified_file_path = f"{file_path}/{new_name}"
|
||||
expected_source = f"{modified_file_path}/{old_name}"
|
||||
expected_dest = f"{modified_file_path}/{new_name}"
|
||||
mock_move.assert_called_once_with(
|
||||
source_path=expected_source, dest_path=expected_dest
|
||||
)
|
||||
|
||||
def test_rename_file_target_exists_raises_exception(self, handler):
|
||||
"""Test rename_file raises exception when target file already exists"""
|
||||
old_name = "old_bios.bin"
|
||||
new_name = "existing_bios.bin"
|
||||
file_path = "ps2/bios"
|
||||
|
||||
with patch.object(handler, "file_exists", return_value=True):
|
||||
with patch.object(handler, "move_file") as mock_move:
|
||||
with pytest.raises(FirmwareAlreadyExistsException):
|
||||
handler.rename_file(old_name, new_name, file_path)
|
||||
|
||||
mock_move.assert_not_called()
|
||||
|
||||
def test_rename_file_file_exists_called_correctly(self, handler):
|
||||
"""Test that rename_file calls file_exists with correct path"""
|
||||
old_name = "old_bios.bin"
|
||||
new_name = "new_bios.bin"
|
||||
file_path = "ps2/bios"
|
||||
|
||||
with patch.object(handler, "file_exists", return_value=False) as mock_exists:
|
||||
with patch.object(handler, "move_file"):
|
||||
handler.rename_file(old_name, new_name, file_path)
|
||||
|
||||
# The method reassigns file_path to include new_name before checking
|
||||
modified_file_path = f"{file_path}/{new_name}"
|
||||
mock_exists.assert_called_once_with(file_path=modified_file_path)
|
||||
|
||||
def test_integration_with_base_handler_methods(self, handler):
|
||||
def test_integration_with_base_handler_methods(self, handler: FSFirmwareHandler):
|
||||
"""Test that FSFirmwareHandler properly inherits from FSHandler"""
|
||||
# Test that handler has base methods
|
||||
assert hasattr(handler, "validate_path")
|
||||
@@ -294,48 +143,72 @@ class TestFSFirmwareHandler:
|
||||
assert hasattr(handler, "stream_file")
|
||||
assert hasattr(handler, "exclude_single_files")
|
||||
|
||||
def test_firmware_path_construction(self, handler, config):
|
||||
def test_firmware_path_construction(self, handler: FSFirmwareHandler, config):
|
||||
"""Test that firmware paths are constructed correctly"""
|
||||
platform_fs_slug = "dreamcast"
|
||||
platform_fs_slug = "n64"
|
||||
|
||||
with patch(
|
||||
"handler.filesystem.firmware_handler.cm.get_config", return_value=config
|
||||
):
|
||||
# Test high priority path
|
||||
with patch("os.path.exists", return_value=True):
|
||||
path = handler.get_firmware_fs_structure(platform_fs_slug)
|
||||
assert path == f"{config.FIRMWARE_FOLDER_NAME}/{platform_fs_slug}"
|
||||
|
||||
# Test normal path
|
||||
with patch("os.path.exists", return_value=False):
|
||||
path = handler.get_firmware_fs_structure(platform_fs_slug)
|
||||
assert path == f"{platform_fs_slug}/{config.FIRMWARE_FOLDER_NAME}"
|
||||
|
||||
def test_error_handling_in_get_firmware(self, handler, config):
|
||||
"""Test error handling in get_firmware method"""
|
||||
platform_fs_slug = "invalid_platform"
|
||||
|
||||
with patch(
|
||||
"handler.filesystem.firmware_handler.cm.get_config", return_value=config
|
||||
):
|
||||
with patch("os.path.exists", return_value=True):
|
||||
with patch.object(
|
||||
handler,
|
||||
"list_files",
|
||||
side_effect=FileNotFoundError("Directory not found"),
|
||||
):
|
||||
with pytest.raises(FileNotFoundError):
|
||||
handler.get_firmware(platform_fs_slug)
|
||||
# Test normal path (high prio doesn't exist)
|
||||
path = handler.get_firmware_fs_structure(platform_fs_slug)
|
||||
assert path == f"{platform_fs_slug}/{config.FIRMWARE_FOLDER_NAME}"
|
||||
|
||||
def test_multiple_platform_handling(self, handler, config):
|
||||
"""Test handling of different platform slugs"""
|
||||
platforms = ["ps1", "ps2", "n64", "dreamcast", "saturn"]
|
||||
platforms = ["n64", "psx"] # Use platforms that actually exist in test data
|
||||
|
||||
with patch(
|
||||
"handler.filesystem.firmware_handler.cm.get_config", return_value=config
|
||||
):
|
||||
with patch("os.path.exists", return_value=True):
|
||||
for platform in platforms:
|
||||
path = handler.get_firmware_fs_structure(platform)
|
||||
assert platform in path
|
||||
assert config.FIRMWARE_FOLDER_NAME in path
|
||||
for platform in platforms:
|
||||
path = handler.get_firmware_fs_structure(platform)
|
||||
assert platform in path
|
||||
assert config.FIRMWARE_FOLDER_NAME in path
|
||||
|
||||
# Test that we can actually get firmware for existing platforms
|
||||
firmware_files = handler.get_firmware(platform)
|
||||
assert len(firmware_files) > 0 # Should have at least one file
|
||||
|
||||
def test_exclude_single_files_integration(self, handler, config):
|
||||
"""Test that exclude_single_files works with actual files"""
|
||||
platform_fs_slug = "n64"
|
||||
|
||||
with patch(
|
||||
"handler.filesystem.firmware_handler.cm.get_config", return_value=config
|
||||
):
|
||||
# Get all files in the directory
|
||||
firmware_path = handler.get_firmware_fs_structure(platform_fs_slug)
|
||||
all_files = handler.list_files(path=firmware_path)
|
||||
|
||||
# Should include .tmp files before exclusion
|
||||
assert "temp.tmp" in all_files
|
||||
assert "bios1.bin" in all_files
|
||||
assert "bios2.bin" in all_files
|
||||
|
||||
# After exclusion, .tmp files should be removed
|
||||
filtered_files = handler.exclude_single_files(all_files)
|
||||
assert "temp.tmp" not in filtered_files
|
||||
assert "bios1.bin" in filtered_files
|
||||
assert "bios2.bin" in filtered_files
|
||||
|
||||
def test_file_operations_with_actual_structure(self, handler: FSFirmwareHandler):
|
||||
"""Test that file operations work with the actual directory structure"""
|
||||
# Test that we can list files
|
||||
n64_files = handler.list_files("n64/bios")
|
||||
assert len(n64_files) > 0
|
||||
|
||||
psx_files = handler.list_files("psx/bios")
|
||||
assert len(psx_files) > 0
|
||||
|
||||
# Test that we can check file existence
|
||||
assert handler.file_exists("n64/bios/bios1.bin")
|
||||
assert handler.file_exists("psx/bios/scph1001.bin")
|
||||
assert not handler.file_exists("n64/bios/nonexistent.bin")
|
||||
|
||||
def test_stream_file_with_actual_files(self, handler: FSFirmwareHandler):
|
||||
"""Test streaming actual files"""
|
||||
with handler.stream_file("n64/bios/bios1.bin") as f:
|
||||
content = f.read()
|
||||
assert len(content) > 0
|
||||
assert b"This is a test N64 BIOS file 1" in content
|
||||
|
||||
1
backend/romm_test/library/n64/bios/bios1.bin
Normal file
1
backend/romm_test/library/n64/bios/bios1.bin
Normal file
@@ -0,0 +1 @@
|
||||
This is a test N64 BIOS file 1
|
||||
1
backend/romm_test/library/n64/bios/bios2.bin
Normal file
1
backend/romm_test/library/n64/bios/bios2.bin
Normal file
@@ -0,0 +1 @@
|
||||
This is a test N64 BIOS file 2
|
||||
1
backend/romm_test/library/n64/bios/temp.tmp
Normal file
1
backend/romm_test/library/n64/bios/temp.tmp
Normal file
@@ -0,0 +1 @@
|
||||
This is a test temporary file
|
||||
1
backend/romm_test/library/psx/bios/scph1001.bin
Normal file
1
backend/romm_test/library/psx/bios/scph1001.bin
Normal file
@@ -0,0 +1 @@
|
||||
This is a test PSX BIOS file
|
||||
Reference in New Issue
Block a user