From c0a00acdc609fb9e84a18e334aece116c54cf64e Mon Sep 17 00:00:00 2001 From: jaredvu Date: Sun, 15 Oct 2023 22:11:41 -0700 Subject: [PATCH] Add validationFn and update tests --- src/constants/networks.ts | 2 +- src/hooks/useInitializePage.ts | 2 + src/hooks/useSelectedNetwork.ts | 3 ++ .../{addressUtils.ts => addressUtils.spec.ts} | 0 src/lib/__test__/network.spec.ts | 38 +++++++++++++++++++ .../{timeUtils.ts => timeUtils.spec.ts} | 14 ++++--- src/lib/network.ts | 4 ++ src/lib/timeUtils.ts | 4 +- src/state/app.ts | 2 + 9 files changed, 61 insertions(+), 8 deletions(-) rename src/lib/__test__/{addressUtils.ts => addressUtils.spec.ts} (100%) create mode 100644 src/lib/__test__/network.spec.ts rename src/lib/__test__/{timeUtils.ts => timeUtils.spec.ts} (86%) create mode 100644 src/lib/network.ts diff --git a/src/constants/networks.ts b/src/constants/networks.ts index b2c8b47..fe289c4 100644 --- a/src/constants/networks.ts +++ b/src/constants/networks.ts @@ -8,5 +8,5 @@ export const AVAILABLE_ENVIRONMENTS = export const CURRENT_ABACUS_DEPLOYMENT = import.meta.env.MODE === 'production' ? 'TESTNET' : 'DEV'; export const ENVIRONMENT_CONFIG_MAP = environments.environments; -export type DydxNetwork = keyof typeof ENVIRONMENT_CONFIG_MAP; +export type DydxNetwork = (typeof AVAILABLE_ENVIRONMENTS.environments)[number]; export const DEFAULT_APP_ENVIRONMENT = AVAILABLE_ENVIRONMENTS.default as DydxNetwork; diff --git a/src/hooks/useInitializePage.ts b/src/hooks/useInitializePage.ts index 05568d8..9a61b97 100644 --- a/src/hooks/useInitializePage.ts +++ b/src/hooks/useInitializePage.ts @@ -10,6 +10,7 @@ import { useLocalStorage } from '@/hooks'; import { initializeLocalization } from '@/state/app'; import abacusStateManager from '@/lib/abacus'; +import { validateAgainstAvailableEnvironments } from '@/lib/network'; export const useInitializePage = () => { const dispatch = useDispatch(); @@ -18,6 +19,7 @@ export const useInitializePage = () => { const [localStorageNetwork] = useLocalStorage({ key: LocalStorageKey.SelectedNetwork, defaultValue: DEFAULT_APP_ENVIRONMENT, + validateFn: validateAgainstAvailableEnvironments, }); useEffect(() => { diff --git a/src/hooks/useSelectedNetwork.ts b/src/hooks/useSelectedNetwork.ts index ca4cbb0..b7086b7 100644 --- a/src/hooks/useSelectedNetwork.ts +++ b/src/hooks/useSelectedNetwork.ts @@ -9,6 +9,8 @@ import { useAccounts, useLocalStorage } from '@/hooks'; import { setSelectedNetwork } from '@/state/app'; import { getSelectedNetwork } from '@/state/appSelectors'; +import { validateAgainstAvailableEnvironments } from '@/lib/network'; + export const useSelectedNetwork = (): { switchNetwork: (network: DydxNetwork) => void; selectedNetwork: DydxNetwork; @@ -20,6 +22,7 @@ export const useSelectedNetwork = (): { const [, setLocalStorageNetwork] = useLocalStorage({ key: LocalStorageKey.SelectedNetwork, defaultValue: DEFAULT_APP_ENVIRONMENT, + validateFn: validateAgainstAvailableEnvironments, }); const switchNetwork = useCallback( diff --git a/src/lib/__test__/addressUtils.ts b/src/lib/__test__/addressUtils.spec.ts similarity index 100% rename from src/lib/__test__/addressUtils.ts rename to src/lib/__test__/addressUtils.spec.ts diff --git a/src/lib/__test__/network.spec.ts b/src/lib/__test__/network.spec.ts new file mode 100644 index 0000000..1ec2c43 --- /dev/null +++ b/src/lib/__test__/network.spec.ts @@ -0,0 +1,38 @@ +import environments from '../../../public/configs/env.json'; + +import { validateAgainstAvailableEnvironments } from '../network'; + +describe('validateAgainstAvailableEnvironments', () => { + describe('production environment', () => { + beforeAll(() => { + jest.mock('../../constants/networks', () => ({ + AVAILABLE_ENVIRONMENTS: { + environments: [], + default: 'dydxprotocol-testnet-dydx', + }, //environments.deployments.TESTNET, + })); + }); + + afterAll(() => { + jest.unmock('../../constants/networks'); + }); + + it('Returns true for valid environments', () => { + expect(validateAgainstAvailableEnvironments('dydxprotocol-testnet-dydx')).toEqual(true); + }); + + it('Returns false for invalid environments', () => { + expect(validateAgainstAvailableEnvironments('dydxprotocol-dev')).toEqual(false); + }); + }); + + describe('staging environment', () => { + it('Returns true for valid environments', () => { + expect(validateAgainstAvailableEnvironments('dydxprotocol-dev')).toEqual(true); + }); + + it('Returns false for invalid environments', () => { + expect(validateAgainstAvailableEnvironments('INVALID')).toEqual(false); + }); + }); +}); diff --git a/src/lib/__test__/timeUtils.ts b/src/lib/__test__/timeUtils.spec.ts similarity index 86% rename from src/lib/__test__/timeUtils.ts rename to src/lib/__test__/timeUtils.spec.ts index 7e61de7..18971bc 100644 --- a/src/lib/__test__/timeUtils.ts +++ b/src/lib/__test__/timeUtils.spec.ts @@ -45,11 +45,15 @@ describe('getStringsForDateTimeDiff', () => { describe('getStringsForTimeInterval', () => { it.each([ - [Duration.fromObject({ months: 2 }), '2', 'MONTHS_ABBREVIATED'], - [Duration.fromObject({ weeks: 3, days: 2 }), '3', 'WEEKS_ABBREVIATED'], - [Duration.fromObject({ days: 5, hours: 12 }), '6', 'DAYS_ABBREVIATED'], - [Duration.fromObject({ hours: 8, minutes: 30 }), '9', 'HOURS_ABBREVIATED'], - [Duration.fromObject({ minutes: 45 }), '45', 'MINUTES_ABBREVIATED'], + [Duration.fromObject({ months: 2 }), '2', 'APP.GENERAL.TIME_STRINGS.MONTHS_ABBREVIATED'], + [Duration.fromObject({ weeks: 3, days: 2 }), '3', 'APP.GENERAL.TIME_STRINGS.WEEKS_ABBREVIATED'], + [Duration.fromObject({ days: 5, hours: 12 }), '6', 'APP.GENERAL.TIME_STRINGS.DAYS_ABBREVIATED'], + [ + Duration.fromObject({ hours: 8, minutes: 30 }), + '9', + 'APP.GENERAL.TIME_STRINGS.HOURS_ABBREVIATED', + ], + [Duration.fromObject({ minutes: 45 }), '45', 'APP.GENERAL.TIME_STRINGS.MINUTES_ABBREVIATED'], ])( 'returns the correct timeString and unitStringKey', (timeInterval, expectedTimeString, expectedUnitStringKey) => { diff --git a/src/lib/network.ts b/src/lib/network.ts new file mode 100644 index 0000000..a5c8dca --- /dev/null +++ b/src/lib/network.ts @@ -0,0 +1,4 @@ +import { AVAILABLE_ENVIRONMENTS, type DydxNetwork } from '@/constants/networks'; + +export const validateAgainstAvailableEnvironments = (value: DydxNetwork) => + AVAILABLE_ENVIRONMENTS.environments.includes(value); diff --git a/src/lib/timeUtils.ts b/src/lib/timeUtils.ts index f676ed1..192a56d 100644 --- a/src/lib/timeUtils.ts +++ b/src/lib/timeUtils.ts @@ -10,7 +10,7 @@ export const getTimestamp = (value?: BigNumberish | null) => ? value : typeof value === 'string' ? new Date(value).getTime() - : new Date(value.toString()).getTime() + : new Date(value.toNumber()).getTime() : undefined; export const getStringsForDateTimeDiff = (dateTime: DateTime) => { @@ -77,4 +77,4 @@ export const formatSeconds = (seconds: number) => { const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; return `${getTimeString(minutes)}:${getTimeString(remainingSeconds)}`; -} +}; diff --git a/src/state/app.ts b/src/state/app.ts index 61e5d65..0ff9231 100644 --- a/src/state/app.ts +++ b/src/state/app.ts @@ -6,6 +6,7 @@ import { LocalStorageKey } from '@/constants/localStorage'; import { DEFAULT_APP_ENVIRONMENT, type DydxNetwork } from '@/constants/networks'; import { getLocalStorage } from '@/lib/localStorage'; +import { validateAgainstAvailableEnvironments } from '@/lib/network'; export interface AppState { apiState: AbacusApiState | undefined; @@ -19,6 +20,7 @@ const initialState: AppState = { selectedNetwork: getLocalStorage({ key: LocalStorageKey.SelectedNetwork, defaultValue: DEFAULT_APP_ENVIRONMENT, + validateFn: validateAgainstAvailableEnvironments, }), };