Files
WonderQ-Project/WonderQ-Admin/tests/test_customer_records.py

273 lines
8.8 KiB
Python

from datetime import datetime
from types import SimpleNamespace
from fastapi.testclient import TestClient
from app.auth import require_customer
from app.database import get_db
from app.main import create_app
from app.models import Customer, Lead, WanfaRoute
class FakeScalarResult:
def __init__(self, items):
self.items = items
def all(self):
return self.items
class FakeDb:
def __init__(self, *, scalar_results=None, scalar_values=None):
self.scalar_results = list(scalar_results or [])
self.scalar_values = list(scalar_values or [])
self.added = []
self.committed = False
def scalars(self, _statement):
return FakeScalarResult(self.scalar_results.pop(0) if self.scalar_results else [])
def scalar(self, _statement):
return self.scalar_values.pop(0) if self.scalar_values else None
def add(self, item):
self.added.append(item)
def flush(self):
for item in self.added:
if not getattr(item, "id", None):
item.id = "browse-history-test"
def commit(self):
self.committed = True
def refresh(self, _item):
return None
def authenticated_app(fake_db, customer):
app = create_app()
app.dependency_overrides[get_db] = lambda: fake_db
app.dependency_overrides[require_customer] = lambda: customer
return app
def make_vehicle_lead(**overrides):
return Lead(
id=overrides.get("id", "lead-1"),
leadType="vehicle",
contactName=overrides.get("contactName", "Damon"),
customerId=overrides.get("customerId", "customer-1"),
destination=overrides.get("destination", "黄果树景区"),
phone=overrides.get("phone", "13800000000"),
travelDate=overrides.get("travelDate", datetime(2026, 8, 25)),
peopleCount=overrides.get("peopleCount", 5),
note=overrides.get("note", "需要儿童座椅"),
vehicleDemand=overrides.get(
"vehicleDemand",
{
"serviceType": "charter",
"charterDuration": "fullDay",
"travelDate": "2026-08-25",
"pickupLocation": "贵阳北站",
"dropoffLocation": "黄果树景区",
"peopleCount": 5,
"luggageCount": 2,
"vehicleOptionTitle": "9座精品商务车",
"specialRequirements": "需要儿童座椅",
},
),
status=overrides.get("status", "new"),
createdAt=overrides.get("createdAt", datetime(2026, 8, 20, 10, 0)),
updatedAt=overrides.get("updatedAt", datetime(2026, 8, 20, 10, 0)),
)
def test_public_vehicle_demands_are_paginated_and_phone_is_masked():
customer = Customer(id="customer-1", phone="13800000000")
lead = make_vehicle_lead()
db = FakeDb(scalar_results=[[lead]], scalar_values=[1])
app = authenticated_app(db, customer)
try:
response = TestClient(app).get(
"/api/public/customer/vehicle-demands?pageNum=2&pageSize=1"
)
finally:
app.dependency_overrides.clear()
assert response.status_code == 200
assert response.json() == {
"code": 200,
"msg": "success",
"data": {
"items": [
{
"id": "lead-1",
"status": "new",
"contactName": "Damon",
"phoneMasked": "138****0000",
"destination": "黄果树景区",
"travelDate": "2026-08-25T00:00:00",
"peopleCount": 5,
"note": "需要儿童座椅",
"vehicleDemand": lead.vehicleDemand,
"createdAt": "2026-08-20T10:00:00",
"updatedAt": "2026-08-20T10:00:00",
}
],
"total": 1,
"pageNum": 2,
"pageSize": 1,
},
}
def test_public_vehicle_demand_detail_only_returns_the_current_customer_record():
customer = Customer(id="customer-1", phone="13800000000")
lead = make_vehicle_lead()
db = FakeDb(scalar_values=[lead])
app = authenticated_app(db, customer)
try:
response = TestClient(app).get("/api/public/customer/vehicle-demands/lead-1")
finally:
app.dependency_overrides.clear()
assert response.status_code == 200
assert response.json()["data"]["id"] == "lead-1"
assert response.json()["data"]["phoneMasked"] == "138****0000"
assert "phone" not in response.json()["data"]
def test_public_vehicle_demand_detail_hides_another_customers_record():
customer = Customer(id="customer-1", phone="13800000000")
db = FakeDb(scalar_values=[None])
app = authenticated_app(db, customer)
try:
response = TestClient(app).get("/api/public/customer/vehicle-demands/lead-other")
finally:
app.dependency_overrides.clear()
assert response.status_code == 404
def test_public_browse_history_is_paginated_for_the_current_customer():
customer = Customer(id="customer-1", phone="13800000000")
history = SimpleNamespace(
id="history-1",
customerId="customer-1",
itemType="wanfa-route",
itemId="family-water",
title="亲子玩水",
image="https://example.test/family-water.jpg",
visitedAt=datetime(2026, 8, 26, 12, 0),
)
db = FakeDb(scalar_results=[[history]], scalar_values=[1])
app = authenticated_app(db, customer)
try:
response = TestClient(app).get(
"/api/public/customer/browse-history?pageNum=1&pageSize=20"
)
finally:
app.dependency_overrides.clear()
assert response.status_code == 200
assert response.json()["data"] == {
"items": [
{
"id": "history-1",
"itemType": "wanfa-route",
"itemId": "family-water",
"title": "亲子玩水",
"image": "https://example.test/family-water.jpg",
"visitedAt": "2026-08-26T12:00:00",
}
],
"total": 1,
"pageNum": 1,
"pageSize": 20,
}
def test_public_browse_history_upserts_a_valid_route_without_accepting_a_customer_id():
customer = Customer(id="customer-1", phone="13800000000")
route = WanfaRoute(
id="family-water",
categoryId="family-route",
title="亲子玩水",
subtitle="贵州·轻松节奏与自然课堂",
image="https://example.test/family-water.jpg",
routeCount=4,
demandKeyword="亲子玩水",
sortOrder=0,
createdAt=datetime(2026, 1, 1),
updatedAt=datetime(2026, 1, 2),
)
db = FakeDb(scalar_values=[route, None])
app = authenticated_app(db, customer)
try:
response = TestClient(app).post(
"/api/public/customer/browse-history",
json={
"customerId": "customer-other",
"itemType": "wanfa-route",
"itemId": "family-water",
},
)
finally:
app.dependency_overrides.clear()
assert response.status_code == 201
history = db.added[0]
assert history.customerId == "customer-1"
assert history.itemType == "wanfa-route"
assert history.itemId == "family-water"
assert history.title == "亲子玩水"
assert history.image == "https://example.test/family-water.jpg"
assert response.json()["data"]["itemId"] == "family-water"
def test_public_browse_history_updates_existing_item_instead_of_creating_a_duplicate():
customer = Customer(id="customer-1", phone="13800000000")
route = WanfaRoute(
id="family-water",
categoryId="family-route",
title="亲子玩水·更新",
subtitle="贵州·轻松节奏与自然课堂",
image="https://example.test/family-water-new.jpg",
routeCount=4,
demandKeyword="亲子玩水",
sortOrder=0,
createdAt=datetime(2026, 1, 1),
updatedAt=datetime(2026, 1, 2),
)
history = SimpleNamespace(
id="history-1",
customerId="customer-1",
itemType="wanfa-route",
itemId="family-water",
title="亲子玩水",
image="https://example.test/family-water-old.jpg",
visitedAt=datetime(2026, 8, 25, 12, 0),
)
db = FakeDb(scalar_values=[route, history])
app = authenticated_app(db, customer)
try:
response = TestClient(app).post(
"/api/public/customer/browse-history",
json={"itemType": "wanfa-route", "itemId": "family-water"},
)
finally:
app.dependency_overrides.clear()
assert response.status_code == 201
assert db.added == []
assert history.title == "亲子玩水·更新"
assert history.image == "https://example.test/family-water-new.jpg"
assert history.visitedAt > datetime(2026, 8, 25, 12, 0)