(feature) Add staff-only Django dashboard views
Add a small template-based UI for inspecting pobsync state through Django. The dashboard shows host, schedule, snapshot, and backup run summaries, while host detail pages show config, schedule, recent runs, and discovered snapshots. Keep the views read-only and staff-protected, document the new dashboard URL, and cover the routes with focused view tests.
This commit is contained in:
83
src/pobsync_backend/tests/test_views.py
Normal file
83
src/pobsync_backend/tests/test_views.py
Normal file
@@ -0,0 +1,83 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from pobsync_backend.models import BackupRun, HostConfig, ScheduleConfig, SnapshotRecord
|
||||
|
||||
|
||||
class ViewTests(TestCase):
|
||||
def setUp(self) -> None:
|
||||
user_model = get_user_model()
|
||||
self.staff_user = user_model.objects.create_user(
|
||||
username="admin",
|
||||
password="secret",
|
||||
is_staff=True,
|
||||
is_superuser=True,
|
||||
)
|
||||
|
||||
def test_dashboard_requires_staff_login(self) -> None:
|
||||
response = self.client.get(reverse("dashboard"))
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertIn("/admin/login/", response["Location"])
|
||||
|
||||
def test_dashboard_renders_hosts_and_latest_runs(self) -> None:
|
||||
self.client.force_login(self.staff_user)
|
||||
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
||||
snapshot = self._snapshot(host, "20260519-021500Z__ABCDEFGH")
|
||||
BackupRun.objects.create(
|
||||
host=host,
|
||||
status=BackupRun.Status.SUCCESS,
|
||||
snapshot=snapshot,
|
||||
started_at=datetime(2026, 5, 19, 2, 15, tzinfo=timezone.utc),
|
||||
)
|
||||
|
||||
response = self.client.get(reverse("dashboard"))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, "Dashboard")
|
||||
self.assertContains(response, "web-01")
|
||||
self.assertContains(response, "20260519-021500Z__ABCDEFGH")
|
||||
self.assertContains(response, "success")
|
||||
|
||||
def test_host_detail_renders_config_schedule_runs_and_snapshots(self) -> None:
|
||||
self.client.force_login(self.staff_user)
|
||||
host = HostConfig.objects.create(
|
||||
host="web-01",
|
||||
address="web-01.example.test",
|
||||
source_root="/srv",
|
||||
retention_daily=7,
|
||||
)
|
||||
ScheduleConfig.objects.create(host=host, cron_expr="15 2 * * *", prune=True, last_status="success")
|
||||
snapshot = self._snapshot(host, "20260519-021500Z__ABCDEFGH")
|
||||
BackupRun.objects.create(host=host, status=BackupRun.Status.SUCCESS, snapshot=snapshot)
|
||||
|
||||
response = self.client.get(reverse("host_detail", args=[host.host]))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, "web-01")
|
||||
self.assertContains(response, "web-01.example.test")
|
||||
self.assertContains(response, "15 2 * * *")
|
||||
self.assertContains(response, "20260519-021500Z__ABCDEFGH")
|
||||
|
||||
def test_host_detail_returns_404_for_unknown_host(self) -> None:
|
||||
self.client.force_login(self.staff_user)
|
||||
|
||||
response = self.client.get(reverse("host_detail", args=["missing-host"]))
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def _snapshot(self, host: HostConfig, dirname: str) -> SnapshotRecord:
|
||||
started_at = datetime.strptime(dirname.split("__", 1)[0], "%Y%m%d-%H%M%SZ").replace(tzinfo=timezone.utc)
|
||||
return SnapshotRecord.objects.create(
|
||||
host=host,
|
||||
kind=SnapshotRecord.Kind.SCHEDULED,
|
||||
dirname=dirname,
|
||||
path=f"/backups/{host.host}/scheduled/{dirname}",
|
||||
status="success",
|
||||
started_at=started_at,
|
||||
)
|
||||
Reference in New Issue
Block a user