diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000000000000000000000000000000000..033fa2fadf64f9739bbf052185fa2af9444dbba6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,10 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "printWidth": 100, + "arrowParens": "avoid", + "plugins": ["prettier-plugin-tailwindcss"], + "tailwindConfig": "./tailwind.config.ts", + "tailwindFunctions": ["twMerge"], + "tabWidth": 2 +} diff --git a/prettier.config.js b/prettier.config.js index 1b959334323fcd05515f269dcfc1b6f595745f48..eec5dca5c09d171184a2d30ee3bd9e029b5e32c2 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -9,4 +9,4 @@ const config = { tabWidth: 2, }; -module.exports = config; \ No newline at end of file +module.exports = config; diff --git a/src/components/FunctionalArea/MapNavigation/MapNavigation.component.test.tsx b/src/components/FunctionalArea/MapNavigation/MapNavigation.component.test.tsx index 601f8c31c777ebbf64fa7b981cbb5bbbe0da2d33..09a00a1a4265386b128a2c1ca32c83cf43d7a15c 100644 --- a/src/components/FunctionalArea/MapNavigation/MapNavigation.component.test.tsx +++ b/src/components/FunctionalArea/MapNavigation/MapNavigation.component.test.tsx @@ -1,11 +1,115 @@ +import { + InitialStoreState, + getReduxWrapperWithStore, +} from '@/utils/testing/getReduxWrapperWithStore'; +import { StoreType } from '@/redux/store'; +import { initialMapDataFixture, openedMapsThreeSubmapsFixture } from '@/redux/map/map.fixtures'; +import { act, render, screen, within } from '@testing-library/react'; +import { MapNavigation } from './MapNavigation.component'; + +const MAIN_MAP_ID = 5053; +const HISTAMINE_MAP_ID = 5052; + +const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => { + const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState); + + return ( + render( + <Wrapper> + <MapNavigation /> + </Wrapper>, + ), + { + store, + } + ); +}; + describe('MapNavigation - component', () => { - it.skip('should render list of currently opened maps, main map should not have close button', () => { - expect(true).toBe(false); + it('should render list of currently opened maps, main map should not have close button', async () => { + renderComponent({ + map: { + data: { ...initialMapDataFixture, openedMaps: openedMapsThreeSubmapsFixture }, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }); + + const mainMapButton = screen.getByRole('button', { name: 'Main map' }); + const mainMapCloseButton = await within(mainMapButton).queryByTestId('close-icon'); + expect(mainMapButton).toBeInTheDocument(); + expect(mainMapCloseButton).not.toBeInTheDocument(); + + const histamineMapButton = screen.getByRole('button', { name: 'Histamine signaling' }); + const histamineMapCloseButton = await within(histamineMapButton).getByTestId('close-icon'); + expect(histamineMapButton).toBeInTheDocument(); + expect(histamineMapCloseButton).toBeInTheDocument(); + + const prknMapButton = screen.getByRole('button', { name: 'PRKN substrates' }); + const prknMapCloseButton = await within(prknMapButton).getByTestId('close-icon'); + expect(prknMapButton).toBeInTheDocument(); + expect(prknMapCloseButton).toBeInTheDocument(); }); - it.skip('should close map tab when clicking on close button while', () => { - expect(true).toBe(false); + + it('should close map tab when clicking on close button while', async () => { + const { store } = renderComponent({ + map: { + data: { + ...initialMapDataFixture, + modelId: MAIN_MAP_ID, + openedMaps: openedMapsThreeSubmapsFixture, + }, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }); + + const histamineMapButton = screen.getByRole('button', { name: 'Histamine signaling' }); + const histamineMapCloseButton = await within(histamineMapButton).getByTestId('close-icon'); + await act(() => { + histamineMapCloseButton.click(); + }); + + const { + map: { + data: { modelId, openedMaps }, + }, + } = store.getState(); + + const isHistamineMapOpened = openedMaps.some(map => map.modelName === 'Histamine signaling'); + + expect(isHistamineMapOpened).toBe(false); + expect(modelId).toBe(MAIN_MAP_ID); }); - it.skip('should close map and open main map if closed currently selected map', () => { - expect(true).toBe(false); + + it('should close map and open main map if closed currently selected map', async () => { + const { store } = renderComponent({ + map: { + data: { + ...initialMapDataFixture, + modelId: HISTAMINE_MAP_ID, + openedMaps: openedMapsThreeSubmapsFixture, + }, + loading: 'succeeded', + error: { message: '', name: '' }, + }, + }); + + const histamineMapButton = screen.getByRole('button', { name: 'Histamine signaling' }); + const histamineMapCloseButton = await within(histamineMapButton).getByTestId('close-icon'); + await act(() => { + histamineMapCloseButton.click(); + }); + + const { + map: { + data: { modelId, openedMaps }, + }, + } = store.getState(); + + const isHistamineMapOpened = openedMaps.some(map => map.modelName === 'Histamine signaling'); + + expect(isHistamineMapOpened).toBe(false); + expect(modelId).toBe(MAIN_MAP_ID); }); }); diff --git a/src/components/Map/Drawer/SubmapsDrawer/SubmapsDrawer.test.tsx b/src/components/Map/Drawer/SubmapsDrawer/SubmapsDrawer.test.tsx index 884d1a17d2bbb9764694c9d779b6921385b015d8..12b9b40ee94a8f800588704a745d8acae4492217 100644 --- a/src/components/Map/Drawer/SubmapsDrawer/SubmapsDrawer.test.tsx +++ b/src/components/Map/Drawer/SubmapsDrawer/SubmapsDrawer.test.tsx @@ -6,9 +6,12 @@ import { act, render, screen } from '@testing-library/react'; import { StoreType } from '@/redux/store'; import { MODELS_MOCK_SHORT } from '@/models/mocks/modelsMock'; import { openedDrawerSubmapsFixture } from '@/redux/drawer/drawerFixture'; -import { initialMapDataFixture } from '@/redux/map/map.fixtures'; +import { initialMapDataFixture, openedMapsThreeSubmapsFixture } from '@/redux/map/map.fixtures'; import { SubmapsDrawer } from './SubmapsDrawer'; +const MAIN_MAP_ID = 5053; +const HISTAMINE_MAP_ID = 5052; + const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => { const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState); @@ -62,7 +65,7 @@ describe('SubmapsDrawer - component', () => { // eslint-disable-next-line no-magic-numbers expect(modelId).toBe(0); expect(openedMaps).not.toContainEqual({ - modelId: 5052, + modelId: HISTAMINE_MAP_ID, modelName: 'Histamine signaling', lastPosition: { x: 0, y: 0, z: 0 }, }); @@ -77,17 +80,42 @@ describe('SubmapsDrawer - component', () => { } = store.getState().map; expect(newOpenedMaps).toContainEqual({ - modelId: 5052, + modelId: HISTAMINE_MAP_ID, modelName: 'Histamine signaling', lastPosition: { x: 0, y: 0, z: 0 }, }); - // eslint-disable-next-line no-magic-numbers - expect(newModelId).toBe(5052); + + expect(newModelId).toBe(HISTAMINE_MAP_ID); }); - it.skip("should set map active if it's already opened", () => { - // const { store } = renderComponent({ - // models: { data: MODELS_MOCK_SHORT, loading: 'succeeded', error: { name: '', message: '' } }, - // map: { data: initialMapDataFixture, loading: 'succeeded', error: { name: '', message: '' } }, - // }); + it("should set map active if it's already opened", async () => { + const { store } = renderComponent({ + models: { data: MODELS_MOCK_SHORT, loading: 'succeeded', error: { name: '', message: '' } }, + map: { + data: { + ...initialMapDataFixture, + modelId: MAIN_MAP_ID, + openedMaps: openedMapsThreeSubmapsFixture, + }, + loading: 'succeeded', + error: { name: '', message: '' }, + }, + }); + + const openHistamineMapButton = screen.getByTestId('Histamine signaling-open'); + await act(() => { + openHistamineMapButton.click(); + }); + + const { + map: { + data: { modelId, openedMaps }, + }, + } = store.getState(); + + const histamineMap = openedMaps.filter(map => map.modelName === 'Histamine signaling'); + + // eslint-disable-next-line no-magic-numbers + expect(histamineMap.length).toBe(1); + expect(modelId).toBe(HISTAMINE_MAP_ID); }); }); diff --git a/src/redux/map/map.constants.ts b/src/redux/map/map.constants.ts index eaaaa21c64a98790b4700bbb41f65b1470881477..cc9663639b7ee71d3845134f6645430bca83a6b8 100644 --- a/src/redux/map/map.constants.ts +++ b/src/redux/map/map.constants.ts @@ -5,6 +5,7 @@ import { DEFAULT_MIN_ZOOM, DEFAULT_TILE_SIZE, } from '@/constants/map'; +import { Point } from '@/types/map'; import { MapData } from './map.types'; export const MAIN_MAP = 'Main map'; @@ -31,3 +32,4 @@ export const MAP_DATA_INITIAL_STATE: MapData = { }; export const MIDDLEWARE_ALLOWED_ACTIONS: string[] = ['map/setMapData', 'map/initMapData']; +export const DEFAULT_POSITION: Point = { x: 0, y: 0, z: 0 }; diff --git a/src/redux/map/map.fixtures.ts b/src/redux/map/map.fixtures.ts index eeed2745fbe9425a1fb12deae1e723675cb2958f..9b063c8d0b4b1904267aaa985c554b64c974d613 100644 --- a/src/redux/map/map.fixtures.ts +++ b/src/redux/map/map.fixtures.ts @@ -1,4 +1,14 @@ -import { MapData } from './map.types'; +import { MapData, OppenedMap } from './map.types'; + +export const openedMapsInitialValueFixture: OppenedMap[] = [ + { modelId: 0, modelName: 'Main map', lastPosition: { x: 0, y: 0, z: 0 } }, +]; + +export const openedMapsThreeSubmapsFixture: OppenedMap[] = [ + { modelId: 5053, modelName: 'Main map', lastPosition: { x: 0, y: 0, z: 0 } }, + { modelId: 5052, modelName: 'Histamine signaling', lastPosition: { x: 0, y: 0, z: 0 } }, + { modelId: 5054, modelName: 'PRKN substrates', lastPosition: { x: 0, y: 0, z: 0 } }, +]; export const initialMapDataFixture: MapData = { projectId: 'pdmap', @@ -18,5 +28,5 @@ export const initialMapDataFixture: MapData = { minZoom: 2, maxZoom: 9, }, - openedMaps: [{ modelId: 0, modelName: 'Main map', lastPosition: { x: 0, y: 0, z: 0 } }], + openedMaps: openedMapsInitialValueFixture, }; diff --git a/src/redux/map/map.thunks.test.ts b/src/redux/map/map.thunks.test.ts index b14e744dab577afaa1b8f25b56d76f2162053908..3297de3b41f56d5881be95af01a74767050f0907 100644 --- a/src/redux/map/map.thunks.test.ts +++ b/src/redux/map/map.thunks.test.ts @@ -80,7 +80,11 @@ describe('map thunks', () => { }); it('should return empty payload', () => { - expect(payload).toStrictEqual({}); + expect(payload).toStrictEqual({ + backgroundId: 0, + modelId: 0, + openedMaps: [{ modelId: 0, modelName: 'Main map', lastPosition: { x: 0, y: 0, z: 0 } }], + }); }); }); }); diff --git a/src/redux/map/map.thunks.ts b/src/redux/map/map.thunks.ts index e6d8fef456ef2f0bda91c46d99cd7c45347c192e..872e317987a5be7ebf557d7562f33eeba6757024 100644 --- a/src/redux/map/map.thunks.ts +++ b/src/redux/map/map.thunks.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-magic-numbers */ import { PROJECT_ID } from '@/constants'; import { createAsyncThunk } from '@reduxjs/toolkit'; import { backgroundsDataSelector } from '../backgrounds/background.selectors'; @@ -7,21 +8,20 @@ import { getModels } from '../models/models.thunks'; import { getAllPublicOverlaysByProjectId } from '../overlays/overlays.thunks'; import type { AppDispatch, RootState } from '../store'; import { InitMapDataActionPayload } from './map.types'; +import { DEFAULT_POSITION, MAIN_MAP } from './map.constants'; const getPayloadFromState = (state: RootState): InitMapDataActionPayload => { const FIRST = 0; const models = modelsDataSelector(state); const backgrounds = backgroundsDataSelector(state); - const modelId = models?.[FIRST]?.idObject; - const backgroundId = backgrounds?.[FIRST]?.id; - - if (!modelId || !backgroundId) { - return {}; - } + const modelId = models?.[FIRST]?.idObject || 0; + const backgroundId = backgrounds?.[FIRST]?.id || 0; + const openedMaps = [{ modelId, modelName: MAIN_MAP, lastPosition: DEFAULT_POSITION }]; return { modelId, backgroundId, + openedMaps, }; }; diff --git a/src/redux/map/map.types.ts b/src/redux/map/map.types.ts index 159388d3c06cef95dd2fe7bae558542570b69736..c49bab99ecf4149d84b11ee59ac5b5b8da6ab715 100644 --- a/src/redux/map/map.types.ts +++ b/src/redux/map/map.types.ts @@ -51,7 +51,11 @@ export type CloseMapActionPayload = Pick<OppenedMap, 'modelId'>; export type CloseMapAction = PayloadAction<CloseMapActionPayload>; -export type InitMapDataActionPayload = { modelId: number; backgroundId: number } | object; +export type InitMapDataActionPayload = { + modelId: number; + backgroundId: number; + openedMaps: OppenedMap[]; +}; export type InitMapDataAction = PayloadAction<SetMapDataAction>;