import React, { PropsWithChildren } from 'react'; import { EffectNumber, ParallaxController, ScrollAxis, } from 'parallax-controller'; import { render } from '@testing-library/react'; import { Parallax } from '.'; import { ParallaxProvider } from '../ParallaxProvider'; import { MockProvider } from '../../testUtils/MockProvider'; import expectRenderError from '../../testUtils/expectRenderError'; import { ALL_PARALLAX_PROPS } from '../../testUtils/tests.constants'; describe('given the component', () => { const preventError = (e: ErrorEvent) => e.preventDefault(); beforeEach(() => { window.addEventListener('error', preventError); }); afterEach(() => { window.removeEventListener('error', preventError); }); describe('when normal configurations are given', () => { it('then it renders correctly', () => { const { asFragment } = render(
); expect(asFragment()).toMatchSnapshot(); }); }); describe('when given children', () => { it('then it renders them', () => { const { getByTestId } = render(
); expect(getByTestId('children')).toBeInTheDocument(); }); }); describe('when given html attributes', () => { it('then it adds them to the returned div', () => { const { container, getByTestId } = render( ); expect(getByTestId('data-test-id')).toBeInTheDocument(); expect(container.querySelector('.my-class')).toBeInTheDocument(); expect(container.querySelector('#test-id')).toBeInTheDocument(); expect(getByTestId('data-test-id')).toHaveAttribute('aria-label', 'Cool'); expect(getByTestId('data-test-id')).toHaveAttribute('data-foo', 'bar'); expect(getByTestId('data-test-id').style.background).toBe('red'); }); }); describe('when not wrapped in the ParallaxProvider', () => { it('to throw because the ParallaxController is not available', () => { expectRenderError(
, 'Could not find `react-scroll-parallax` context value. Please ensure the component is wrapped in a ', 1 ); }); }); describe.each(ALL_PARALLAX_PROPS)('when the prop %s is given', (props) => { it('then it renders without issue and calls create element with props', () => { const controller = ParallaxController.init({ scrollAxis: ScrollAxis.vertical, }); controller.createElement = vi.fn(controller.createElement); function Wrapper(props: PropsWithChildren<{}>) { return ( {props.children} ); } const { asFragment } = render(, { wrapper: Wrapper, }); expect(asFragment()).toMatchSnapshot(); expect(controller.createElement).toHaveBeenCalledWith({ el: expect.any(HTMLElement), props, }); }); }); describe('when wrapped in the ParallaxProvider', () => { it('then is creates an element in the controller on mount', () => { const controller = ParallaxController.init({ scrollAxis: ScrollAxis.vertical, }); controller.createElement = vi.fn(controller.createElement); render( ); expect(controller.createElement).toHaveBeenCalledWith({ el: expect.any(HTMLElement), props: { translateY: [-100, 100] }, }); }); it('then it removes an element in the controller when unmounting', () => { const controller = ParallaxController.init({ scrollAxis: ScrollAxis.vertical, }); controller.removeElementById = vi.fn(); const { unmount } = render(
); const element = controller.getElements()[0]; unmount(); expect(controller.removeElementById).toHaveBeenCalledWith(element.id); }); it('then it updates an element in the controller when receiving relevant new props', () => { const controller = ParallaxController.init({ scrollAxis: ScrollAxis.vertical, }); controller.updateElementPropsById = vi.fn(); function Wrapper(props: PropsWithChildren<{}>) { return ( {props.children} ); } const { rerender } = render(, { wrapper: Wrapper, }); rerender( ); const element = controller.getElements()[0]; expect(controller.updateElementPropsById).toHaveBeenCalledWith( element.id, { disabled: false, translateX: [100, -100], translateY: [-100, 100], } ); const newProps = { disabled: false, x: [-40, -60] as EffectNumber, y: [10, 80] as EffectNumber, }; rerender( ); expect(controller.updateElementPropsById).toHaveBeenCalledWith( element.id, { disabled: false, translateX: [-40, -60], translateY: [10, 80], } ); // only update with valid props rerender( ); expect(controller.updateElementPropsById).toHaveBeenCalledTimes(2); }); it('then it handles disabled prop updates', () => { const controller = ParallaxController.init({ scrollAxis: ScrollAxis.vertical, }); controller.updateElementPropsById = vi.fn(); controller.resetElementStyles = vi.fn(); function Wrapper(props: PropsWithChildren<{}>) { return ( {props.children} ); } const { rerender } = render( , { wrapper: Wrapper, } ); rerender( ); const element = controller.getElements()[0]; expect(controller.resetElementStyles).toHaveBeenCalledWith(element); expect(controller.updateElementPropsById).toHaveBeenCalledWith( element.id, { disabled: true, translateX: [100, -100], translateY: [-100, 100], } ); }); it('then it resets styles on an element if the disabled prop is true', () => { const controller = ParallaxController.init({ scrollAxis: ScrollAxis.vertical, }); controller.resetElementStyles = vi.fn(); function Wrapper(props: PropsWithChildren<{}>) { return ( {props.children} ); } const offX: EffectNumber = [100, -100]; const offY: EffectNumber = [100, -100]; const { rerender } = render( , { wrapper: Wrapper, } ); rerender( ); expect(controller.resetElementStyles).toHaveBeenCalled(); }); }); });