diff --git a/src/frontend/flask_app/templates/admin/stations.html b/src/frontend/flask_app/templates/admin/stations.html index 2c45cbe..4590462 100644 --- a/src/frontend/flask_app/templates/admin/stations.html +++ b/src/frontend/flask_app/templates/admin/stations.html @@ -477,7 +477,7 @@ function stationManagement(initialStations, initialRecipes) { }); if (!resp.ok) { const result = await resp.json().catch(() => ({})); - alert(result.detail || '{{ _("Errore nell\'eliminazione") }}'); + alert(result.detail || "{{ _('Errore nella eliminazione') }}"); return; } this.stations = this.stations.filter(s => s.id !== this.deleteTarget.id); @@ -528,7 +528,7 @@ function stationManagement(initialStations, initialRecipes) { }); const result = await resp.json(); if (!resp.ok) { - this.errorMsg = result.detail || '{{ _("Errore nell\'assegnazione") }}'; + this.errorMsg = result.detail || "{{ _('Errore nella assegnazione') }}"; return; } const recipe = this.allRecipes.find(r => r.id === parseInt(this.recipeToAdd, 10)); diff --git a/src/frontend/flask_app/tests/test_template_js_syntax.py b/src/frontend/flask_app/tests/test_template_js_syntax.py new file mode 100644 index 0000000..611aa53 --- /dev/null +++ b/src/frontend/flask_app/tests/test_template_js_syntax.py @@ -0,0 +1,127 @@ +"""Verify that inline (i.e. without `src=`) so we don't try +# to syntax-check Alpine.js / Plotly bundles served from a CDN. +_INLINE_SCRIPT_RX = re.compile( + r"]*\bsrc=)[^>]*>(.*?)", + re.DOTALL | re.IGNORECASE, +) + + +def _node_check(script: str, label: str) -> None: + """Fail the test if `node --check` rejects `script`.""" + if not script.strip(): + return + node = shutil.which("node") + if node is None: + pytest.skip("node binary not found on PATH; cannot validate JS syntax") + + fd, path = tempfile.mkstemp(suffix=".js") + try: + with os.fdopen(fd, "w", encoding="utf-8") as f: + f.write(script) + result = subprocess.run( + [node, "--check", path], + capture_output=True, + text=True, + timeout=10, + ) + finally: + os.unlink(path) + + if result.returncode != 0: + snippet = script.strip() + if len(snippet) > 600: + snippet = snippet[:600] + "\n…(truncated)…" + pytest.fail( + f"{label}: node rejected the inline