From 2860ce981f5820f5e95dec97fdaa95a735adf498 Mon Sep 17 00:00:00 2001 From: sdobbert Date: Thu, 2 Oct 2025 15:31:16 +0200 Subject: [PATCH] fix: conflate dublicated unittests --- jest.config.cjs | 7 +- .../BackgroundLayerChooser.spec.tsx | 76 ++++++++++--------- .../BackgroundLayerChooser.tsx | 9 ++- .../BackgroundLayerPreview.spec.tsx | 70 +++++++++++++++++ .../FeatureLabelModal.spec.tsx | 1 + src/Field/SearchField/SearchField.spec.tsx | 13 +++- 6 files changed, 133 insertions(+), 43 deletions(-) diff --git a/jest.config.cjs b/jest.config.cjs index 65dcd4e20..a12156f92 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -36,7 +36,12 @@ module.exports = { }, collectCoverageFrom: [ 'src/**/*.{ts,tsx}', - '!src/**/*example*.*' + '!src/**/*example*.*', + '!src/**/*.d.ts', + '!src/index.ts', + '!src/Context/MapContext/MapContext.tsx', // only a placeholder + '!src/Hook/useDropTargetMap.ts', // only a placeholder + '!src/Hook/useMap.ts' // only a placeholder ], coverageDirectory: '/coverage', testEnvironment: 'jsdom', diff --git a/src/BackgroundLayerChooser/BackgroundLayerChooser.spec.tsx b/src/BackgroundLayerChooser/BackgroundLayerChooser.spec.tsx index 1d591eed0..3d2a1253d 100644 --- a/src/BackgroundLayerChooser/BackgroundLayerChooser.spec.tsx +++ b/src/BackgroundLayerChooser/BackgroundLayerChooser.spec.tsx @@ -7,8 +7,9 @@ import OlLayerGroup from 'ol/layer/Group'; import OlSourceImageWMS from 'ol/source/ImageWMS'; import React from 'react'; -import { render, fireEvent, screen, waitFor } from '@testing-library/react'; +import { render, fireEvent, screen, waitFor, act, cleanup } from '@testing-library/react'; +import { renderInMapContext } from '@terrestris/react-util/dist/Util/rtlTestUtils'; import TestUtil from '../Util/TestUtil'; import BackgroundLayerChooser from './BackgroundLayerChooser'; @@ -19,10 +20,10 @@ describe('BackgroundLayerChooser', () => { beforeEach(() => { layers = [ new OlLayerTile({ - source: new OlSourceOsm() + source: new OlSourceOsm() }), new OlLayerTile({ - source: new OlSourceOsm() + source: new OlSourceOsm() }) ]; layers[0].set('name', 'Layer 1'); @@ -33,9 +34,11 @@ describe('BackgroundLayerChooser', () => { }); afterEach(() => { + cleanup(); map?.dispose(); layers = []; }); + it('renders button and preview', () => { const { container } = render(); expect(container.querySelector('.bg-layer-chooser')).toBeInTheDocument(); @@ -43,44 +46,23 @@ describe('BackgroundLayerChooser', () => { expect(container.querySelector('#overview-map')).toBeInTheDocument(); }); - it('shows layer options when button is clicked', () => { - const { container } = render(); - fireEvent.click(container.querySelector('.bg-layer-chooser') as HTMLElement); - waitFor(() => { - expect(container.querySelectorAll('.bg-preview').length).toBe(2); + it('selects a layer and updates preview', async () => { + const { container } = renderInMapContext(map, ); + const btn = container.querySelector('.change-bg-btn'); + await act(async () => { + btn && fireEvent.click(btn); }); - }); - it('selects a layer and updates preview', () => { - const { container } = render(); - fireEvent.click(container.querySelector('.bg-layer-chooser') as HTMLElement); - waitFor(() => { - expect(container.querySelectorAll('.bg-preview').length).toBe(2); - fireEvent.click(container.querySelectorAll('.bg-preview')[1]); - }); - waitFor(() => { - expect(screen.getByText('Layer 1')).toBeInTheDocument(); - expect(screen.getByText('Layer 2')).toBeInTheDocument(); + const previews = await waitFor(() => container.querySelectorAll('.bg-preview')); + await waitFor(() => { + expect(previews.length).toBeGreaterThan(0); }); - }); - - it('renders no background button if allowEmptyBackground is true', () => { - const { container } = render(); - fireEvent.click(container.querySelector('.bg-layer-chooser') as HTMLElement); - waitFor(() => { - expect(screen.getByText('No Background')).toBeInTheDocument(); + await act(async () => { + previews[0] && fireEvent.click(previews[0]); }); - }); - it('selects no background and updates preview', () => { - const { container } = render(); - fireEvent.click(container.querySelector('.bg-layer-chooser') as HTMLElement); - waitFor(() => { - const noBgButtons = screen.getAllByText('No Background'); - fireEvent.click(noBgButtons[1]); - }); - waitFor(() => { - expect(screen.getAllByText('No Background').length).toBeGreaterThan(0); + await waitFor(() => { + expect(container.querySelector('.bg-preview .layer-title')?.textContent).toBe('Layer 1'); }); }); @@ -142,4 +124,26 @@ describe('BackgroundLayerChooser', () => { expect(screen.getAllByText('No Background').length).toBeGreaterThan(0); }); }); + + it('filters layers using backgroundLayerFilter', async () => { + const filter = (l: any) => l.get('name') === 'Layer 2'; + const { container } = renderInMapContext( + map, + + ); + const btn = container.querySelector('.change-bg-btn'); + await act(async () => { + btn && fireEvent.click(btn); + }); + await waitFor(() => { + const previews = container.querySelectorAll('.layer-preview'); + expect(previews.length).toBe(1); + const title = (previews[0] as Element).querySelector('.layer-title')?.textContent; + expect(title).toBe('Layer 2'); + }); + }); }); diff --git a/src/BackgroundLayerChooser/BackgroundLayerChooser.tsx b/src/BackgroundLayerChooser/BackgroundLayerChooser.tsx index e3823b7e0..2bea6b7cd 100644 --- a/src/BackgroundLayerChooser/BackgroundLayerChooser.tsx +++ b/src/BackgroundLayerChooser/BackgroundLayerChooser.tsx @@ -115,9 +115,10 @@ export const BackgroundLayerChooser: React.FC = ({ }, [map, layerOptionsVisible]); useEffect(() => { - const activeLayerCand = layers.find(l => l.getVisible()); - - if (!initiallySelectedLayer) { + if (initiallySelectedLayer) { + setSelectedLayer(initiallySelectedLayer); + } else { + const activeLayerCand = layers.find(l => l.getVisible()); setSelectedLayer(activeLayerCand as OlLayer); } }, [initiallySelectedLayer, layers]); @@ -227,7 +228,7 @@ export const BackgroundLayerChooser: React.FC = ({ layerOptionsVisible && (
{ - layers.map(layer => ( + layers.filter(backgroundLayerFilter).map(layer => ( { ); expect(screen.getByText('Test Layer')).toBeInTheDocument(); expect(container.querySelector('.map')).toBeInTheDocument(); + expect(container.querySelector('.layer-preview')).toBeInTheDocument(); }); it('calls onClick when clicked', () => { @@ -62,6 +66,19 @@ describe('BackgroundLayerPreview', () => { }); }); + it('renders the title from layer name', () => { + const onClick = jest.fn(); + const backgroundLayerFilter = () => true; + const { getByText } = render( + + ); + expect(getByText('Test Layer')).toBeInTheDocument(); + }); + it('renders custom title if titleRenderer is provided', () => { render( { const mapDiv = container.querySelector('.map'); expect(mapDiv).toHaveStyle({ width: '200px', height: '150px' }); }); + + it('renders with an Image layer', () => { + // Use a minimal valid Image source for OlLayerImage + const layer = new OlLayerImage({ + source: new ImageStatic({ + url: '', + imageExtent: [0, 0, 1, 1], + projection: 'EPSG:3857' + }) + }); + layer.set('name', 'ImageLayer'); + const onClick = jest.fn(); + const backgroundLayerFilter = () => true; + const { getByText } = render( + + ); + expect(getByText('ImageLayer')).toBeInTheDocument(); + }); + + it('handles backgroundLayerFilter returning false', () => { + layer = new OlLayerTile({ source: new OlSourceOsm() }); + layer.set('name', 'FilteredOut'); + const onClick = jest.fn(); + const backgroundLayerFilter = () => false; + const { getByText } = render( + + ); + expect(getByText('FilteredOut')).toBeInTheDocument(); + }); + + it('handles a layer that is not Tile or Image', () => { + // Use a LayerGroup as a non-Tile/Image layer + const group = new OlLayerGroup(); + group.set('name', 'GroupLayer'); + const onClick = jest.fn(); + const backgroundLayerFilter = () => true; + const { getByText } = render( + + ); + expect(getByText('GroupLayer')).toBeInTheDocument(); + }); }); diff --git a/src/FeatureLabelModal/FeatureLabelModal.spec.tsx b/src/FeatureLabelModal/FeatureLabelModal.spec.tsx index 28d6b0a21..b50fc9029 100644 --- a/src/FeatureLabelModal/FeatureLabelModal.spec.tsx +++ b/src/FeatureLabelModal/FeatureLabelModal.spec.tsx @@ -44,6 +44,7 @@ describe('', () => { onCancel={onCancel} /> ); + expect(screen.getByRole('dialog')).toBeInTheDocument(); expect(screen.getByText('Test label')).toBeInTheDocument(); }); diff --git a/src/Field/SearchField/SearchField.spec.tsx b/src/Field/SearchField/SearchField.spec.tsx index 7eb6b8c71..296a18697 100644 --- a/src/Field/SearchField/SearchField.spec.tsx +++ b/src/Field/SearchField/SearchField.spec.tsx @@ -5,12 +5,12 @@ import OlFeature from 'ol/Feature'; import OlPoint from 'ol/geom/Point'; import OlMap from 'ol/Map'; import OlView from 'ol/View'; -import { render, fireEvent, waitFor } from '@testing-library/react'; +import { render, fireEvent, waitFor, screen } from '@testing-library/react'; import { SearchField, SearchProps } from './SearchField'; describe('', () => { - const coord = [829729, 6708850]; + const coord = [1, 2]; let map: OlMap; let feature: OlFeature; @@ -82,4 +82,13 @@ describe('', () => { expect(mockProps.onSearchCompleted).toHaveBeenCalledWith(searchCollection); }); }); + + it('disables autocomplete popup if autoCompleteDisabled is true', async () => { + render(); + const input = screen.getByRole('combobox'); + fireEvent.change(input, { target: { value: 'A' } }); + // Wait a bit to ensure popup would have rendered if enabled + await new Promise(res => setTimeout(res, 300)); + expect(screen.queryByText('A')).not.toBeInTheDocument(); + }); });