From fe71c4696bf6cb23d02f010867573010e2f8a660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadeusz=20Miesi=C4=85c?= <tadeusz.miesiac@gmail.com> Date: Wed, 20 Dec 2023 11:14:43 +0100 Subject: [PATCH] refactor(getoverlayfeatures): extraced helper functions to separate files, added tests --- .../createOverlayGeometryFeature.test.ts | 49 +++++++++++++ .../createOverlayGeometryFeature.ts | 13 ++++ .../getColorByAvailableProperties.test.ts | 73 +++++++++++++++++++ .../getColorByAvailableProperties.ts | 18 +++++ .../overlaysLayer/getOverlayFeatures.ts | 32 +------- src/constants/backgrounds.ts | 1 + src/redux/backgrounds/background.selectors.ts | 3 +- 7 files changed, 159 insertions(+), 30 deletions(-) create mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.test.ts create mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.ts create mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.test.ts create mode 100644 src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.ts create mode 100644 src/constants/backgrounds.ts diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.test.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.test.ts new file mode 100644 index 00000000..8ee12221 --- /dev/null +++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.test.ts @@ -0,0 +1,49 @@ +import { createOverlayGeometryFeature } from './createOverlayGeometryFeature'; + +describe('createOverlayGeometryFeature', () => { + it('should create a feature with the correct geometry and style', () => { + const xMin = 0; + const yMin = 0; + const xMax = 10; + const yMax = 10; + const colorHexString = '#FF0000'; + + const feature = createOverlayGeometryFeature([xMin, yMin, xMax, yMax], colorHexString); + + expect(feature.getGeometry()!.getCoordinates()).toEqual([ + [ + [xMin, yMin], + [xMin, yMax], + [xMax, yMax], + [xMax, yMin], + [xMin, yMin], + ], + ]); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - getStyle() is not typed + expect(feature.getStyle().getFill().getColor()).toEqual(colorHexString); + }); + + it('should create a feature with the correct geometry and style when using a different color', () => { + const xMin = -5; + const yMin = -5; + const xMax = 5; + const yMax = 5; + const colorHexString = '#00FF00'; + + const feature = createOverlayGeometryFeature([xMin, yMin, xMax, yMax], colorHexString); + + expect(feature.getGeometry()!.getCoordinates()).toEqual([ + [ + [xMin, yMin], + [xMin, yMax], + [xMax, yMax], + [xMax, yMin], + [xMin, yMin], + ], + ]); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - getStyle() is not typed + expect(feature.getStyle().getFill().getColor()).toEqual(colorHexString); + }); +}); diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.ts new file mode 100644 index 00000000..90887721 --- /dev/null +++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.ts @@ -0,0 +1,13 @@ +import { Fill, Style } from 'ol/style'; +import { fromExtent } from 'ol/geom/Polygon'; +import Feature from 'ol/Feature'; +import type Polygon from 'ol/geom/Polygon'; + +export const createOverlayGeometryFeature = ( + [xMin, yMin, xMax, yMax]: number[], + color: string, +): Feature<Polygon> => { + const feature = new Feature({ geometry: fromExtent([xMin, yMin, xMax, yMax]) }); + feature.setStyle(new Style({ fill: new Fill({ color }) })); + return feature; +}; diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.test.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.test.ts new file mode 100644 index 00000000..6b71e37e --- /dev/null +++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.test.ts @@ -0,0 +1,73 @@ +import { OverlayBioEntityRender } from '@/types/OLrendering'; +import { getColorByAvailableProperties } from './getColorByAvailableProperties'; + +describe('getColorByAvailableProperties', () => { + const ENTITY: OverlayBioEntityRender = { + id: 0, + modelId: 0, + x1: 0, + y1: 0, + x2: 0, + y2: 0, + width: 0, + height: 0, + value: null, + overlayId: 0, + color: null, + }; + + const getHexTricolorGradientColorWithAlpha = jest.fn().mockReturnValue('#FFFFFF'); + const defaultColor = '#000000'; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should return the result of getHexTricolorGradientColorWithAlpha if entity has a value equal to 0', () => { + const entity = { ...ENTITY, value: 0 }; + const result = getColorByAvailableProperties( + entity, + getHexTricolorGradientColorWithAlpha, + defaultColor, + ); + + expect(result).toEqual('#FFFFFF'); + expect(getHexTricolorGradientColorWithAlpha).toHaveBeenCalledWith(entity.value); + }); + + it('should return the result of getHexTricolorGradientColorWithAlpha if entity has a value', () => { + const entity = { ...ENTITY, value: -0.2137 }; + const result = getColorByAvailableProperties( + entity, + getHexTricolorGradientColorWithAlpha, + defaultColor, + ); + + expect(result).toEqual('#FFFFFF'); + expect(getHexTricolorGradientColorWithAlpha).toHaveBeenCalledWith(entity.value); + }); + + it('should return the result of convertDecimalToHex if entity has a color', () => { + const entity = { ...ENTITY, color: { rgb: -65536, alpha: 0 } }; // red color + + const result = getColorByAvailableProperties( + entity, + getHexTricolorGradientColorWithAlpha, + defaultColor, + ); + + expect(result).toEqual('#ff0000'); + expect(getHexTricolorGradientColorWithAlpha).not.toHaveBeenCalled(); + }); + + it('should return the default color if entity has neither a value nor a color', () => { + const result = getColorByAvailableProperties( + ENTITY, + getHexTricolorGradientColorWithAlpha, + defaultColor, + ); + + expect(result).toEqual('#000000'); + expect(getHexTricolorGradientColorWithAlpha).not.toHaveBeenCalled(); + }); +}); diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.ts new file mode 100644 index 00000000..b7ac985f --- /dev/null +++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/getColorByAvailableProperties.ts @@ -0,0 +1,18 @@ +import { ZERO } from '@/constants/common'; +import type { GetHex3ColorGradientColorWithAlpha } from '@/hooks/useTriColorLerp'; +import { OverlayBioEntityRender } from '@/types/OLrendering'; +import { convertDecimalToHex } from '@/utils/convert/convertDecimalToHex'; + +export const getColorByAvailableProperties = ( + entity: OverlayBioEntityRender, + getHexTricolorGradientColorWithAlpha: GetHex3ColorGradientColorWithAlpha, + defaultColor: string, +): string => { + if (typeof entity.value === 'number') { + return getHexTricolorGradientColorWithAlpha(entity.value || ZERO); + } + if (entity.color) { + return convertDecimalToHex(entity.color.rgb); + } + return defaultColor; +}; diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/getOverlayFeatures.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/getOverlayFeatures.ts index 1cb81f70..a2a7fb43 100644 --- a/src/components/Map/MapViewer/utils/config/overlaysLayer/getOverlayFeatures.ts +++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/getOverlayFeatures.ts @@ -1,20 +1,10 @@ -import { ZERO } from '@/constants/common'; import type { GetHex3ColorGradientColorWithAlpha } from '@/hooks/useTriColorLerp'; import { OverlayBioEntityRender } from '@/types/OLrendering'; -import { convertDecimalToHex } from '@/utils/convert/convertDecimalToHex'; import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection'; -import Feature from 'ol/Feature'; -import Polygon, { fromExtent } from 'ol/geom/Polygon'; -import { Fill, Style } from 'ol/style'; - -export const createOverlayGeometryFeature = ( - [xMin, yMin, xMax, yMax]: number[], - color: string, -): Feature<Polygon> => { - const feature = new Feature({ geometry: fromExtent([xMin, yMin, xMax, yMax]) }); - feature.setStyle(new Style({ fill: new Fill({ color }) })); - return feature; -}; +import type Feature from 'ol/Feature'; +import type Polygon from 'ol/geom/Polygon'; +import { createOverlayGeometryFeature } from './createOverlayGeometryFeature'; +import { getColorByAvailableProperties } from './getColorByAvailableProperties'; type GetOverlayFeaturesProps = { bioEntities: OverlayBioEntityRender[]; @@ -23,20 +13,6 @@ type GetOverlayFeaturesProps = { defaultColor: string; }; -export const getColorByAvailableProperties = ( - entity: OverlayBioEntityRender, - getHexTricolorGradientColorWithAlpha: GetHex3ColorGradientColorWithAlpha, - defaultColor: string, -): string => { - if (entity.value) { - return getHexTricolorGradientColorWithAlpha(entity.value || ZERO); - } - if (entity.color) { - return convertDecimalToHex(entity.color.rgb); - } - return defaultColor; -}; - export const getOverlayFeatures = ({ bioEntities, pointToProjection, diff --git a/src/constants/backgrounds.ts b/src/constants/backgrounds.ts new file mode 100644 index 00000000..1bfb4619 --- /dev/null +++ b/src/constants/backgrounds.ts @@ -0,0 +1 @@ +export const EMPTY_BACKGROUND_NAME = 'Empty'; diff --git a/src/redux/backgrounds/background.selectors.ts b/src/redux/backgrounds/background.selectors.ts index 7c3d5924..b8443ab5 100644 --- a/src/redux/backgrounds/background.selectors.ts +++ b/src/redux/backgrounds/background.selectors.ts @@ -1,4 +1,5 @@ import { createSelector } from '@reduxjs/toolkit'; +import { EMPTY_BACKGROUND_NAME } from '@/constants/backgrounds'; import { mapDataSelector } from '../map/map.selectors'; import { rootSelector } from '../root/root.selectors'; @@ -37,8 +38,6 @@ export const currentBackgroundImagePathSelector = createSelector( image => (image ? image.path : ''), ); -const EMPTY_BACKGROUND_NAME = 'Empty'; - export const emptyBackgroundIdSelector = createSelector(backgroundsDataSelector, backgrounds => { const emptyBackground = backgrounds?.find( background => background.name === EMPTY_BACKGROUND_NAME, -- GitLab