From f69c9238455c8b46d6f178f96809e403795006ef Mon Sep 17 00:00:00 2001 From: Conor Brady Date: Wed, 7 Aug 2024 11:59:47 -0700 Subject: [PATCH] more cleanup --- .vscode/settings.json | 2 + api/app/schemas/morecast_v2.py | 91 +++++++++++-------- web/src/api/moreCast2API.test.ts | 2 +- web/src/api/moreCast2API.ts | 3 - web/src/app/rootReducer.ts | 3 - .../slices/wf1AuthenticationSlice.test.ts | 49 ---------- .../auth/slices/wf1AuthenticationSlice.ts | 49 ---------- .../moreCast2/components/TabbedDataGrid.tsx | 7 +- 8 files changed, 59 insertions(+), 147 deletions(-) delete mode 100644 web/src/features/auth/slices/wf1AuthenticationSlice.test.ts delete mode 100644 web/src/features/auth/slices/wf1AuthenticationSlice.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index d382f4814..547226c76 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -78,6 +78,7 @@ "HAINES", "hourlies", "HRDPS", + "Indeterminates", "luxon", "maxx", "maxy", @@ -94,6 +95,7 @@ "PRECIP", "PRIMEM", "PROJCS", + "pydantic", "RDPS", "rocketchat", "sfms", diff --git a/api/app/schemas/morecast_v2.py b/api/app/schemas/morecast_v2.py index 7c7d89913..9e72ceff1 100644 --- a/api/app/schemas/morecast_v2.py +++ b/api/app/schemas/morecast_v2.py @@ -1,4 +1,4 @@ -""" This module contains pydantic models for Morecast v2""" +"""This module contains pydantic models for Morecast v2""" from enum import Enum from typing import List, Optional @@ -7,66 +7,74 @@ class ModelChoice(str, Enum): - """ Enumerator for all valid forecasted value types """ - GDPS = 'GDPS' - GFS = 'GFS' - HRDPS = 'HRDPS' - NAM = 'NAM' - MANUAL = 'MANUAL' - RDPS = 'RDPS' + """Enumerator for all valid forecasted value types""" + + GDPS = "GDPS" + GFS = "GFS" + HRDPS = "HRDPS" + NAM = "NAM" + MANUAL = "MANUAL" + RDPS = "RDPS" class WeatherDeterminate(str, Enum): - """ Enumerator for all valid determinate weather sources""" - GDPS = 'GDPS' - GDPS_BIAS = 'GDPS_BIAS' - GFS = 'GFS' - GFS_BIAS = 'GFS_BIAS' - HRDPS = 'HRDPS' - HRDPS_BIAS = 'HRDPS_BIAS' - NAM = 'NAM' - NAM_BIAS = 'NAM_BIAS' - RDPS = 'RDPS' - RDPS_BIAS = 'RDPS_BIAS' - GRASS_CURING_CWFIS = 'Grass_Curing_CWFIS' + """Enumerator for all valid determinate weather sources""" + + GDPS = "GDPS" + GDPS_BIAS = "GDPS_BIAS" + GFS = "GFS" + GFS_BIAS = "GFS_BIAS" + HRDPS = "HRDPS" + HRDPS_BIAS = "HRDPS_BIAS" + NAM = "NAM" + NAM_BIAS = "NAM_BIAS" + RDPS = "RDPS" + RDPS_BIAS = "RDPS_BIAS" + GRASS_CURING_CWFIS = "Grass_Curing_CWFIS" # non prediction models - FORECAST = 'Forecast' - ACTUAL = 'Actual' + FORECAST = "Forecast" + ACTUAL = "Actual" class ForecastedTemperature(BaseModel): - """ Forecaster chosen temperature """ + """Forecaster chosen temperature""" + temp: float choice: ModelChoice class ForecastedRH(BaseModel): - """ Forecaster chosen rh """ + """Forecaster chosen rh""" + rh: float choice: ModelChoice class ForecastedPrecip(BaseModel): - """ Forecaster chosen 24-hour precipitation mm """ + """Forecaster chosen 24-hour precipitation mm""" + precip: float choice: ModelChoice class ForecastedWindSpeed(BaseModel): - """ Forecaster chosen wind speed """ + """Forecaster chosen wind speed""" + wind_speed: float choice: ModelChoice class ForecastedWindDirection(BaseModel): - """ Forecaster chosen wind direction """ + """Forecaster chosen wind direction""" + wind_direction: float choice: ModelChoice class MoreCastForecastInput(BaseModel): - """ Forecasted daily request """ + """Forecasted daily request""" + station_code: int for_date: int temp: float @@ -78,28 +86,32 @@ class MoreCastForecastInput(BaseModel): class MoreCastForecastRequest(BaseModel): - """ Incoming daily forecasts to be saved """ - token: str # WF1 token + """Incoming daily forecasts to be saved""" + forecasts: List[MoreCastForecastInput] class MoreCastForecastOutput(MoreCastForecastInput): - """ Outgoing forecast daily response item """ + """Outgoing forecast daily response item""" + update_timestamp: int class MorecastForecastResponse(BaseModel): - """ Outgoing forecast daily response """ + """Outgoing forecast daily response""" + forecasts: List[MoreCastForecastOutput] class ObservedDailiesForStations(BaseModel): - """ Request for observed dailies for stations """ + """Request for observed dailies for stations""" + station_codes: List[int] class StationDailyFromWF1(BaseModel): - """ Daily weather data (forecast or observed) for a specific station and date retrieved from WF1 API """ + """Daily weather data (forecast or observed) for a specific station and date retrieved from WF1 API""" + created_by: str forecast_id: str station_code: int @@ -113,12 +125,14 @@ class StationDailyFromWF1(BaseModel): class StationDailiesResponse(BaseModel): - """ List of StationDailyFromWF1 records as response """ + """List of StationDailyFromWF1 records as response""" + dailies: List[StationDailyFromWF1] class WeatherIndeterminate(BaseModel): - """ Used to represent a predicted or actual value """ + """Used to represent a predicted or actual value""" + station_code: int station_name: str determinate: WeatherDeterminate @@ -153,8 +167,9 @@ class WF1ForecastRecordType(BaseModel): class WF1PostForecast(BaseModel): - """ Used to represent a forecast to be POSTed to WF1 """ - archive: str = 'false' + """Used to represent a forecast to be POSTed to WF1""" + + archive: str = "false" createdBy: Optional[str] = None id: Optional[str] = None station: str # station URL diff --git a/web/src/api/moreCast2API.test.ts b/web/src/api/moreCast2API.test.ts index 50b152725..5576aa3e9 100644 --- a/web/src/api/moreCast2API.test.ts +++ b/web/src/api/moreCast2API.test.ts @@ -52,7 +52,7 @@ describe('moreCast2API', () => { }) it('should call submit endpoint for forecast submission', async () => { axios.post = jest.fn().mockResolvedValue({ status: 201 }) - const res = await submitMoreCastForecastRecords('testToken', [ + const res = await submitMoreCastForecastRecords([ buildMorecast2Forecast('1', 1, 'one', DateTime.fromObject({ year: 2021, month: 1, day: 1 })), buildMorecast2Forecast('2', 2, 'two', DateTime.fromObject({ year: 2021, month: 1, day: 1 })) ]) diff --git a/web/src/api/moreCast2API.ts b/web/src/api/moreCast2API.ts index 8a69680a1..c402ccaac 100644 --- a/web/src/api/moreCast2API.ts +++ b/web/src/api/moreCast2API.ts @@ -176,7 +176,6 @@ export interface MoreCast2ForecastRecord { } export interface MoreCastForecastRequest { - wf1Token: string forecasts: MoreCast2ForecastRecord[] } @@ -203,14 +202,12 @@ export const marshalMoreCast2ForecastRecords = (forecasts: MoreCast2ForecastRow[ * @returns True if the response is a 201, otherwise false. */ export async function submitMoreCastForecastRecords( - token: string, forecasts: MoreCast2ForecastRow[] ): Promise<{ success: boolean; errorMessage?: string }> { const forecastRecords = marshalMoreCast2ForecastRecords(forecasts) const url = `/morecast-v2/forecast` try { const { status } = await axios.post(url, { - token, forecasts: forecastRecords }) return { success: status === 201 } diff --git a/web/src/app/rootReducer.ts b/web/src/app/rootReducer.ts index 8b836d33b..52f49e00f 100644 --- a/web/src/app/rootReducer.ts +++ b/web/src/app/rootReducer.ts @@ -5,7 +5,6 @@ import percentilesReducer from 'features/percentileCalculator/slices/percentiles import cHainesModelRunReducer from 'features/cHaines/slices/cHainesModelRunsSlice' import cHainesPredictionReducer from 'features/cHaines/slices/cHainesPredictionsSlice' import authReducer from 'features/auth/slices/authenticationSlice' -import wf1AuthReducer from 'features/auth/slices/wf1AuthenticationSlice' import hfiCalculatorDailiesReducer, { HFICalculatorState } from 'features/hfiCalculator/slices/hfiCalculatorSlice' import hfiStationsReducer from 'features/hfiCalculator/slices/stationsSlice' import hfiReadyReducer, { HFIReadyState } from 'features/hfiCalculator/slices/hfiReadySlice' @@ -29,7 +28,6 @@ const rootReducer = combineReducers({ cHainesModelRuns: cHainesModelRunReducer, cHainesPredictions: cHainesPredictionReducer, authentication: authReducer, - wf1Authentication: wf1AuthReducer, hfiCalculatorDailies: hfiCalculatorDailiesReducer, hfiStations: hfiStationsReducer, hfiReady: hfiReadyReducer, @@ -60,7 +58,6 @@ export const selectPercentiles = (state: RootState) => state.percentiles export const selectCHainesModelRuns = (state: RootState) => state.cHainesModelRuns export const selectChainesPredictions = (state: RootState) => state.cHainesPredictions export const selectAuthentication = (state: RootState) => state.authentication -export const selectWf1Authentication = (state: RootState) => state.wf1Authentication export const selectToken = (state: RootState) => state.authentication.token export const selectFireBehaviourCalcResult = (state: RootState) => state.fbaCalculatorResults export const selectHFIStations = (state: RootState) => state.hfiStations diff --git a/web/src/features/auth/slices/wf1AuthenticationSlice.test.ts b/web/src/features/auth/slices/wf1AuthenticationSlice.test.ts deleted file mode 100644 index d6e9da5c5..000000000 --- a/web/src/features/auth/slices/wf1AuthenticationSlice.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import wf1AuthReducer, { - initialState, - authenticated, - unAuthenticated, - authenticateError -} from 'features/auth/slices/wf1AuthenticationSlice' - -describe('wf1AuthenticationSlice', () => { - const testToken = 'testToken' - - describe('reducer', () => { - it('should be initialized with correct state', () => { - expect( - wf1AuthReducer(undefined, { - type: undefined - }) - ).toEqual(initialState) - }) - it('should set authenticate start when authenticateStart is called', () => { - expect(wf1AuthReducer(initialState, authenticated(testToken))).toEqual({ - ...initialState, - wf1Token: testToken - }) - }) - it('should unset token when unAuthenticated is dispatched ', () => { - const signedInState = { - ...initialState, - wf1Token: testToken - } - - expect(wf1AuthReducer(signedInState, unAuthenticated())).toEqual({ - ...initialState, - wf1Token: undefined - }) - }) - it('should unset token and set error when authenticateError is dispatched ', () => { - const signedInState = { - ...initialState, - wf1Token: testToken - } - - expect(wf1AuthReducer(signedInState, authenticateError('error'))).toEqual({ - ...initialState, - wf1Token: undefined, - error: 'error' - }) - }) - }) -}) diff --git a/web/src/features/auth/slices/wf1AuthenticationSlice.ts b/web/src/features/auth/slices/wf1AuthenticationSlice.ts deleted file mode 100644 index f07bdcc8a..000000000 --- a/web/src/features/auth/slices/wf1AuthenticationSlice.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { createSlice, PayloadAction } from '@reduxjs/toolkit' -import { AppThunk } from 'app/store' - -interface State { - wf1Token: string | undefined - error: string | null -} - -export const initialState: State = { - wf1Token: undefined, - error: null -} - -const wf1AuthSlice = createSlice({ - name: 'wf1Authentication', - initialState, - reducers: { - authenticated(state: State, action: PayloadAction) { - state.wf1Token = action.payload - }, - unAuthenticated(state: State) { - state.wf1Token = undefined - }, - authenticateError(state: State, action: PayloadAction) { - state.wf1Token = undefined - state.error = action.payload - } - } -}) - -export const { authenticated, unAuthenticated, authenticateError } = wf1AuthSlice.actions - -export default wf1AuthSlice.reducer - -export const wf1Authenticate = - (wf1Token: string): AppThunk => - dispatch => { - dispatch(authenticated(wf1Token)) - } - -export const wf1Signout = (): AppThunk => async dispatch => { - dispatch(unAuthenticated()) -} - -export const wf1AuthenticateError = - (error: string): AppThunk => - dispatch => { - dispatch(authenticateError(error)) - } diff --git a/web/src/features/moreCast2/components/TabbedDataGrid.tsx b/web/src/features/moreCast2/components/TabbedDataGrid.tsx index 4f6319501..d7f30242b 100644 --- a/web/src/features/moreCast2/components/TabbedDataGrid.tsx +++ b/web/src/features/moreCast2/components/TabbedDataGrid.tsx @@ -26,7 +26,7 @@ import { selectSelectedStations } from 'features/moreCast2/slices/selectedStatio import { cloneDeep, groupBy, isEqual, isNull, isUndefined } from 'lodash' import SaveForecastButton from 'features/moreCast2/components/SaveForecastButton' import { ROLES } from 'features/auth/roles' -import { selectAuthentication, selectWf1Authentication } from 'app/rootReducer' +import { selectAuthentication } from 'app/rootReducer' import { DateRange } from 'components/dateRangePicker/types' import MoreCast2Snackbar from 'features/moreCast2/components/MoreCast2Snackbar' import { isForecastRowPredicate, getRowsToSave, isForecastValid } from 'features/moreCast2/saveForecasts' @@ -74,7 +74,6 @@ const TabbedDataGrid = ({ fromTo, setFromTo, fetchWeatherIndeterminates }: Tabbe const selectedStations = useSelector(selectSelectedStations) const loading = useSelector(selectWeatherIndeterminatesLoading) const { roles, isAuthenticated } = useSelector(selectAuthentication) - const { wf1Token } = useSelector(selectWf1Authentication) // All MoreCast2Rows derived from WeatherIndeterminates in dataSlice.ts. Updates in response to // a change of station group or date range. @@ -449,9 +448,9 @@ const TabbedDataGrid = ({ fromTo, setFromTo, fetchWeatherIndeterminates }: Tabbe } const handleSaveClick = async () => { - if (isForecastValid(visibleRows) && !isUndefined(wf1Token)) { + if (isForecastValid(visibleRows)) { const rowsToSave: MoreCast2ForecastRow[] = getRowsToSave(visibleRows) - const result = await submitMoreCastForecastRecords(wf1Token, rowsToSave) + const result = await submitMoreCastForecastRecords(rowsToSave) if (result.success) { setSnackbarMessage(FORECAST_SAVED_MESSAGE) setSnackbarSeverity('success')