Replaces the read-only 'NFO Diagnostics' page with a full per-anime
Settings page reached from the right-click context menu on series cards.
Users can now view and edit key, name, folder, tmdb_id, tvdb_id and site
for each anime; changes are persisted to the DB and optionally written
back to the NFO file or used to regenerate it.
Backend
- Rename NfoDiagnosticsResponse -> NfoSettingsResponse,
NfoSeriesDiagnostics -> NfoSeriesSettings
- Rename get_nfo_diagnostics -> get_nfo_settings,
repair_nfo -> repair_nfo_settings
- Fix nfo.py bug: repair was calling non-existent
update_series_nfo_status(); now uses update_nfo_status() and an
explicit AnimeSeriesService.update(nfo_path=...)
- New endpoints on /api/anime/{key}:
GET /settings -> AnimeSettingsResponse
PUT /settings -> AnimeSettingsResponse
(body: name/folder/tmdb_id/tvdb_id/site,
options: apply_to_nfo, rename_disk)
POST /regenerate-nfo -> AnimeSettingsRegenerateNfoResponse
- New Pydantic models: AnimeSettingsResponse,
AnimeSettingsUpdateRequest, AnimeSettingsRegenerateNfoResponse
- /anime/settings page route; /settings/nfo now 301-redirects to it
Frontend
- New AniWorld.AnimeSettingsManager JS module (single-page form,
no tabs) with public API init/loadSeries/saveSettings/regenerateNfo/
validateField/populateForm/showSaveSuccess/showError
- New anime-settings.html template + anime-settings.css
- Right-click menu: data-action 'nfo-diagnostics' replaced by
'anime-settings' (label 'Anime Settings'), navigates to
/anime/settings?key=...
- Library 'Open NFO Diagnostics' link renamed to 'Open Anime Settings'
Bug fix
- context-menu click handler was calling hide() BEFORE building the
navigation URL, which cleared currentSeriesKey to null and produced
/anime/settings?key=null. Captures the key into a local const first.
Regression-locked by tests/frontend/unit/context_menu.test.js.
Tests
- 21 new pytest tests in tests/api/test_anime_settings_endpoints.py
(GET/PUT/regenerate-nfo, auth, validation, nfo-repair bug regression)
- tests/api/test_nfo_endpoints.py trimmed to 6 focused tests
- 31 new Vitest unit tests for AnimeSettingsManager
- 5 new Vitest unit tests for ContextMenu (incl. source-invariant
regression guard for the hide()-before-key bug)
- 5 new Playwright E2E tests covering right-click, direct nav,
legacy /settings/nfo redirect, and context-menu labels
- New vitest.config.js (environment: happy-dom)
Docs
- Docs/API.md: new section 'Anime Settings Endpoints'
- Docs/CHANGELOG.md: documents the rename and the context-menu bug fix
Verified
- pytest: 27/27 (21 new + 6 trimmed nfo)
- vitest: 36/36 (31 anime-settings + 5 context-menu)
- playwright e2e: 5/5
Frontend Integration Tests
This directory contains integration tests for the existing JavaScript frontend (app.js, websocket_client.js, queue.js) with the FastAPI backend.
Test Coverage
test_existing_ui_integration.py
Comprehensive test suite for frontend-backend integration:
Authentication Tests (TestFrontendAuthentication)
- Auth status endpoint behavior (configured/not configured/authenticated states)
- JWT token login flow
- Logout functionality
- Unauthorized request handling (401 responses)
- Authenticated request success
Anime API Tests (TestFrontendAnimeAPI)
- GET /api/v1/anime - anime list retrieval
- POST /api/v1/anime/search - search functionality
- POST /api/v1/anime/rescan - trigger library rescan
Download API Tests (TestFrontendDownloadAPI)
- Adding episodes to download queue
- Getting queue status
- Starting/pausing/stopping download queue
WebSocket Integration Tests (TestFrontendWebSocketIntegration)
- WebSocket connection establishment with JWT token
- Queue update broadcasts
- Download progress updates
Configuration API Tests (TestFrontendConfigAPI)
- GET /api/config - configuration retrieval
- POST /api/config - configuration updates
JavaScript Integration Tests (TestFrontendJavaScriptIntegration)
- Bearer token authentication pattern (makeAuthenticatedRequest)
- 401 error handling
- Queue operations compatibility
Error Handling Tests (TestFrontendErrorHandling)
- JSON error responses
- Validation error handling (400/422)
Real-Time Update Tests (TestFrontendRealTimeUpdates)
- download_started notifications
- download_completed notifications
- Multiple clients receiving broadcasts
Data Format Tests (TestFrontendDataFormats)
- Anime list format validation
- Queue status format validation
- WebSocket message format validation
Running the Tests
Run all frontend integration tests:
pytest tests/frontend/test_existing_ui_integration.py -v
Run specific test class:
pytest tests/frontend/test_existing_ui_integration.py::TestFrontendAuthentication -v
Run single test:
pytest tests/frontend/test_existing_ui_integration.py::TestFrontendAuthentication::test_login_returns_jwt_token -v
Key Test Patterns
Authenticated Client Fixture
Most tests use the authenticated_client fixture which:
- Sets up master password
- Logs in to get JWT token
- Adds Authorization header to all requests
WebSocket Testing
WebSocket tests use async context managers to establish connections:
async with authenticated_client.websocket_connect(
f"/ws/connect?token={token}"
) as websocket:
message = await websocket.receive_json()
# Test message format
API Mocking
Service layer is mocked to isolate frontend-backend integration:
with patch("src.server.api.anime.get_anime_service") as mock:
mock_service = AsyncMock()
mock_service.get_all_series = AsyncMock(return_value=[...])
mock.return_value = mock_service
Frontend JavaScript Files Tested
- app.js: Main application logic, authentication, anime management
- websocket_client.js: WebSocket client wrapper, connection management
- queue.js: Download queue management, real-time updates
Integration Points Verified
- Authentication Flow: JWT token generation, validation, and usage
- API Endpoints: All REST API endpoints used by frontend
- WebSocket Communication: Real-time event broadcasting
- Data Formats: Response formats match frontend expectations
- Error Handling: Proper error responses for frontend consumption
Dependencies
- pytest
- pytest-asyncio
- httpx (for async HTTP testing)
- FastAPI test client with WebSocket support
Notes
- Tests use in-memory state, no database persistence
- Auth service is reset before each test
- WebSocket service singleton is reused across tests
- Fixtures are scoped appropriately to avoid test pollution