"""Tests for the NFO Management API endpoints. Covers the live endpoints in src/server/api/nfo.py: - GET /api/nfo/{key}/diagnostics - POST /api/nfo/{key}/repair - GET /api/nfo/{key}/validate - GET /api/nfo/needs-repair - POST /api/nfo/batch/repair Note: Legacy endpoints referenced in v1.x (e.g. /api/nfo/{id}/check, /create, /update, /content, /missing, /batch/create) no longer exist in the codebase — they were replaced by the consolidated diagnostic, repair, validate, needs-repair, batch/repair endpoints and the new Anime Settings page (see tests/api/test_anime_settings_endpoints.py). """ from unittest.mock import AsyncMock, Mock, patch import pytest from httpx import ASGITransport, AsyncClient from src.server.fastapi_app import app from src.server.services.auth_service import auth_service @pytest.fixture(autouse=True) def reset_auth(): auth_service._hash = None auth_service._failed.clear() yield auth_service._hash = None auth_service._failed.clear() @pytest.fixture async def client(): transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://test") as ac: yield ac @pytest.fixture async def authenticated_client(client): await client.post( "/api/auth/setup", json={"master_password": "TestPassword123!"}, ) resp = await client.post( "/api/auth/login", json={"password": "TestPassword123!"}, ) token = resp.json()["access_token"] client.headers.update({"Authorization": f"Bearer {token}"}) yield client class TestNFOAuthRequirements: """All NFO endpoints must require authentication.""" @pytest.mark.asyncio async def test_get_diagnostics_requires_auth(self, client): resp = await client.get("/api/nfo/any-key/diagnostics") assert resp.status_code in (401, 503) @pytest.mark.asyncio async def test_post_repair_requires_auth(self, client): resp = await client.post("/api/nfo/any-key/repair") assert resp.status_code in (401, 503) @pytest.mark.asyncio async def test_get_validate_requires_auth(self, client): resp = await client.get("/api/nfo/any-key/validate") assert resp.status_code in (401, 503) @pytest.mark.asyncio async def test_get_needs_repair_requires_auth(self, client): resp = await client.get("/api/nfo/needs-repair") assert resp.status_code in (401, 503) @pytest.mark.asyncio async def test_post_batch_repair_requires_auth(self, client): resp = await client.post( "/api/nfo/batch/repair", json=["key1", "key2"], ) assert resp.status_code in (401, 503) class TestNFOEndpointModels: """Verify the response models use the renamed classes (regression test for the rename from NfoDiagnosticsResponse -> NfoSettingsResponse).""" def test_renamed_settings_response_model_exists(self): # Confirm the old names are gone from src.server import models from src.server.models.nfo import ( NfoRepairResponse, NfoSeriesSettings, NfoSettingsResponse, ) nfo_module = models.nfo assert hasattr(nfo_module, "NfoSettingsResponse") assert hasattr(nfo_module, "NfoSeriesSettings") assert hasattr(nfo_module, "NfoRepairResponse") # The diagnostic prefix should NOT be present anymore assert not hasattr(nfo_module, "NfoDiagnosticsResponse") assert not hasattr(nfo_module, "NfoSeriesDiagnostics")