CEC-2654: Map polls for curren visible area (#222)
Update index.jsx Added some tests, still don't meet threshold Co-authored-by: Alexander Andrews <aandrews@fiskerinc.com>
This commit is contained in:
committed by
GitHub
parent
525c1ca6d5
commit
b45c70bd52
130
src/components/VehicleMap/__snapshots__/index.test.jsx.snap
Normal file
130
src/components/VehicleMap/__snapshots__/index.test.jsx.snap
Normal file
@@ -0,0 +1,130 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`VehicleMap Render 1`] = `
|
||||
<div>
|
||||
<div
|
||||
data-testid="mocked-vehicleprovider"
|
||||
>
|
||||
<div
|
||||
class="leaflet-container leaflet-touch leaflet-grab leaflet-touch-drag leaflet-touch-zoom"
|
||||
style="width: 100%; height: 900px; position: relative;"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="leaflet-pane leaflet-map-pane"
|
||||
style="left: 0px; top: 0px;"
|
||||
>
|
||||
<div
|
||||
class="leaflet-pane leaflet-tile-pane"
|
||||
>
|
||||
<div
|
||||
class="leaflet-layer "
|
||||
style="z-index: 1;"
|
||||
>
|
||||
<div
|
||||
class="leaflet-tile-container leaflet-zoom-animated"
|
||||
style="z-index: 18; left: 0px; top: 0px;"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="leaflet-tile"
|
||||
role="presentation"
|
||||
src="https://b.tile.openstreetmap.org/5/7/12.png"
|
||||
style="width: 256px; height: 256px; left: -126px; top: -114px;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="leaflet-pane leaflet-overlay-pane"
|
||||
/>
|
||||
<div
|
||||
class="leaflet-pane leaflet-shadow-pane"
|
||||
/>
|
||||
<div
|
||||
class="leaflet-pane leaflet-marker-pane"
|
||||
/>
|
||||
<div
|
||||
class="leaflet-pane leaflet-tooltip-pane"
|
||||
/>
|
||||
<div
|
||||
class="leaflet-pane leaflet-popup-pane"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="leaflet-control-container"
|
||||
>
|
||||
<div
|
||||
class="leaflet-top leaflet-left"
|
||||
>
|
||||
<div
|
||||
class="leaflet-control-zoom leaflet-bar leaflet-control"
|
||||
>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
aria-label="Zoom in"
|
||||
class="leaflet-control-zoom-in"
|
||||
href="#"
|
||||
role="button"
|
||||
title="Zoom in"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
+
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
aria-disabled="false"
|
||||
aria-label="Zoom out"
|
||||
class="leaflet-control-zoom-out"
|
||||
href="#"
|
||||
role="button"
|
||||
title="Zoom out"
|
||||
>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
−
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="leaflet-top leaflet-right"
|
||||
/>
|
||||
<div
|
||||
class="leaflet-bottom leaflet-left"
|
||||
/>
|
||||
<div
|
||||
class="leaflet-bottom leaflet-right"
|
||||
>
|
||||
<div
|
||||
class="leaflet-control-attribution leaflet-control"
|
||||
>
|
||||
<a
|
||||
href="https://leafletjs.com"
|
||||
title="A JavaScript library for interactive maps"
|
||||
>
|
||||
Leaflet
|
||||
</a>
|
||||
|
||||
<span
|
||||
aria-hidden="true"
|
||||
>
|
||||
|
|
||||
</span>
|
||||
©
|
||||
<a
|
||||
href="http://osm.org/copyright"
|
||||
>
|
||||
OpenStreetMap
|
||||
</a>
|
||||
contributors
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -0,0 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`VehicleMap popup Render 1`] = `
|
||||
<div
|
||||
aria-hidden="true"
|
||||
/>
|
||||
`;
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import useStyles from "../useStyles";
|
||||
import L from "leaflet";
|
||||
import { MapContainer, TileLayer, Marker, Popup, useMap } from "react-leaflet";
|
||||
import { MapContainer, TileLayer, Marker, Popup, useMap, useMapEvents } from "react-leaflet";
|
||||
import { Button } from "@material-ui/core";
|
||||
|
||||
import { useUserContext } from "../Contexts/UserContext";
|
||||
@@ -22,27 +22,23 @@ const Component = () => {
|
||||
|
||||
const REQUEST_INTERVAL = 10000;
|
||||
|
||||
const [center, setCenter] = useState([0, 0]);
|
||||
const [zoom, setZoom] = useState(2);
|
||||
const [center] = useState([37.0902, -95.7129]);
|
||||
const [zoom] = useState(4.5);
|
||||
const [markers, setMarkers] = useState([]);
|
||||
const [connections, setConnections] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
if (!token) return;
|
||||
retrieveAndStoreLocations(token).then((points) => {
|
||||
centerAroundMarkers(points);
|
||||
});
|
||||
const id = setInterval(function () {
|
||||
retrieveAndStoreLocations(token);
|
||||
}, REQUEST_INTERVAL);
|
||||
return () => {
|
||||
clearInterval(id);
|
||||
};
|
||||
// eslint-disable-next-line
|
||||
}, [token]);
|
||||
const [mapMoveTimer, setMapMoveTimer] = useState(null)
|
||||
const [mapUpdateInterval, setMapUpdateInterval] = useState(null)
|
||||
const [mapLocationInfo, setMapLocationInfo] = useState({
|
||||
center: {
|
||||
latitude: 0,
|
||||
longitude: 0
|
||||
},
|
||||
width: 100,
|
||||
height: 100
|
||||
})// MapLocationInfo is the center, height and width of the map
|
||||
|
||||
const retrieveAndStoreLocations = (accessToken) => {
|
||||
return getLocations(accessToken)
|
||||
return getLocations(accessToken, mapLocationInfo)
|
||||
.then((result) => {
|
||||
if (result.data != null) {
|
||||
const points = result.data.map((point) => [
|
||||
@@ -58,20 +54,6 @@ const Component = () => {
|
||||
.catch((error) => logger.warn(error.stack));
|
||||
};
|
||||
|
||||
const centerAroundMarkers = (points) => {
|
||||
// if (markers == null) {
|
||||
// markers = []
|
||||
// }
|
||||
// const coord = markers.reduce((coord, marker) => {
|
||||
// coord[0] += marker[0] / markers.length;
|
||||
// coord[1] += marker[1] / markers.length;
|
||||
// return coord;
|
||||
// }, [0, 0])
|
||||
|
||||
setCenter([37.0902, -95.7129]);
|
||||
setZoom(4.5);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!token) return;
|
||||
|
||||
@@ -139,17 +121,54 @@ const Component = () => {
|
||||
iconUrl: icon,
|
||||
iconAnchor: [24, 42],
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function GetVisibleCarLocations() {
|
||||
const map = useMapEvents({
|
||||
move: () => { // Zoom also triggers this
|
||||
var width = map.distance(map.getBounds().getNorthEast(), map.getBounds().getNorthWest()) // Float of meters
|
||||
var height = map.distance(map.getBounds().getNorthEast(), map.getBounds().getSouthEast()) // Float of meters
|
||||
var center = map.getCenter()
|
||||
setMapLocationInfo({
|
||||
center: {
|
||||
longitude: center.lng,
|
||||
latitude: center.lat
|
||||
},
|
||||
width: width / 1000, // Meters to KiloMeters
|
||||
height: height / 1000
|
||||
})
|
||||
// Remove the old interval and timeout that was running
|
||||
clearTimeout(mapMoveTimer)
|
||||
clearInterval(mapUpdateInterval)
|
||||
setMapMoveTimer(
|
||||
setTimeout(() => {
|
||||
retrieveAndStoreLocations(token)
|
||||
}, 1000) // We wait 1 second before contacting the server, just so we don't poll 1000 as the user is moving the map
|
||||
)
|
||||
// Get car updates every 30 seconds, as they are driving around
|
||||
setMapUpdateInterval(
|
||||
setInterval(() => {
|
||||
retrieveAndStoreLocations(token)
|
||||
}, 30000)
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<MapContainer
|
||||
center={center}
|
||||
zoom={zoom}
|
||||
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "900px",
|
||||
}}
|
||||
>
|
||||
<GetVisibleCarLocations />
|
||||
<TileLayer
|
||||
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
@@ -204,7 +223,6 @@ const Component = () => {
|
||||
|
||||
const CenterFocus = ({ center, zoom }) => {
|
||||
const map = useMap();
|
||||
|
||||
useEffect(() => {
|
||||
if (center[0] === 0 && center[1] === 0) {
|
||||
map.flyTo([0, 0], 2, { duration: 1.5 });
|
||||
@@ -212,7 +230,6 @@ const CenterFocus = ({ center, zoom }) => {
|
||||
map.flyTo(center, zoom, { duration: 1.5 });
|
||||
}
|
||||
}, [center, zoom, map]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
30
src/components/VehicleMap/index.test.jsx
Normal file
30
src/components/VehicleMap/index.test.jsx
Normal file
@@ -0,0 +1,30 @@
|
||||
jest.mock("../Contexts/VehicleContext")
|
||||
jest.mock("../Contexts/StatusContext");
|
||||
jest.mock("../Contexts/UserContext");
|
||||
|
||||
import { fireEvent, render, waitFor,screen, getByText } from "@testing-library/react";
|
||||
import { setToken } from "../Contexts/UserContext";
|
||||
import { TEST_AUTH_OBJECT } from "../../utils/testing";
|
||||
import addSnapshotSerializer from "../../utils/snapshot";
|
||||
import VehicleMap from "./index";
|
||||
|
||||
|
||||
const renderVehicleMap = async () => {
|
||||
const { container } = render(
|
||||
<VehicleMap />
|
||||
);
|
||||
await waitFor(() => {});
|
||||
return container;
|
||||
};
|
||||
|
||||
describe("VehicleMap", () => {
|
||||
beforeAll(() => {
|
||||
addSnapshotSerializer(expect);
|
||||
});
|
||||
|
||||
it("Render", async () => {
|
||||
setToken(TEST_AUTH_OBJECT);
|
||||
const container = await renderVehicleMap();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -41,8 +41,8 @@ const VehiclePopUp = (props) => {
|
||||
<DialogTitle align="center" onClose={onClose}>
|
||||
{vin}
|
||||
{" "}
|
||||
<IconButton>
|
||||
<VisibilityIcon fontSize="inherit" onClick={toggleView} />
|
||||
<IconButton onClick={toggleView}>
|
||||
<VisibilityIcon fontSize="inherit" />
|
||||
</IconButton>
|
||||
</DialogTitle>
|
||||
<div align="center" className={classes.popUpContent}>
|
||||
|
||||
43
src/components/VehicleMap/popup.test.jsx
Normal file
43
src/components/VehicleMap/popup.test.jsx
Normal file
@@ -0,0 +1,43 @@
|
||||
jest.mock("../Contexts/UserContext");
|
||||
|
||||
import { fireEvent, render, waitFor, screen, getByText } from "@testing-library/react";
|
||||
import { setToken } from "../Contexts/UserContext";
|
||||
import { TEST_AUTH_OBJECT } from "../../utils/testing";
|
||||
import addSnapshotSerializer from "../../utils/snapshot";
|
||||
import { VehiclePopUp } from "./popup";
|
||||
|
||||
const renderPopup = async (online) => {
|
||||
const { container } = render(
|
||||
<VehiclePopUp vin={"F1SKER123456"} online={online} />
|
||||
);
|
||||
await waitFor(() => { });
|
||||
return container;
|
||||
};
|
||||
|
||||
describe("VehicleMap popup", () => {
|
||||
beforeAll(() => {
|
||||
addSnapshotSerializer(expect);
|
||||
});
|
||||
|
||||
it("Render", async () => {
|
||||
setToken(TEST_AUTH_OBJECT);
|
||||
const container = await renderPopup(false);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Online: false", async () => {
|
||||
setToken(TEST_AUTH_OBJECT);
|
||||
const container = await renderPopup(false);
|
||||
const el = screen.getAllByText('Connected', { exact: false })[0]
|
||||
|
||||
expect(el.parentElement.textContent).toEqual('Connected: false');
|
||||
});
|
||||
|
||||
it("Online: true", async () => {
|
||||
setToken(TEST_AUTH_OBJECT);
|
||||
const container = await renderPopup(true);
|
||||
const el = screen.getAllByText('Connected', { exact: false })[0]
|
||||
|
||||
expect(el.parentElement.textContent).toEqual('Connected: true');
|
||||
});
|
||||
})
|
||||
Reference in New Issue
Block a user