diff --git a/frontend/src/components/DataLayersCheckboxGroup.test.tsx b/frontend/src/components/DataLayersCheckboxGroup.test.tsx index 394cd955..2dca8149 100644 --- a/frontend/src/components/DataLayersCheckboxGroup.test.tsx +++ b/frontend/src/components/DataLayersCheckboxGroup.test.tsx @@ -43,12 +43,10 @@ describe('Test suite for DataLayersCheckboxGroup', () => { DATA_LAYER_GROUPS.forEach(({ name, layers }) => { screen.getByRole('button', { name, pressed: true }) layers.forEach((layer) => { - const cb = screen.getByLabelText(layer.name) - expect(cb).not.toBeChecked() if (layer.url) { + const cb = screen.getByLabelText(layer.name) + expect(cb).not.toBeChecked() expect(cb).toBeEnabled() - } else { - expect(cb).toBeDisabled() } }) }) diff --git a/frontend/src/components/DataLayersToggleGroup.tsx b/frontend/src/components/DataLayersToggleGroup.tsx index 340710ab..e8a955aa 100644 --- a/frontend/src/components/DataLayersToggleGroup.tsx +++ b/frontend/src/components/DataLayersToggleGroup.tsx @@ -62,17 +62,18 @@ export function DataLayersToggleGroup({ - {group.layers.map((layer: DataLayer) => ( - } - checked={isDataLayerChecked(layer)} - label={layer.name} - disabled={!layer.url} - className="data-layers-checkbox-item" - onChange={() => onLayerToggle(layer)} - /> - ))} + {group.layers.map((layer: DataLayer) => + layer.url ? ( + } + checked={isDataLayerChecked(layer)} + label={layer.name} + className="data-layers-checkbox-item" + onChange={() => onLayerToggle(layer)} + /> + ) : null, + )} diff --git a/frontend/src/pages/map/MapView.test.tsx b/frontend/src/pages/map/MapView.test.tsx index 707a84ac..736f999a 100644 --- a/frontend/src/pages/map/MapView.test.tsx +++ b/frontend/src/pages/map/MapView.test.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { screen } from '@testing-library/react' +import { fireEvent, screen } from '@testing-library/react' import { render } from '@/test-utils' import { initialState as initialOmrrState } from '@/features/omrr/omrr-slice' @@ -7,12 +7,16 @@ import { initialState as initialMapState } from '@/features/map/map-slice' import { mockOmrrData } from '@/mocks/mock-omrr-data' import { themeBreakpointValues } from '@/theme' import MapView from './MapView' -import { ActiveToolEnum } from '@/constants/constants' +import OmrrData from '@/interfaces/omrr' describe('Test suite for MapView', () => { - it('should render the MapView with markers', async () => { - render(, { - screenWidth: themeBreakpointValues.xxl, + function renderComponent( + screenWidth: number, + filteredResults: OmrrData[] = mockOmrrData, + isMyLocationVisible = false, + ) { + return render(, { + screenWidth, withStateProvider: true, withRouter: true, initialState: { @@ -20,14 +24,18 @@ describe('Test suite for MapView', () => { ...initialOmrrState, allResults: mockOmrrData, searchByFilteredResults: mockOmrrData, - filteredResults: mockOmrrData, + filteredResults, status: 'succeeded', }, map: { ...initialMapState, + isMyLocationVisible, }, }, }) + } + it('should render the MapView with markers', async () => { + renderComponent(themeBreakpointValues.xxl) const mapView = screen.getByTestId('map-view') expect(mapView).not.toHaveClass('map-view--small') @@ -44,20 +52,7 @@ describe('Test suite for MapView', () => { }) it('should render the MapView with no markers on a small screen', async () => { - const { user } = render(, { - screenWidth: themeBreakpointValues.sm - 10, - withStateProvider: true, - initialState: { - omrr: { - ...initialOmrrState, - status: 'succeeded', - }, - map: { - ...initialMapState, - isMyLocationVisible: true, - }, - }, - }) + const { user } = renderComponent(themeBreakpointValues.sm - 10, [], true) const mapView = screen.getByTestId('map-view') expect(mapView).toHaveClass('map-view--small') @@ -120,4 +115,95 @@ describe('Test suite for MapView', () => { await user.click(backBtn) expect(screen.queryByPlaceholderText('Search')).not.toBeInTheDocument() }) + + it('should render the MapView and test point search', async () => { + const { user } = renderComponent(themeBreakpointValues.xxl, mockOmrrData) + + const pointSearchBtn = screen.getByRole('button', { name: 'Point Search' }) + await user.click(pointSearchBtn) + + const cancelBtn = screen.getByRole('button', { name: 'Cancel' }) + screen.getByRole('button', { name: 'Set Radius' }) + screen.getByText('Click to place center point') + + const map = document.querySelector('.leaflet-container') as HTMLElement + await user.click(map) + + expect(document.querySelector('.point-search-circle')).toBeInTheDocument() + + await user.click(cancelBtn) + + expect( + screen.queryByText('Click to place center point'), + ).not.toBeInTheDocument() + }) + + it('should render the MapView and test polygon search', async () => { + const { user } = renderComponent(themeBreakpointValues.xxl, mockOmrrData) + + const pointSearchBtn = screen.getByRole('button', { + name: 'Polygon Search', + }) + await user.click(pointSearchBtn) + + const cancelBtn = screen.getByRole('button', { name: 'Cancel' }) + const deleteBtn = screen.getByRole('button', { name: 'Delete Last Point' }) + expect(deleteBtn).toBeDisabled() + const finishBtn = screen.getByRole('button', { name: 'Finish Shape' }) + expect(finishBtn).toBeDisabled() + screen.getByText('Click to start drawing shape') + + expect( + document.querySelector('.polygon-search-line--dotted'), + ).not.toBeInTheDocument() + expect( + document.querySelector('.polygon-search-line'), + ).not.toBeInTheDocument() + expect( + document.querySelector('.polygon-search-polygon'), + ).not.toBeInTheDocument() + + const map = document.querySelector('.leaflet-container') as HTMLElement + fireEvent.mouseOver(map) + fireEvent.mouseMove(map, { clientX: 50, clientY: 50 }) + await user.click(map) + fireEvent.mouseMove(map, { clientX: 60, clientY: 60 }) + await user.click(map) + fireEvent.mouseMove(map, { clientX: 60, clientY: 70 }) + await user.click(map) + fireEvent.mouseOut(map) + + const lines = document.querySelectorAll('.polygon-search-line') + expect(lines).toHaveLength(2) + expect(deleteBtn).toBeEnabled() + expect(finishBtn).toBeEnabled() + + await user.click(cancelBtn) + + expect( + screen.queryByText('Click to start drawing shape'), + ).not.toBeInTheDocument() + }) + + it('should render the MapView and test data layers', async () => { + const { user } = renderComponent(themeBreakpointValues.xxl, []) + + const dataLayersBtn = screen.getByRole('button', { + name: 'Data Layers', + }) + await user.click(dataLayersBtn) + + screen.getByText(/^All data layers sourced/) + expect( + screen.queryByRole('button', { name: 'Reset Layers' }), + ).not.toBeInTheDocument() + const layerCb = screen.getByRole('checkbox', { name: 'Aquifers - All' }) + expect(layerCb).not.toBeChecked() + await user.click(layerCb) + expect(layerCb).toBeChecked() + + const resetBtn = screen.getByRole('button', { name: 'Reset Layers' }) + await user.click(resetBtn) + expect(layerCb).not.toBeChecked() + }) }) diff --git a/frontend/src/pages/map/drawer/MapBottomDrawer.tsx b/frontend/src/pages/map/drawer/MapBottomDrawer.tsx index 9017cc71..63acb8b9 100644 --- a/frontend/src/pages/map/drawer/MapBottomDrawer.tsx +++ b/frontend/src/pages/map/drawer/MapBottomDrawer.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react' +import { useState } from 'react' import { useDispatch } from 'react-redux' import clsx from 'clsx' import { IconButton } from '@mui/material' @@ -7,11 +7,7 @@ import { DataLayersCheckboxGroup } from '@/components/DataLayersCheckboxGroup' import { FilterByCheckboxGroup } from '@/components/FilterByCheckboxGroup' import { SearchByRadioGroup } from '@/components/SearchByRadioGroup' import { ActiveToolEnum } from '@/constants/constants' -import { - setActiveTool, - setDrawerExpanded, - useActiveTool, -} from '@/features/map/map-slice' +import { setActiveTool, useActiveTool } from '@/features/map/map-slice' import { setCircleFilter, setPolygonFilter } from '@/features/omrr/omrr-slice' import { SearchResultsList } from './SearchResultsList' import { PolygonSearch } from '../search/PolygonSearch' diff --git a/frontend/src/pages/map/layers/PointSearchLayer.tsx b/frontend/src/pages/map/layers/PointSearchLayer.tsx index cb1c9235..36c033ed 100644 --- a/frontend/src/pages/map/layers/PointSearchLayer.tsx +++ b/frontend/src/pages/map/layers/PointSearchLayer.tsx @@ -5,8 +5,8 @@ import { Circle, useMap, useMapEvents } from 'react-leaflet' import { ActiveToolEnum, MIN_CIRCLE_RADIUS } from '@/constants/constants' import { useActiveTool } from '@/features/map/map-slice' import { setCircleFilter, useCircleFilter } from '@/features/omrr/omrr-slice' -import { useMapCrosshairsCursor } from '@/pages/map/hooks/useMapCrosshairsCursor' -import { CrosshairsTooltipMarker } from '@/pages/map/layers/CrosshairsTooltipMarker' +import { useMapCrosshairsCursor } from '../hooks/useMapCrosshairsCursor' +import { CrosshairsTooltipMarker } from './CrosshairsTooltipMarker' export function PointSearchLayer() { const activeTool = useActiveTool() @@ -42,7 +42,6 @@ function CircleLayer() { stroke fill className="point-search-circle" - data-testid="point-search-circle" /> )} diff --git a/frontend/src/pages/map/search/MapSearch.css b/frontend/src/pages/map/search/MapSearch.css index e7cfee3c..6f44237c 100644 --- a/frontend/src/pages/map/search/MapSearch.css +++ b/frontend/src/pages/map/search/MapSearch.css @@ -91,8 +91,6 @@ button.map-button--active:hover { .map-search-tool-row { flex: 1 1 100%; display: flex; - justify-content: flex-start; - align-items: center; } .map-search-tool-box { diff --git a/frontend/src/pages/map/search/MapSearch.tsx b/frontend/src/pages/map/search/MapSearch.tsx index c94a327e..1b28be71 100644 --- a/frontend/src/pages/map/search/MapSearch.tsx +++ b/frontend/src/pages/map/search/MapSearch.tsx @@ -71,13 +71,11 @@ export function MapSearch() { {isLarge && (isPolygonTool || isPointTool) && ( - <> -
-
- {isPolygonTool ? : } -
+
+
+ {isPolygonTool ? : }
- +
)} ) diff --git a/frontend/src/pages/map/search/PolygonSearch.test.tsx b/frontend/src/pages/map/search/PolygonSearch.test.tsx index abebfa31..975bea5e 100644 --- a/frontend/src/pages/map/search/PolygonSearch.test.tsx +++ b/frontend/src/pages/map/search/PolygonSearch.test.tsx @@ -1,15 +1,11 @@ -import { fireEvent, screen } from '@testing-library/react' +import { screen } from '@testing-library/react' import { PolygonSearch } from './PolygonSearch' import { render } from '@/test-utils' -import { - initialState, - useCircleFilter, - usePolygonFilter, -} from '@/features/omrr/omrr-slice' +import { initialState, usePolygonFilter } from '@/features/omrr/omrr-slice' import { useActiveTool } from '@/features/map/map-slice' -import { CircleFilter, PolygonFilter } from '@/interfaces/omrr-filter' -import { ActiveToolEnum, MIN_CIRCLE_RADIUS } from '@/constants/constants' +import { PolygonFilter } from '@/interfaces/omrr-filter' +import { ActiveToolEnum } from '@/constants/constants' import { LatLngTuple } from 'leaflet' interface State { diff --git a/frontend/src/test-setup.ts b/frontend/src/test-setup.ts index ac6ffd82..1cc8e4a1 100644 --- a/frontend/src/test-setup.ts +++ b/frontend/src/test-setup.ts @@ -45,6 +45,25 @@ if (typeof window.URL.revokeObjectURL === 'undefined') { }) } +// Support SVG in leaflet, so that Polylines work +// https://stackoverflow.com/questions/54382414/fixing-react-leaflet-testing-error-cannot-read-property-layeradd-of-null/54384719#54384719 +const createElementNSOrig = document.createElementNS +// @ts-ignore +document.createElementNS = function (namespaceURI, qualifiedName) { + if ( + namespaceURI === 'http://www.w3.org/2000/svg' && + qualifiedName === 'svg' + ) { + const element = createElementNSOrig.apply(this, [ + namespaceURI, + qualifiedName, + ]) + ;(element as any).createSVGRect = () => {} + return element + } + return createElementNSOrig.apply(this, [namespaceURI, qualifiedName]) +} + // Define geolocation and permissions query const geoLocationResult: GeolocationPosition = { coords: {