From e370fba7e35ce47a83ae074704613c8388e540eb Mon Sep 17 00:00:00 2001 From: Conor Brady Date: Wed, 7 Aug 2024 12:13:34 -0700 Subject: [PATCH] Fix test --- .vscode/settings.json | 1 + api/app/morecast_v2/forecasts.py | 5 +- api/app/routers/morecast_v2.py | 11 +-- .../morecast_v2/test_morecast_v2_endpoint.py | 74 ++++++++++--------- 4 files changed, 47 insertions(+), 44 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 547226c76..dc8ad8381 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -78,6 +78,7 @@ "HAINES", "hourlies", "HRDPS", + "idir", "Indeterminates", "luxon", "maxx", diff --git a/api/app/morecast_v2/forecasts.py b/api/app/morecast_v2/forecasts.py index a7ec300e8..a4648185a 100644 --- a/api/app/morecast_v2/forecasts.py +++ b/api/app/morecast_v2/forecasts.py @@ -87,11 +87,10 @@ async def construct_wf1_forecasts(session: ClientSession, forecast_records: List return wf1_forecasts -async def format_as_wf1_post_forecasts(session: ClientSession, forecast_records: List[MoreCastForecastInput], username: str) -> List[WF1PostForecast]: +async def format_as_wf1_post_forecasts(session: ClientSession, forecast_records: List[MoreCastForecastInput], username: str, headers: dict) -> List[WF1PostForecast]: """Returns list of forecast records re-formatted in the data structure WF1 API expects""" - header = await get_auth_header(session) station_codes = [record.station_code for record in forecast_records] - stations = await get_wfwx_stations_from_station_codes(session, header, station_codes) + stations = await get_wfwx_stations_from_station_codes(session, headers, station_codes) unique_stations = list(set(stations)) wf1_post_forecasts = await construct_wf1_forecasts(session, forecast_records, unique_stations, username) return wf1_post_forecasts diff --git a/api/app/routers/morecast_v2.py b/api/app/routers/morecast_v2.py index 8880d469f..cfca4c49d 100644 --- a/api/app/routers/morecast_v2.py +++ b/api/app/routers/morecast_v2.py @@ -111,7 +111,8 @@ async def save_forecasts(forecasts: MoreCastForecastRequest, response: Response, async with ClientSession() as client_session: try: - wf1_forecast_records = await format_as_wf1_post_forecasts(client_session, forecasts_list, username) + headers = await get_auth_header(client_session) + wf1_forecast_records = await format_as_wf1_post_forecasts(client_session, forecasts_list, username, headers) await post_forecasts(client_session, forecasts=wf1_forecast_records) station_ids = [wfwx_station.stationId for wfwx_station in wf1_forecast_records] @@ -152,9 +153,9 @@ async def get_yesterdays_actual_dailies(today: date, request: ObservedDailiesFor async with ClientSession() as session: header = await get_auth_header(session) - yeserday_dailies = await get_dailies_for_stations_and_date(session, header, time_of_interest, time_of_interest, unique_station_codes) + yesterday_dailies = await get_dailies_for_stations_and_date(session, header, time_of_interest, time_of_interest, unique_station_codes) - return StationDailiesResponse(dailies=yeserday_dailies) + return StationDailiesResponse(dailies=yesterday_dailies) @router.post("/observed-dailies/{start_date}/{end_date}", response_model=StationDailiesResponse) @@ -237,8 +238,8 @@ async def get_determinates_for_date_range(start_date: date, end_date: date, requ # for a given date, we need to show the forecast from the wf1 API for one station, and the forecast # from our API database for another station. We can check this by testing for the presence of an # actual for the given date and station; if an actual exists we use the forecast from our API database. - transformed_forceasts_to_add = filter_for_api_forecasts(transformed_forecasts, wf1_actuals) + transformed_forecasts_to_add = filter_for_api_forecasts(transformed_forecasts, wf1_actuals) - wf1_forecasts.extend(transformed_forceasts_to_add) + wf1_forecasts.extend(transformed_forecasts_to_add) return IndeterminateDailiesResponse(actuals=wf1_actuals, forecasts=wf1_forecasts, grass_curing=grass_curing, predictions=predictions) diff --git a/api/app/tests/morecast_v2/test_morecast_v2_endpoint.py b/api/app/tests/morecast_v2/test_morecast_v2_endpoint.py index 410c58521..5ee9336ef 100644 --- a/api/app/tests/morecast_v2/test_morecast_v2_endpoint.py +++ b/api/app/tests/morecast_v2/test_morecast_v2_endpoint.py @@ -5,24 +5,22 @@ from aiohttp import ClientSession from app.schemas.shared import StationsRequest from app.tests.common import default_mock_client_get -from app.schemas.morecast_v2 import (MoreCastForecastInput, - MoreCastForecastRequest, StationDailyFromWF1) +from app.schemas.morecast_v2 import MoreCastForecastInput, MoreCastForecastRequest, StationDailyFromWF1 import app.routers.morecast_v2 from app.tests.utils.mock_jwt_decode_role import MockJWTDecodeWithRole -morecast_v2_post_url = '/api/morecast-v2/forecast' -morecast_v2_get_url = '/api/morecast-v2/forecasts/2023-03-15' +morecast_v2_post_url = "/api/morecast-v2/forecast" +morecast_v2_get_url = "/api/morecast-v2/forecasts/2023-03-15" morecast_v2_post_by_date_range_url = "/api/morecast-v2/forecasts/2023-03-15/2023-03-19" -today = '2022-10-07' -morecast_v2_post_yesterday_dailies_url = f'/api/morecast-v2/yesterday-dailies/{today}' +today = "2022-10-07" +morecast_v2_post_yesterday_dailies_url = f"/api/morecast-v2/yesterday-dailies/{today}" morecast_v2_post_determinates_url = "/api/morecast-v2/determinates/2023-03-15/2023-03-19" decode_fn = "jwt.decode" -forecast = MoreCastForecastRequest(token="testToken", forecasts=[MoreCastForecastInput( - station_code=1, for_date=1, temp=10.0, rh=40.1, precip=70.2, wind_speed=20.3, wind_direction=40)]) +forecast = MoreCastForecastRequest(token="testToken", forecasts=[MoreCastForecastInput(station_code=1, for_date=1, temp=10.0, rh=40.1, precip=70.2, wind_speed=20.3, wind_direction=40)]) stations = StationsRequest(stations=[1, 2]) @@ -44,66 +42,69 @@ async def async_client(): def test_get_forecast_unauthorized(client: TestClient): - """ forecast role required for retrieving forecasts """ + """forecast role required for retrieving forecasts""" response = client.get(morecast_v2_get_url) assert response.status_code == 401 def test_get_forecast_authorized(client: TestClient, monkeypatch: pytest.MonkeyPatch): - """ forecast role required for persisting a forecast """ + """forecast role required for persisting a forecast""" def mock_admin_role_function(*_, **__): - return MockJWTDecodeWithRole('morecast2_write_forecast') + return MockJWTDecodeWithRole("morecast2_write_forecast") monkeypatch.setattr(decode_fn, mock_admin_role_function) - monkeypatch.setattr(app.routers.morecast_v2, 'get_user_forecasts_for_date', lambda *_: []) + monkeypatch.setattr(app.routers.morecast_v2, "get_user_forecasts_for_date", lambda *_: []) response = client.get(morecast_v2_get_url) assert response.status_code == 200 def test_post_forecast_unauthorized(client: TestClient): - """ forecast role required for persisting a forecast """ + """forecast role required for persisting a forecast""" response = client.post(morecast_v2_post_url, json=[]) assert response.status_code == 401 @pytest.mark.anyio -def test_post_forecast_authorized(client: TestClient, - monkeypatch: pytest.MonkeyPatch): - """ Allowed to post station changes with correct role""" +def test_post_forecast_authorized(client: TestClient, monkeypatch: pytest.MonkeyPatch): + """Allowed to post station changes with correct role""" def mock_admin_role_function(*_, **__): - return MockJWTDecodeWithRole('morecast2_write_forecast') + return MockJWTDecodeWithRole("morecast2_write_forecast") monkeypatch.setattr(decode_fn, mock_admin_role_function) - async def mock_format_as_wf1_post_forecasts(client_session, forecasts_to_save): + async def mock_format_as_wf1_post_forecasts(client_session, forecasts_to_save, username, headers): return [] - monkeypatch.setattr(app.routers.morecast_v2, 'format_as_wf1_post_forecasts', mock_format_as_wf1_post_forecasts) + monkeypatch.setattr(app.routers.morecast_v2, "format_as_wf1_post_forecasts", mock_format_as_wf1_post_forecasts) - async def mock_post_forecasts(client_session, token, forecasts): + async def mock_post_forecasts(client_session, forecasts): return None - monkeypatch.setattr(app.routers.morecast_v2, 'post_forecasts', mock_post_forecasts) + monkeypatch.setattr(app.routers.morecast_v2, "post_forecasts", mock_post_forecasts) - response = client.post(morecast_v2_post_url, json=forecast.dict()) + async def mock_get_auth_header(_): + return dict() + + monkeypatch.setattr(app.routers.morecast_v2, "get_auth_header", mock_get_auth_header) + + response = client.post(morecast_v2_post_url, json=forecast.model_dump()) assert response.status_code == 201 def test_post_forecasts_by_date_range_unauthorized(client: TestClient): - """ forecast role required for persisting a forecast """ + """forecast role required for persisting a forecast""" response = client.post(morecast_v2_post_by_date_range_url, json=[]) assert response.status_code == 401 -def test_post_forecast_by_date_range_authorized(client: TestClient, - monkeypatch: pytest.MonkeyPatch): - """ Allowed to post station changes with correct role""" +def test_post_forecast_by_date_range_authorized(client: TestClient, monkeypatch: pytest.MonkeyPatch): + """Allowed to post station changes with correct role""" def mock_admin_role_function(*_, **__): - return MockJWTDecodeWithRole('morecast2_write_forecast') + return MockJWTDecodeWithRole("morecast2_write_forecast") monkeypatch.setattr(decode_fn, mock_admin_role_function) @@ -112,31 +113,32 @@ def mock_admin_role_function(*_, **__): def test_get_yesterday_dailies_unauthorized(client: TestClient): - """ user must be authenticated to retrieve yesterday dailies """ + """user must be authenticated to retrieve yesterday dailies""" response = client.post(morecast_v2_post_yesterday_dailies_url, json={"station_codes": [209, 211, 302]}) assert response.status_code == 401 def test_get_yesterday_dailies_authorized(client: TestClient, monkeypatch: pytest.MonkeyPatch): - """ user must be authenticated to retrieve yesterday dailies """ + """user must be authenticated to retrieve yesterday dailies""" + def mock_admin_role_function(*_, **__): - return MockJWTDecodeWithRole('morecast2_write_forecast') + return MockJWTDecodeWithRole("morecast2_write_forecast") monkeypatch.setattr(decode_fn, mock_admin_role_function) - monkeypatch.setattr(ClientSession, 'get', default_mock_client_get) + monkeypatch.setattr(ClientSession, "get", default_mock_client_get) requested_station_codes = [209, 211, 302] response = client.post(morecast_v2_post_yesterday_dailies_url, json={"station_codes": requested_station_codes}) assert response.status_code == 200 - parsed_dailies = [StationDailyFromWF1.model_validate(raw_daily) for raw_daily in response.json().get('dailies')] + parsed_dailies = [StationDailyFromWF1.model_validate(raw_daily) for raw_daily in response.json().get("dailies")] assert len(parsed_dailies) == 3 - today_date = datetime.strptime(today, '%Y-%m-%d').date() + today_date = datetime.strptime(today, "%Y-%m-%d").date() for requested_station_code, response in zip(requested_station_codes, parsed_dailies): assert requested_station_code == response.station_code - assert response.utcTimestamp.tzname() == 'UTC' + assert response.utcTimestamp.tzname() == "UTC" assert response.utcTimestamp.year == today_date.year assert response.utcTimestamp.month == today_date.month assert response.utcTimestamp.day == today_date.day - 1 @@ -151,10 +153,10 @@ def test_get_determinates_unauthorized(client: TestClient): @pytest.mark.anyio async def test_get_determinates_authorized(anyio_backend, async_client: AsyncClient, monkeypatch: pytest.MonkeyPatch): def mock_admin_role_function(*_, **__): - return MockJWTDecodeWithRole('morecast2_write_forecast') + return MockJWTDecodeWithRole("morecast2_write_forecast") monkeypatch.setattr(decode_fn, mock_admin_role_function) - monkeypatch.setattr(ClientSession, 'get', default_mock_client_get) + monkeypatch.setattr(ClientSession, "get", default_mock_client_get) response = await async_client.post(morecast_v2_post_determinates_url, json={"stations": [209, 211, 302]}) assert response.status_code == 200