122 lines
4.1 KiB
Python
122 lines
4.1 KiB
Python
|
|
"""
|
||
|
|
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)
|