mirror of
https://github.com/rommapp/romm.git
synced 2026-06-30 07:45:52 +00:00
complete tests for tasks folder
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
import os
|
||||
|
||||
import pytest
|
||||
from tasks.update_launchbox_metadata import UpdateLaunchboxMetadataTask
|
||||
@@ -13,93 +12,11 @@ def task():
|
||||
|
||||
@pytest.fixture
|
||||
def sample_zip_content():
|
||||
"""Create sample ZIP content with XML files"""
|
||||
zip_buffer = BytesIO()
|
||||
test_dir = os.path.dirname(__file__)
|
||||
sample_path = os.path.join(test_dir, "fixtures", "sample_metadata.zip")
|
||||
|
||||
with zipfile.ZipFile(zip_buffer, "w") as zip_file:
|
||||
# Add Platforms.xml
|
||||
platforms_xml = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<Platform>
|
||||
<Name>Nintendo 64</Name>
|
||||
<PlatformType>Console</PlatformType>
|
||||
<ReleaseDate>1996-06-23</ReleaseDate>
|
||||
</Platform>
|
||||
<Platform>
|
||||
<Name>PlayStation</Name>
|
||||
<PlatformType>Console</PlatformType>
|
||||
<ReleaseDate>1994-12-03</ReleaseDate>
|
||||
</Platform>
|
||||
</LaunchBox>"""
|
||||
zip_file.writestr("Platforms.xml", platforms_xml)
|
||||
|
||||
# Add Metadata.xml
|
||||
metadata_xml = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<Game>
|
||||
<DatabaseID>67890</DatabaseID>
|
||||
<Name>Crash Bandicoot</Name>
|
||||
<Platform>PlayStation</Platform>
|
||||
<ReleaseDate>1996-09-09</ReleaseDate>
|
||||
<Genre>Platformer</Genre>
|
||||
</Game>
|
||||
<Game>
|
||||
<DatabaseID>12345</DatabaseID>
|
||||
<Name>Super Mario 64</Name>
|
||||
<Platform>Nintendo 64</Platform>
|
||||
<ReleaseDate>1996-06-23</ReleaseDate>
|
||||
<Genre>Platformer</Genre>
|
||||
</Game>
|
||||
<GameAlternateName>
|
||||
<AlternateName>Super Mario 64 (USA)</AlternateName>
|
||||
<DatabaseID>12345</DatabaseID>
|
||||
</GameAlternateName>
|
||||
<GameImage>
|
||||
<DatabaseID>12345</DatabaseID>
|
||||
<FileName>super_mario_64.jpg</FileName>
|
||||
<Type>Cover</Type>
|
||||
</GameImage>
|
||||
<GameImage>
|
||||
<DatabaseID>12345</DatabaseID>
|
||||
<FileName>super_mario_64_screenshot.jpg</FileName>
|
||||
<Type>Screenshot</Type>
|
||||
</GameImage>
|
||||
</LaunchBox>"""
|
||||
zip_file.writestr("Metadata.xml", metadata_xml)
|
||||
|
||||
# Add Mame.xml
|
||||
mame_xml = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<MameFile>
|
||||
<FileName>mario.zip</FileName>
|
||||
<GameName>mario</GameName>
|
||||
<Description>Super Mario Bros.</Description>
|
||||
</MameFile>
|
||||
<MameFile>
|
||||
<FileName>pacman.zip</FileName>
|
||||
<GameName>pacman</GameName>
|
||||
<Description>Pac-Man</Description>
|
||||
</MameFile>
|
||||
</LaunchBox>"""
|
||||
zip_file.writestr("Mame.xml", mame_xml)
|
||||
|
||||
# Add Files.xml
|
||||
files_xml = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<File>
|
||||
<FileName>super_mario_64.z64</FileName>
|
||||
<FileType>ROM</FileType>
|
||||
<Size>8388608</Size>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>crash_bandicoot.bin</FileName>
|
||||
<FileType>ROM</FileType>
|
||||
<Size>524288000</Size>
|
||||
</File>
|
||||
</LaunchBox>"""
|
||||
zip_file.writestr("Files.xml", files_xml)
|
||||
|
||||
return zip_buffer.getvalue()
|
||||
with open(sample_path, "rb") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
11
backend/tasks/tests/fixtures/Platforms.xml
vendored
Normal file
11
backend/tasks/tests/fixtures/Platforms.xml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<Platform>
|
||||
<Name></Name>
|
||||
<PlatformType>Console</PlatformType>
|
||||
</Platform>
|
||||
<Platform>
|
||||
<Name>Valid Platform</Name>
|
||||
<PlatformType></PlatformType>
|
||||
</Platform>
|
||||
</LaunchBox>
|
||||
BIN
backend/tasks/tests/fixtures/sample_metadata.zip
vendored
Normal file
BIN
backend/tasks/tests/fixtures/sample_metadata.zip
vendored
Normal file
Binary file not shown.
13
backend/tasks/tests/fixtures/sample_metadata/Files.xml
vendored
Normal file
13
backend/tasks/tests/fixtures/sample_metadata/Files.xml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<File>
|
||||
<FileName>super_mario_64.z64</FileName>
|
||||
<FileType>ROM</FileType>
|
||||
<Size>8388608</Size>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>crash_bandicoot.bin</FileName>
|
||||
<FileType>ROM</FileType>
|
||||
<Size>524288000</Size>
|
||||
</File>
|
||||
</LaunchBox>
|
||||
13
backend/tasks/tests/fixtures/sample_metadata/Mame.xml
vendored
Normal file
13
backend/tasks/tests/fixtures/sample_metadata/Mame.xml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<MameFile>
|
||||
<FileName>mario.zip</FileName>
|
||||
<GameName>mario</GameName>
|
||||
<Description>Super Mario Bros.</Description>
|
||||
</MameFile>
|
||||
<MameFile>
|
||||
<FileName>pacman.zip</FileName>
|
||||
<GameName>pacman</GameName>
|
||||
<Description>Pac-Man</Description>
|
||||
</MameFile>
|
||||
</LaunchBox>
|
||||
31
backend/tasks/tests/fixtures/sample_metadata/Metadata.xml
vendored
Normal file
31
backend/tasks/tests/fixtures/sample_metadata/Metadata.xml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<Game>
|
||||
<DatabaseID>67890</DatabaseID>
|
||||
<Name>Crash Bandicoot</Name>
|
||||
<Platform>PlayStation</Platform>
|
||||
<ReleaseDate>1996-09-09</ReleaseDate>
|
||||
<Genre>Platformer</Genre>
|
||||
</Game>
|
||||
<Game>
|
||||
<DatabaseID>12345</DatabaseID>
|
||||
<Name>Super Mario 64</Name>
|
||||
<Platform>Nintendo 64</Platform>
|
||||
<ReleaseDate>1996-06-23</ReleaseDate>
|
||||
<Genre>Platformer</Genre>
|
||||
</Game>
|
||||
<GameAlternateName>
|
||||
<AlternateName>Super Mario 64 (USA)</AlternateName>
|
||||
<DatabaseID>12345</DatabaseID>
|
||||
</GameAlternateName>
|
||||
<GameImage>
|
||||
<DatabaseID>12345</DatabaseID>
|
||||
<FileName>super_mario_64.jpg</FileName>
|
||||
<Type>Cover</Type>
|
||||
</GameImage>
|
||||
<GameImage>
|
||||
<DatabaseID>12345</DatabaseID>
|
||||
<FileName>super_mario_64_screenshot.jpg</FileName>
|
||||
<Type>Screenshot</Type>
|
||||
</GameImage>
|
||||
</LaunchBox>
|
||||
BIN
backend/tasks/tests/fixtures/sample_metadata_with_empty_elements.zip
vendored
Normal file
BIN
backend/tasks/tests/fixtures/sample_metadata_with_empty_elements.zip
vendored
Normal file
Binary file not shown.
50
backend/tasks/tests/test_scan_library.py
Normal file
50
backend/tasks/tests/test_scan_library.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from handler.scan_handler import ScanType
|
||||
from tasks.scan_library import ScanLibraryTask, scan_library_task
|
||||
from tasks.tasks import PeriodicTask
|
||||
|
||||
|
||||
class TestScanLibraryTask:
|
||||
@pytest.fixture
|
||||
def task(self):
|
||||
return ScanLibraryTask()
|
||||
|
||||
def test_init(self, task):
|
||||
"""Test task initialization"""
|
||||
assert task.func == "tasks.scan_library.scan_library_task.run"
|
||||
assert task.description == "library scan"
|
||||
|
||||
@patch("tasks.scan_library.ENABLE_SCHEDULED_RESCAN", True)
|
||||
@patch("tasks.scan_library.scan_platforms")
|
||||
@patch("tasks.scan_library.log")
|
||||
async def test_run_enabled(self, mock_log, mock_scan_platforms, task):
|
||||
"""Test run when scheduled rescan is enabled"""
|
||||
mock_scan_platforms.return_value = AsyncMock()
|
||||
|
||||
await task.run()
|
||||
|
||||
mock_log.info.assert_any_call("Scheduled library scan started...")
|
||||
mock_scan_platforms.assert_called_once_with([], scan_type=ScanType.UNIDENTIFIED)
|
||||
mock_log.info.assert_any_call("Scheduled library scan done")
|
||||
|
||||
@patch("tasks.scan_library.ENABLE_SCHEDULED_RESCAN", False)
|
||||
@patch("tasks.scan_library.scan_platforms")
|
||||
@patch("tasks.scan_library.log")
|
||||
async def test_run_disabled(self, mock_log, mock_scan_platforms, task):
|
||||
"""Test run when scheduled rescan is disabled"""
|
||||
task.unschedule = MagicMock()
|
||||
|
||||
await task.run()
|
||||
|
||||
mock_log.info.assert_called_once_with(
|
||||
"Scheduled library scan not enabled, unscheduling..."
|
||||
)
|
||||
task.unschedule.assert_called_once()
|
||||
mock_scan_platforms.assert_not_called()
|
||||
|
||||
def test_task_instance(self):
|
||||
"""Test that the module-level task instance is created correctly"""
|
||||
assert isinstance(scan_library_task, ScanLibraryTask)
|
||||
assert scan_library_task.func == "tasks.scan_library.scan_library_task.run"
|
||||
300
backend/tasks/tests/test_tasks.py
Normal file
300
backend/tasks/tests/test_tasks.py
Normal file
@@ -0,0 +1,300 @@
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
from exceptions.task_exceptions import SchedulerException
|
||||
from rq.job import Job
|
||||
from tasks.tasks import PeriodicTask, RemoteFilePullTask, tasks_scheduler
|
||||
|
||||
|
||||
class ConcretePeriodicTask(PeriodicTask):
|
||||
"""Concrete implementation for testing abstract PeriodicTask"""
|
||||
|
||||
async def run(self, *args, **kwargs):
|
||||
return "test_result"
|
||||
|
||||
|
||||
class TestPeriodicTask:
|
||||
@pytest.fixture
|
||||
def task(self):
|
||||
return ConcretePeriodicTask(
|
||||
func="test.function",
|
||||
description="test task",
|
||||
enabled=True,
|
||||
cron_string="0 0 * * *",
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def disabled_task(self):
|
||||
return ConcretePeriodicTask(
|
||||
func="test.disabled.function",
|
||||
description="disabled task",
|
||||
enabled=False,
|
||||
cron_string="0 0 * * *",
|
||||
)
|
||||
|
||||
def test_init(self, task):
|
||||
"""Test task initialization"""
|
||||
assert task.func == "test.function"
|
||||
assert task.description == "test task"
|
||||
assert task.enabled is True
|
||||
assert task.cron_string == "0 0 * * *"
|
||||
|
||||
def test_init_default_description(self):
|
||||
"""Test that description defaults to func when not provided"""
|
||||
task = ConcretePeriodicTask(func="test.function", description=None)
|
||||
assert task.description == "test.function"
|
||||
|
||||
@patch.object(tasks_scheduler, "get_jobs")
|
||||
def test_get_existing_job_found(self, mock_get_jobs, task):
|
||||
"""Test finding an existing job"""
|
||||
mock_job = MagicMock(spec=Job)
|
||||
mock_job.func_name = "test.function"
|
||||
mock_get_jobs.return_value = [mock_job]
|
||||
|
||||
result = task._get_existing_job()
|
||||
assert result == mock_job
|
||||
|
||||
@patch.object(tasks_scheduler, "get_jobs")
|
||||
def test_get_existing_job_not_found(self, mock_get_jobs, task):
|
||||
"""Test when no existing job is found"""
|
||||
mock_job = MagicMock(spec=Job)
|
||||
mock_job.func_name = "other.function"
|
||||
mock_get_jobs.return_value = [mock_job]
|
||||
|
||||
result = task._get_existing_job()
|
||||
assert result is None
|
||||
|
||||
@patch.object(tasks_scheduler, "get_jobs")
|
||||
def test_get_existing_job_empty_list(self, mock_get_jobs, task):
|
||||
"""Test when no jobs exist"""
|
||||
mock_get_jobs.return_value = []
|
||||
|
||||
result = task._get_existing_job()
|
||||
assert result is None
|
||||
|
||||
@patch.object(ConcretePeriodicTask, "_get_existing_job")
|
||||
@patch.object(ConcretePeriodicTask, "schedule")
|
||||
def test_init_enabled_no_existing_job(
|
||||
self, mock_schedule, mock_get_existing_job, task
|
||||
):
|
||||
"""Test init when task is enabled and no existing job"""
|
||||
mock_get_existing_job.return_value = None
|
||||
mock_schedule.return_value = "scheduled"
|
||||
|
||||
result = task.init()
|
||||
|
||||
mock_schedule.assert_called_once()
|
||||
assert result == "scheduled"
|
||||
|
||||
@patch.object(ConcretePeriodicTask, "_get_existing_job")
|
||||
@patch.object(ConcretePeriodicTask, "unschedule")
|
||||
def test_init_disabled_with_existing_job(
|
||||
self, mock_unschedule, mock_get_existing_job, disabled_task
|
||||
):
|
||||
"""Test init when task is disabled but has existing job"""
|
||||
mock_job = MagicMock()
|
||||
mock_get_existing_job.return_value = mock_job
|
||||
mock_unschedule.return_value = "unscheduled"
|
||||
|
||||
result = disabled_task.init()
|
||||
|
||||
mock_unschedule.assert_called_once()
|
||||
assert result == "unscheduled"
|
||||
|
||||
@patch.object(ConcretePeriodicTask, "_get_existing_job")
|
||||
def test_init_enabled_with_existing_job(self, mock_get_existing_job, task):
|
||||
"""Test init when task is enabled and job already exists"""
|
||||
mock_job = MagicMock()
|
||||
mock_get_existing_job.return_value = mock_job
|
||||
|
||||
result = task.init()
|
||||
|
||||
assert result is None # Should do nothing
|
||||
|
||||
@patch.object(ConcretePeriodicTask, "_get_existing_job")
|
||||
@patch.object(tasks_scheduler, "cron")
|
||||
def test_schedule_success(self, mock_cron, mock_get_existing_job, task):
|
||||
"""Test successful scheduling"""
|
||||
mock_get_existing_job.return_value = None
|
||||
mock_cron.return_value = "scheduled_job"
|
||||
|
||||
result = task.schedule()
|
||||
|
||||
mock_cron.assert_called_once_with(
|
||||
"0 0 * * *", func="test.function", repeat=None
|
||||
)
|
||||
assert result == "scheduled_job"
|
||||
|
||||
def test_schedule_not_enabled(self, disabled_task):
|
||||
"""Test scheduling when task is not enabled"""
|
||||
with pytest.raises(
|
||||
SchedulerException, match="Scheduled disabled task is not enabled."
|
||||
):
|
||||
disabled_task.schedule()
|
||||
|
||||
@patch.object(ConcretePeriodicTask, "_get_existing_job")
|
||||
@patch("tasks.tasks.log")
|
||||
def test_schedule_already_scheduled(self, mock_log, mock_get_existing_job, task):
|
||||
"""Test scheduling when job already exists"""
|
||||
mock_job = MagicMock()
|
||||
mock_get_existing_job.return_value = mock_job
|
||||
|
||||
result = task.schedule()
|
||||
|
||||
mock_log.info.assert_called_once_with("Test task is already scheduled.")
|
||||
assert result is None
|
||||
|
||||
def test_schedule_no_cron_string(self):
|
||||
"""Test scheduling with no cron string"""
|
||||
task = ConcretePeriodicTask(
|
||||
func="test.function",
|
||||
description="test task",
|
||||
enabled=True,
|
||||
cron_string=None,
|
||||
)
|
||||
|
||||
with patch.object(task, "_get_existing_job", return_value=None):
|
||||
result = task.schedule()
|
||||
assert result is None
|
||||
|
||||
@patch.object(ConcretePeriodicTask, "_get_existing_job")
|
||||
@patch.object(tasks_scheduler, "cancel")
|
||||
@patch("tasks.tasks.log")
|
||||
def test_unschedule_success(
|
||||
self, mock_log, mock_cancel, mock_get_existing_job, task
|
||||
):
|
||||
"""Test successful unscheduling"""
|
||||
mock_job = MagicMock()
|
||||
mock_get_existing_job.return_value = mock_job
|
||||
|
||||
task.unschedule()
|
||||
|
||||
mock_cancel.assert_called_once_with(mock_job)
|
||||
mock_log.info.assert_called_once_with("Test task unscheduled.")
|
||||
|
||||
@patch.object(ConcretePeriodicTask, "_get_existing_job")
|
||||
@patch("tasks.tasks.log")
|
||||
def test_unschedule_not_scheduled(self, mock_log, mock_get_existing_job, task):
|
||||
"""Test unscheduling when no job exists"""
|
||||
mock_get_existing_job.return_value = None
|
||||
|
||||
task.unschedule()
|
||||
|
||||
mock_log.info.assert_called_once_with("Test task is not scheduled.")
|
||||
|
||||
async def test_run_abstract_method(self, task):
|
||||
"""Test that run method works in concrete implementation"""
|
||||
result = await task.run()
|
||||
assert result == "test_result"
|
||||
|
||||
|
||||
class TestRemoteFilePullTask:
|
||||
@pytest.fixture
|
||||
def task(self):
|
||||
return RemoteFilePullTask(
|
||||
func="test.remote.function",
|
||||
description="remote test task",
|
||||
enabled=True,
|
||||
cron_string="0 0 * * *",
|
||||
url="https://example.com/data.json",
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def disabled_task(self):
|
||||
return RemoteFilePullTask(
|
||||
func="test.remote.disabled.function",
|
||||
description="disabled remote task",
|
||||
enabled=False,
|
||||
url="https://example.com/data.json",
|
||||
)
|
||||
|
||||
def test_init(self, task):
|
||||
"""Test RemoteFilePullTask initialization"""
|
||||
assert task.func == "test.remote.function"
|
||||
assert task.description == "remote test task"
|
||||
assert task.enabled is True
|
||||
assert task.url == "https://example.com/data.json"
|
||||
|
||||
@patch("tasks.tasks.ctx_httpx_client")
|
||||
@patch("tasks.tasks.log")
|
||||
async def test_run_success(self, mock_log, mock_ctx_httpx_client, task):
|
||||
"""Test successful remote file pull"""
|
||||
mock_client = AsyncMock()
|
||||
mock_response = AsyncMock()
|
||||
mock_response.content = b"test content"
|
||||
mock_client.get.return_value = mock_response
|
||||
mock_ctx_httpx_client.get.return_value = mock_client
|
||||
|
||||
result = await task.run(force=True)
|
||||
|
||||
mock_client.get.assert_called_once_with(
|
||||
"https://example.com/data.json", timeout=120
|
||||
)
|
||||
mock_response.raise_for_status.assert_called_once()
|
||||
mock_log.info.assert_called_once_with("Scheduled remote test task started...")
|
||||
assert result == b"test content"
|
||||
|
||||
@patch("tasks.tasks.ctx_httpx_client")
|
||||
@patch("tasks.tasks.log")
|
||||
async def test_run_http_error(self, mock_log, mock_ctx_httpx_client, task):
|
||||
"""Test handling of HTTP errors"""
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get.side_effect = httpx.HTTPError("Connection failed")
|
||||
mock_ctx_httpx_client.get.return_value = mock_client
|
||||
|
||||
result = await task.run(force=True)
|
||||
|
||||
mock_log.error.assert_called()
|
||||
assert result is None
|
||||
|
||||
@patch("tasks.tasks.ctx_httpx_client")
|
||||
@patch("tasks.tasks.log")
|
||||
async def test_run_response_error(self, mock_log, mock_ctx_httpx_client, task):
|
||||
"""Test handling of response status errors"""
|
||||
mock_client = AsyncMock()
|
||||
mock_response = MagicMock()
|
||||
|
||||
# Create a proper HTTPStatusError
|
||||
http_error = httpx.HTTPStatusError(
|
||||
"404 Not Found", request=MagicMock(), response=MagicMock()
|
||||
)
|
||||
mock_response.raise_for_status.side_effect = http_error
|
||||
mock_client.get.return_value = mock_response
|
||||
mock_ctx_httpx_client.get.return_value = mock_client
|
||||
|
||||
result = await task.run(force=True)
|
||||
|
||||
# Verify the specific error logging calls
|
||||
mock_log.error.assert_any_call(
|
||||
"Scheduled remote test task failed", exc_info=True
|
||||
)
|
||||
mock_log.error.assert_any_call(http_error)
|
||||
assert result is None
|
||||
|
||||
@patch.object(RemoteFilePullTask, "unschedule")
|
||||
@patch("tasks.tasks.log")
|
||||
async def test_run_disabled_not_forced(
|
||||
self, mock_log, mock_unschedule, disabled_task
|
||||
):
|
||||
"""Test run when task is disabled and not forced"""
|
||||
result = await disabled_task.run(force=False)
|
||||
|
||||
mock_log.info.assert_called_once_with(
|
||||
"Scheduled disabled remote task not enabled, unscheduling..."
|
||||
)
|
||||
mock_unschedule.assert_called_once()
|
||||
assert result is None
|
||||
|
||||
@patch("tasks.tasks.ctx_httpx_client")
|
||||
async def test_run_disabled_but_forced(self, mock_ctx_httpx_client, disabled_task):
|
||||
"""Test run when task is disabled but forced"""
|
||||
mock_client = AsyncMock()
|
||||
mock_response = AsyncMock()
|
||||
mock_response.content = b"forced content"
|
||||
mock_client.get.return_value = mock_response
|
||||
mock_ctx_httpx_client.get.return_value = mock_client
|
||||
|
||||
result = await disabled_task.run(force=True)
|
||||
|
||||
assert result == b"forced content"
|
||||
@@ -1,7 +1,7 @@
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
import os
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import anyio
|
||||
import pytest
|
||||
from tasks.tasks import RemoteFilePullTask
|
||||
from tasks.update_launchbox_metadata import (
|
||||
@@ -165,23 +165,13 @@ class TestUpdateLaunchboxMetadataTask:
|
||||
task,
|
||||
):
|
||||
"""Test handling of XML elements with empty or missing text"""
|
||||
# Create XML with empty elements
|
||||
zip_buffer = BytesIO()
|
||||
with zipfile.ZipFile(zip_buffer, "w") as zip_file:
|
||||
platforms_xml = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<Platform>
|
||||
<Name></Name>
|
||||
<PlatformType>Console</PlatformType>
|
||||
</Platform>
|
||||
<Platform>
|
||||
<Name>Valid Platform</Name>
|
||||
<PlatformType></PlatformType>
|
||||
</Platform>
|
||||
</LaunchBox>"""
|
||||
zip_file.writestr("Platforms.xml", platforms_xml)
|
||||
test_dir = os.path.dirname(__file__)
|
||||
sample_path = os.path.join(
|
||||
test_dir, "fixtures", "sample_metadata_with_empty_elements.zip"
|
||||
)
|
||||
|
||||
mock_super_run.return_value = zip_buffer.getvalue()
|
||||
async with await anyio.open_file(sample_path, "rb") as f:
|
||||
mock_super_run.return_value = await f.read()
|
||||
|
||||
# Create a mock pipeline with async context manager support
|
||||
mock_pipe = AsyncMock()
|
||||
@@ -214,19 +204,13 @@ class TestUpdateLaunchboxMetadataTask:
|
||||
task,
|
||||
):
|
||||
"""Test handling when some XML files are missing from the ZIP"""
|
||||
# Create ZIP with only Platforms.xml
|
||||
zip_buffer = BytesIO()
|
||||
with zipfile.ZipFile(zip_buffer, "w") as zip_file:
|
||||
platforms_xml = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LaunchBox>
|
||||
<Platform>
|
||||
<Name>Test Platform</Name>
|
||||
<PlatformType>Console</PlatformType>
|
||||
</Platform>
|
||||
</LaunchBox>"""
|
||||
zip_file.writestr("Platforms.xml", platforms_xml)
|
||||
test_dir = os.path.dirname(__file__)
|
||||
sample_path = os.path.join(
|
||||
test_dir, "fixtures", "sample_metadata_with_empty_elements.zip"
|
||||
)
|
||||
|
||||
mock_super_run.return_value = zip_buffer.getvalue()
|
||||
async with await anyio.open_file(sample_path, "rb") as f:
|
||||
mock_super_run.return_value = await f.read()
|
||||
|
||||
# Create a mock pipeline with async context manager support
|
||||
mock_pipe = AsyncMock()
|
||||
|
||||
Reference in New Issue
Block a user