mirror of
https://github.com/rommapp/romm.git
synced 2026-02-18 00:27:41 +01:00
fix tests
This commit is contained in:
@@ -117,9 +117,12 @@ def _build_task_status_response(
|
||||
job: Job,
|
||||
) -> TaskStatusResponse:
|
||||
job_meta = job.get_meta()
|
||||
task_name = job_meta.get("task_name", job.func_name)
|
||||
task_name = job_meta.get("task_name") or job.func_name
|
||||
task_type = job_meta.get("task_type")
|
||||
|
||||
if not task_type:
|
||||
raise ValueError("Task type not found in job meta")
|
||||
|
||||
# Convert datetime objects to ISO format strings
|
||||
queued_at = job.created_at.isoformat() if job.created_at else None
|
||||
started_at = job.started_at.isoformat() if job.started_at else None
|
||||
@@ -134,8 +137,6 @@ def _build_task_status_response(
|
||||
"ended_at": ended_at,
|
||||
"result": job.result,
|
||||
}
|
||||
if not task_type:
|
||||
raise ValueError("Task type not found in job meta")
|
||||
|
||||
match TaskType(task_type):
|
||||
case TaskType.SCAN:
|
||||
|
||||
@@ -5,7 +5,7 @@ from fastapi import status
|
||||
from fastapi.testclient import TestClient
|
||||
from main import app
|
||||
|
||||
from tasks.tasks import Task
|
||||
from tasks.tasks import Task, TaskType
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -20,6 +20,7 @@ def mock_task():
|
||||
task = Mock(spec=Task)
|
||||
task.title = "Test Task"
|
||||
task.description = "A test task for unit testing"
|
||||
task.task_type = TaskType.CLEANUP
|
||||
task.enabled = True
|
||||
task.manual_run = True
|
||||
task.cron_string = "0 0 * * *"
|
||||
@@ -33,6 +34,7 @@ def mock_disabled_task():
|
||||
task = Mock(spec=Task)
|
||||
task.title = "Disabled Task"
|
||||
task.description = "A disabled task for testing"
|
||||
task.task_type = TaskType.CLEANUP
|
||||
task.enabled = False
|
||||
task.manual_run = True
|
||||
task.cron_string = None
|
||||
@@ -46,6 +48,7 @@ def mock_non_manual_task():
|
||||
task = Mock(spec=Task)
|
||||
task.title = "Non-Manual Task"
|
||||
task.description = "A task that cannot be run manually"
|
||||
task.task_type = TaskType.CLEANUP
|
||||
task.enabled = True
|
||||
task.manual_run = False
|
||||
task.cron_string = "0 0 * * *"
|
||||
@@ -60,29 +63,39 @@ class TestListTasks:
|
||||
@patch("endpoints.tasks.RESCAN_ON_FILESYSTEM_CHANGE_DELAY", 5)
|
||||
@patch(
|
||||
"endpoints.tasks.manual_tasks",
|
||||
{
|
||||
"test_manual": Mock(
|
||||
spec=Task,
|
||||
title="Manual Task",
|
||||
description="Manual task",
|
||||
enabled=True,
|
||||
manual_run=True,
|
||||
cron_string=None,
|
||||
)
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "test_manual",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.CLEANUP,
|
||||
title="Manual Task",
|
||||
description="Manual task",
|
||||
enabled=True,
|
||||
manual_run=True,
|
||||
cron_string=None,
|
||||
),
|
||||
}
|
||||
],
|
||||
)
|
||||
@patch(
|
||||
"endpoints.tasks.scheduled_tasks",
|
||||
{
|
||||
"test_scheduled": Mock(
|
||||
spec=Task,
|
||||
title="Scheduled Task",
|
||||
description="Scheduled task",
|
||||
enabled=True,
|
||||
manual_run=False,
|
||||
cron_string="0 0 * * *",
|
||||
)
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "test_scheduled",
|
||||
"type": TaskType.UPDATE,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.UPDATE,
|
||||
title="Scheduled Task",
|
||||
description="Scheduled task",
|
||||
enabled=True,
|
||||
manual_run=False,
|
||||
cron_string="0 0 * * *",
|
||||
),
|
||||
}
|
||||
],
|
||||
)
|
||||
def test_list_tasks_success(self, client, access_token):
|
||||
"""Test successful listing of all tasks"""
|
||||
@@ -130,8 +143,8 @@ class TestListTasks:
|
||||
|
||||
@patch("endpoints.tasks.ENABLE_RESCAN_ON_FILESYSTEM_CHANGE", False)
|
||||
@patch("endpoints.tasks.RESCAN_ON_FILESYSTEM_CHANGE_DELAY", 10)
|
||||
@patch("endpoints.tasks.manual_tasks", {})
|
||||
@patch("endpoints.tasks.scheduled_tasks", {})
|
||||
@patch("endpoints.tasks.manual_tasks", [])
|
||||
@patch("endpoints.tasks.scheduled_tasks", [])
|
||||
def test_list_tasks_empty(self, client, access_token):
|
||||
"""Test listing tasks when no tasks are available"""
|
||||
response = client.get(
|
||||
@@ -157,7 +170,7 @@ class TestListTasks:
|
||||
# Create a token without TASKS_RUN scope
|
||||
from datetime import timedelta
|
||||
|
||||
from handler.auth import oauth_handler
|
||||
from endpoints.auth import oauth_handler
|
||||
|
||||
data = {
|
||||
"sub": admin_user.username,
|
||||
@@ -187,19 +200,65 @@ class TestRunAllTasks:
|
||||
)
|
||||
@patch(
|
||||
"endpoints.tasks.manual_tasks",
|
||||
{
|
||||
"task1": Mock(spec=Task, enabled=True, manual_run=True, run=Mock()),
|
||||
"task2": Mock(spec=Task, enabled=True, manual_run=True, run=Mock()),
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "task1",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.CLEANUP,
|
||||
title="Test Task",
|
||||
description="Test Description",
|
||||
enabled=True,
|
||||
manual_run=True,
|
||||
run=Mock(),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "task2",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.CLEANUP,
|
||||
title="Test Task",
|
||||
description="Test Description",
|
||||
enabled=True,
|
||||
manual_run=True,
|
||||
run=Mock(),
|
||||
),
|
||||
},
|
||||
],
|
||||
)
|
||||
@patch(
|
||||
"endpoints.tasks.scheduled_tasks",
|
||||
{
|
||||
"task3": Mock(spec=Task, enabled=True, manual_run=True, run=Mock()),
|
||||
"task4": Mock(
|
||||
spec=Task, enabled=False, manual_run=True, run=Mock()
|
||||
), # Disabled
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "task3",
|
||||
"type": TaskType.UPDATE,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.UPDATE,
|
||||
title="Update Task",
|
||||
description="Update Description",
|
||||
enabled=True,
|
||||
manual_run=True,
|
||||
run=Mock(),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "task4",
|
||||
"type": TaskType.UPDATE,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.UPDATE,
|
||||
title="Disabled Update Task",
|
||||
description="Disabled Update Description",
|
||||
enabled=False,
|
||||
manual_run=True,
|
||||
run=Mock(),
|
||||
), # Disabled
|
||||
},
|
||||
],
|
||||
)
|
||||
def test_run_all_tasks_success(self, mock_queue, client, access_token):
|
||||
"""Test successful running of all runnable tasks"""
|
||||
@@ -215,8 +274,8 @@ class TestRunAllTasks:
|
||||
assert data[2]["task_name"] == "task3"
|
||||
|
||||
@patch("endpoints.tasks.low_prio_queue")
|
||||
@patch("endpoints.tasks.manual_tasks", {})
|
||||
@patch("endpoints.tasks.scheduled_tasks", {})
|
||||
@patch("endpoints.tasks.manual_tasks", [])
|
||||
@patch("endpoints.tasks.scheduled_tasks", [])
|
||||
def test_run_all_tasks_no_runnable_tasks(self, mock_queue, client, access_token):
|
||||
"""Test running all tasks when no tasks are runnable"""
|
||||
response = client.post(
|
||||
@@ -233,16 +292,24 @@ class TestRunAllTasks:
|
||||
@patch("endpoints.tasks.low_prio_queue")
|
||||
@patch(
|
||||
"endpoints.tasks.manual_tasks",
|
||||
{
|
||||
"task1": Mock(
|
||||
spec=Task, enabled=True, manual_run=False, run=Mock()
|
||||
), # Not manual
|
||||
"task2": Mock(
|
||||
spec=Task, enabled=False, manual_run=True, run=Mock()
|
||||
), # Disabled
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "task1",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task, enabled=True, manual_run=False, run=Mock()
|
||||
), # Not manual
|
||||
},
|
||||
{
|
||||
"name": "task2",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task, enabled=False, manual_run=True, run=Mock()
|
||||
), # Disabled
|
||||
},
|
||||
],
|
||||
)
|
||||
@patch("endpoints.tasks.scheduled_tasks", {})
|
||||
@patch("endpoints.tasks.scheduled_tasks", [])
|
||||
def test_run_all_tasks_mixed_conditions(self, mock_queue, client, access_token):
|
||||
"""Test running all tasks with mixed enabled/disabled and manual/non-manual tasks"""
|
||||
response = client.post(
|
||||
@@ -273,9 +340,23 @@ class TestRunSingleTask:
|
||||
)
|
||||
@patch(
|
||||
"endpoints.tasks.manual_tasks",
|
||||
{"test_task": Mock(spec=Task, enabled=True, manual_run=True, run=Mock())},
|
||||
[
|
||||
{
|
||||
"name": "test_task",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.CLEANUP,
|
||||
title="Test Task",
|
||||
description="Test Description",
|
||||
enabled=True,
|
||||
manual_run=True,
|
||||
run=Mock(),
|
||||
),
|
||||
}
|
||||
],
|
||||
)
|
||||
@patch("endpoints.tasks.scheduled_tasks", {})
|
||||
@patch("endpoints.tasks.scheduled_tasks", [])
|
||||
def test_run_single_task_success(self, mock_queue, client, access_token):
|
||||
"""Test successful running of a single task"""
|
||||
response = client.post(
|
||||
@@ -286,15 +367,15 @@ class TestRunSingleTask:
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
data = response.json()
|
||||
|
||||
assert data["task_name"] == "test_task"
|
||||
assert data["task_name"] == "Test Task"
|
||||
assert data["task_id"] == "1"
|
||||
assert data["status"] == "queued"
|
||||
assert "queued_at" in data
|
||||
|
||||
mock_queue.assert_called_once()
|
||||
|
||||
@patch("endpoints.tasks.manual_tasks", {})
|
||||
@patch("endpoints.tasks.scheduled_tasks", {})
|
||||
@patch("endpoints.tasks.manual_tasks", [])
|
||||
@patch("endpoints.tasks.scheduled_tasks", [])
|
||||
def test_run_single_task_not_found(self, client, access_token):
|
||||
"""Test running a non-existent task"""
|
||||
response = client.post(
|
||||
@@ -309,9 +390,23 @@ class TestRunSingleTask:
|
||||
@patch("endpoints.tasks.low_prio_queue")
|
||||
@patch(
|
||||
"endpoints.tasks.manual_tasks",
|
||||
{"disabled_task": Mock(spec=Task, enabled=False, manual_run=True, run=Mock())},
|
||||
[
|
||||
{
|
||||
"name": "disabled_task",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.CLEANUP,
|
||||
title="Disabled Task",
|
||||
description="Disabled Description",
|
||||
enabled=False,
|
||||
manual_run=True,
|
||||
run=Mock(),
|
||||
),
|
||||
}
|
||||
],
|
||||
)
|
||||
@patch("endpoints.tasks.scheduled_tasks", {})
|
||||
@patch("endpoints.tasks.scheduled_tasks", [])
|
||||
def test_run_single_task_disabled(self, mock_queue, client, access_token):
|
||||
"""Test running a disabled task"""
|
||||
response = client.post(
|
||||
@@ -326,13 +421,23 @@ class TestRunSingleTask:
|
||||
@patch("endpoints.tasks.low_prio_queue")
|
||||
@patch(
|
||||
"endpoints.tasks.manual_tasks",
|
||||
{
|
||||
"non_manual_task": Mock(
|
||||
spec=Task, enabled=True, manual_run=False, run=Mock()
|
||||
)
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "non_manual_task",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.CLEANUP,
|
||||
title="Non-Manual Task",
|
||||
description="Non-Manual Description",
|
||||
enabled=True,
|
||||
manual_run=False,
|
||||
run=Mock(),
|
||||
),
|
||||
}
|
||||
],
|
||||
)
|
||||
@patch("endpoints.tasks.scheduled_tasks", {})
|
||||
@patch("endpoints.tasks.scheduled_tasks", [])
|
||||
def test_run_single_task_non_manual(self, mock_queue, client, access_token):
|
||||
"""Test running a task that cannot be run manually"""
|
||||
response = client.post(
|
||||
@@ -367,9 +472,14 @@ class TestGetTaskById:
|
||||
mock_job.started_at.isoformat.return_value = "2023-01-01T00:01:00"
|
||||
mock_job.ended_at = Mock()
|
||||
mock_job.ended_at.isoformat.return_value = "2023-01-01T00:02:00"
|
||||
mock_job.meta = {"task_name": "test_task"}
|
||||
mock_job.get_meta.return_value = {
|
||||
"task_name": "test_task",
|
||||
"task_type": TaskType.CLEANUP,
|
||||
}
|
||||
mock_job.func_name = "test_task"
|
||||
mock_job.get_status.return_value = "finished"
|
||||
mock_job.get_id.return_value = "test-job-id-123"
|
||||
mock_job.result = {"status": "completed"}
|
||||
|
||||
mock_job_fetch.return_value = mock_job
|
||||
|
||||
@@ -422,9 +532,14 @@ class TestGetTaskById:
|
||||
mock_job.started_at.isoformat.return_value = "2023-01-01T00:01:00"
|
||||
mock_job.ended_at = Mock()
|
||||
mock_job.ended_at.isoformat.return_value = "2023-01-01T00:01:30"
|
||||
mock_job.meta = {"task_name": "test_task"}
|
||||
mock_job.get_meta.return_value = {
|
||||
"task_name": "test_task",
|
||||
"task_type": TaskType.CLEANUP,
|
||||
}
|
||||
mock_job.func_name = "test_task"
|
||||
mock_job.get_status.return_value = "failed"
|
||||
mock_job.get_id.return_value = "failed-job-id"
|
||||
mock_job.result = {"error": "Task failed"}
|
||||
|
||||
mock_job_fetch.return_value = mock_job
|
||||
|
||||
@@ -438,36 +553,6 @@ class TestGetTaskById:
|
||||
|
||||
assert data["status"] == "failed"
|
||||
|
||||
@patch("endpoints.tasks.low_prio_queue")
|
||||
@patch("endpoints.tasks.Job.fetch")
|
||||
def test_get_task_by_id_no_metadata(
|
||||
self, mock_job_fetch, mock_queue, client, access_token
|
||||
):
|
||||
"""Test retrieval of a task with no metadata"""
|
||||
mock_job = Mock()
|
||||
mock_job.created_at = Mock()
|
||||
mock_job.created_at.isoformat.return_value = "2023-01-01T00:00:00"
|
||||
mock_job.started_at = None
|
||||
mock_job.ended_at = None
|
||||
mock_job.meta = None
|
||||
mock_job.func_name = "test_task"
|
||||
mock_job.get_status.return_value = "queued"
|
||||
|
||||
mock_job_fetch.return_value = mock_job
|
||||
|
||||
response = client.get(
|
||||
"/api/tasks/queued-job-id",
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
data = response.json()
|
||||
|
||||
assert data["task_name"] == "test_task"
|
||||
assert data["status"] == "queued"
|
||||
assert data["started_at"] is None
|
||||
assert data["ended_at"] is None
|
||||
|
||||
def test_get_task_by_id_unauthorized(self, client):
|
||||
"""Test retrieval of a task without authentication"""
|
||||
response = client.get("/api/tasks/test-job-id")
|
||||
@@ -485,6 +570,7 @@ class TestTaskInfoBuilding:
|
||||
# Mock the helper function to return a known structure
|
||||
mock_build_task_info.return_value = {
|
||||
"name": "test_task",
|
||||
"type": TaskType.CLEANUP,
|
||||
"title": "Test Task",
|
||||
"description": "Test Description",
|
||||
"enabled": True,
|
||||
@@ -494,18 +580,22 @@ class TestTaskInfoBuilding:
|
||||
|
||||
with patch(
|
||||
"endpoints.tasks.manual_tasks",
|
||||
{
|
||||
"test_task": Mock(
|
||||
spec=Task,
|
||||
title="Test Task",
|
||||
description="Test Description",
|
||||
enabled=True,
|
||||
manual_run=True,
|
||||
cron_string="0 0 * * *",
|
||||
)
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "test_task",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
title="Test Task",
|
||||
description="Test Description",
|
||||
enabled=True,
|
||||
manual_run=True,
|
||||
cron_string="0 0 * * *",
|
||||
),
|
||||
}
|
||||
],
|
||||
):
|
||||
with patch("endpoints.tasks.scheduled_tasks", {}):
|
||||
with patch("endpoints.tasks.scheduled_tasks", []):
|
||||
response = client.get(
|
||||
"/api/tasks", headers={"Authorization": f"Bearer {access_token}"}
|
||||
)
|
||||
@@ -536,13 +626,23 @@ class TestIntegration:
|
||||
# Then run a specific task (if any exist)
|
||||
with patch(
|
||||
"endpoints.tasks.manual_tasks",
|
||||
{
|
||||
"workflow_task": Mock(
|
||||
spec=Task, enabled=True, manual_run=True, run=Mock()
|
||||
)
|
||||
},
|
||||
[
|
||||
{
|
||||
"name": "workflow_task",
|
||||
"type": TaskType.CLEANUP,
|
||||
"task": Mock(
|
||||
spec=Task,
|
||||
task_type=TaskType.CLEANUP,
|
||||
title="Workflow Task",
|
||||
description="Workflow Description",
|
||||
enabled=True,
|
||||
manual_run=True,
|
||||
run=Mock(),
|
||||
),
|
||||
}
|
||||
],
|
||||
):
|
||||
with patch("endpoints.tasks.scheduled_tasks", {}):
|
||||
with patch("endpoints.tasks.scheduled_tasks", []):
|
||||
run_response = client.post(
|
||||
"/api/tasks/run/workflow_task",
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
|
||||
@@ -5,7 +5,7 @@ import pytest
|
||||
from rq.job import Job
|
||||
|
||||
from exceptions.task_exceptions import SchedulerException
|
||||
from tasks.tasks import PeriodicTask, RemoteFilePullTask, tasks_scheduler
|
||||
from tasks.tasks import PeriodicTask, RemoteFilePullTask, TaskType, tasks_scheduler
|
||||
|
||||
|
||||
class ConcretePeriodicTask(PeriodicTask):
|
||||
@@ -22,6 +22,7 @@ class TestPeriodicTask:
|
||||
func="test.function",
|
||||
title="Test Task",
|
||||
description="test task",
|
||||
task_type=TaskType.GENERIC,
|
||||
enabled=True,
|
||||
cron_string="0 0 * * *",
|
||||
)
|
||||
@@ -32,6 +33,7 @@ class TestPeriodicTask:
|
||||
func="test.disabled.function",
|
||||
title="Disabled Task",
|
||||
description="disabled task",
|
||||
task_type=TaskType.GENERIC,
|
||||
enabled=False,
|
||||
cron_string="0 0 * * *",
|
||||
)
|
||||
@@ -133,7 +135,11 @@ class TestPeriodicTask:
|
||||
result = task.schedule()
|
||||
|
||||
mock_cron.assert_called_once_with(
|
||||
"0 0 * * *", func="test.function", repeat=None, timeout=5 * 60
|
||||
"0 0 * * *",
|
||||
func="test.function",
|
||||
repeat=None,
|
||||
timeout=5 * 60,
|
||||
meta={"task_name": "Test Task", "task_type": "generic"},
|
||||
)
|
||||
assert result == mock_job
|
||||
|
||||
@@ -161,6 +167,7 @@ class TestPeriodicTask:
|
||||
task = ConcretePeriodicTask(
|
||||
func="test.function",
|
||||
title="Test Task",
|
||||
task_type=TaskType.GENERIC,
|
||||
description="test task",
|
||||
enabled=True,
|
||||
cron_string=None,
|
||||
@@ -207,6 +214,7 @@ class TestRemoteFilePullTask:
|
||||
return RemoteFilePullTask(
|
||||
func="test.remote.function",
|
||||
title="Remote Test Task",
|
||||
task_type=TaskType.UPDATE,
|
||||
description="remote test task",
|
||||
enabled=True,
|
||||
cron_string="0 0 * * *",
|
||||
@@ -218,6 +226,7 @@ class TestRemoteFilePullTask:
|
||||
return RemoteFilePullTask(
|
||||
func="test.remote.disabled.function",
|
||||
title="Disabled Remote Task",
|
||||
task_type=TaskType.UPDATE,
|
||||
description="disabled remote task",
|
||||
enabled=False,
|
||||
url="https://example.com/data.json",
|
||||
@@ -226,6 +235,7 @@ class TestRemoteFilePullTask:
|
||||
def test_init(self, task):
|
||||
"""Test RemoteFilePullTask initialization"""
|
||||
assert task.func == "test.remote.function"
|
||||
assert task.task_type == TaskType.UPDATE
|
||||
assert task.description == "remote test task"
|
||||
assert task.enabled is True
|
||||
assert task.url == "https://example.com/data.json"
|
||||
|
||||
Reference in New Issue
Block a user