Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = {
],
transformIgnorePatterns: [
'node_modules/(?!(ol|@camptocamp/inkmap|@terrestris/*[a-z]*-util|d3-selection|color-*[a-z]*)|(rc-*[a-z]*)|' +
'filter-obj|query-string|decode-uri-component|split-on-first|shpjs/|rbush|quickselect|geostyler-openlayers-parser|' +
'filter-obj|query-string|decode-uri-component|split-on-first|shpjs/|rbush|quickselect|geostyler-openlayers-parser|ol-mapbox-style|pbf|' +
'geostyler-style|geotiff|quick-lru|quickselect|jsts)'
],
setupFiles: [
Expand All @@ -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: '<rootDir>/coverage',
testEnvironment: 'jsdom',
Expand Down
189 changes: 189 additions & 0 deletions src/BackgroundLayerChooser/BackgroundLayerChooser.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import * as React from 'react';

import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM'
// import TileWMS from 'ol/source/TileWMS';

import {
renderInMapContext
} from '@terrestris/react-util/dist/Util/rtlTestUtils';

import BackgroundLayerChooser from './BackgroundLayerChooser';
import { act, fireEvent, waitFor } from '@testing-library/react';

describe('<BackGroundLayerChooser />', () => {

let map: Map;
let layers: TileLayer[];

function createLayers() {
return [
new TileLayer({
source: new OSM(),
properties: {
name: 'OSM',
isBackgroundLayer: true
}
}),
new TileLayer({
source: new OSM(),
properties: {
name: 'OSM2',
isBackgroundLayer: true
}
})
];
}

beforeEach(() => {
layers = createLayers();
map = new Map({
view: new View({
center: [0, 0],
zoom: 1
}),
layers
});
});


describe('#Basics', () => {
it('is defined', () => {
expect(BackgroundLayerChooser).not.toBeUndefined();
});

it('can be rendered', () => {
const { container } = renderInMapContext(
map,
<BackgroundLayerChooser
layers={layers}
allowEmptyBackground={true}
/>
);
expect(container.querySelector('.bg-layer-chooser')).toBeInTheDocument();
});
});

it('shows layer cards when button is clicked', async () => {
const { container } = renderInMapContext(
map,
<BackgroundLayerChooser
layers={layers}
allowEmptyBackground={true}
/>
);
const btn = container.querySelector('.change-bg-btn');
await act(async () => {
btn && fireEvent.click(btn);
});
await waitFor(() => {
expect(container.querySelector('.layer-cards')).toBeInTheDocument();
expect(container.querySelectorAll('.layer-preview').length).toBeGreaterThan(0);
});
});

it('calls titleRenderer for each layer', async () => {
const titleRenderer = jest.fn(l => <span>Layer: {l.get('name')}</span>);
const { container } = renderInMapContext(
map,
<BackgroundLayerChooser
layers={layers}
allowEmptyBackground={true}
titleRenderer={titleRenderer}
/>
);
const btn = container.querySelector('.change-bg-btn');
await act(async () => {
btn && fireEvent.click(btn);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this is only because of the querySelector possibly returning null? To satisfy the typechecking?

If the btn does not exist in the document, the event will not be fired and the error might be hard to debug.

maybe something like this works as well:

const btn = await waitFor(() => container.querySelector('.btn'));

await act(async () => {
  fireEvent.click(btn);
});

?

});
await waitFor(() => {
expect(titleRenderer).toHaveBeenCalled();
});
});

it('shows no background option and selects it', async () => {
const { container } = renderInMapContext(
map,
<BackgroundLayerChooser
layers={layers}
allowEmptyBackground={true}
noBackgroundTitle="None"
/>
);
const btn = container.querySelector('.change-bg-btn');
await act(async () => {
btn && fireEvent.click(btn);
});
const noBg = await waitFor(() => container.querySelector('.no-background'));
expect(noBg).toBeInTheDocument();
await act(async () => {
noBg && fireEvent.click(noBg);
});
await waitFor(() => {
expect(container.querySelector('.bg-preview .layer-title')?.textContent).toBe('None');
});
});

it('selects a background layer when preview is clicked', async () => {
const { container } = renderInMapContext(
map,
<BackgroundLayerChooser
layers={layers}
allowEmptyBackground={true}
/>
);
const btn = container.querySelector('.change-bg-btn');
await act(async () => {
btn && fireEvent.click(btn);
});
const previews = await waitFor(() => container.querySelectorAll('.layer-preview'));
expect(previews.length).toBeGreaterThan(0);
await act(async () => {
previews[0] && fireEvent.click(previews[0]);
});
await waitFor(() => {
expect(container.querySelector('.bg-preview .layer-title')?.textContent).toBe('OSM');
});
});

it('respects initiallySelectedLayer prop', async () => {
// Do not set allowEmptyBackground, so 'No Background' is not selected
const { container } = renderInMapContext(
map,
<BackgroundLayerChooser
layers={layers}
allowEmptyBackground={false}
initiallySelectedLayer={layers[1]}
/>
);
await waitFor(() => {
expect(container.querySelector('.bg-preview .layer-title')?.textContent).toBe('OSM2');
});
});

it('filters layers using backgroundLayerFilter', async () => {
const filter = (l: any) => l.get('name') === 'OSM2';
const { container } = renderInMapContext(
map,
<BackgroundLayerChooser
layers={layers}
allowEmptyBackground={false}
backgroundLayerFilter={filter}
/>
);
const btn = container.querySelector('.change-bg-btn');
await act(async () => {
btn && fireEvent.click(btn);
});
await waitFor(() => {
// Only OSM2 should be present
const previews = container.querySelectorAll('.layer-preview');
expect(previews.length).toBe(1);
const title = (previews[0] as Element).querySelector('.layer-title')?.textContent;
expect(title).toBe('OSM2');
});
});

});
9 changes: 5 additions & 4 deletions src/BackgroundLayerChooser/BackgroundLayerChooser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,10 @@ export const BackgroundLayerChooser: React.FC<BackgroundLayerChooserProps> = ({
}, [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]);
Expand Down Expand Up @@ -227,7 +228,7 @@ export const BackgroundLayerChooser: React.FC<BackgroundLayerChooserProps> = ({
layerOptionsVisible && (
<div className="layer-cards">
{
layers.map(layer => (
layers.filter(backgroundLayerFilter).map(layer => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catches!

<BackgroundLayerPreview
key={getUid(layer)}
activeLayer={selectedLayer}
Expand Down
Loading