Spaces:
Running
Running
File size: 3,317 Bytes
b324c71 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | """
Unit tests for the public Business Footing Framework route (routes/bff_form.py)
and the shared public-form checks (utils/public_forms.py). Firestore is mocked.
"""
from unittest.mock import MagicMock, patch
import pytest
from fastapi import HTTPException
from routes import bff_form
from routes.bff_form import SubmissionIn, submit
from utils.public_forms import clean_phone
@pytest.fixture(autouse=True)
def _reset_limits():
bff_form.limiter.reset()
def _body(**over):
base = dict(
name=" Ada Obi ", email=" Ada@Example.com ", phone="0803 123 4567", consent=True,
what=dict(businessStage="early", businessName="Ada Books", sectorId="retail_trade",
subsectorId="bookshops", nicheId="other", customNiche="Children's books",
products=["Story books", " ", "School texts"]),
why=dict(whyRaw=" I love reading ", valueProposition="Good books at fair prices"),
how=dict(locationType="physical", state="Lagos", city="Ikeja",
hours={"monday": {"open": "09:00", "close": "18:00", "off": False}},
demographics={"ageRanges": ["21–25"]}, channels={"social_media": ["Instagram"]},
revenueStreams="Book sales"),
startedAt=1, sessionId="s-1",
)
base.update(over)
return SubmissionIn(**base)
def _db():
db = MagicMock()
db.collection.return_value.add.return_value = (None, MagicMock(id="doc1"))
return db
def test_stores_answers_contact_and_labels():
db = _db()
with patch.object(bff_form.firestore, "client", return_value=db):
out = submit(_body())
assert out == {"success": True, "id": "doc1"}
db.collection.assert_called_with("bff_submissions")
doc = db.collection.return_value.add.call_args[0][0]
assert (doc["name"], doc["email"], doc["phone"]) == ("Ada Obi", "ada@example.com", "0803 123 4567")
assert doc["what"]["products"] == ["Story books", "School texts"]
assert doc["why"]["whyRaw"] == "I love reading"
assert doc["labels"]["niche"] == "Children's books" and doc["labels"]["stage"].startswith("Running for 1")
assert doc["how"]["hours"]["monday"]["open"] == "09:00"
@pytest.mark.parametrize("over", [
{"consent": False}, {"email": "nope"}, {"phone": "12345"},
{"what": dict(businessStage="unknown", businessName="X", sectorId="a", subsectorId="b", nicheId="c")},
{"what": dict(businessStage="idea", businessName="X", sectorId="a", subsectorId="b", nicheId="other")},
])
def test_rejects_bad_submissions(over):
with pytest.raises(HTTPException) as e:
submit(_body(**over))
assert e.value.status_code == 400
def test_rate_limits_per_browser():
with patch.object(bff_form.firestore, "client", return_value=_db()):
for _ in range(5):
submit(_body())
with pytest.raises(HTTPException) as e:
submit(_body())
assert e.value.status_code == 429
@pytest.mark.parametrize("raw,ok", [
("+234 803 123 4567", True), ("(0803) 123-4567", True), ("08031234567", True),
("123", False), ("0803 abc 4567", False), ("+1234567890123456", False),
])
def test_phone_check(raw, ok):
if ok:
assert clean_phone(raw) == " ".join(raw.split())
else:
with pytest.raises(HTTPException):
clean_phone(raw)
|