-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3765 from terrestris/refactor-scale-combo
Refactor `ScaleCombo` to function component
- Loading branch information
Showing
3 changed files
with
224 additions
and
456 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,182 +1,124 @@ | ||
import MapUtil from '@terrestris/ol-util/dist/MapUtil/MapUtil'; | ||
import { renderInMapContext } from '@terrestris/react-util/dist/Util/rtlTestUtils'; | ||
import { act, render, screen } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import React from 'react'; | ||
|
||
import TestUtil from '../../Util/TestUtil'; | ||
import ScaleCombo from './ScaleCombo'; | ||
|
||
describe('<ScaleCombo />', () => { | ||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('is defined', () => { | ||
expect(ScaleCombo).not.toBeUndefined(); | ||
expect(ScaleCombo).toBeDefined(); | ||
}); | ||
|
||
it('can be rendered', () => { | ||
const map = TestUtil.createMap(); | ||
const wrapper = TestUtil.mountComponent(ScaleCombo, { | ||
map | ||
}); | ||
expect(wrapper).not.toBeUndefined(); | ||
const { container } = render(<ScaleCombo />); | ||
expect(container).toBeVisible(); | ||
}); | ||
|
||
it('passes style prop', () => { | ||
it('calls onZoomLevelSelect when a scale is selected', async () => { | ||
const onZoomLevelSelect = jest.fn(); | ||
const map = TestUtil.createMap(); | ||
const props = { | ||
map, | ||
style: { | ||
backgroundColor: 'yellow' | ||
} | ||
}; | ||
const wrapper = TestUtil.mountComponent(ScaleCombo, props); | ||
expect(wrapper.getDOMNode()).toHaveStyle('backgroundColor: yellow'); | ||
renderInMapContext(map, | ||
<ScaleCombo | ||
onZoomLevelSelect={onZoomLevelSelect} | ||
scales={[100, 200]} | ||
open | ||
/> | ||
); | ||
|
||
const entry = screen.getByText('1:100'); | ||
|
||
await userEvent.click(entry); | ||
|
||
expect(onZoomLevelSelect).toHaveBeenCalledWith('100'); | ||
TestUtil.removeMap(map); | ||
}); | ||
|
||
describe('#getOptionsFromMap', () => { | ||
it('is defined', () => { | ||
const map = TestUtil.createMap(); | ||
const wrapper = TestUtil.mountComponent(ScaleCombo, { | ||
map | ||
}); | ||
const instance = wrapper.instance() as ScaleCombo; | ||
expect(instance.getOptionsFromMap).not.toBeUndefined(); | ||
it('creates options array from given map with resolutions', () => { | ||
const testResolutions = [560, 280, 140, 70, 28]; | ||
const map = TestUtil.createMap({ | ||
resolutions: testResolutions | ||
}); | ||
|
||
it('creates options array from resolutions set on the map', () => { | ||
const map = TestUtil.createMap(); | ||
renderInMapContext(map, ( | ||
<ScaleCombo | ||
open | ||
/> | ||
)); | ||
|
||
const getOptionsFromMapSpy = jest.spyOn(ScaleCombo.prototype, 'getOptionsFromMap'); | ||
const options = screen.getAllByText((text, element) => element?.tagName === 'DIV' && /1:/.test(text)); | ||
|
||
TestUtil.mountComponent(ScaleCombo, { | ||
map | ||
}); | ||
|
||
expect(getOptionsFromMapSpy).toHaveBeenCalledTimes(1); | ||
getOptionsFromMapSpy.mockRestore(); | ||
|
||
TestUtil.removeMap(map); | ||
}); | ||
expect(options).toHaveLength(testResolutions.length); | ||
TestUtil.removeMap(map); | ||
}); | ||
|
||
it('creates options array from given map without resolutions', () => { | ||
const map = TestUtil.createMap(); | ||
const wrapper = TestUtil.mountComponent(ScaleCombo, { | ||
scales: [], | ||
map: map | ||
}); | ||
|
||
// Reset the scales array, as getOptionsFromMap() will be called in | ||
// constructor. | ||
wrapper.setState({scales: []}); | ||
const instance = wrapper.instance() as ScaleCombo; | ||
const scales = instance.getOptionsFromMap(); | ||
expect(scales).toBeInstanceOf(Array); | ||
|
||
TestUtil.removeMap(map); | ||
it('creates options array from given map with filtered resolutions', () => { | ||
const testResolutions = [560, 280, 140, 70, 28, 19, 15, 14, 13, 9]; | ||
const map = TestUtil.createMap({ | ||
resolutions: testResolutions | ||
}); | ||
|
||
it('creates options array from given map with resolutions', () => { | ||
const testResolutions = [560, 280, 140, 70, 28]; | ||
const map = TestUtil.createMap({ | ||
resolutions: testResolutions | ||
}); | ||
const wrapper = TestUtil.mountComponent(ScaleCombo, { | ||
scales: [], | ||
map: map | ||
}); | ||
|
||
// Reset the scales array, as getOptionsFromMap() will be called in | ||
// constructor. | ||
wrapper.setState({scales: []}); | ||
|
||
const instance = wrapper.instance() as ScaleCombo; | ||
const scales = instance.getOptionsFromMap(); | ||
|
||
expect(scales).toBeInstanceOf(Array); | ||
expect(scales).toHaveLength(testResolutions.length); | ||
|
||
let testResolution = testResolutions[testResolutions.length - 1]; | ||
const roundScale = (Math.round(MapUtil.getScaleForResolution(testResolution ,'m')!)); | ||
const resolutionsFilter = (res: number) => { | ||
return res >= 19 || res <= 13; | ||
}; | ||
|
||
expect(scales[0]).toBe(roundScale); | ||
const expectedLength = testResolutions.filter(resolutionsFilter).length; | ||
|
||
TestUtil.removeMap(map); | ||
}); | ||
renderInMapContext(map, ( | ||
<ScaleCombo | ||
open | ||
resolutionsFilter={resolutionsFilter} | ||
/> | ||
)); | ||
|
||
it('creates options array from given map with filtered resolutions', () => { | ||
const testResolutions = [560, 280, 140, 70, 28, 19, 15, 14, 13, 9]; | ||
const map = TestUtil.createMap({ | ||
resolutions: testResolutions | ||
}); | ||
const options = screen.getAllByText((text, element) => element?.tagName === 'DIV' && /1:/.test(text)); | ||
|
||
// eslint-disable-next-line | ||
const resolutionsFilter = (res: number) => { | ||
return res >= 19 || res <= 13; | ||
}; | ||
|
||
const expectedLength = testResolutions.filter(resolutionsFilter).length; | ||
expect(options).toHaveLength(expectedLength); | ||
TestUtil.removeMap(map); | ||
}); | ||
|
||
const wrapper = TestUtil.mountComponent(ScaleCombo, { | ||
map: map, | ||
scales: [], | ||
resolutionsFilter | ||
}); | ||
it('zooms the map to the clicked scale', async () => { | ||
const map = TestUtil.createMap(); | ||
|
||
// Reset the scales array, as getOptionsFromMap() will be called in | ||
// constructor. | ||
wrapper.setState({scales: []}); | ||
renderInMapContext(map, | ||
<ScaleCombo | ||
scales={[100, 200, 300, 400, 500]} | ||
open | ||
/> | ||
); | ||
|
||
const instance = wrapper.instance() as ScaleCombo; | ||
const scales = instance.getOptionsFromMap(); | ||
expect(scales).toBeInstanceOf(Array); | ||
expect(scales).toHaveLength(expectedLength); | ||
expect(map.getView().getResolution()).toBeCloseTo(1); | ||
|
||
const roundScale = MapUtil.roundScale(MapUtil.getScaleForResolution( | ||
testResolutions[testResolutions.length - 2] ,'m')!); | ||
const entry = screen.getByText('1:300'); | ||
|
||
expect(scales[1]).toBe(roundScale); | ||
await userEvent.click(entry); | ||
|
||
TestUtil.removeMap(map); | ||
}); | ||
expect(map.getView().getResolution()).toBeCloseTo(0.08); | ||
TestUtil.removeMap(map); | ||
}); | ||
|
||
describe('#determineOptionKeyForZoomLevel', () => { | ||
it('is defined', () => { | ||
const map = TestUtil.createMap(); | ||
const wrapper = TestUtil.mountComponent(ScaleCombo, { | ||
map | ||
}); | ||
const instance = wrapper.instance() as ScaleCombo; | ||
expect(instance.determineOptionKeyForZoomLevel).not.toBeUndefined(); | ||
}); | ||
it('sets the correct scale on map zoom', () => { | ||
const map = TestUtil.createMap(); | ||
|
||
it('returns "undefied" for erronous zoom level or if exceeds number of valid zoom levels ', () => { | ||
const map = TestUtil.createMap(); | ||
const scaleArray = [100, 200, 300]; | ||
const wrapper = TestUtil.mountComponent(ScaleCombo, { | ||
map, | ||
scales: scaleArray | ||
}); | ||
renderInMapContext(map, | ||
<ScaleCombo | ||
scales={[100, 200, 300, 400, 500]} | ||
/> | ||
); | ||
|
||
let component = wrapper.instance() as ScaleCombo; | ||
expect(component.determineOptionKeyForZoomLevel(undefined)).toBeUndefined(); | ||
expect(component.determineOptionKeyForZoomLevel(17.123)).toBeUndefined(); | ||
expect(component.determineOptionKeyForZoomLevel(scaleArray.length)).toBeUndefined(); | ||
expect(map.getView().getResolution()).toBeCloseTo(1); | ||
|
||
TestUtil.removeMap(map); | ||
act(() => { | ||
map.getView().setZoom(4); | ||
}); | ||
|
||
it('returns matching key for zoom level', () => { | ||
const map = TestUtil.createMap(); | ||
const scaleArray = [100, 200, 300]; | ||
const wrapper = TestUtil.mountComponent(ScaleCombo, { | ||
map, | ||
scales: scaleArray | ||
}); | ||
const index = 1; | ||
let component = wrapper.instance() as ScaleCombo; | ||
expect(component.determineOptionKeyForZoomLevel(index)).toBe(scaleArray[index].toString()); | ||
|
||
TestUtil.removeMap(map); | ||
}); | ||
const entry = screen.getByText('1:100'); | ||
|
||
expect(entry).toBeVisible(); | ||
}); | ||
|
||
}); |
Oops, something went wrong.