import { render, waitFor } from '@testing-library/react';
import omit from 'lodash.omit';
import { ReactElement, Suspense } from 'react';
import { Marker } from './marker';
import { NaverMapContext } from '../contexts/naver-map';
const map = {} as naver.maps.Map;
function renderOverlay(overlay: ReactElement) {
return render(overlay, {
wrapper: ({ children }) => (
{children}
),
});
}
const mockPosition = { equals: jest.fn(() => false) };
let options = {} as naver.maps.MarkerOptions;
const mockMethods = {
getMap: jest.fn(),
setMap: jest.fn(),
getOptions: jest.fn((key: keyof naver.maps.MarkerOptions) => Object.assign({ [key]: options[key] })),
setOptions: jest.fn((opt: any) => {
Object.assign(options, opt, { position: mockPosition });
}),
getPosition: jest.fn(() => mockPosition),
setPosition: jest.fn(),
};
const mockMarker = jest.fn().mockImplementation((opt) => {
Object.assign(options, opt, { position: mockPosition });
return mockMethods;
});
describe('', () => {
beforeEach(() => {
options = {} as naver.maps.MarkerOptions;
mockMarker.mockClear();
Object.values(mockMethods).forEach(mock => mock.mockClear());
// @ts-expect-error mocking navermaps client loader
window.naver = { maps: { Marker: mockMarker } };
});
it('should currectly handle options without props', async () => {
const { rerender, unmount } = renderOverlay();
await waitFor(() => expect(window.naver.maps).toBeTruthy());
expect(mockMethods.setMap).toBeCalledWith(map);
expect(mockMethods.setPosition).not.toBeCalled();
expect(mockMethods.setOptions).not.toBeCalled();
const position = {} as naver.maps.Point;
rerender();
expect(mockMethods.setPosition).toBeCalledWith(position);
unmount();
expect(mockMethods.setMap).toBeCalledWith(null);
});
it('should currectly handle options with props', () => {
const position = {} as naver.maps.Point;
const animation = 0;
const icon = '';
const shape = {} as naver.maps.MarkerShape;
const title = 'title';
const cursor = '';
const clickable = true;
const draggable = true;
const visible = true;
const zIndex = 0;
const { rerender } = renderOverlay();
expect(mockMethods.setMap).toBeCalledWith(map);
expect(omit(options, ['position'])).toEqual({
animation,
icon,
shape,
title,
cursor,
clickable,
draggable,
visible,
zIndex,
});
const diffPosition1 = {} as naver.maps.Coord;
const diffTitle1 = 'title1';
const sameClickable1 = true;
rerender();
expect(mockMethods.setPosition).toBeCalledWith(diffPosition1);
expect(mockMethods.setOptions).toBeCalledWith({ title: diffTitle1 });
});
it('should ignore change when uncontrolled props is set', () => {
const position = {} as naver.maps.Point;
const title = 'title';
const { rerender } = renderOverlay();
const position1 = {} as naver.maps.Coord;
const title1 = 'title1';
// position, defaultPosition 어느것이 변경되더라도 position이 변경되지 않아야한다.
const prevCallCount = mockMethods.setPosition.mock.calls.length;
rerender();
expect(prevCallCount).toBe(mockMethods.setPosition.mock.calls.length);
expect(mockMethods.setOptions).toBeCalledWith({ title: title1 });
});
it('should ignore position change when position is equal', () => {
const position = {} as naver.maps.Point;
const { rerender } = renderOverlay();
const prevCallCount = mockMethods.setPosition.mock.calls.length;
mockPosition.equals.mockImplementationOnce(() => true);
rerender();
expect(prevCallCount).toBe(mockMethods.setPosition.mock.calls.length);
});
});