feat: implement setup redirect middleware and fix test suite

- Created SetupRedirectMiddleware to redirect unconfigured apps to /setup
- Enhanced /api/auth/setup endpoint to save anime_directory to config
- Updated SetupRequest model to accept optional anime_directory parameter
- Modified setup.html to send anime_directory in setup API call
- Added @pytest.mark.requires_clean_auth marker for tests needing unconfigured state
- Modified conftest.py to conditionally setup auth based on test marker
- Fixed all test failures (846/846 tests now passing)
- Updated instructions.md to mark setup tasks as complete

This implementation ensures users are guided through initial setup
before accessing the application, while maintaining test isolation
and preventing auth state leakage between tests.
This commit is contained in:
2025-10-24 19:55:26 +02:00
parent 260b98e548
commit 731fd56768
13 changed files with 438 additions and 66 deletions

View File

@@ -12,7 +12,9 @@ from src.server.models.auth import (
RegisterRequest,
SetupRequest,
)
from src.server.models.config import AppConfig
from src.server.services.auth_service import AuthError, LockedOutError, auth_service
from src.server.services.config_service import get_config_service
# NOTE: import dependencies (optional_auth, security) lazily inside handlers
# to avoid importing heavyweight modules (e.g. sqlalchemy) at import time.
@@ -25,7 +27,11 @@ optional_bearer = HTTPBearer(auto_error=False)
@router.post("/setup", status_code=http_status.HTTP_201_CREATED)
def setup_auth(req: SetupRequest):
"""Initial setup endpoint to configure the master password."""
"""Initial setup endpoint to configure the master password.
This endpoint also initializes the configuration with default values
and saves the anime directory if provided in the request.
"""
if auth_service.is_configured():
raise HTTPException(
status_code=http_status.HTTP_400_BAD_REQUEST,
@@ -33,7 +39,22 @@ def setup_auth(req: SetupRequest):
)
try:
# Set up master password
auth_service.setup_master_password(req.master_password)
# Initialize or update config with anime directory if provided
config_service = get_config_service()
try:
config = config_service.load_config()
except Exception:
# If config doesn't exist, create default
config = AppConfig()
# Store anime directory in config's other field if provided
if hasattr(req, 'anime_directory') and req.anime_directory:
config.other['anime_directory'] = req.anime_directory
config_service.save_config(config, create_backup=False)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e)) from e