Spaces:
Running
Running
File size: 3,132 Bytes
89a70e2 | 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 | """
Unit tests for utils/niche_requests.py and the /niche-request route: the list of
niches people couldn't find. Firestore is mocked.
"""
from unittest.mock import MagicMock, patch
import pytest
from fastapi import HTTPException
from utils import niche_requests
from routes.bff import NicheRequestIn, niche_request
def test_key_ignores_case_spacing_and_punctuation():
assert niche_requests.niche_key(" School Stationery! ") == "school-stationery"
assert niche_requests.niche_key("school stationery") == "school-stationery"
assert niche_requests.niche_key("!!!") == ""
def test_route_rejects_text_without_letters():
with pytest.raises(HTTPException) as e:
niche_request(NicheRequestIn(text="!!!"), user={"uid": "u1"})
assert e.value.status_code == 400
def test_list_hides_who_asked_and_sorts_by_count():
def doc(id_, **d):
m = MagicMock(id=id_)
m.to_dict.return_value = d
return m
db = MagicMock()
db.collection.return_value.stream.return_value = [
doc("a", text="A", userCount=1, uids=["u1"], status="open"),
doc("b", text="B", userCount=3, uids=["u1", "u2", "u3"], status="open"),
doc("c", text="C", userCount=9, uids=["x"], status="added"),
]
with patch.object(niche_requests.firestore, "client", return_value=db):
rows = niche_requests.list_requests("open")
assert [r["text"] for r in rows] == ["B", "A"]
assert all("uids" not in r for r in rows)
def test_set_status_validates():
with pytest.raises(ValueError):
niche_requests.set_status("x", "deleted")
def _fake_firestore(existing: dict | None):
fs = MagicMock()
fs.transactional = lambda f: f # run the body directly with our fake transaction
snap = MagicMock(exists=existing is not None)
snap.to_dict.return_value = existing or {}
ref = fs.client.return_value.collection.return_value.document.return_value
ref.get.return_value = snap
tx = fs.client.return_value.transaction.return_value
return fs, ref, tx
def test_record_counts_each_person_once_and_keeps_where_they_put_it():
fs, ref, tx = _fake_firestore({"uids": ["u1"], "sectors": ["trade_commerce/retail_trade"], "status": "added"})
with patch.object(niche_requests, "firestore", fs):
key = niche_requests.record("u1", "School stationery", "trade_commerce", "retail_trade")
assert key == "school-stationery"
saved = tx.set.call_args[0][1]
assert saved["userCount"] == 1 and saved["uids"] == ["u1"]
assert saved["sectors"] == ["trade_commerce/retail_trade"]
assert saved["status"] == "added" # an admin decision isn't reset by a new request
assert saved["text"] == "School stationery"
assert "firstAt" not in saved
def test_record_new_niche_starts_open_with_one_person():
fs, ref, tx = _fake_firestore(None)
with patch.object(niche_requests, "firestore", fs):
niche_requests.record("u2", "Shoe repair")
saved = tx.set.call_args[0][1]
assert saved["userCount"] == 1 and saved["status"] == "open" and "firstAt" in saved
assert saved["sectors"] == []
|