From 02d9a86fa1a656b07fb8ead6c89c6a1f111d58ea Mon Sep 17 00:00:00 2001 From: Angel-Dijoux Date: Mon, 1 Jan 2024 01:10:40 +0100 Subject: [PATCH] test: write tests for search formation + onisep api call --- .../formation/scrap/get_main_formation.py | 15 ++--- .../formation/scrap/search_formation.py | 15 ++--- .../tests/unit/test_connect_to_onisep_api.py | 60 +++++++++++++++++++ .../unit/test_search_onisep_formations.py | 57 ++++++++++++++++++ .../formation/scrap/utils/get_onisep_data.py | 17 ++++++ 5 files changed, 144 insertions(+), 20 deletions(-) create mode 100644 src/business_logic/formation/scrap/tests/unit/test_connect_to_onisep_api.py create mode 100644 src/business_logic/formation/scrap/tests/unit/test_search_onisep_formations.py diff --git a/src/business_logic/formation/scrap/get_main_formation.py b/src/business_logic/formation/scrap/get_main_formation.py index bbc5dc9..745e662 100644 --- a/src/business_logic/formation/scrap/get_main_formation.py +++ b/src/business_logic/formation/scrap/get_main_formation.py @@ -3,18 +3,13 @@ format_formations, ) from src.business_logic.formation.scrap.types import FormationsWithTotal -from src.business_logic.formation.scrap.utils.get_onisep_data import get_onisep_data - - -def _get_raw_main_formations(limit: int = 10, offset: int = None) -> dict: - params = f"/search?&size={limit}" - if offset: - params += f"&from={offset}" - return get_onisep_data(params) +from src.business_logic.formation.scrap.utils.get_onisep_data import ( + get_raw_data, +) def get_main_formations(limit: int = 10, offset: int = None) -> FormationsWithTotal: - data = _get_raw_main_formations(limit, offset) + data = get_raw_data(limit, offset) formated_formations = format_formations(data["results"]) @@ -24,7 +19,7 @@ def get_main_formations(limit: int = 10, offset: int = None) -> FormationsWithTo def auth_get_main_formations( user_id: int, limit: int = 10, offset: int = None ) -> FormationsWithTotal: - data = _get_raw_main_formations(limit, offset) + data = get_raw_data(limit, offset) formated_formations = format_formation_with_is_favorite(user_id, data["results"]) diff --git a/src/business_logic/formation/scrap/search_formation.py b/src/business_logic/formation/scrap/search_formation.py index 67254e6..72f249f 100644 --- a/src/business_logic/formation/scrap/search_formation.py +++ b/src/business_logic/formation/scrap/search_formation.py @@ -3,20 +3,15 @@ format_formations, ) from src.business_logic.formation.scrap.types import FormationsWithTotal -from src.business_logic.formation.scrap.utils.get_onisep_data import get_onisep_data - - -def _get_raw_search_data(query: str, limit: int, offset: int = None) -> dict: - params = f"/search?q={query}&size={limit}" - if offset: - params += f"&from={offset}" - return get_onisep_data(params) +from src.business_logic.formation.scrap.utils.get_onisep_data import ( + get_raw_data, +) def search_formations( query: str, limit: int, offset: int = None ) -> FormationsWithTotal: - data = _get_raw_search_data(query, limit, offset) + data = get_raw_data(query, limit, offset) formated_formations = format_formations(data["results"]) @@ -26,7 +21,7 @@ def search_formations( def auth_search_formations( user_id: int, query: str, limit: int, offset: int = None ) -> FormationsWithTotal: - data = _get_raw_search_data(query, limit, offset) + data = get_raw_data(query, limit, offset) formated_formations = format_formation_with_is_favorite(user_id, data["results"]) return FormationsWithTotal(data["total"], formated_formations) diff --git a/src/business_logic/formation/scrap/tests/unit/test_connect_to_onisep_api.py b/src/business_logic/formation/scrap/tests/unit/test_connect_to_onisep_api.py new file mode 100644 index 0000000..637ebd3 --- /dev/null +++ b/src/business_logic/formation/scrap/tests/unit/test_connect_to_onisep_api.py @@ -0,0 +1,60 @@ +from unittest.mock import MagicMock, patch + +import pytest +from src.business_logic.formation.exceptions import NoOnisepAPIException +from src.business_logic.formation.scrap.utils.get_onisep_data import get_raw_data + +from src.constants.http_status_codes import ( + HTTP_200_OK, + HTTP_401_UNAUTHORIZED, + HTTP_500_INTERNAL_SERVER_ERROR, +) + + +@pytest.fixture +def mock_onisep_request(): + with patch( + "src.business_logic.formation.scrap.utils.get_onisep_data.requests.get" + ) as mock_requests_get: + yield mock_requests_get + + +def test_get_onisep_data_successful(mock_onisep_request): + # Arrange + mock_response = MagicMock() + mock_response.status_code = HTTP_200_OK + mock_response.json.return_value = {"total": "5173"} + mock_onisep_request.return_value = mock_response + # Act + result = get_raw_data("SHR") + # Assert + assert result == {"total": "5173"} + + +def test_get_onisep_data_retry_after_unauthorized(mock_onisep_request): + # Arrange + unauthorized_response = MagicMock() + unauthorized_response.status_code = HTTP_401_UNAUTHORIZED + authorized_response = MagicMock() + authorized_response.status_code = HTTP_200_OK + authorized_response.json.return_value = {"total": "5173"} + + # Set up the responses for the two requests + mock_onisep_request.side_effect = [unauthorized_response, authorized_response] + + # Act + result = get_raw_data("SHR") + + # Assert + assert result == {"total": "5173"} + + +def test_get_onisep_data_raises_exception(mock_onisep_request): + # Arrange + mock_response = MagicMock() + mock_response.status_code = HTTP_500_INTERNAL_SERVER_ERROR + mock_onisep_request.return_value = mock_response + + # Act and Assert + with pytest.raises(NoOnisepAPIException): + get_raw_data("SHR") diff --git a/src/business_logic/formation/scrap/tests/unit/test_search_onisep_formations.py b/src/business_logic/formation/scrap/tests/unit/test_search_onisep_formations.py new file mode 100644 index 0000000..e8089b8 --- /dev/null +++ b/src/business_logic/formation/scrap/tests/unit/test_search_onisep_formations.py @@ -0,0 +1,57 @@ +from unittest.mock import patch + +import pytest +from src.business_logic.formation.scrap.search_formation import search_formations +from src.business_logic.formation.scrap.types import ( + FormationsWithTotal, +) +from src.business_logic.formation.scrap.utils.format_formations import format_formations + + +MOKED_RESEARCH = { + "total": 5754, + "size": 1, + "results": [ + { + "code_nsf": "334", + "sigle_type_formation": "", + "libelle_type_formation": "baccalauréat technologique", + "libelle_formation_principal": "bac techno STHR Sciences et technologies de l'hôtellerie et de la restauration", + "sigle_formation": "STHR", + "duree": "1 an", + "niveau_de_sortie_indicatif": "Bac ou équivalent", + "code_rncp": "", + "niveau_de_certification": "4", + "libelle_niveau_de_certification": "niveau 4 (bac ou équivalent)", + "tutelle": "Ministère chargé de l'Éducation nationale et de la Jeunesse", + "url_et_id_onisep": "http://www.onisep.fr/http/redirection/formation/slug/FOR.494", + "domainesous-domaine": "hôtellerie-restauration, tourisme/hôtellerie | hôtellerie-restauration, tourisme/restauration", + } + ], +} + + +@pytest.fixture +def mock_search_formations(): + with patch( + "src.business_logic.formation.scrap.search_formation.get_raw_data" + ) as mock_get_raw_data: + yield mock_get_raw_data + + +def test_search_formations_successful(mock_search_formations): + # Arrange + mock_search_formations.return_value = MOKED_RESEARCH + + # Act + formations = search_formations("STHR", 1) + + # Assert + moked_formation = MOKED_RESEARCH["results"] + waited_formations = format_formations(moked_formation) + waited_result = FormationsWithTotal( + total=MOKED_RESEARCH["total"], formations=waited_formations + ) + + assert formations == waited_result + mock_search_formations.assert_called_once_with("STHR", 1, None) diff --git a/src/business_logic/formation/scrap/utils/get_onisep_data.py b/src/business_logic/formation/scrap/utils/get_onisep_data.py index 4105669..807a234 100644 --- a/src/business_logic/formation/scrap/utils/get_onisep_data.py +++ b/src/business_logic/formation/scrap/utils/get_onisep_data.py @@ -23,3 +23,20 @@ def get_onisep_data(params: str) -> dict: raise NoOnisepAPIException( f"\n status: {response.status_code} \n message : Onisep API is down. \n dataset : {DATASET} \n headers : {HEADERS} " ) + + +def get_raw_data( + query: str = None, + limit: int = 10, + offset: int = None, + is_main_formations: bool = True, +) -> dict: + if is_main_formations: + params = f"/search?&size={limit}" + else: + params = f"/search?q={query}&size={limit}" + + if offset: + params += f"&from={offset}" + + return get_onisep_data(params)