diff --git a/.vscode/settings.json b/.vscode/settings.json index 23380ff..09edb50 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,8 @@ "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, "chat.tools.terminal.autoApprove": { - "pytest": true + "pytest": true, + "uv": true, + "true": true } } \ No newline at end of file diff --git a/app/api/api_router.py b/app/api/api_router.py index 9d1f6e8..45f7352 100644 --- a/app/api/api_router.py +++ b/app/api/api_router.py @@ -4,11 +4,11 @@ from app.api import api_messages from app.api.endpoints import ( auth, humidity, + iot, pets, pressure, temperature, users, - iot, ) auth_router = APIRouter() diff --git a/app/api/endpoints/iot.py b/app/api/endpoints/iot.py index 453d36d..f2c66af 100644 --- a/app/api/endpoints/iot.py +++ b/app/api/endpoints/iot.py @@ -18,7 +18,7 @@ router = APIRouter() ) async def log_iot_readings( data: IoTLogRequest, session: AsyncSession = Depends(deps.get_session) -) -> dict: +) -> dict[str, int]: total = 0 for device in data.devices: diff --git a/app/tests/test_api/test_deps.py b/app/tests/test_api/test_deps.py index 8d00084..ae4dbd7 100644 --- a/app/tests/test_api/test_deps.py +++ b/app/tests/test_api/test_deps.py @@ -1,24 +1,25 @@ import types +from typing import Any, cast import pytest -from fastapi import HTTPException +from fastapi import HTTPException, status +from sqlalchemy.ext.asyncio import AsyncSession -from app.api import deps -from app.api import api_messages +from app.api import api_messages, deps class FakeSession: - async def scalar(self, _query): + async def scalar(self, _query: Any) -> Any: return None @pytest.mark.asyncio -async def test_get_current_user_raises_when_user_removed(monkeypatch): +async def test_get_current_user_raises_when_user_removed(monkeypatch: pytest.MonkeyPatch) -> None: # make verify_jwt_token return an object with .sub monkeypatch.setattr(deps, "verify_jwt_token", lambda token: types.SimpleNamespace(sub="non-existent")) with pytest.raises(HTTPException) as excinfo: - await deps.get_current_user(token="ignored", session=FakeSession()) + await deps.get_current_user(token="ignored", session=cast(AsyncSession, FakeSession())) - assert excinfo.value.status_code == 401 + assert excinfo.value.status_code == status.HTTP_401_UNAUTHORIZED assert excinfo.value.detail == api_messages.JWT_ERROR_USER_REMOVED diff --git a/app/tests/test_api/test_iot.py b/app/tests/test_api/test_iot.py index c8674f5..5416b1e 100644 --- a/app/tests/test_api/test_iot.py +++ b/app/tests/test_api/test_iot.py @@ -37,8 +37,9 @@ async def test_log_iot_readings_persists_multiple(client: AsyncClient, session: response = await client.post(app.url_path_for("log_iot_readings"), json=payload) assert response.status_code == status.HTTP_201_CREATED - assert response.json()["logged_count"] == 3 + expected_count = sum(len(d["readings"]) for d in payload["devices"]) + assert response.json()["logged_count"] == expected_count rows = await session.scalars(select(IoTReading)) all_readings = list(rows.all()) - assert len(all_readings) >= 3 + assert len(all_readings) >= expected_count