feat: expand platform APIs, sources, and test coverage
Some checks failed
CI/CD Pipeline / Run Tests (pull_request) Successful in 1m53s
CI/CD Pipeline / Telegram Notify Success (push) Has been cancelled
CI/CD Pipeline / Run Tests (push) Has been cancelled
CI/CD Pipeline / Code Quality Checks (push) Has been cancelled
CI/CD Pipeline / Code Quality Checks (pull_request) Failing after 2m54s
CI/CD Pipeline / Telegram Notify Success (pull_request) Has been skipped

This commit is contained in:
2026-03-17 12:56:48 +01:00
parent b505c67968
commit 3d298ce352
101 changed files with 8387 additions and 292 deletions

View File

@@ -0,0 +1,122 @@
from __future__ import annotations
from pathlib import Path
from tempfile import TemporaryDirectory
from types import SimpleNamespace
from unittest.mock import MagicMock, patch
from apps.backups.models import BackupExportJob
from apps.backups.services import BackupArtifact
from apps.backups.tasks import _resolve_backup_target_path, generate_backup_for_date
from django.test import TestCase, override_settings
from tests.apps.user.factories import UserFactory
class BackupTasksTest(TestCase):
def test_resolve_backup_target_path_creates_directory_and_renames_existing_file(self):
with TemporaryDirectory() as tmp_dir:
with override_settings(BACKUP_EXPORT_DIRECTORY=tmp_dir):
existing = Path(tmp_dir) / "backup.zip"
existing.write_bytes(b"existing")
with patch("apps.backups.tasks.uuid.uuid4") as uuid_mock:
uuid_mock.return_value.hex = "deadbeefcafebabe"
target = _resolve_backup_target_path("backup.zip")
self.assertEqual(target.name, "backup_deadbeef.zip")
def test_generate_backup_for_date_returns_skipped_when_job_is_missing(self):
generate_backup_for_date.push_request(id="task-missing")
try:
result = generate_backup_for_date.run(job_id=999999)
finally:
generate_backup_for_date.pop_request()
self.assertEqual(result, {"status": "skipped", "reason": "job_not_found"})
def test_generate_backup_for_date_builds_archive_and_updates_job(self):
user = UserFactory.create_user()
job = BackupExportJob.objects.create(
actual_date=user.date_joined.date(),
requested_by=user,
status=BackupExportJob.Status.PENDING,
)
background_job = MagicMock()
artifact = BackupArtifact(
archive_bytes=b"zip-bytes",
archive_filename="backup.zip",
bin_filename="backup.bin",
checksum_filename="backup.zip.sha256",
checksum_sha256="a" * 64,
organizations_count=5,
actual_date=job.actual_date,
)
with TemporaryDirectory() as tmp_dir:
with override_settings(BACKUP_EXPORT_DIRECTORY=tmp_dir):
generate_backup_for_date.push_request(id="task-success")
try:
with patch(
"apps.backups.tasks.BackgroundJobService.get_by_task_id_or_none",
return_value=None,
):
with patch(
"apps.backups.tasks.BackgroundJobService.create_job",
return_value=background_job,
) as create_job_mock:
with patch(
"apps.backups.tasks.BackupExportService.build_backup_archive",
return_value=artifact,
) as build_mock:
result = generate_backup_for_date.run(job_id=job.id)
finally:
generate_backup_for_date.pop_request()
job.refresh_from_db()
self.assertEqual(job.status, BackupExportJob.Status.SUCCESS)
self.assertEqual(job.task_id, "task-success")
self.assertEqual(job.archive_filename, "backup.zip")
self.assertEqual(job.checksum_filename, "backup.zip.sha256")
self.assertEqual(job.organizations_count, 5)
self.assertTrue(Path(job.archive_path).is_file())
self.assertEqual(result["status"], "success")
self.assertEqual(result["archive_filename"], "backup.zip")
create_job_mock.assert_called_once()
build_mock.assert_called_once_with(actual_date=job.actual_date)
background_job.mark_started.assert_called_once_with()
background_job.update_progress.assert_any_call(10, "Подготовка backup-данных")
background_job.update_progress.assert_any_call(70, "Запись архива на диск")
background_job.complete.assert_called_once_with(result=result)
def test_generate_backup_for_date_marks_failure(self):
user = UserFactory.create_user()
job = BackupExportJob.objects.create(
actual_date=user.date_joined.date(),
requested_by=user,
status=BackupExportJob.Status.PENDING,
)
background_job = MagicMock()
generate_backup_for_date.push_request(id="task-failure")
try:
with patch(
"apps.backups.tasks.BackgroundJobService.get_by_task_id_or_none",
return_value=background_job,
):
with patch(
"apps.backups.tasks.BackupExportService.build_backup_archive",
side_effect=RuntimeError("boom"),
):
with patch("apps.backups.tasks.logger.exception") as logger_mock:
with self.assertRaisesMessage(RuntimeError, "boom"):
generate_backup_for_date.run(job_id=job.id)
finally:
generate_backup_for_date.pop_request()
logger_mock.assert_called_once()
background_job.fail.assert_called_once_with(error="boom")
job.refresh_from_db()
self.assertEqual(job.status, BackupExportJob.Status.FAILURE)
self.assertEqual(job.error, "boom")