diff --git a/tests/test_app.py b/tests/test_app.py index 95f4139..480691b 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -1,3 +1,4 @@ +from pathlib import Path from urllib.parse import unquote import pytest @@ -186,3 +187,12 @@ def test_live_status(logged_in): data = logged_in.get("/live/status").json() assert data["ok"] is True assert {vm["name"] for vm in data["vms"]} == {"web01", "db01"} + + +def test_uploader_collects_file_before_disabling_input(): + """Заблокированное поле браузер не отправляет: загрузка уходила пустой (44 байта) и получала 422.""" + script = (Path(__file__).resolve().parents[1] / "web" / "static" / "panel.js").read_text() + uploader = script[script.index("function wireUploader"):script.index("/* ---------------------------------------------------- operation page */")] + assert "input.disabled = active" in uploader + assert uploader.index("new FormData(form)") < uploader.index("setActive(true)") + assert "xhr.send(data)" in uploader diff --git a/web/static/panel.js b/web/static/panel.js index 60a41b1..049c878 100644 --- a/web/static/panel.js +++ b/web/static/panel.js @@ -300,6 +300,8 @@ const file = input.files[0]; if (!valid(file)) { setError('Выберите файл'); return; } const started = Date.now(); + // FormData собираем до setActive: заблокированное поле файла браузер в отправку не включает. + const data = new FormData(form); xhr = new XMLHttpRequest(); setActive(true); progress.hidden = false; progress.classList.remove('success', 'danger'); statusEl.textContent = 'Загрузка на сервер…'; @@ -337,7 +339,7 @@ xhr.open('POST', form.action); xhr.setRequestHeader('Accept', 'application/json'); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); - xhr.send(new FormData(form)); + xhr.send(data); }); showFile(); }