Improve Django admin navigation for backup data
Add linked admin summaries for hosts, snapshots, and backup runs so the SQL-first backup state is easier to inspect from the Django admin. Hosts now link to their filtered snapshot and run lists, backup runs link back to their snapshot, and snapshots show base/run relationships without requiring filesystem inspection. Cover the new admin display helpers with focused tests.
This commit is contained in:
96
src/pobsync_backend/tests/test_admin.py
Normal file
96
src/pobsync_backend/tests/test_admin.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from django.contrib.admin.sites import AdminSite
|
||||
from django.test import TestCase
|
||||
|
||||
from pobsync_backend.admin import BackupRunAdmin, HostConfigAdmin, SnapshotRecordAdmin
|
||||
from pobsync_backend.models import BackupRun, HostConfig, ScheduleConfig, SnapshotRecord
|
||||
|
||||
|
||||
class AdminDisplayTests(TestCase):
|
||||
def test_host_admin_links_to_related_snapshots_and_runs(self) -> None:
|
||||
site = AdminSite()
|
||||
admin = HostConfigAdmin(HostConfig, site)
|
||||
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
||||
snapshot = SnapshotRecord.objects.create(
|
||||
host=host,
|
||||
kind="scheduled",
|
||||
dirname="20260519-021500Z__ABCDEFGH",
|
||||
path="/backups/web-01/scheduled/20260519-021500Z__ABCDEFGH",
|
||||
)
|
||||
BackupRun.objects.create(host=host, status=BackupRun.Status.SUCCESS, snapshot=snapshot)
|
||||
|
||||
snapshot_link = str(admin.snapshot_count_link(host))
|
||||
run_link = str(admin.backup_run_count_link(host))
|
||||
|
||||
self.assertIn("/admin/pobsync_backend/snapshotrecord/", snapshot_link)
|
||||
self.assertIn(f"host__id__exact={host.pk}", snapshot_link)
|
||||
self.assertIn(">1<", snapshot_link)
|
||||
self.assertIn("/admin/pobsync_backend/backuprun/", run_link)
|
||||
self.assertIn(f"host__id__exact={host.pk}", run_link)
|
||||
self.assertIn(">1<", run_link)
|
||||
|
||||
def test_host_admin_summarizes_schedule_and_latest_run(self) -> None:
|
||||
site = AdminSite()
|
||||
admin = HostConfigAdmin(HostConfig, site)
|
||||
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
||||
|
||||
self.assertEqual(admin.schedule_state(host), "none")
|
||||
|
||||
ScheduleConfig.objects.create(host=host, cron_expr="15 2 * * *", enabled=True)
|
||||
host.refresh_from_db()
|
||||
BackupRun.objects.create(
|
||||
host=host,
|
||||
status=BackupRun.Status.SUCCESS,
|
||||
started_at=datetime(2026, 5, 19, 2, 15, tzinfo=timezone.utc),
|
||||
)
|
||||
|
||||
self.assertEqual(admin.schedule_state(host), "15 2 * * *")
|
||||
self.assertEqual(admin.latest_run_state(host), "success 2026-05-19 02:15")
|
||||
|
||||
def test_snapshot_admin_links_to_base_and_backup_runs(self) -> None:
|
||||
site = AdminSite()
|
||||
admin = SnapshotRecordAdmin(SnapshotRecord, site)
|
||||
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
||||
base = SnapshotRecord.objects.create(
|
||||
host=host,
|
||||
kind="scheduled",
|
||||
dirname="20260518-021500Z__BASESNAP",
|
||||
path="/backups/web-01/scheduled/20260518-021500Z__BASESNAP",
|
||||
)
|
||||
child = SnapshotRecord.objects.create(
|
||||
host=host,
|
||||
kind="scheduled",
|
||||
dirname="20260519-021500Z__CHILDSNP",
|
||||
path="/backups/web-01/scheduled/20260519-021500Z__CHILDSNP",
|
||||
base=base,
|
||||
)
|
||||
BackupRun.objects.create(host=host, status=BackupRun.Status.SUCCESS, snapshot=child)
|
||||
|
||||
base_link = str(admin.base_link(child))
|
||||
run_link = str(admin.backup_run_count_link(child))
|
||||
|
||||
self.assertIn(f"/admin/pobsync_backend/snapshotrecord/{base.pk}/change/", base_link)
|
||||
self.assertIn(base.dirname, base_link)
|
||||
self.assertIn("/admin/pobsync_backend/backuprun/", run_link)
|
||||
self.assertIn(f"snapshot__id__exact={child.pk}", run_link)
|
||||
self.assertIn(">1<", run_link)
|
||||
|
||||
def test_backup_run_admin_links_to_snapshot(self) -> None:
|
||||
site = AdminSite()
|
||||
admin = BackupRunAdmin(BackupRun, site)
|
||||
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
||||
snapshot = SnapshotRecord.objects.create(
|
||||
host=host,
|
||||
kind="scheduled",
|
||||
dirname="20260519-021500Z__ABCDEFGH",
|
||||
path="/backups/web-01/scheduled/20260519-021500Z__ABCDEFGH",
|
||||
)
|
||||
run = BackupRun.objects.create(host=host, status=BackupRun.Status.SUCCESS, snapshot=snapshot)
|
||||
|
||||
snapshot_link = str(admin.snapshot_link(run))
|
||||
|
||||
self.assertIn(f"/admin/pobsync_backend/snapshotrecord/{snapshot.pk}/change/", snapshot_link)
|
||||
self.assertIn(snapshot.dirname, snapshot_link)
|
||||
Reference in New Issue
Block a user