/** * Copyright (c) 2019 Paul Armstrong */ import React from 'react'; import RelativeModal from '../RelativeModal'; import { Dimensions, MeasureOnSuccessCallback, Text, View } from 'react-native'; import { fireEvent, render } from '@testing-library/react'; describe('RelativeModal', () => { let viewRef; beforeEach(() => { viewRef = React.createRef(); render(); }); test('renders in a portal', () => { const portal = document.createElement('div'); portal.setAttribute('id', 'menuPortal'); document.body.appendChild(portal); jest .spyOn(viewRef.current, 'measureInWindow') .mockImplementation((fn: (x: number, y: number, width: number, height: number) => void): void => { fn(20, 100, 40, 30); }); const { queryAllByText } = render( tacos , { container: portal, } ); expect(queryAllByText('tacos')).toHaveLength(1); }); test('renders directly without a portal available', () => { jest .spyOn(viewRef.current, 'measureInWindow') .mockImplementation((fn: (x: number, y: number, width: number, height: number) => void): void => { fn(20, 100, 40, 30); }); const { queryAllByText } = render( tacos burritos ); expect(queryAllByText('tacos')).toHaveLength(1); expect(queryAllByText('burritos')).toHaveLength(1); }); test('clicking outside calls dismiss', () => { const handleDismiss = jest.fn(); const { getByTestId } = render( tacos ); fireEvent.touchStart(getByTestId('overlay')); fireEvent.touchEnd(getByTestId('overlay')); expect(handleDismiss).toHaveBeenCalledTimes(1); }); describe('render position', () => { test('avoids right window edge', () => { jest.spyOn(Dimensions, 'get').mockReturnValue({ width: 400, height: 400, scale: 1, fontScale: 1 }); jest.spyOn(View.prototype, 'measure').mockImplementation((fn: MeasureOnSuccessCallback): void => { fn(0, 0, 50, 30, 0, 0); }); jest .spyOn(viewRef.current, 'measureInWindow') .mockImplementation((fn: (x: number, y: number, width: number, height: number) => void): void => { fn(380, 200, 50, 10); }); const { getByRole } = render( tacos ); expect(getByRole('menu').style).toMatchObject({ top: '210px', left: '350px', }); }); test('avoids left window edge', () => { jest.spyOn(Dimensions, 'get').mockReturnValue({ width: 400, height: 400, scale: 1, fontScale: 1 }); jest.spyOn(View.prototype, 'measure').mockImplementation((fn: MeasureOnSuccessCallback): void => { fn(0, 0, 45, 30, 0, 0); }); jest .spyOn(viewRef.current, 'measureInWindow') .mockImplementation((fn: (x: number, y: number, width: number, height: number) => void): void => { fn(-10, 200, 20, 10); }); const { getByRole } = render( tacos ); expect(getByRole('menu').style).toMatchObject({ top: '210px', left: '0px', }); }); test('avoids bottom window edge', () => { jest.spyOn(Dimensions, 'get').mockReturnValue({ width: 400, height: 400, scale: 1, fontScale: 1 }); jest.spyOn(View.prototype, 'measure').mockImplementation((fn: MeasureOnSuccessCallback): void => { fn(0, 0, 45, 30, 0, 0); }); jest .spyOn(viewRef.current, 'measureInWindow') .mockImplementation((fn: (x: number, y: number, width: number, height: number) => void): void => { fn(200, 390, 20, 10); }); const { getByRole } = render( tacos ); expect(getByRole('menu').style).toMatchObject({ top: '360px', left: '200px', }); }); }); });