fix: ruff lint + format fixes in tests, ESLint fixes in frontend
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
"""Additional tests for vehicle_service and router to reach 80% coverage."""
|
||||
|
||||
import uuid
|
||||
from datetime import date, datetime, timezone
|
||||
from datetime import date
|
||||
from decimal import Decimal
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.vehicle import MobileDeListing, Vehicle
|
||||
from app.models.vehicle import Vehicle
|
||||
from app.services import vehicle_service
|
||||
|
||||
|
||||
@@ -84,25 +83,38 @@ class TestVehicleServiceDirect:
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_vehicles_pagination(self, db_session):
|
||||
"""list_vehicles respects page and page_size."""
|
||||
fins = ["WDB9066351L123450", "WDB9066351L123451", "WDB9066351L123452",
|
||||
"WDB9066351L123453", "WDB9066351L123454"]
|
||||
fins = [
|
||||
"WDB9066351L123450",
|
||||
"WDB9066351L123451",
|
||||
"WDB9066351L123452",
|
||||
"WDB9066351L123453",
|
||||
"WDB9066351L123454",
|
||||
]
|
||||
for fin in fins:
|
||||
data = _make_vehicle_data(fin=fin)
|
||||
vehicle = Vehicle(**data)
|
||||
db_session.add(vehicle)
|
||||
await db_session.flush()
|
||||
|
||||
vehicles, total = await vehicle_service.list_vehicles(db_session, page=1, page_size=2)
|
||||
vehicles, total = await vehicle_service.list_vehicles(
|
||||
db_session, page=1, page_size=2
|
||||
)
|
||||
assert len(vehicles) == 2
|
||||
assert total == 5
|
||||
|
||||
vehicles_page2, _ = await vehicle_service.list_vehicles(db_session, page=2, page_size=2)
|
||||
vehicles_page2, _ = await vehicle_service.list_vehicles(
|
||||
db_session, page=2, page_size=2
|
||||
)
|
||||
assert len(vehicles_page2) == 2
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_vehicles_sort_ascending(self, db_session):
|
||||
"""list_vehicles sorts ascending by make."""
|
||||
makes_fins = [("Zebra", "WDB9066351L000001"), ("Alpha", "WDB9066351L000002"), ("Mike", "WDB9066351L000003")]
|
||||
makes_fins = [
|
||||
("Zebra", "WDB9066351L000001"),
|
||||
("Alpha", "WDB9066351L000002"),
|
||||
("Mike", "WDB9066351L000003"),
|
||||
]
|
||||
for make, fin in makes_fins:
|
||||
data = _make_vehicle_data(make=make, fin=fin)
|
||||
vehicle = Vehicle(**data)
|
||||
@@ -114,14 +126,18 @@ class TestVehicleServiceDirect:
|
||||
assert makes == sorted(makes)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_vehicles_sort_invalid_field_defaults_to_created_at(self, db_session):
|
||||
async def test_list_vehicles_sort_invalid_field_defaults_to_created_at(
|
||||
self, db_session
|
||||
):
|
||||
"""list_vehicles falls back to created_at sort for invalid field."""
|
||||
data = _make_vehicle_data()
|
||||
vehicle = Vehicle(**data)
|
||||
db_session.add(vehicle)
|
||||
await db_session.flush()
|
||||
|
||||
vehicles, total = await vehicle_service.list_vehicles(db_session, sort="invalid_field")
|
||||
vehicles, total = await vehicle_service.list_vehicles(
|
||||
db_session, sort="invalid_field"
|
||||
)
|
||||
assert total == 1
|
||||
assert len(vehicles) == 1
|
||||
|
||||
@@ -134,7 +150,9 @@ class TestVehicleServiceDirect:
|
||||
db_session.add(Vehicle(**data2))
|
||||
await db_session.flush()
|
||||
|
||||
vehicles, total = await vehicle_service.list_vehicles(db_session, min_price=50000)
|
||||
vehicles, total = await vehicle_service.list_vehicles(
|
||||
db_session, min_price=50000
|
||||
)
|
||||
assert total == 1
|
||||
assert float(vehicles[0].price) >= 50000
|
||||
|
||||
@@ -147,7 +165,9 @@ class TestVehicleServiceDirect:
|
||||
db_session.add(Vehicle(**data2))
|
||||
await db_session.flush()
|
||||
|
||||
vehicles, total = await vehicle_service.list_vehicles(db_session, max_price=40000)
|
||||
vehicles, total = await vehicle_service.list_vehicles(
|
||||
db_session, max_price=40000
|
||||
)
|
||||
assert total == 1
|
||||
assert float(vehicles[0].price) <= 40000
|
||||
|
||||
@@ -158,7 +178,9 @@ class TestVehicleServiceDirect:
|
||||
db_session.add(Vehicle(**data))
|
||||
await db_session.flush()
|
||||
|
||||
vehicles, total = await vehicle_service.list_vehicles(db_session, search="123456")
|
||||
vehicles, total = await vehicle_service.list_vehicles(
|
||||
db_session, search="123456"
|
||||
)
|
||||
assert total == 1
|
||||
assert "123456" in vehicles[0].fin
|
||||
|
||||
@@ -169,7 +191,9 @@ class TestVehicleServiceDirect:
|
||||
db_session.add(Vehicle(**data))
|
||||
await db_session.flush()
|
||||
|
||||
vehicles, total = await vehicle_service.list_vehicles(db_session, search="Munich")
|
||||
vehicles, total = await vehicle_service.list_vehicles(
|
||||
db_session, search="Munich"
|
||||
)
|
||||
assert total == 1
|
||||
assert vehicles[0].location == "Munich"
|
||||
|
||||
@@ -181,14 +205,18 @@ class TestVehicleServiceDirect:
|
||||
db_session.add(vehicle)
|
||||
await db_session.flush()
|
||||
|
||||
result = await vehicle_service.get_vehicle_by_fin(db_session, "WDB9066351L999999")
|
||||
result = await vehicle_service.get_vehicle_by_fin(
|
||||
db_session, "WDB9066351L999999"
|
||||
)
|
||||
assert result is not None
|
||||
assert result.fin == "WDB9066351L999999"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_vehicle_by_fin_not_found(self, db_session):
|
||||
"""get_vehicle_by_fin returns None for nonexistent FIN."""
|
||||
result = await vehicle_service.get_vehicle_by_fin(db_session, "NONEXISTENT1234567")
|
||||
result = await vehicle_service.get_vehicle_by_fin(
|
||||
db_session, "NONEXISTENT1234567"
|
||||
)
|
||||
assert result is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -302,14 +330,20 @@ class TestRouterAdditionalPaths:
|
||||
assert data["total"] >= 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_vehicle_verkaeufer_allowed(self, verkaeufer_client, sample_vehicle_data):
|
||||
async def test_create_vehicle_verkaeufer_allowed(
|
||||
self, verkaeufer_client, sample_vehicle_data
|
||||
):
|
||||
"""POST /api/v1/vehicles works for verkaeufer role (not admin-only)."""
|
||||
sample_vehicle_data["fin"] = "WDB9066351L654321"
|
||||
response = await verkaeufer_client.post("/api/v1/vehicles/", json=sample_vehicle_data)
|
||||
response = await verkaeufer_client.post(
|
||||
"/api/v1/vehicles/", json=sample_vehicle_data
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_vehicle_fin_duplicate_returns_409(self, admin_client, sample_vehicle_data):
|
||||
async def test_update_vehicle_fin_duplicate_returns_409(
|
||||
self, admin_client, sample_vehicle_data
|
||||
):
|
||||
"""PUT /api/v1/vehicles/:id with duplicate FIN returns 409."""
|
||||
sample_vehicle_data["fin"] = "WDB9066351L111111"
|
||||
resp1 = await admin_client.post("/api/v1/vehicles/", json=sample_vehicle_data)
|
||||
@@ -329,7 +363,9 @@ class TestRouterAdditionalPaths:
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_vehicles_empty_result(self, admin_client):
|
||||
"""GET /api/v1/vehicles with filters that match nothing returns empty list."""
|
||||
response = await admin_client.get("/api/v1/vehicles/?type=baumaschine&min_price=999999")
|
||||
response = await admin_client.get(
|
||||
"/api/v1/vehicles/?type=baumaschine&min_price=999999"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["total"] == 0
|
||||
@@ -342,11 +378,16 @@ class TestRouterAdditionalPaths:
|
||||
assert response.status_code == 422
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_push_to_mobile_de_failure_still_returns_202(self, admin_client, created_vehicle):
|
||||
async def test_push_to_mobile_de_failure_still_returns_202(
|
||||
self, admin_client, created_vehicle
|
||||
):
|
||||
"""POST /api/v1/vehicles/:id/mobile-de/push returns 202 even when mobile.de API fails."""
|
||||
import httpx
|
||||
|
||||
vehicle_id = created_vehicle["id"]
|
||||
with patch("app.services.mobilede_service.httpx.AsyncClient") as mock_client_cls:
|
||||
with patch(
|
||||
"app.services.mobilede_service.httpx.AsyncClient"
|
||||
) as mock_client_cls:
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 500
|
||||
mock_response.text = "Internal Server Error"
|
||||
@@ -359,16 +400,23 @@ class TestRouterAdditionalPaths:
|
||||
mock_client.__aexit__ = AsyncMock(return_value=None)
|
||||
mock_client_cls.return_value = mock_client
|
||||
|
||||
response = await admin_client.post(f"/api/v1/vehicles/{vehicle_id}/mobile-de/push")
|
||||
response = await admin_client.post(
|
||||
f"/api/v1/vehicles/{vehicle_id}/mobile-de/push"
|
||||
)
|
||||
|
||||
assert response.status_code == 202
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mobile_de_status_after_failed_push(self, admin_client, created_vehicle):
|
||||
async def test_mobile_de_status_after_failed_push(
|
||||
self, admin_client, created_vehicle
|
||||
):
|
||||
"""GET /api/v1/vehicles/:id/mobile-de/status shows fehler after failed push."""
|
||||
import httpx
|
||||
|
||||
vehicle_id = created_vehicle["id"]
|
||||
with patch("app.services.mobilede_service.httpx.AsyncClient") as mock_client_cls:
|
||||
with patch(
|
||||
"app.services.mobilede_service.httpx.AsyncClient"
|
||||
) as mock_client_cls:
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 500
|
||||
mock_response.text = "Internal Server Error"
|
||||
@@ -383,7 +431,9 @@ class TestRouterAdditionalPaths:
|
||||
|
||||
await admin_client.post(f"/api/v1/vehicles/{vehicle_id}/mobile-de/push")
|
||||
|
||||
response = await admin_client.get(f"/api/v1/vehicles/{vehicle_id}/mobile-de/status")
|
||||
response = await admin_client.get(
|
||||
f"/api/v1/vehicles/{vehicle_id}/mobile-de/status"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["synced"] is False
|
||||
|
||||
Reference in New Issue
Block a user