fix: ruff lint + format fixes in tests, ESLint fixes in frontend

This commit is contained in:
2026-07-17 21:28:58 +02:00
parent 341d0c6f38
commit fbb1b39b57
56 changed files with 1399 additions and 721 deletions
+78 -33
View File
@@ -1,17 +1,10 @@
"""Tests for vehicle CRUD endpoints and mobile.de integration."""
import uuid
from datetime import date
from decimal import Decimal
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
import pytest_asyncio
from httpx import ASGITransport, AsyncClient
from app.database import Base, get_db
from app.main import app
from app.models.vehicle import MobileDeListing, Vehicle
@pytest_asyncio.fixture
@@ -50,7 +43,9 @@ class TestVehicleList:
"""GET /api/v1/vehicles tests."""
@pytest.mark.asyncio
async def test_list_vehicles_returns_200_with_pagination(self, admin_client, created_vehicle):
async def test_list_vehicles_returns_200_with_pagination(
self, admin_client, created_vehicle
):
"""GET /api/v1/vehicles returns 200 with paginated list."""
response = await admin_client.get("/api/v1/vehicles/?page=1&page_size=20")
assert response.status_code == 200
@@ -74,7 +69,9 @@ class TestVehicleList:
assert item["vehicle_type"] == "lkw"
@pytest.mark.asyncio
async def test_list_vehicles_filter_by_availability(self, admin_client, created_vehicle):
async def test_list_vehicles_filter_by_availability(
self, admin_client, created_vehicle
):
"""GET /api/v1/vehicles?availability=available returns filtered results."""
response = await admin_client.get("/api/v1/vehicles/?availability=available")
assert response.status_code == 200
@@ -92,9 +89,13 @@ class TestVehicleList:
assert data["items"][0]["created_at"] >= data["items"][1]["created_at"]
@pytest.mark.asyncio
async def test_list_vehicles_filter_by_price_range(self, admin_client, created_vehicle):
async def test_list_vehicles_filter_by_price_range(
self, admin_client, created_vehicle
):
"""GET /api/v1/vehicles?min_price=40000&max_price=50000 returns filtered results."""
response = await admin_client.get("/api/v1/vehicles/?min_price=40000&max_price=50000")
response = await admin_client.get(
"/api/v1/vehicles/?min_price=40000&max_price=50000"
)
assert response.status_code == 200
data = response.json()
for item in data["items"]:
@@ -123,7 +124,9 @@ class TestVehicleCreate:
@pytest.mark.asyncio
async def test_create_vehicle_returns_201(self, admin_client, sample_vehicle_data):
"""POST /api/v1/vehicles with valid data returns 201."""
response = await admin_client.post("/api/v1/vehicles/", json=sample_vehicle_data)
response = await admin_client.post(
"/api/v1/vehicles/", json=sample_vehicle_data
)
assert response.status_code == 201
data = response.json()
assert data["make"] == sample_vehicle_data["make"]
@@ -133,38 +136,58 @@ class TestVehicleCreate:
assert data["id"] is not None
@pytest.mark.asyncio
async def test_create_vehicle_missing_make_returns_422(self, admin_client, sample_vehicle_data):
async def test_create_vehicle_missing_make_returns_422(
self, admin_client, sample_vehicle_data
):
"""POST /api/v1/vehicles without make returns 422."""
del sample_vehicle_data["make"]
response = await admin_client.post("/api/v1/vehicles/", json=sample_vehicle_data)
response = await admin_client.post(
"/api/v1/vehicles/", json=sample_vehicle_data
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_create_vehicle_missing_fin_returns_422(self, admin_client, sample_vehicle_data):
async def test_create_vehicle_missing_fin_returns_422(
self, admin_client, sample_vehicle_data
):
"""POST /api/v1/vehicles without fin returns 422."""
del sample_vehicle_data["fin"]
response = await admin_client.post("/api/v1/vehicles/", json=sample_vehicle_data)
response = await admin_client.post(
"/api/v1/vehicles/", json=sample_vehicle_data
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_create_vehicle_short_fin_returns_422(self, admin_client, sample_vehicle_data):
async def test_create_vehicle_short_fin_returns_422(
self, admin_client, sample_vehicle_data
):
"""POST /api/v1/vehicles with short FIN returns 422."""
sample_vehicle_data["fin"] = "SHORT"
response = await admin_client.post("/api/v1/vehicles/", json=sample_vehicle_data)
response = await admin_client.post(
"/api/v1/vehicles/", json=sample_vehicle_data
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_create_vehicle_duplicate_fin_returns_409(self, admin_client, sample_vehicle_data, created_vehicle):
async def test_create_vehicle_duplicate_fin_returns_409(
self, admin_client, sample_vehicle_data, created_vehicle
):
"""POST /api/v1/vehicles with duplicate FIN returns 409."""
response = await admin_client.post("/api/v1/vehicles/", json=sample_vehicle_data)
response = await admin_client.post(
"/api/v1/vehicles/", json=sample_vehicle_data
)
assert response.status_code == 409
@pytest.mark.asyncio
async def test_create_vehicle_auto_computes_power_hp(self, admin_client, sample_vehicle_data):
async def test_create_vehicle_auto_computes_power_hp(
self, admin_client, sample_vehicle_data
):
"""POST /api/v1/vehicles auto-computes power_hp from power_kw."""
sample_vehicle_data["power_kw"] = 100
sample_vehicle_data.pop("power_hp", None)
response = await admin_client.post("/api/v1/vehicles/", json=sample_vehicle_data)
response = await admin_client.post(
"/api/v1/vehicles/", json=sample_vehicle_data
)
assert response.status_code == 201
data = response.json()
assert data["power_hp"] == 136 # 100 * 1.35962 ≈ 136
@@ -218,7 +241,9 @@ class TestVehicleUpdate:
assert response.status_code == 404
@pytest.mark.asyncio
async def test_update_vehicle_no_fields_returns_400(self, admin_client, created_vehicle):
async def test_update_vehicle_no_fields_returns_400(
self, admin_client, created_vehicle
):
"""PUT /api/v1/vehicles/:id with no fields returns 400."""
vehicle_id = created_vehicle["id"]
response = await admin_client.put(
@@ -232,7 +257,9 @@ class TestVehicleDelete:
"""DELETE /api/v1/vehicles/:id tests."""
@pytest.mark.asyncio
async def test_delete_vehicle_returns_200_with_deleted_at(self, admin_client, created_vehicle):
async def test_delete_vehicle_returns_200_with_deleted_at(
self, admin_client, created_vehicle
):
"""DELETE /api/v1/vehicles/:id returns 200 and sets deleted_at."""
vehicle_id = created_vehicle["id"]
response = await admin_client.delete(f"/api/v1/vehicles/{vehicle_id}")
@@ -259,7 +286,9 @@ class TestVehicleDelete:
assert item["id"] != vehicle_id
@pytest.mark.asyncio
async def test_deleted_vehicle_returns_404_on_detail(self, admin_client, created_vehicle):
async def test_deleted_vehicle_returns_404_on_detail(
self, admin_client, created_vehicle
):
"""After soft-delete, GET /api/v1/vehicles/:id returns 404."""
vehicle_id = created_vehicle["id"]
await admin_client.delete(f"/api/v1/vehicles/{vehicle_id}")
@@ -274,7 +303,9 @@ class TestMobileDePush:
async def test_push_returns_202(self, admin_client, created_vehicle):
"""POST /api/v1/vehicles/:id/mobile-de/push returns 202."""
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 = 201
mock_response.json.return_value = {"id": "mobile-de-ad-123"}
@@ -285,7 +316,9 @@ class TestMobileDePush:
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
data = response.json()
@@ -305,20 +338,28 @@ class TestMobileDeStatus:
"""GET /api/v1/vehicles/:id/mobile-de/status tests."""
@pytest.mark.asyncio
async def test_status_returns_200_with_no_listing(self, admin_client, created_vehicle):
async def test_status_returns_200_with_no_listing(
self, admin_client, created_vehicle
):
"""GET /api/v1/vehicles/:id/mobile-de/status returns 200 with pending status when no listing exists."""
vehicle_id = created_vehicle["id"]
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
assert data["sync_status"] == "pending"
@pytest.mark.asyncio
async def test_status_returns_200_with_synced_listing(self, admin_client, created_vehicle):
async def test_status_returns_200_with_synced_listing(
self, admin_client, created_vehicle
):
"""GET /api/v1/vehicles/:id/mobile-de/status returns 200 with sync info after push."""
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 = 201
mock_response.json.return_value = {"id": "mobile-de-ad-456"}
@@ -331,7 +372,9 @@ class TestMobileDeStatus:
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 True
@@ -342,5 +385,7 @@ class TestMobileDeStatus:
async def test_status_nonexistent_vehicle_returns_404(self, admin_client):
"""GET /api/v1/vehicles/:id/mobile-de/status with nonexistent ID returns 404."""
fake_id = str(uuid.uuid4())
response = await admin_client.get(f"/api/v1/vehicles/{fake_id}/mobile-de/status")
response = await admin_client.get(
f"/api/v1/vehicles/{fake_id}/mobile-de/status"
)
assert response.status_code == 404