How to test this window resize hook?

211 Views Asked by At

I've created a widget component that can be embedded on a webapp as a script. It is not embedded in an IFrame therefore lives inside the webapp's window object. This embedded component is responsive and applies different margin classes(tailwind) based on its own resizing, but not on the resizing of the webapp's window itself, hence why I use a hook to make this component responsive and not media queries. The component and hook work how I intend them to work just wondering what the best way of testing this is? Any help appreciated!


import { useContainerWidth } from 'custom-hooks'

function EmbeddedComponent() {
  const { targetRef, containerWidth } = useContainerWidth()
 
  return (
       <div
         data-testid="test-embeddedComponent"
         className={clsx(
            containerWidth < 640 && 'my-0',
            containerWidth >= 640 && containerWidth < 768 && 'my-8',
            conatinerWidth >= 768 && containerWidth < 1024 && 'my-16',
            containerWidth >= 1024 && 'my-20'
         )}
       >
         <LayoutComponent containerWidth={containerWidth} />
       </div>
  )
}

function LayoutComponent({ containerWidth }: { containerWidth: number }) {
  return (
       <div>
           <div
             className={clsx(
                containerWidth < 640 && 'mb-2',
                containerWidth >= 640 && containerWidth < 768 && 'mb-7',
                conatinerWidth >= 768 && containerWidth < 1024 && 'mb-12',
                containerWidth >= 1024 && 'mb-14'
             )}
           >
              <TopComponent/>
           </div>
           <div>
              <BottomComponent/>
           </div>
       </div>
}


export function useContainerWidth() {
   const [containerWidth, setContainerWidth] = React.useState(400)
   const targetRef = React.useRef<HTMLDivElement>(null)

   React.useEffect(() => {
      if (window === undefined) return

      getContainerWidth()

      window.addEventListener('resize', getContainerWidth)

      function getContainerWidth() {
          if (targetRef.current) {
             setContainerWidth(targetRef.current.offsetWidth)
          }
      }

      return () => {
         window.removeEventListener('resize', getContainerWidth)
      }
   }, [containerWidth])

   return {
      containerWidth,
      targetRef
   }
}

This is how far I got with the testing but pretty clueless


it('should apply the right margin classes on resize', () => {

    ??? How do I test this ???
    ??? what do I do with targetRef ???

    const { result } = renderHook(() => useContainerWidth())
    jest.spyOn(window, ???).mockReturnValue(650)
    render(<EmbeddedComponent />)
    expect(screen.getByTestId('test-embeddedComponent')).toHaveClass('my-8')

    ??? Can I then set window size to something else like 800 ???
    expect(screen.getByTestId('test-embeddedComponent')).toHaveClass('my-16')
  }
)


// I've also tried this one

it('should apply the right margins for a window size', async () => {
    const { result } = renderHook(() => useContainerWidth())

    act(() => {
      window.resizeTo(650, 650)
    })

    await mockDelay(300)

    expect(result.current.containerWidth).toBe(650)
    expect(screen.getByTestId('test-embeddedComponent')).toHaveClass('my-8')
  })
0

There are 0 best solutions below