""" Tests for form submission. A form definition is created once per session, then submissions are POSTed against that definition's ID. Run: pytest Forms/test_form_submission.py -v """ import os import pytest import requests BASE_URL = os.environ.get("WP_BASE_URL", "http://localhost/wordpress") DEFINITION_ENDPOINT = f"{BASE_URL}/wp-json/reservations/v1/form-definition" FORM_ENDPOINT = f"{BASE_URL}/wp-json/reservations/v1/form" FORM_DEFINITION = { "elements": [ { "type": "input-text", "name": "email", "label": "Email", "required": True, "validation": "email", }, { "type": "input-text", "name": "name", "label": "Name", "required": False, }, { "type": "button", "name": "submit", "label": "Submit", }, ] } @pytest.fixture(scope="module") def form_id(): r = requests.post(DEFINITION_ENDPOINT, json={"name": "Test submission form", "definition": FORM_DEFINITION}) assert r.status_code == 201, f"Failed to create form definition: {r.text}" return r.json()["id"] def submit(form_id: int, data: dict) -> requests.Response: return requests.post(f"{FORM_ENDPOINT}/{form_id}", json=data) class TestFormSubmissionSuccess: def test_valid_submission_returns_200(self, form_id): r = submit(form_id, {"email": "user@example.com", "name": "Alice"}) assert r.status_code == 200 def test_valid_submission_returns_success_true(self, form_id): r = submit(form_id, {"email": "user@example.com", "name": "Alice"}) assert r.json()["success"] is True def test_valid_submission_returns_submit_id(self, form_id): r = submit(form_id, {"email": "user@example.com", "name": "Alice"}) body = r.json() assert "submit_id" in body assert isinstance(body["submit_id"], int) assert body["submit_id"] > 0 def test_valid_submission_has_values(self, form_id): r = submit(form_id, {"email": "user@example.com", "name": "Alice"}) values = r.json()["values"] assert values["email"] == "user@example.com" assert values["name"] == "Alice" def test_optional_name_can_be_omitted(self, form_id): r = submit(form_id, {"email": "user@example.com"}) assert r.status_code == 200 assert r.json()["success"] is True class TestFormSubmissionValidation: def test_missing_email_returns_400(self, form_id): r = submit(form_id, {"name": "Alice"}) assert r.status_code == 400 def test_missing_email_returns_required_error(self, form_id): r = submit(form_id, {"name": "Alice"}) errors = r.json()["errors"] email_error = next((e for e in errors if e["element"] == "email"), None) assert email_error is not None assert email_error["code"] == "required" def test_invalid_email_returns_400(self, form_id): r = submit(form_id, {"email": "not-an-email", "name": "Alice"}) assert r.status_code == 400 def test_invalid_email_returns_invalid_email_error(self, form_id): r = submit(form_id, {"email": "not-an-email", "name": "Alice"}) errors = r.json()["errors"] email_error = next((e for e in errors if e["element"] == "email"), None) assert email_error is not None assert email_error["code"] == "invalid_email" def test_empty_email_returns_required_error(self, form_id): r = submit(form_id, {"email": "", "name": "Alice"}) errors = r.json()["errors"] email_error = next((e for e in errors if e["element"] == "email"), None) assert email_error is not None assert email_error["code"] == "required" class TestFormSubmissionNotFound: def test_unknown_form_id_returns_400(self): r = submit(999999, {"email": "user@example.com"}) assert r.status_code == 400 def test_unknown_form_id_returns_not_found_error(self): r = submit(999999, {"email": "user@example.com"}) errors = r.json()["errors"] assert any(e["code"] == "not_found" for e in errors)