Skip to content
Snippets Groups Projects
Commit 51c0cbf6 authored by Adrian Orłów's avatar Adrian Orłów
Browse files

test: add tests for modal render overview image

parent 6c6b5035
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!75feat: add overview image render layer (MIN-178)
Pipeline #82851 passed
Showing
with 622 additions and 24 deletions
import { BASE_MAP_IMAGES_URL } from '@/constants';
import { projectFixture } from '@/models/fixtures/projectFixture';
import { MODAL_INITIAL_STATE_MOCK } from '@/redux/modal/modal.mock';
import { PROJECT_OVERVIEW_IMAGE_MOCK } from '@/redux/project/project.mock';
import { StoreType } from '@/redux/store';
import {
InitialStoreState,
getReduxWrapperWithStore,
} from '@/utils/testing/getReduxWrapperWithStore';
import { render, screen } from '@testing-library/react';
import { OverviewImagesModal } from './OverviewImagesModal.component';
jest.mock('./utils/useOverviewImageSize', () => ({
__esModule: true,
useOverviewImageSize: jest.fn().mockImplementation(() => ({
width: 200,
height: 300,
})),
}));
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
return (
render(
<Wrapper>
<OverviewImagesModal />
</Wrapper>,
),
{
store,
}
);
};
describe('OverviewImagesModal - component', () => {
describe('when currentImage is NOT valid', () => {
beforeEach(() => {
renderComponent({
project: {
data: {
...projectFixture,
overviewImageViews: [],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: 0,
},
},
});
});
it('should not render component', () => {
const element = screen.queryByTestId('overview-images-modal');
expect(element).toBeNull();
});
});
describe('when currentImage is valid', () => {
beforeEach(() => {
renderComponent({
project: {
data: {
...projectFixture,
overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: PROJECT_OVERVIEW_IMAGE_MOCK.idObject,
},
},
});
});
it('should render component', () => {
const element = screen.queryByTestId('overview-images-modal');
expect(element).not.toBeNull();
});
it('should render image with valid src', () => {
const imageElement = screen.getByAltText('overview');
const result = `${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`;
expect(imageElement.getAttribute('src')).toBe(result);
});
it('should render image wrapper with valid size', () => {
const imageElement = screen.getByAltText('overview');
const wrapperElement = imageElement.closest('div');
const wrapperStyle = wrapperElement?.getAttribute('style');
expect(wrapperStyle).toBe('width: 200px; height: 300px;');
});
});
});
......@@ -16,8 +16,16 @@ export const OverviewImagesModal: React.FC = () => {
setContainerRect(node.getBoundingClientRect());
}, []);
if (!imageUrl) {
return null;
}
return (
<div className="flex h-full w-full items-center justify-center bg-white" ref={handleRect}>
<div
data-testid="overview-images-modal"
className="flex h-full w-full items-center justify-center bg-white"
ref={handleRect}
>
<div className="relative" style={{ width, height }}>
<img alt="overview" className="block h-full w-full" src={imageUrl} />
{/* TODO: interactions - clickable elements (in next task) */}
......
import { getFinalImageSize } from './getFinalImageSize';
describe('getFinalImageSize - util', () => {
const cases = [
[
{ width: 0, height: 0 },
{ width: 0, height: 0 },
{ width: 0, height: 0, sizeFactor: 0 },
],
[
{ width: 100, height: 100 },
{ width: 100, height: 100 },
{ width: 100, height: 100, sizeFactor: 1 },
],
[
{ width: 100, height: 100 },
{ width: 200, height: 250 },
{ width: 80, height: 100, sizeFactor: 0.4 },
],
[
{ width: 10, height: 40 },
{ width: 40, height: 60 },
{ width: 10, height: 15, sizeFactor: 0.25 },
],
];
it.each(cases)(
'should return valid size and size factor',
(containerSize, maxImageSize, finalSize) => {
expect(getFinalImageSize(containerSize, maxImageSize)).toStrictEqual(finalSize);
},
);
});
import { ZERO } from '@/constants/common';
import { ImageContainerSize, OverviewImageSize } from '../OverviewImageModal.types';
interface GetFinalImageSizeResult extends OverviewImageSize {
sizeFactor: number;
}
export const getFinalImageSize = (
containerSize: ImageContainerSize,
maxImageSize: OverviewImageSize,
): GetFinalImageSizeResult => {
const maxHeight = Math.min(containerSize.height, maxImageSize.height);
const maxWidth = Math.min(containerSize.width, maxImageSize.width);
const heightSizeFactor = maxHeight / maxImageSize.height;
const widthSizeFactor = maxWidth / maxImageSize.width;
const sizeFactor = Math.min(heightSizeFactor, widthSizeFactor);
const width = maxImageSize.width * sizeFactor;
const height = maxImageSize.height * sizeFactor;
return {
height: height || ZERO,
width: width || ZERO,
sizeFactor: sizeFactor || ZERO,
};
};
import { BASE_MAP_IMAGES_URL } from '@/constants';
import { DEFAULT_OVERVIEW_IMAGE_SIZE } from '@/constants/project';
import { projectFixture } from '@/models/fixtures/projectFixture';
import { MODAL_INITIAL_STATE_MOCK } from '@/redux/modal/modal.mock';
import { PROJECT_OVERVIEW_IMAGE_MOCK } from '@/redux/project/project.mock';
import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
import { renderHook } from '@testing-library/react';
import { useOverviewImage } from './useOverviewImage';
describe('useOverviewImage - hook', () => {
describe('when image data is invalid', () => {
const { Wrapper } = getReduxWrapperWithStore({
project: {
data: {
...projectFixture,
overviewImageViews: [],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: 0,
},
},
});
const { result } = renderHook(() => useOverviewImage({ containerRect: undefined }), {
wrapper: Wrapper,
});
it('should return default size of image and empty imageUrl', () => {
expect(result.current).toStrictEqual({
imageUrl: '',
size: DEFAULT_OVERVIEW_IMAGE_SIZE,
});
});
});
describe('when containerReact is undefined', () => {
const { Wrapper } = getReduxWrapperWithStore({
project: {
data: {
...projectFixture,
overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: PROJECT_OVERVIEW_IMAGE_MOCK.idObject,
},
},
});
const { result } = renderHook(() => useOverviewImage({ containerRect: undefined }), {
wrapper: Wrapper,
});
it('should return default size of image and valid imageUrl', () => {
const imageUrl = `${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`;
expect(result.current).toStrictEqual({
imageUrl,
size: DEFAULT_OVERVIEW_IMAGE_SIZE,
});
});
});
describe('when containerReact is valid', () => {
const { Wrapper } = getReduxWrapperWithStore({
project: {
data: {
...projectFixture,
overviewImageViews: [
{
...PROJECT_OVERVIEW_IMAGE_MOCK,
height: 500,
width: 500,
},
],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: PROJECT_OVERVIEW_IMAGE_MOCK.idObject,
},
},
});
const { result } = renderHook(
() => useOverviewImage({ containerRect: { width: 100, height: 200 } as DOMRect }),
{
wrapper: Wrapper,
},
);
it('should return size of image and valid imageUrl', () => {
const imageUrl = `${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`;
expect(result.current).toStrictEqual({
imageUrl,
size: { height: 100, width: 100, sizeFactor: 0.2 },
});
});
});
});
/* eslint-disable no-magic-numbers */
import { DEFAULT_OVERVIEW_IMAGE_SIZE } from '@/constants/project';
import { projectFixture } from '@/models/fixtures/projectFixture';
import { MODAL_INITIAL_STATE_MOCK } from '@/redux/modal/modal.mock';
import { PROJECT_OVERVIEW_IMAGE_MOCK } from '@/redux/project/project.mock';
import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
import { renderHook } from '@testing-library/react';
import { useOverviewImageSize } from './useOverviewImageSize';
describe('useOverviewImageSize - hook', () => {
describe('when currentImage is not valid', () => {
const { Wrapper } = getReduxWrapperWithStore({
project: {
data: {
...projectFixture,
overviewImageViews: [],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: 0,
},
},
});
const { result } = renderHook(
() => useOverviewImageSize({ containerRect: { width: 800, height: 600 } as DOMRect }),
{
wrapper: Wrapper,
},
);
it('should return default value', () => {
expect(result.current).toStrictEqual(DEFAULT_OVERVIEW_IMAGE_SIZE);
});
});
describe('when containerRect is not valid', () => {
const { Wrapper } = getReduxWrapperWithStore({
project: {
data: {
...projectFixture,
overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: PROJECT_OVERVIEW_IMAGE_MOCK.idObject,
},
},
});
const { result } = renderHook(() => useOverviewImageSize({ containerRect: undefined }), {
wrapper: Wrapper,
});
it('should return default value', () => {
expect(result.current).toStrictEqual(DEFAULT_OVERVIEW_IMAGE_SIZE);
});
});
describe('when data is valid', () => {
const { Wrapper } = getReduxWrapperWithStore({
project: {
data: {
...projectFixture,
overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: PROJECT_OVERVIEW_IMAGE_MOCK.idObject,
},
},
});
const { result } = renderHook(
() => useOverviewImageSize({ containerRect: { width: 1600, height: 1000 } as DOMRect }),
{
wrapper: Wrapper,
},
);
const { height, width, sizeFactor } = result.current;
it('should return calculated height, width, sizeFactor', () => {
expect(height).toBeCloseTo(1000);
expect(width).toBeCloseTo(1429.7);
expect(sizeFactor).toBeCloseTo(0.247);
});
});
});
import { DEFAULT_OVERVIEW_IMAGE_SIZE } from '@/constants/project';
import { currentOverviewImageSelector } from '@/redux/project/project.selectors';
import { useSelector } from 'react-redux';
import { ImageContainerSize, OverviewImageSize } from '../OverviewImageModal.types';
import { OverviewImageSize } from '../OverviewImageModal.types';
import { getFinalImageSize } from './getFinalImageSize';
interface UseOverviewImageArgs {
containerRect?: DOMRect;
......@@ -11,27 +12,6 @@ interface UseOverviewImageResult extends OverviewImageSize {
sizeFactor: number;
}
const getFinalImageSize = (
containerSize: ImageContainerSize,
maxImageSize: OverviewImageSize,
): UseOverviewImageResult => {
const maxHeight = Math.min(containerSize.height, maxImageSize.height);
const maxWidth = Math.min(containerSize.width, maxImageSize.width);
const heightSizeFactor = maxHeight / maxImageSize.height;
const widthSizeFactor = maxWidth / maxImageSize.width;
const sizeFactor = Math.min(heightSizeFactor, widthSizeFactor);
const width = maxImageSize.width * sizeFactor;
const height = maxImageSize.height * sizeFactor;
return {
height,
width,
sizeFactor,
};
};
export const useOverviewImageSize = ({
containerRect,
}: UseOverviewImageArgs): UseOverviewImageResult => {
......
import { BASE_MAP_IMAGES_URL } from '@/constants';
import { projectFixture } from '@/models/fixtures/projectFixture';
import { MODAL_INITIAL_STATE_MOCK } from '@/redux/modal/modal.mock';
import { PROJECT_OVERVIEW_IMAGE_MOCK } from '@/redux/project/project.mock';
import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
import { renderHook } from '@testing-library/react';
import { useOverviewImageUrl } from './useOverviewImageUrl';
describe('useOverviewImageUrl - hook', () => {
describe('when currentImage data is valid', () => {
const { Wrapper } = getReduxWrapperWithStore({
project: {
data: {
...projectFixture,
overviewImageViews: [],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: 0,
},
},
});
it('should return valid url', () => {
const { result } = renderHook(() => useOverviewImageUrl(), { wrapper: Wrapper });
expect(result.current).toBe('');
});
});
describe('when currentImage data is valid', () => {
const { Wrapper } = getReduxWrapperWithStore({
project: {
data: {
...projectFixture,
overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
},
loading: 'succeeded',
error: { message: '', name: '' },
},
modal: {
...MODAL_INITIAL_STATE_MOCK,
overviewImagesState: {
imageId: PROJECT_OVERVIEW_IMAGE_MOCK.idObject,
},
},
});
it('should return valid url', () => {
const { result } = renderHook(() => useOverviewImageUrl(), { wrapper: Wrapper });
expect(result.current).toBe(
`${BASE_MAP_IMAGES_URL}/map_images/${PROJECT_OVERVIEW_IMAGE_MOCK.filename}`,
);
});
});
});
......@@ -5,5 +5,5 @@ export const DEFAULT_OVERVIEW_IMAGE_HEIGHT = 500;
export const DEFAULT_OVERVIEW_IMAGE_SIZE = {
width: DEFAULT_OVERVIEW_IMAGE_WIDTH,
height: DEFAULT_OVERVIEW_IMAGE_HEIGHT,
sizeFactor: 0,
sizeFactor: 1,
};
import { DEFAULT_ERROR } from '@/constants/errors';
import { OverviewImageView } from '@/types/models';
import { ProjectState } from './project.types';
export const PROJECT_STATE_INITIAL_MOCK: ProjectState = {
......@@ -6,3 +7,165 @@ export const PROJECT_STATE_INITIAL_MOCK: ProjectState = {
loading: 'idle',
error: DEFAULT_ERROR,
};
export const PROJECT_OVERVIEW_IMAGE_MOCK: OverviewImageView = {
idObject: 440,
filename: '9d4911bdeeea752f076e57a91d9b1f45/biolayout_main_root.png',
width: 5776,
height: 4040,
links: [
{
idObject: 2062,
polygon: [
{
x: 515,
y: 2187,
},
{
x: 1073,
y: 2187,
},
{
x: 1073,
y: 2520,
},
{
x: 515,
y: 2520,
},
],
zoomLevel: 4,
modelPoint: {
x: 3473,
y: 5871,
},
modelLinkId: 5053,
type: 'OverviewModelLink',
},
{
idObject: 2063,
polygon: [
{
x: 2410,
y: 1360,
},
{
x: 2692,
y: 1360,
},
{
x: 2692,
y: 1570,
},
{
x: 2410,
y: 1570,
},
],
imageLinkId: 435,
type: 'OverviewImageLink',
},
{
idObject: 2064,
polygon: [
{
x: 2830,
y: 497,
},
{
x: 3256,
y: 497,
},
{
x: 3256,
y: 832,
},
{
x: 2830,
y: 832,
},
],
zoomLevel: 5,
modelPoint: {
x: 8081,
y: 1240,
},
modelLinkId: 5053,
type: 'OverviewModelLink',
},
{
idObject: 2065,
polygon: [
{
x: 3232,
y: 2259,
},
{
x: 3520,
y: 2259,
},
{
x: 3520,
y: 2456,
},
{
x: 3232,
y: 2456,
},
],
imageLinkId: 433,
type: 'OverviewImageLink',
},
{
idObject: 2066,
polygon: [
{
x: 4205,
y: 761,
},
{
x: 4625,
y: 761,
},
{
x: 4625,
y: 1102,
},
{
x: 4205,
y: 1102,
},
],
zoomLevel: 5,
modelPoint: {
x: 7488,
y: 11986,
},
modelLinkId: 5053,
type: 'OverviewModelLink',
},
{
idObject: 2067,
polygon: [
{
x: 4960,
y: 1971,
},
{
x: 5241,
y: 1971,
},
{
x: 5241,
y: 2163,
},
{
x: 4960,
y: 2163,
},
],
imageLinkId: 434,
type: 'OverviewImageLink',
},
],
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment