Sfoglia il codice sorgente

test(web): routes/Camera

Paul Armstrong 4 anni fa
parent
commit
52a29ed00a
2 ha cambiato i file con 84 aggiunte e 24 eliminazioni
  1. 24 24
      web/src/routes/CameraMap.jsx
  2. 60 0
      web/src/routes/__tests__/Camera.test.jsx

+ 24 - 24
web/src/routes/CameraMap.jsx

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

+ 60 - 0
web/src/routes/__tests__/Camera.test.jsx

@@ -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');
+  });
+});