diff --git a/l4d2web/tests/test_blueprints.py b/l4d2web/tests/test_blueprints.py index 20982a3..cad2025 100644 --- a/l4d2web/tests/test_blueprints.py +++ b/l4d2web/tests/test_blueprints.py @@ -411,3 +411,45 @@ def test_blueprint_detail_picker_emits_hidden_overlay_ids_in_order(user_client) second = body.find('name="overlay_ids" value="1"') assert first != -1 and second != -1 assert first < second + + +def test_blueprint_config_form_post_round_trip(user_client) -> None: + """Pin the form-POST contract for the `config` textarea: a multi-line + value sent in the POST body re-renders inside the textarea on the + subsequent GET. The CodeMirror 6 editor wires a submit-time copy + handler that writes `controller.getValue()` into `textarea.value` + before the browser serializes the form; if that handler regresses, + this test breaks before the e2e suite even runs.""" + create = user_client.post( + "/blueprints", + data={ + "name": "form-contract", + "arguments": "", + "config": "", + "overlay_ids": [], + }, + headers={"X-CSRF-Token": "test-token"}, + ) + assert create.status_code == 302 + blueprint_path = create.headers["Location"] + + pinned_config = "// pinned by form-contract test\nsv_cheats 0\nexec server.cfg\n" + update = user_client.post( + blueprint_path, + data={ + "name": "form-contract", + "arguments": "", + "config": pinned_config, + "overlay_ids": [], + }, + headers={"X-CSRF-Token": "test-token"}, + ) + assert update.status_code == 302 + + page = user_client.get(blueprint_path) + assert page.status_code == 200 + body = page.get_data(as_text=True) + # The route may normalize trailing whitespace; assert each non-empty + # line round-tripped into the rendered textarea. + for line in ("// pinned by form-contract test", "sv_cheats 0", "exec server.cfg"): + assert line in body, f"line not found in rendered page: {line!r}"