test(web): routes/Camera

This commit is contained in:
Paul Armstrong 2021-02-12 16:30:14 -08:00 committed by Blake Blackshear
parent 5eaf8a5448
commit 52a29ed00a
2 changed files with 84 additions and 24 deletions

View File

@ -29,8 +29,8 @@ export default function CameraMasks({ camera, url }) {
Array.isArray(motionMask) Array.isArray(motionMask)
? motionMask.map((mask) => getPolylinePoints(mask)) ? motionMask.map((mask) => getPolylinePoints(mask))
: motionMask : motionMask
? [getPolylinePoints(motionMask)] ? [getPolylinePoints(motionMask)]
: [] : []
); );
const [zonePoints, setZonePoints] = useState( const [zonePoints, setZonePoints] = useState(
@ -44,8 +44,8 @@ export default function CameraMasks({ camera, url }) {
[name]: Array.isArray(objectFilters[name].mask) [name]: Array.isArray(objectFilters[name].mask)
? objectFilters[name].mask.map((mask) => getPolylinePoints(mask)) ? objectFilters[name].mask.map((mask) => getPolylinePoints(mask))
: objectFilters[name].mask : objectFilters[name].mask
? [getPolylinePoints(objectFilters[name].mask)] ? [getPolylinePoints(objectFilters[name].mask)]
: [], : [],
}), }),
{} {}
) )
@ -128,11 +128,11 @@ ${motionMaskPoints.map((mask, i) => ` - ${polylinePointsToPolyline(mask)}`)
const handleCopyZones = useCallback(async () => { const handleCopyZones = useCallback(async () => {
await window.navigator.clipboard.writeText(` zones: await window.navigator.clipboard.writeText(` zones:
${Object.keys(zonePoints) ${Object.keys(zonePoints)
.map( .map(
(zoneName) => ` ${zoneName}: (zoneName) => ` ${zoneName}:
coordinates: ${polylinePointsToPolyline(zonePoints[zoneName])}` coordinates: ${polylinePointsToPolyline(zonePoints[zoneName])}`
) )
.join('\n')}`); .join('\n')}`);
}, [zonePoints]); }, [zonePoints]);
// Object methods // Object methods
@ -164,14 +164,14 @@ ${Object.keys(zonePoints)
await window.navigator.clipboard.writeText(` objects: await window.navigator.clipboard.writeText(` objects:
filters: filters:
${Object.keys(objectMaskPoints) ${Object.keys(objectMaskPoints)
.map((objectName) => .map((objectName) =>
objectMaskPoints[objectName].length objectMaskPoints[objectName].length
? ` ${objectName}: ? ` ${objectName}:
mask: ${polylinePointsToPolyline(objectMaskPoints[objectName])}` mask: ${polylinePointsToPolyline(objectMaskPoints[objectName])}`
: '' : ''
) )
.filter(Boolean) .filter(Boolean)
.join('\n')}`); .join('\n')}`);
}, [objectMaskPoints]); }, [objectMaskPoints]);
const handleAddToObjectMask = useCallback( const handleAddToObjectMask = useCallback(
@ -360,15 +360,15 @@ function EditableMask({ onChange, points, scale, snap, width, height }) {
{!scaledPoints {!scaledPoints
? null ? null
: scaledPoints.map(([x, y], i) => ( : scaledPoints.map(([x, y], i) => (
<PolyPoint <PolyPoint
boundingRef={boundingRef} boundingRef={boundingRef}
index={i} index={i}
onMove={handleMovePoint} onMove={handleMovePoint}
onRemove={handleRemovePoint} onRemove={handleRemovePoint}
x={x + MaskInset} x={x + MaskInset}
y={y + MaskInset} y={y + MaskInset}
/> />
))} ))}
<div className="absolute inset-0 right-0 bottom-0" onClick={handleAddPoint} ref={boundingRef} /> <div className="absolute inset-0 right-0 bottom-0" onClick={handleAddPoint} ref={boundingRef} />
<svg <svg
width="100%" width="100%"

View File

@ -0,0 +1,60 @@
import { h } from 'preact';
import * as AutoUpdatingCameraImage from '../../components/AutoUpdatingCameraImage';
import * as Api from '../../api';
import * as Context from '../../context';
import Camera from '../Camera';
import { fireEvent, render, screen } from '@testing-library/preact';
jest.mock('../../api/baseUrl');
describe('Camera Route', () => {
let mockUsePersistence, mockSetOptions;
beforeEach(() => {
mockSetOptions = jest.fn();
mockUsePersistence = jest.spyOn(Context, 'usePersistence').mockImplementation(() => [{}, mockSetOptions]);
jest.spyOn(Api, 'useConfig').mockImplementation(() => ({
data: { cameras: { front: { name: 'front', objects: { track: ['taco', 'cat', 'dog'] } } } },
}));
jest.spyOn(Api, 'useApiHost').mockImplementation(() => 'http://base-url.local:5000');
jest.spyOn(AutoUpdatingCameraImage, 'default').mockImplementation(({ searchParams }) => {
return <div data-testid="mock-image">{searchParams.toString()}</div>;
});
});
test('reads camera feed options from persistence', async () => {
mockUsePersistence.mockReturnValue([
{
bbox: true,
timestamp: false,
zones: true,
mask: false,
motion: true,
regions: false,
},
mockSetOptions,
]);
render(<Camera camera="front" />);
fireEvent.click(screen.queryByText('Show Options'));
expect(screen.queryByTestId('mock-image')).toHaveTextContent(
'bbox=1&timestamp=0&zones=1&mask=0&motion=1&regions=0'
);
});
test('updates camera feed options to persistence', async () => {
mockUsePersistence
.mockReturnValueOnce([{}, mockSetOptions])
.mockReturnValueOnce([{ bbox: true }, mockSetOptions])
.mockReturnValueOnce([{ bbox: true, timestamp: true }, mockSetOptions]);
render(<Camera camera="front" />);
fireEvent.click(screen.queryByText('Show Options'));
fireEvent.change(screen.queryByTestId('bbox-input'), { target: { checked: true } });
fireEvent.change(screen.queryByTestId('timestamp-input'), { target: { checked: true } });
fireEvent.click(screen.queryByText('Hide Options'));
expect(mockSetOptions).toHaveBeenCalledWith({ bbox: true, timestamp: true });
expect(screen.queryByTestId('mock-image')).toHaveTextContent('bbox=1&timestamp=1');
});
});