Skip to content

Commit d0df420

Browse files
Use only the vehicle types in the app config when fetching from the URL (#840)
1 parent ea97b32 commit d0df420

File tree

4 files changed

+72
-8
lines changed

4 files changed

+72
-8
lines changed

packages/common/src/apps/appStateProvider.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { CaptureAppConfig, Sight, SteeringWheelPosition, VehicleType } from '@monkvision/types';
22
import { sights } from '@monkvision/sights';
3-
import React, { PropsWithChildren, useCallback, useContext, useEffect, useState } from 'react';
3+
import React, {
4+
PropsWithChildren,
5+
useCallback,
6+
useContext,
7+
useEffect,
8+
useMemo,
9+
useState,
10+
} from 'react';
411
import { useLoadingState, useObjectMemo } from '../hooks';
512
import { MonkSearchParam, useMonkSearchParams } from './searchParams';
613
import { MonkAppState, MonkAppStateContext } from './appState';
@@ -57,6 +64,14 @@ function getSights(
5764
});
5865
}
5966

67+
function getAvailableVehicleTypes(config: CaptureAppConfig): VehicleType[] {
68+
return (
69+
config.enableSteeringWheelPosition
70+
? Object.keys(config.sights.left)
71+
: Object.keys(config.sights)
72+
) as VehicleType[];
73+
}
74+
6075
/**
6176
* A React context provider that declares the state for the common parameters used by Monk applications. The parameters
6277
* are described in the `MonkAppState` interface. Using options available in the App config (`config` prop), this
@@ -77,7 +92,8 @@ export function MonkAppStateProvider({
7792
const [inspectionId, setInspectionId] = useState<string | null>(null);
7893
const [vehicleType, setVehicleType] = useState<VehicleType | null>(null);
7994
const [steeringWheel, setSteeringWheel] = useState<SteeringWheelPosition | null>(null);
80-
const monkSearchParams = useMonkSearchParams();
95+
const availableVehicleTypes = useMemo(() => getAvailableVehicleTypes(config), [config]);
96+
const monkSearchParams = useMonkSearchParams({ availableVehicleTypes });
8197
useAppStateMonitoring({ authToken, inspectionId, vehicleType, steeringWheel });
8298
useAppStateAnalytics({ inspectionId });
8399

packages/common/src/apps/searchParams.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,26 @@ function validateParamValue<T extends string>(
7272
return validValuesArray.includes(value) ? (value as T) : null;
7373
}
7474

75+
/**
76+
* Options accepted by the useMonkSearchParams hook.
77+
*/
78+
export interface UseMonkSearchParamsOptions {
79+
/**
80+
* The list of available vehicle types to allow.
81+
*
82+
* @default Object.values(VehicleType)
83+
*/
84+
availableVehicleTypes?: VehicleType[];
85+
}
86+
7587
/**
7688
* Custom hook used to return a getter function used to fetch the value of different MonkSearchParams.
7789
*
7890
* @see MonkSearchParam
7991
*/
80-
export function useMonkSearchParams(): { get: MonkSearchParamsGetter } {
92+
export function useMonkSearchParams({ availableVehicleTypes }: UseMonkSearchParamsOptions = {}): {
93+
get: MonkSearchParamsGetter;
94+
} {
8195
const searchParams = useSearchParams();
8296

8397
const get = useCallback(
@@ -89,7 +103,7 @@ export function useMonkSearchParams(): { get: MonkSearchParamsGetter } {
89103
case MonkSearchParam.INSPECTION_ID:
90104
return value;
91105
case MonkSearchParam.VEHICLE_TYPE:
92-
return validateParamValue(value, VehicleType);
106+
return validateParamValue(value, availableVehicleTypes ?? VehicleType);
93107
case MonkSearchParam.STEERING_WHEEL:
94108
return validateParamValue(value, SteeringWheelPosition);
95109
case MonkSearchParam.LANGUAGE:

packages/common/test/apps/appStateProvider.test.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
MonkSearchParam,
2020
STORAGE_KEY_AUTH_TOKEN,
2121
useMonkAppState,
22+
useMonkSearchParams,
2223
} from '../../src';
2324

2425
let params: MonkAppState | null = null;
@@ -210,6 +211,23 @@ describe('MonkAppStateProvider', () => {
210211
unmount();
211212
});
212213

214+
it('should pass the available sights from the config to the useMonkSearchParams hook', () => {
215+
const props = createProps();
216+
const { unmount } = render(
217+
<MonkAppStateProvider {...props}>
218+
<TestComponent />
219+
</MonkAppStateProvider>,
220+
);
221+
222+
expect(useMonkSearchParams).toHaveBeenCalledWith(
223+
expect.objectContaining({
224+
availableVehicleTypes: expect.arrayContaining(Object.keys(props.config.sights)),
225+
}),
226+
);
227+
228+
unmount();
229+
});
230+
213231
describe('getCurrentSights function', () => {
214232
it('should return the proper sights when steering wheel is not enabled', () => {
215233
const props = createProps();
@@ -236,6 +254,10 @@ describe('MonkAppStateProvider', () => {
236254
props.config.fetchFromSearchParams = true;
237255
props.config.enableSteeringWheelPosition = true;
238256
(props.config as any).sights = {
257+
[SteeringWheelPosition.LEFT]: {
258+
[VehicleType.HATCHBACK]: ['test-sight-3', 'test-sight-4'],
259+
[VehicleType.CUV]: ['test-sight-1', 'test-sight-2'],
260+
},
239261
[SteeringWheelPosition.RIGHT]: {
240262
[VehicleType.HATCHBACK]: ['test-sight-1', 'test-sight-2'],
241263
[VehicleType.CUV]: ['test-sight-3', 'test-sight-4'],

packages/common/test/apps/searchParams.test.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { SteeringWheelPosition, VehicleType } from '@monkvision/types';
2+
import { renderHook } from '@testing-library/react-hooks';
3+
import { MonkSearchParam, useMonkSearchParams, useSearchParams, zlibDecompress } from '../../src';
24

35
const zlibDecompressResult = 'zlibDecompress-result-test';
46

@@ -10,9 +12,6 @@ jest.mock('../../src/utils', () => ({
1012
zlibDecompress: jest.fn(() => zlibDecompressResult),
1113
}));
1214

13-
import { renderHook } from '@testing-library/react-hooks';
14-
import { MonkSearchParam, useMonkSearchParams, zlibDecompress, useSearchParams } from '../../src';
15-
1615
function mockSearchParams(searchParams: Partial<Record<MonkSearchParam, string>>) {
1716
const get = jest.fn((param) => searchParams[param as MonkSearchParam]);
1817
(useSearchParams as jest.Mock).mockImplementationOnce(() => ({ get }));
@@ -87,10 +86,23 @@ describe('MonkSearchParams utils', () => {
8786
unmount();
8887
});
8988

89+
it('should return a null vehicle type if the value found in the search params is not in the available vehicle types', () => {
90+
mockSearchParams({ [MonkSearchParam.VEHICLE_TYPE]: VehicleType.VAN });
91+
const { result, unmount } = renderHook(useMonkSearchParams, {
92+
initialProps: { availableVehicleTypes: [VehicleType.HATCHBACK, VehicleType.CITY] },
93+
});
94+
95+
expect(result.current.get(MonkSearchParam.VEHICLE_TYPE)).toBeNull();
96+
97+
unmount();
98+
});
99+
90100
it('should return the vehicle type if it is found in the search params', () => {
91101
const vehicleType = VehicleType.HATCHBACK;
92102
mockSearchParams({ [MonkSearchParam.VEHICLE_TYPE]: vehicleType });
93-
const { result, unmount } = renderHook(useMonkSearchParams);
103+
const { result, unmount } = renderHook(useMonkSearchParams, {
104+
initialProps: { availableVehicleTypes: [vehicleType] },
105+
});
94106

95107
expect(result.current.get(MonkSearchParam.VEHICLE_TYPE)).toEqual(vehicleType);
96108

0 commit comments

Comments
 (0)