changes
This commit is contained in:
192
tests/test_phone_book_api.py
Normal file
192
tests/test_phone_book_api.py
Normal file
@@ -0,0 +1,192 @@
|
||||
import os
|
||||
import uuid
|
||||
import csv
|
||||
import io
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
# Ensure required env vars for app import/config
|
||||
os.environ.setdefault("SECRET_KEY", "x" * 32)
|
||||
os.environ.setdefault("DATABASE_URL", "sqlite:////tmp/delphi_test.sqlite")
|
||||
|
||||
from app.main import app # noqa: E402
|
||||
from app.auth.security import get_current_user # noqa: E402
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def client():
|
||||
# Override auth to bypass JWT for these tests
|
||||
class _User:
|
||||
def __init__(self):
|
||||
self.id = "test"
|
||||
self.username = "tester"
|
||||
self.is_admin = True
|
||||
self.is_active = True
|
||||
|
||||
app.dependency_overrides[get_current_user] = lambda: _User()
|
||||
|
||||
try:
|
||||
yield TestClient(app)
|
||||
finally:
|
||||
app.dependency_overrides.pop(get_current_user, None)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def phone_book_data(client: TestClient):
|
||||
gid1 = f"PBGRP1-{uuid.uuid4().hex[:6]}"
|
||||
gid2 = f"PBGRP2-{uuid.uuid4().hex[:6]}"
|
||||
|
||||
def _create_customer(cid: str, last: str, first: str, group: str):
|
||||
payload = {
|
||||
"id": cid,
|
||||
"last": last,
|
||||
"first": first,
|
||||
"group": group,
|
||||
"email": f"{cid.lower()}@example.com",
|
||||
}
|
||||
resp = client.post("/api/customers/", json=payload)
|
||||
assert resp.status_code == 200, resp.text
|
||||
|
||||
def _add_phone(cid: str, location: str, number: str):
|
||||
resp = client.post(f"/api/customers/{cid}/phones", json={"location": location, "phone": number})
|
||||
assert resp.status_code == 200, resp.text
|
||||
|
||||
# Create entries for letters A, B and non-alpha '#'
|
||||
cid_a1 = f"PB-{uuid.uuid4().hex[:6]}-A1"
|
||||
cid_a2 = f"PB-{uuid.uuid4().hex[:6]}-A2"
|
||||
cid_b1 = f"PB-{uuid.uuid4().hex[:6]}-B1"
|
||||
cid_hash = f"PB-{uuid.uuid4().hex[:6]}-H"
|
||||
|
||||
_create_customer(cid_a1, last="Alpha", first="Alice", group=gid1)
|
||||
_add_phone(cid_a1, "Office", "111-111-1111")
|
||||
_add_phone(cid_a1, "Mobile", "111-111-2222")
|
||||
|
||||
_create_customer(cid_a2, last="Able", first="Andy", group=gid1)
|
||||
_add_phone(cid_a2, "Office", "222-222-2222")
|
||||
|
||||
_create_customer(cid_b1, last="Beta", first="Bob", group=gid2)
|
||||
_add_phone(cid_b1, "Home", "333-333-3333")
|
||||
|
||||
_create_customer(cid_hash, last="123Company", first="NA", group=gid1)
|
||||
_add_phone(cid_hash, "Main", "444-444-4444")
|
||||
|
||||
try:
|
||||
yield {
|
||||
"gid1": gid1,
|
||||
"gid2": gid2,
|
||||
"ids": [cid_a1, cid_a2, cid_b1, cid_hash],
|
||||
}
|
||||
finally:
|
||||
# Cleanup
|
||||
for cid in [cid_a1, cid_a2, cid_b1, cid_hash]:
|
||||
client.delete(f"/api/customers/{cid}")
|
||||
|
||||
|
||||
def _parse_csv(text: str):
|
||||
reader = csv.reader(io.StringIO(text))
|
||||
rows = list(reader)
|
||||
return rows[0], rows[1:]
|
||||
|
||||
|
||||
def test_phone_book_csv_letter_column_when_grouped_by_letter(client: TestClient, phone_book_data):
|
||||
# Only include our test group gid1 to avoid interference
|
||||
gid = phone_book_data["gid1"]
|
||||
resp = client.get(
|
||||
"/api/customers/phone-book",
|
||||
params={
|
||||
"format": "csv",
|
||||
"mode": "numbers",
|
||||
"grouping": "letter",
|
||||
"groups": gid,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
assert "text/csv" in resp.headers.get("content-type", "")
|
||||
header, rows = _parse_csv(resp.text)
|
||||
assert "Letter" in header
|
||||
# Ensure letters include 'A' and '#'
|
||||
letters = {r[header.index("Letter")] for r in rows}
|
||||
assert "A" in letters and "#" in letters
|
||||
|
||||
|
||||
def test_phone_book_html_sections_by_letter_with_page_break(client: TestClient, phone_book_data):
|
||||
gid = phone_book_data["gid1"]
|
||||
resp = client.get(
|
||||
"/api/customers/phone-book",
|
||||
params={
|
||||
"format": "html",
|
||||
"mode": "numbers",
|
||||
"grouping": "letter",
|
||||
"page_break": "1",
|
||||
"groups": gid,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
# Snapshot-style checks: section headers and page-break class
|
||||
assert "Letter: A" in html
|
||||
assert "Letter: #" in html
|
||||
assert "class=\"section-title\"" in html
|
||||
assert "page-break" in html # later sections should have page-break class
|
||||
|
||||
|
||||
def test_phone_book_html_group_then_letter_sections(client: TestClient, phone_book_data):
|
||||
gid1 = phone_book_data["gid1"]
|
||||
gid2 = phone_book_data["gid2"]
|
||||
# Include both groups to verify group and nested letter sections
|
||||
resp = client.get(
|
||||
"/api/customers/phone-book",
|
||||
params=[
|
||||
("format", "html"),
|
||||
("mode", "addresses"),
|
||||
("grouping", "group_letter"),
|
||||
("groups", gid1),
|
||||
("groups", gid2),
|
||||
],
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert f"Group: {gid1}" in html
|
||||
assert f"Group: {gid2}" in html
|
||||
assert "Letter: A" in html or "Letter: #" in html
|
||||
|
||||
|
||||
def test_phone_book_csv_no_letter_for_grouping_none(client: TestClient, phone_book_data):
|
||||
gid = phone_book_data["gid1"]
|
||||
resp = client.get(
|
||||
"/api/customers/phone-book",
|
||||
params={
|
||||
"format": "csv",
|
||||
"mode": "numbers",
|
||||
"grouping": "none",
|
||||
"groups": gid,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
header, rows = _parse_csv(resp.text)
|
||||
assert "Letter" not in header
|
||||
# Basic sanity: names and phones are present
|
||||
assert any("Alpha" in ",".join(row) or "Able" in ",".join(row) for row in rows)
|
||||
|
||||
|
||||
def test_phone_book_respects_group_filter(client: TestClient, phone_book_data):
|
||||
gid2 = phone_book_data["gid2"]
|
||||
resp = client.get(
|
||||
"/api/customers/phone-book",
|
||||
params={
|
||||
"format": "csv",
|
||||
"mode": "numbers",
|
||||
"grouping": "letter",
|
||||
"groups": gid2,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
header, rows = _parse_csv(resp.text)
|
||||
# Only Beta/Bob (gid2) should be present
|
||||
all_text = "\n".join([",".join(r) for r in rows])
|
||||
assert "Beta" in all_text or "Bob" in all_text
|
||||
# Ensure gid1 names are not present
|
||||
assert "Alpha" not in all_text and "Able" not in all_text
|
||||
|
||||
|
||||
Reference in New Issue
Block a user