""" Tests pour les routes PWA (manifest.json, sw.js). Couvre: - Servir le manifest à la racine - Servir le Service Worker à la racine avec l'en-tête Service-Worker-Allowed - Validation du contenu JSON du manifest """ import json import pytest pytestmark = pytest.mark.unit class TestManifest: """Tests pour GET /manifest.json.""" @pytest.mark.asyncio async def test_manifest_served(self, client): """Le manifest est servi à /manifest.json avec le bon content-type.""" resp = await client.get("/manifest.json") assert resp.status_code == 200 content_type = resp.headers.get("content-type", "") assert "manifest+json" in content_type or "application/json" in content_type @pytest.mark.asyncio async def test_manifest_valid_json(self, client): """Le manifest contient les champs PWA requis.""" resp = await client.get("/manifest.json") assert resp.status_code == 200 data = json.loads(resp.text) assert "name" in data assert "icons" in data assert "start_url" in data assert "display" in data assert data["display"] == "standalone" assert len(data["icons"]) >= 2 class TestServiceWorker: """Tests pour GET /sw.js.""" @pytest.mark.asyncio async def test_sw_served(self, client): """Le Service Worker est servi à /sw.js.""" resp = await client.get("/sw.js") assert resp.status_code == 200 content_type = resp.headers.get("content-type", "") assert "javascript" in content_type @pytest.mark.asyncio async def test_sw_has_scope_header(self, client): """Le Service Worker a l'en-tête Service-Worker-Allowed.""" resp = await client.get("/sw.js") assert resp.status_code == 200 assert resp.headers.get("service-worker-allowed") == "/" @pytest.mark.asyncio async def test_sw_contains_cache_logic(self, client): """Le Service Worker contient la logique de cache.""" resp = await client.get("/sw.js") assert resp.status_code == 200 body = resp.text assert "caches" in body assert "install" in body assert "fetch" in body