From c92e2d340ecddd07703f52a3b84abf4a96ad25e1 Mon Sep 17 00:00:00 2001 From: Lukas Date: Sun, 18 Jan 2026 12:18:42 +0100 Subject: [PATCH] Fix JSON parsing in NFO JavaScript modules - Add response.json() calls in nfo-manager.js for all API calls - Add response.json() calls in nfo-config.js for all API calls - Fix createNFO, refreshNFO, viewNFO, getSeriesWithoutNFO functions - Fix load and testTMDBConnection functions - All API responses must be parsed before accessing properties --- docs/instructions.md | 5 ++- src/server/web/static/js/index/nfo-config.js | 18 ++++++-- src/server/web/static/js/index/nfo-manager.js | 44 ++++++++++++++----- tests/unit/test_nfo_dependency.py | 7 +-- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/docs/instructions.md b/docs/instructions.md index 54e9393..2d698c5 100644 --- a/docs/instructions.md +++ b/docs/instructions.md @@ -132,12 +132,15 @@ All tasks completed! Recent issues have been resolved. **Solution:** Modified `get_nfo_service()` dependency function to check `settings.tmdb_api_key` first, and if not found, fall back to loading from `config.json` directly. This ensures the TMDB API key is always available even after hot reloads in development. **Files Modified:** + - [src/server/api/nfo.py](../src/server/api/nfo.py) **Tests Added:** + - [tests/unit/test_nfo_dependency.py](../tests/unit/test_nfo_dependency.py) - Tests for config fallback behavior -**Verification:** +**Verification:** + - All 4 unit tests pass - NFO endpoints work correctly even after server reloads - Falls back gracefully to config.json when settings are reset diff --git a/src/server/web/static/js/index/nfo-config.js b/src/server/web/static/js/index/nfo-config.js index 1551429..4f99893 100644 --- a/src/server/web/static/js/index/nfo-config.js +++ b/src/server/web/static/js/index/nfo-config.js @@ -18,7 +18,13 @@ AniWorld.NFOConfig = (function() { */ async function load() { try { - const config = await AniWorld.ApiClient.request(API.CONFIG); + const response = await AniWorld.ApiClient.request(API.CONFIG); + + if (!response) { + throw new Error('Failed to load configuration'); + } + + const config = await response.json(); if (config && config.nfo) { const nfo = config.nfo; @@ -148,10 +154,16 @@ AniWorld.NFOConfig = (function() { } ); - if (response && response.valid) { + if (!response) { + throw new Error('No response from server'); + } + + const data = await response.json(); + + if (data && data.valid) { AniWorld.UI.showToast('TMDB API key is valid!', 'success'); } else { - const message = response && response.message ? response.message : 'Invalid API key'; + const message = data && data.message ? data.message : 'Invalid API key'; AniWorld.UI.showToast('TMDB validation failed: ' + message, 'error'); } } catch (error) { diff --git a/src/server/web/static/js/index/nfo-manager.js b/src/server/web/static/js/index/nfo-manager.js index 54f2abb..4fec717 100644 --- a/src/server/web/static/js/index/nfo-manager.js +++ b/src/server/web/static/js/index/nfo-manager.js @@ -32,9 +32,15 @@ AniWorld.NFOManager = (function() { } ); - if (response && response.message) { - AniWorld.UI.showToast(response.message || 'NFO created successfully', 'success'); - return response; + if (!response) { + throw new Error('Failed to create NFO'); + } + + const data = await response.json(); + + if (data && data.message) { + AniWorld.UI.showToast(data.message || 'NFO created successfully', 'success'); + return data; } else { throw new Error('Failed to create NFO'); } @@ -66,9 +72,15 @@ AniWorld.NFOManager = (function() { } ); - if (response && response.message) { - AniWorld.UI.showToast(response.message || 'NFO updated successfully', 'success'); - return response; + if (!response) { + throw new Error('Failed to refresh NFO'); + } + + const data = await response.json(); + + if (data && data.message) { + AniWorld.UI.showToast(data.message || 'NFO updated successfully', 'success'); + return data; } else { throw new Error('Failed to refresh NFO'); } @@ -97,8 +109,14 @@ AniWorld.NFOManager = (function() { `/api/nfo/${encodeURIComponent(seriesKey)}/content` ); - if (response && response.content) { - return response; + if (!response) { + throw new Error('No NFO data available'); + } + + const data = await response.json(); + + if (data && data.content) { + return data; } else { throw new Error('No NFO data available'); } @@ -200,8 +218,14 @@ AniWorld.NFOManager = (function() { try { const response = await AniWorld.ApiClient.request('/api/nfo/missing'); - if (response && response.series) { - return response; + if (!response) { + throw new Error('Failed to get series without NFO'); + } + + const data = await response.json(); + + if (data && data.series) { + return data; } else { throw new Error('Failed to get series without NFO'); } diff --git a/tests/unit/test_nfo_dependency.py b/tests/unit/test_nfo_dependency.py index 74ad352..fde9fa2 100644 --- a/tests/unit/test_nfo_dependency.py +++ b/tests/unit/test_nfo_dependency.py @@ -3,13 +3,14 @@ Tests that get_nfo_service() correctly loads TMDB API key from config.json when it's not in settings (e.g., after server reload in development). """ -import pytest from unittest.mock import MagicMock, patch + +import pytest from fastapi import HTTPException -from src.server.api.nfo import get_nfo_service -from src.server.models.config import NFOConfig, AppConfig from src.config.settings import settings +from src.server.api.nfo import get_nfo_service +from src.server.models.config import AppConfig, NFOConfig @pytest.mark.asyncio