Add CarPass gamification scoring foundation
This commit is contained in:
@@ -14,7 +14,7 @@ from app.core.config import settings
|
||||
from app.db.base import Base
|
||||
from app.db.session import get_session
|
||||
from app.main import app
|
||||
from app.models import car, expense, push, user # noqa: F401
|
||||
from app.models import car, expense, gamification, push, user # noqa: F401
|
||||
|
||||
TEST_BOT_TOKEN = "123456:test-token"
|
||||
TEST_INTERNAL_TOKEN = "internal-test-token"
|
||||
|
||||
86
tests/test_gamification.py
Normal file
86
tests/test_gamification.py
Normal file
@@ -0,0 +1,86 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_vehicle_score_is_backend_driven(client, auth_headers) -> None:
|
||||
vehicle = (
|
||||
await client.post(
|
||||
"/api/my/vehicles",
|
||||
headers=auth_headers,
|
||||
json={
|
||||
"name": "Passport car",
|
||||
"make": "Hyundai",
|
||||
"model": "Avante",
|
||||
"year": 2020,
|
||||
"license_plate": "12 가 3456",
|
||||
"license_plate_country": "KR",
|
||||
"vin": "KMHCT41BAHU123456",
|
||||
"fuel_type": "gasoline",
|
||||
"current_odometer": 12000,
|
||||
"engine_oil_type": "5W-30",
|
||||
"engine_oil_volume_l": 4.2,
|
||||
},
|
||||
)
|
||||
).json()
|
||||
await client.post(
|
||||
"/api/fuel",
|
||||
headers=auth_headers,
|
||||
json={
|
||||
"car_id": vehicle["id"],
|
||||
"entry_date": "2026-05-12",
|
||||
"odometer": 12000,
|
||||
"liters": 35,
|
||||
"price_per_liter": 2,
|
||||
},
|
||||
)
|
||||
|
||||
response = await client.get(f"/api/my/vehicles/{vehicle['id']}/score", headers=auth_headers)
|
||||
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert payload["vehicle_id"] == vehicle["id"]
|
||||
assert payload["completeness_score"] >= 70
|
||||
assert payload["profile_quality"] in {"strong", "high_confidence"}
|
||||
assert isinstance(payload["missing_items"], list)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_timeline_contains_fuel_service_and_achievements(client, auth_headers) -> None:
|
||||
vehicle = (await client.post("/api/my/vehicles", headers=auth_headers, json={"name": "Timeline car"})).json()
|
||||
await client.post(
|
||||
"/api/service",
|
||||
headers=auth_headers,
|
||||
json={
|
||||
"car_id": vehicle["id"],
|
||||
"entry_date": "2026-05-12",
|
||||
"service_type": "maintenance",
|
||||
"title": "Oil service",
|
||||
"total_cost": 100,
|
||||
},
|
||||
)
|
||||
await client.get(f"/api/my/vehicles/{vehicle['id']}/score", headers=auth_headers)
|
||||
|
||||
response = await client.get(f"/api/my/vehicles/{vehicle['id']}/timeline", headers=auth_headers)
|
||||
|
||||
assert response.status_code == 200
|
||||
item_types = {item["type"] for item in response.json()}
|
||||
assert "service" in item_types
|
||||
assert "achievement" in item_types
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_service_center_trust_score_requires_employee_access(client, auth_headers, other_auth_headers) -> None:
|
||||
center = (
|
||||
await client.post(
|
||||
"/api/service-centers",
|
||||
headers=auth_headers,
|
||||
json={"display_name": "Trust Service", "country": "KR", "city": "Seoul"},
|
||||
)
|
||||
).json()
|
||||
|
||||
forbidden = await client.get(f"/api/service-centers/{center['id']}/trust-score", headers=other_auth_headers)
|
||||
allowed = await client.get(f"/api/service-centers/{center['id']}/trust-score", headers=auth_headers)
|
||||
|
||||
assert forbidden.status_code == 403
|
||||
assert allowed.status_code == 200
|
||||
assert allowed.json()["trust_level"] == "new_service"
|
||||
Reference in New Issue
Block a user