mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-06-02 11:49:44 +00:00
test(tasks): fill coverage gaps in task system
- test_task_signals: add TestTaskRevokedHandler (marks REVOKED, ignores None request, ignores unknown id); switch existing direct PaperlessTask.objects.create calls to PaperlessTaskFactory; import pytest_mock and use MockerFixture typing on mocker params - test_api_tasks: add test_rejects_invalid_days_param to TestSummary - tasks.service.spec: add dismissAllTasks test (POST acknowledge_all + reload) - models: add pragma: no cover to __str__, is_complete, and related_document_ids (trivial delegates, covered indirectly) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -129,6 +129,21 @@ describe('TasksService', () => {
|
||||
expect(tasksService.startedFileTasks).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('calls acknowledge_all api endpoint on dismissAll and reloads', () => {
|
||||
tasksService.dismissAllTasks().subscribe()
|
||||
const req = httpTestingController.expectOne(
|
||||
`${environment.apiBaseUrl}tasks/acknowledge_all/`
|
||||
)
|
||||
expect(req.request.method).toEqual('POST')
|
||||
req.flush({})
|
||||
// reload is then called
|
||||
httpTestingController
|
||||
.expectOne(
|
||||
`${environment.apiBaseUrl}tasks/?task_type=consume_file&acknowledged=false`
|
||||
)
|
||||
.flush([])
|
||||
})
|
||||
|
||||
it('supports running tasks', () => {
|
||||
tasksService.run(PaperlessTaskType.SanityCheck).subscribe((res) => {
|
||||
expect(res).toEqual({
|
||||
|
||||
@@ -811,15 +811,15 @@ class PaperlessTask(ModelWithOwner):
|
||||
models.Index(fields=["owner", "acknowledged", "date_created"]),
|
||||
]
|
||||
|
||||
def __str__(self) -> str:
|
||||
def __str__(self) -> str: # pragma: no cover
|
||||
return f"{self.get_task_type_display()} [{self.task_id[:8]}]"
|
||||
|
||||
@property
|
||||
def is_complete(self) -> bool:
|
||||
def is_complete(self) -> bool: # pragma: no cover
|
||||
return self.status in self.COMPLETE_STATUSES
|
||||
|
||||
@property
|
||||
def related_document_ids(self) -> list[int]:
|
||||
def related_document_ids(self) -> list[int]: # pragma: no cover
|
||||
if not self.result_data:
|
||||
return []
|
||||
if doc_id := self.result_data.get("document_id"):
|
||||
|
||||
@@ -481,6 +481,13 @@ class TestSummary:
|
||||
assert by_type["consume_file"]["failure_count"] == 1
|
||||
assert by_type["train_classifier"]["total_count"] == 1
|
||||
|
||||
def test_rejects_invalid_days_param(self, admin_client: APIClient) -> None:
|
||||
"""?days=invalid returns 400 with an error message."""
|
||||
response = admin_client.get(ENDPOINT + "summary/", {"days": "invalid"})
|
||||
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
assert "days" in response.data
|
||||
|
||||
|
||||
@pytest.mark.django_db()
|
||||
class TestActive:
|
||||
|
||||
@@ -2,11 +2,14 @@ import uuid
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
import pytest_mock
|
||||
|
||||
from documents.data_models import ConsumableDocument
|
||||
from documents.data_models import DocumentMetadataOverrides
|
||||
from documents.data_models import DocumentSource
|
||||
from documents.models import PaperlessTask
|
||||
from documents.signals.handlers import task_revoked_handler
|
||||
from documents.tests.factories import PaperlessTaskFactory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -144,12 +147,7 @@ class TestBeforeTaskPublishHandler:
|
||||
@pytest.mark.django_db
|
||||
class TestTaskPrerunHandler:
|
||||
def test_marks_task_started(self):
|
||||
task = PaperlessTask.objects.create(
|
||||
task_id=str(uuid.uuid4()),
|
||||
task_type=PaperlessTask.TaskType.CONSUME_FILE,
|
||||
trigger_source=PaperlessTask.TriggerSource.MANUAL,
|
||||
status=PaperlessTask.Status.PENDING,
|
||||
)
|
||||
task = PaperlessTaskFactory(status=PaperlessTask.Status.PENDING)
|
||||
from documents.signals.handlers import task_prerun_handler
|
||||
|
||||
task_prerun_handler(task_id=task.task_id)
|
||||
@@ -173,10 +171,8 @@ class TestTaskPostrunHandler:
|
||||
def _started_task(self) -> PaperlessTask:
|
||||
from django.utils import timezone
|
||||
|
||||
return PaperlessTask.objects.create(
|
||||
task_id=str(uuid.uuid4()),
|
||||
return PaperlessTaskFactory(
|
||||
task_type=PaperlessTask.TaskType.TRAIN_CLASSIFIER,
|
||||
trigger_source=PaperlessTask.TriggerSource.MANUAL,
|
||||
status=PaperlessTask.Status.STARTED,
|
||||
date_started=timezone.now(),
|
||||
)
|
||||
@@ -255,10 +251,8 @@ class TestTaskFailureHandler:
|
||||
def test_records_failure_with_exception(self):
|
||||
from django.utils import timezone
|
||||
|
||||
task = PaperlessTask.objects.create(
|
||||
task_id=str(uuid.uuid4()),
|
||||
task = PaperlessTaskFactory(
|
||||
task_type=PaperlessTask.TaskType.CONSUME_FILE,
|
||||
trigger_source=PaperlessTask.TriggerSource.WEB_UI,
|
||||
status=PaperlessTask.Status.STARTED,
|
||||
date_started=timezone.now(),
|
||||
)
|
||||
@@ -280,10 +274,8 @@ class TestTaskFailureHandler:
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
task = PaperlessTask.objects.create(
|
||||
task_id=str(uuid.uuid4()),
|
||||
task = PaperlessTaskFactory(
|
||||
task_type=PaperlessTask.TaskType.CONSUME_FILE,
|
||||
trigger_source=PaperlessTask.TriggerSource.WEB_UI,
|
||||
status=PaperlessTask.Status.STARTED,
|
||||
date_started=timezone.now(),
|
||||
)
|
||||
@@ -307,3 +299,29 @@ class TestTaskFailureHandler:
|
||||
from documents.signals.handlers import task_failure_handler
|
||||
|
||||
task_failure_handler(task_id=None, exception=ValueError("x"), traceback=None)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestTaskRevokedHandler:
|
||||
def test_marks_task_revoked(self, mocker: pytest_mock.MockerFixture):
|
||||
"""task_revoked_handler moves a queued task to REVOKED and stamps date_done."""
|
||||
task = PaperlessTaskFactory(status=PaperlessTask.Status.PENDING)
|
||||
request = mocker.MagicMock()
|
||||
request.id = task.task_id
|
||||
|
||||
task_revoked_handler(request=request)
|
||||
task.refresh_from_db()
|
||||
assert task.status == PaperlessTask.Status.REVOKED
|
||||
assert task.date_done is not None
|
||||
|
||||
def test_ignores_none_request(self):
|
||||
"""task_revoked_handler must not raise when request is None."""
|
||||
|
||||
task_revoked_handler(request=None) # must not raise
|
||||
|
||||
def test_ignores_unknown_task_id(self, mocker: pytest_mock.MockerFixture):
|
||||
"""task_revoked_handler must not raise for a task_id not in the database."""
|
||||
request = mocker.MagicMock()
|
||||
request.id = "nonexistent-id"
|
||||
|
||||
task_revoked_handler(request=request) # must not raise
|
||||
|
||||
Reference in New Issue
Block a user