diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.test.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.test.tsx index 9c245a247ee17a1d0ae73d10b5d509ae3db9656a..d10ba567c9fff0d174a8d04d32da4a212e978ce6 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.test.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.test.tsx @@ -7,6 +7,9 @@ import { import { bioEntitiesContentFixture } from '@/models/fixtures/bioEntityContentsFixture'; import { StoreType } from '@/redux/store'; import { BioEntity } from '@/types/models'; +import { act } from 'react-dom/test-utils'; +import { MAP_INITIAL_STATE } from '@/redux/map/map.constants'; +import { DEFAULT_MAX_ZOOM } from '@/constants/map'; import { BioEntitiesPinsListItem } from './BioEntitiesPinsListItem.component'; const BIO_ENTITY = bioEntitiesContentFixture[0].bioEntity; @@ -84,4 +87,46 @@ describe('BioEntitiesPinsListItem - component ', () => { expect(screen.getByText(secondPinReferenceType, { exact: false })).toBeInTheDocument(); expect(screen.getByText(secondPinReferenceResource, { exact: false })).toBeInTheDocument(); }); + it('should center map to pin coordinates after click on pin icon', async () => { + const { store } = renderComponent(BIO_ENTITY.name, BIO_ENTITY, { + map: { + ...MAP_INITIAL_STATE, + data: { + ...MAP_INITIAL_STATE.data, + modelId: 5052, + size: { + width: 256, + height: 256, + tileSize: 256, + minZoom: 1, + maxZoom: 1, + }, + position: { + initial: { + x: 0, + y: 0, + z: 2, + }, + last: { + x: 1, + y: 1, + z: 3, + }, + }, + }, + }, + }); + const button = screen.getByTestId('center-to-pin-button'); + expect(button).toBeInTheDocument(); + + act(() => { + button.click(); + }); + + expect(store.getState().map.data.position.last).toEqual({ + x: BIO_ENTITY.x, + y: BIO_ENTITY.y, + z: DEFAULT_MAX_ZOOM, + }); + }); }); diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.tsx index 9ede50c32f507e54aec266cb6cb20a361fe63311..1ded6e3dd2f3dbabeeef738930e47a7103e17e28 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/BioEntitiesResultsList/BioEntitiesPinsList/BioEntitiesPinsListItem/BioEntitiesPinsListItem.component.tsx @@ -32,7 +32,12 @@ export const BioEntitiesPinsListItem = ({ className="mb-4 flex w-full flex-col gap-3 rounded-lg border-[1px] border-solid border-greyscale-500 p-4" > <div className="flex w-full flex-row items-center gap-2"> - <button type="button" onClick={handleCenterMapToPin} className="mr-2 shrink-0"> + <button + type="button" + onClick={handleCenterMapToPin} + className="mr-2 shrink-0" + data-testid="center-to-pin-button" + > <Icon name="pin" className={getPinColor('bioEntity')} /> </button> <p> diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.test.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.test.tsx index fdc457a0a2a6b776dcf6fb1381e79468c8624c4f..cff97d8b721a5e7023a8e26504afcc747174e606 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.test.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.test.tsx @@ -10,8 +10,27 @@ import { } from '@/utils/testing/getReduxWrapperWithStore'; import { render, screen } from '@testing-library/react'; // import { MODELS_MOCK_SHORT } from '@/models/mocks/modelsMock'; +import { act } from 'react-dom/test-utils'; import { PinTypeWithNone } from '../PinsList.types'; import { PinsListItem } from './PinsListItem.component'; +import { useVisiblePinsPolygonCoordinates } from './hooks/useVisiblePinsPolygonCoordinates'; + +const setBounds = jest.fn(); + +setBounds.mockImplementation(() => {}); +jest.mock('../../../../../../../utils/map/useSetBounds', () => ({ + _esModule: true, + useSetBounds: (): jest.Mock => setBounds, +})); + +const useVisiblePinsPolygonCoordinatesMock = useVisiblePinsPolygonCoordinates as jest.Mock; + +jest.mock('./hooks/useVisiblePinsPolygonCoordinates', () => ({ + _esModule: true, + useVisiblePinsPolygonCoordinates: jest.fn(), +})); + +setBounds.mockImplementation(() => {}); const DRUGS_PIN = { name: drugsFixture[0].targets[0].name, @@ -111,4 +130,37 @@ describe('PinsListItem - component ', () => { expect(screen.queryByText('Available in submaps:')).toBeNull(); }); + it('should not call setBounds if coordinates do not exist', () => { + useVisiblePinsPolygonCoordinatesMock.mockImplementation(() => undefined); + + renderComponent(DRUGS_PIN.name, DRUGS_PIN.pin, 'drugs'); + + const buttonCenterMapToPin = screen.getByTestId('center-to-pin'); + + expect(buttonCenterMapToPin).toBeInTheDocument(); + + act(() => { + buttonCenterMapToPin.click(); + }); + + expect(setBounds).not.toHaveBeenCalled(); + }); + it('should call setBounds if coordinates exist', () => { + useVisiblePinsPolygonCoordinatesMock.mockImplementation(() => [ + [292, 333], + [341, 842], + ]); + + renderComponent(DRUGS_PIN.name, DRUGS_PIN.pin, 'drugs'); + + const buttonCenterMapToPin = screen.getByTestId('center-to-pin'); + + expect(buttonCenterMapToPin).toBeInTheDocument(); + + act(() => { + buttonCenterMapToPin.click(); + }); + + expect(setBounds).toHaveBeenCalled(); + }); }); diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.tsx b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.tsx index 4dd3452dd0ad97dc06030ef7212cce0777c29c07..1f5ec270c52f3f3b55a3ab99055801c0e3deed67 100644 --- a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.tsx +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/PinsListItem.component.tsx @@ -44,7 +44,12 @@ export const PinsListItem = ({ name, type, pin }: PinsListItemProps): JSX.Elemen return ( <div className="mb-4 flex w-full flex-col gap-3 rounded-lg border-[1px] border-solid border-greyscale-500 p-4"> <div className="flex w-full flex-row items-center gap-2"> - <button type="button" className="mr-2 shrink-0" onClick={handleCenterMapToPin}> + <button + type="button" + className="mr-2 shrink-0" + onClick={handleCenterMapToPin} + data-testid="center-to-pin" + > <Icon name="pin" className={getPinColor(type)} /> </button> <p> diff --git a/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/hooks/useVisiblePinsPolygonCoordinates.test.ts b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/hooks/useVisiblePinsPolygonCoordinates.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..f45826095806be323410a5ce0176199c35d1786d --- /dev/null +++ b/src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/hooks/useVisiblePinsPolygonCoordinates.test.ts @@ -0,0 +1,123 @@ +/* eslint-disable no-magic-numbers */ +import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore'; +import { renderHook } from '@testing-library/react'; +import { MAP_INITIAL_STATE } from '@/redux/map/map.constants'; +import { bioEntityContentFixture } from '@/models/fixtures/bioEntityContentsFixture'; +import { useVisiblePinsPolygonCoordinates } from './useVisiblePinsPolygonCoordinates'; + +describe('useVisiblePinsPolygonCoordinates - hook', () => { + it('should return undefined if receives empty array', () => { + const { Wrapper } = getReduxWrapperWithStore({ + map: { + ...MAP_INITIAL_STATE, + data: { + ...MAP_INITIAL_STATE.data, + modelId: 5052, + size: { + width: 256, + height: 256, + tileSize: 256, + minZoom: 1, + maxZoom: 1, + }, + }, + }, + }); + + const { result } = renderHook(() => useVisiblePinsPolygonCoordinates([]), { + wrapper: Wrapper, + }); + + expect(result.current).toBe(undefined); + }); + it('should return undefined if received array does not contain bioEntities with current map id', () => { + const { Wrapper } = getReduxWrapperWithStore({ + map: { + ...MAP_INITIAL_STATE, + data: { + ...MAP_INITIAL_STATE.data, + modelId: 5052, + size: { + width: 256, + height: 256, + tileSize: 256, + minZoom: 1, + maxZoom: 1, + }, + }, + }, + }); + + const { result } = renderHook( + () => + useVisiblePinsPolygonCoordinates([ + { + ...bioEntityContentFixture.bioEntity, + model: 52, + }, + { + ...bioEntityContentFixture.bioEntity, + model: 51, + }, + ]), + { + wrapper: Wrapper, + }, + ); + + expect(result.current).toBe(undefined); + }); + it('should return coordinates if received array contain bioEntities with current map id', () => { + const { Wrapper } = getReduxWrapperWithStore({ + map: { + ...MAP_INITIAL_STATE, + data: { + ...MAP_INITIAL_STATE.data, + modelId: 5052, + size: { + width: 256, + height: 256, + tileSize: 256, + minZoom: 1, + maxZoom: 1, + }, + }, + }, + }); + + const { result } = renderHook( + () => + useVisiblePinsPolygonCoordinates([ + { + ...bioEntityContentFixture.bioEntity, + model: 5051, + x: 97, + y: 53, + z: 1, + }, + { + ...bioEntityContentFixture.bioEntity, + model: 5052, + x: 12, + y: 25, + z: 1, + }, + { + ...bioEntityContentFixture.bioEntity, + model: 5052, + x: 16, + y: 16, + z: 1, + }, + ]), + { + wrapper: Wrapper, + }, + ); + + expect(result.current).toEqual([ + [-18158992, 16123932], + [-17532820, 17532820], + ]); + }); +});