From 695496124ba9702547306beb8fcf6d3f22dc6757 Mon Sep 17 00:00:00 2001
From: Mateusz Winiarczyk <mateusz.winiarczyk@appunite.com>
Date: Thu, 22 Feb 2024 17:43:26 +0100
Subject: [PATCH] feat(pins): add possibility to center map to pin after
 clicking pin icon

---
 ...BioEntitiesPinsListItem.component.test.tsx |  45 +++++++
 .../BioEntitiesPinsListItem.component.tsx     |   7 +-
 .../PinsListItem.component.test.tsx           |  52 ++++++++
 .../PinsListItem/PinsListItem.component.tsx   |   7 +-
 .../useVisiblePinsPolygonCoordinates.test.ts  | 123 ++++++++++++++++++
 5 files changed, 232 insertions(+), 2 deletions(-)
 create mode 100644 src/components/Map/Drawer/SearchDrawerWrapper/ResultsList/PinsList/PinsListItem/hooks/useVisiblePinsPolygonCoordinates.test.ts

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 9c245a24..d10ba567 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 9ede50c3..1ded6e3d 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 fdc457a0..cff97d8b 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 4dd3452d..1f5ec270 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 00000000..f4582609
--- /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],
+    ]);
+  });
+});
-- 
GitLab