diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f869851..d8b8cfc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: run: pytest --cov=. --cov-config=.coveragerc --cov-report xml:coverage.xml - name: SonarCloud scan uses: sonarsource/sonarcloud-github-action@master - if: (github.event.sender.login == github.event.repository.owner.login) && (github.repository == 'lnx85/osservaprezzi.py') && (github.ref == 'refs/heads/main') + if: (github.event.sender.login == github.event.repository.owner.login) && (github.repository == 'lnx85/osservaprezzi.py') env: GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/osservaprezzi/client.py b/osservaprezzi/client.py index 7154832..ec51ca5 100644 --- a/osservaprezzi/client.py +++ b/osservaprezzi/client.py @@ -40,16 +40,12 @@ def __init__(self, session: ClientSession) -> None: async def get_brands(self) -> list[Brand]: """Get brands.""" json = await self._get(PATH_API_BRANDS) - if "loghi" in json: - return [brand_from_json(data) for data in json["loghi"]] - return [] + return [brand_from_json(data) for data in json.get("loghi", [])] async def get_fuels(self) -> list[Fuel]: """Get registered fuels.""" json = await self._get(PATH_API_FUELS) - if "results" in json: - return [fuel_from_json(data) for data in json["results"]] - return [] + return [fuel_from_json(data) for data in json.get("results", [])] async def get_stations( self, @@ -63,16 +59,12 @@ async def get_stations( if fuel_type is not None: payload["fuelType"] = fuel_type json = await self._post(PATH_API_ZONES, payload) - if "results" in json: - return [station_from_json(data) for data in json["results"]] - return [] + return [station_from_json(data) for data in json.get("results", [])] async def get_station(self, station_id: int) -> Station | None: """Get station.""" json = await self._get(PATH_API_SERVICE_AREA % station_id) - if "id" in json: - return station_from_json(json) - return None + return station_from_json(json) if "id" in json else None async def _get(self, path: str) -> dict[str, Any]: """Perform a GET request.""" diff --git a/tests/conftest.py b/tests/conftest.py index 5f82c6c..7d9ee50 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,9 +4,9 @@ import logging from typing import TYPE_CHECKING, Any -from unittest.mock import patch +from unittest.mock import AsyncMock, patch -from aiohttp import ClientSession +from aiohttp import ClientError, ClientSession import pytest from osservaprezzi.client import Osservaprezzi @@ -30,9 +30,41 @@ def mock_client_get_response( yield response +@pytest.fixture +def mock_client_get_response_timeout() -> Generator[AsyncMock, None, None]: + with patch( + "aiohttp.ClientSession.get", side_effect=TimeoutError + ) as mock_client_get_response_timeout: + yield mock_client_get_response_timeout + + +@pytest.fixture +def mock_client_get_response_error() -> Generator[AsyncMock, None, None]: + with patch( + "aiohttp.ClientSession.get", side_effect=ClientError + ) as mock_client_get_response_error: + yield mock_client_get_response_error + + @pytest.fixture def mock_client_post_response( response: dict[str, Any], ) -> Generator[dict[str, Any], None, None]: with patch("osservaprezzi.client.Osservaprezzi._post", return_value=response): yield response + + +@pytest.fixture +def mock_client_post_response_timeout() -> Generator[AsyncMock, None, None]: + with patch( + "aiohttp.ClientSession.post", side_effect=TimeoutError + ) as mock_client_get_response_timeout: + yield mock_client_get_response_timeout + + +@pytest.fixture +def mock_client_post_response_error() -> Generator[AsyncMock, None, None]: + with patch( + "aiohttp.ClientSession.post", side_effect=ClientError + ) as mock_client_post_response_error: + yield mock_client_post_response_error diff --git a/tests/test_client.py b/tests/test_client.py new file mode 100644 index 0000000..de16e72 --- /dev/null +++ b/tests/test_client.py @@ -0,0 +1,43 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +from osservaprezzi.exceptions import ApiError, ApiTimeoutError +from osservaprezzi.models import GPSCoordinates + +if TYPE_CHECKING: + from osservaprezzi.client import Osservaprezzi + + +@pytest.mark.usefixtures("client", "mock_client_get_response_timeout") +async def test_get_response_timeout( + client: Osservaprezzi, +) -> None: + with pytest.raises(ApiTimeoutError): + await client.get_fuels() + + +@pytest.mark.usefixtures("client", "mock_client_get_response_error") +async def test_get_response_error( + client: Osservaprezzi, +) -> None: + with pytest.raises(ApiError): + await client.get_fuels() + + +@pytest.mark.usefixtures("client", "mock_client_post_response_timeout") +async def test_post_response_timeout( + client: Osservaprezzi, +) -> None: + with pytest.raises(ApiTimeoutError): + await client.get_stations(GPSCoordinates(45.542662, 10.225224), radius=5) + + +@pytest.mark.usefixtures("client", "mock_client_post_response_error") +async def test_post_response_error( + client: Osservaprezzi, +) -> None: + with pytest.raises(ApiError): + await client.get_stations(GPSCoordinates(45.542662, 10.225224), radius=5)