Skip to content

Commit

Permalink
Fix test
Browse files Browse the repository at this point in the history
  • Loading branch information
conbrad committed Aug 7, 2024
1 parent f69c923 commit e370fba
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 44 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"HAINES",
"hourlies",
"HRDPS",
"idir",
"Indeterminates",
"luxon",
"maxx",
Expand Down
5 changes: 2 additions & 3 deletions api/app/morecast_v2/forecasts.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 6 additions & 5 deletions api/app/routers/morecast_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
74 changes: 38 additions & 36 deletions api/app/tests/morecast_v2/test_morecast_v2_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])

Expand All @@ -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)

Expand All @@ -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
Expand All @@ -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

0 comments on commit e370fba

Please sign in to comment.