feat(main): main

This commit is contained in:
2026-03-20 15:00:24 -04:00
parent af3076342a
commit c9718c5483
30 changed files with 2513 additions and 559 deletions

53
api/tests/test_auth.py Normal file
View File

@@ -0,0 +1,53 @@
import json
import pytest
from core.models import AppUser
@pytest.mark.django_db
def test_login_sets_bounded_session_expiry(client, settings):
settings.SESSION_COOKIE_AGE = 3600
AppUser.objects.create_user(
username="auth_user",
email="auth@example.com",
password="secret-pass-123",
)
response = client.post(
"/api/auth/login",
data=json.dumps({"username": "auth_user", "password": "secret-pass-123"}),
content_type="application/json",
)
assert response.status_code == 200
assert response.json()["success"] is True
# Session should be persisted, but bounded to SESSION_COOKIE_AGE.
assert 0 < client.session.get_expiry_age() <= settings.SESSION_COOKIE_AGE
@pytest.mark.django_db
def test_logout_forces_session_logout(client):
AppUser.objects.create_user(
username="logout_user",
email="logout@example.com",
password="secret-pass-123",
)
login_response = client.post(
"/api/auth/login",
data=json.dumps({"username": "logout_user", "password": "secret-pass-123"}),
content_type="application/json",
)
assert login_response.status_code == 200
assert client.get("/api/auth/me").status_code == 200
logout_response = client.post("/api/auth/logout")
assert logout_response.status_code == 200
# Session is no longer authenticated after explicit logout.
assert client.get("/api/auth/me").status_code == 401

82
api/tests/test_backups.py Normal file
View File

@@ -0,0 +1,82 @@
import json
from pathlib import Path
import pytest
from core.models import AppUser, BackupSchedule, Library, MediaSource, MediaItem
@pytest.fixture
def admin_user(db):
return AppUser.objects.create_superuser("backup_admin", "backup@example.com", "secret-pass-123")
@pytest.mark.django_db
def test_backup_schedule_requires_admin(client):
response = client.get("/api/backups/settings")
assert response.status_code == 401
@pytest.mark.django_db
def test_backup_schedule_get_and_update(client, admin_user):
client.login(username="backup_admin", password="secret-pass-123")
response = client.get("/api/backups/settings")
assert response.status_code == 200
payload = {
"enabled": True,
"frequency": "weekly",
"minute": 30,
"hour": 3,
"day_of_week": 6,
"day_of_month": 1,
"retention_count": 5,
}
update = client.put(
"/api/backups/settings",
data=json.dumps(payload),
content_type="application/json",
)
assert update.status_code == 200
schedule = BackupSchedule.get_solo()
assert schedule.enabled is True
assert schedule.frequency == "weekly"
assert schedule.retention_count == 5
@pytest.mark.django_db
def test_backup_now_writes_json_and_strips_cached_paths(client, admin_user, settings, tmp_path):
settings.BACKUP_ROOT = str(tmp_path)
client.login(username="backup_admin", password="secret-pass-123")
library = Library.objects.create(owner_user=admin_user, name="Backup Lib")
source = MediaSource.objects.create(
library=library,
name="YT",
source_type="youtube_playlist",
uri="https://example.com/list",
)
MediaItem.objects.create(
media_source=source,
title="Cached Item",
item_kind="movie",
runtime_seconds=60,
file_path="https://youtube.com/watch?v=abc",
cached_file_path="/tmp/pytv_cache/abc.mp4",
)
resp = client.post("/api/backups/run")
assert resp.status_code == 200
filename = resp.json()["filename"]
backup_path = Path(settings.BACKUP_ROOT) / filename
assert backup_path.exists()
payload = json.loads(backup_path.read_text(encoding="utf-8"))
media_entries = [x for x in payload["items"] if x["model"] == "core.mediaitem"]
assert media_entries
assert media_entries[0]["fields"]["cached_file_path"] is None