/
tsps
/
case_loader
Обзор
Документация
Войти
/
tsps
/
case_loader
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
tests/test_job_processor.py
145 строк
7 KB
Василий Петров
Разрешаем перезапуск failed-задач
01 мар 2026, 20:02
01 мар 2026, 20:02
9c0c73b
Код
Авторство
О чём код?
from unittest.mock import Mock, patch from app.services.job_processor import process_document_import_job class TestJobProcessor: def test_process_job_success(self): """Тест успешной обработки задачи: статус меняется на in_progress → completed с результатом""" # Мокаем зависимости mock_search_params = { "judge_id": 42, "court_id": 7, "document_type_id": 3, "date_from": "2026-01-01", "date_to": "2026-01-31" } mock_result = { "total_documents_found": 5, "successfully_saved": 5 } # Создаём моки mock_parser = Mock() mock_fetcher = Mock() mock_fetcher.fetch_cases.return_value = mock_result # Патчим зависимости with patch("app.services.job_processor._get_job_status_and_params", return_value=('created', mock_search_params)), \ patch("app.services.job_processor._update_job_status") as mock_update_status, \ patch("app.services.job_processor.PdfParser", return_value=mock_parser), \ patch("app.services.job_processor.DataFetcher", return_value=mock_fetcher): # Вызываем тестируемый метод process_document_import_job(job_id=123) # Проверяем последовательность вызовов обновления статуса assert mock_update_status.call_count == 2 # Первый вызов: in_progress call1 = mock_update_status.call_args_list[0] assert call1.args[1] == 123 # job_id assert call1.args[2] == "in_progress" # status # Второй вызов: completed с результатом call2 = mock_update_status.call_args_list[1] assert call2.args[1] == 123 # job_id assert call2.args[2] == "completed" # status assert call2.kwargs.get("result_summary") == mock_result # Проверяем, что фетчер вызвался с правильными параметрами mock_fetcher.fetch_cases.assert_called_once_with(mock_search_params) def test_process_job_failure(self): """Тест обработки ошибки: статус меняется на failed с сообщением об ошибке""" mock_search_params = { "judge_id": 42, "court_id": 7, "document_type_id": 3, "date_from": "2026-01-01", "date_to": "2026-01-31" } # Патчим зависимости with patch("app.services.job_processor._get_job_status_and_params", return_value=('created', mock_search_params)), \ patch("app.services.job_processor._update_job_status") as mock_update_status, \ patch("app.services.job_processor.PdfParser"), \ patch("app.services.job_processor.DataFetcher") as mock_fetcher_class: # Настраиваем фетчер на выброс исключения mock_fetcher = Mock() mock_fetcher.fetch_cases.side_effect = Exception("Ошибка при скачивании PDF") mock_fetcher_class.return_value = mock_fetcher # Вызываем тестируемый метод и ждём исключение try: process_document_import_job(job_id=123) assert False, "Должно было выброситься исключение" except Exception as e: assert str(e) == "Ошибка при скачивании PDF" # Проверяем последовательность вызовов обновления статуса assert mock_update_status.call_count == 2 # Первый вызов: in_progress call1 = mock_update_status.call_args_list[0] assert call1.args[2] == "in_progress" # Второй вызов: failed с сообщением об ошибке call2 = mock_update_status.call_args_list[1] assert call2.args[2] == "failed" assert call2.kwargs.get("error_message") == "Ошибка при скачивании PDF" def test_process_job_not_found(self): """Тест: задача не найдена в базе данных""" # Патчим _get_job_status_and_params на выброс ValueError with patch("app.services.job_processor._get_job_status_and_params", side_effect=ValueError("Задача с ID 999 не найдена")): # Вызываем тестируемый метод и ждём исключение try: process_document_import_job(job_id=999) assert False, "Должно было выброситься исключение" except ValueError as e: assert str(e) == "Задача с ID 999 не найдена" def test_process_job_restart_from_failed(self): """Тест перезапуска задачи: статус 'failed' допускает повторную обработку""" mock_search_params = {"judge_id": 42} mock_result = {"total_documents_found": 2, "successfully_saved": 2} mock_parser = Mock() mock_fetcher = Mock() mock_fetcher.fetch_cases.return_value = mock_result with patch("app.services.job_processor._get_job_status_and_params", return_value=('failed', mock_search_params)), \ patch("app.services.job_processor._update_job_status") as mock_update_status, \ patch("app.services.job_processor.PdfParser", return_value=mock_parser), \ patch("app.services.job_processor.DataFetcher", return_value=mock_fetcher): process_document_import_job(job_id=456) # Задача со статусом 'failed' должна обработаться assert mock_update_status.call_count == 2 assert mock_update_status.call_args_list[0].args[2] == "in_progress" assert mock_update_status.call_args_list[1].args[2] == "completed" mock_fetcher.fetch_cases.assert_called_once_with(mock_search_params) def test_process_job_skips_in_progress(self): """Тест: задача со статусом 'in_progress' пропускается (защита от дублей)""" with patch("app.services.job_processor._get_job_status_and_params", return_value=('in_progress', {})), \ patch("app.services.job_processor._update_job_status") as mock_update_status, \ patch("app.services.job_processor.PdfParser"), \ patch("app.services.job_processor.DataFetcher") as mock_fetcher_class: process_document_import_job(job_id=789) # Статус не должен обновляться, фетчер не должен вызываться mock_update_status.assert_not_called() mock_fetcher_class.assert_not_called()