UNPKG

monday-ui-react-core

Version:

Official monday.com UI resources for application development in React.js

131 lines (111 loc) 4.21 kB
import React, { forwardRef, useRef, useEffect } from "react"; import { fireEvent, render, cleanup, act, screen } from "@testing-library/react"; import useMergeRefs from "./useMergeRefs"; import { sinon, expect } from "../test/test-helpers"; describe("useMergeRefs", () => { let Component; let internalRef; describe("set ref", () => { beforeEach(() => { Component = forwardRef((props, ref) => { internalRef = useRef(null); const mergedRef = useMergeRefs({ refs: [ref, internalRef] }); return ( <div {...props} ref={mergedRef}> Lorem ipsum dolor sit amet </div> ); }); }); afterEach(() => { internalRef = null; Component = null; cleanup(); }); it("should be able to render Component", () => { render(<Component />); }); it("should be able to set internal ref", () => { expect(internalRef).to.eq(null); render(<Component />); expect(internalRef.current.innerText).to.eq("Lorem ipsum dolor sit amet"); }); it("should be able to set object prop ref", () => { const propRef = {}; expect(internalRef).to.eq(null); render(<Component ref={propRef} />); expect(internalRef.current.innerText).to.eq("Lorem ipsum dolor sit amet"); expect(propRef.current.innerText).to.eq("Lorem ipsum dolor sit amet"); }); it("should be able to set function prop ref", () => { const state = {}; const propRef = ref => { state._ref = ref; }; expect(internalRef).to.eq(null); render(<Component ref={propRef} />); expect(internalRef.current.innerText).to.eq("Lorem ipsum dolor sit amet"); expect(state._ref.innerText).to.eq("Lorem ipsum dolor sit amet"); }); }); describe("call event listeners based on refs", () => { let innerRefCallbackStub; let outerRefCallbackStub; beforeEach(() => { innerRefCallbackStub = sinon.stub(); outerRefCallbackStub = sinon.stub(); Component = forwardRef((props, ref) => { internalRef = useRef(); const mergedRef = useMergeRefs({ refs: [ref, internalRef] }); useEffect(() => { internalRef.current.addEventListener("click", innerRefCallbackStub); return () => { internalRef.current.removeEventListener("click", innerRefCallbackStub); }; }, []); return ( <div {...props} ref={mergedRef}> Lorem ipsum dolor sit amet </div> ); }); }); afterEach(() => { cleanup(); internalRef = null; Component = null; innerRefCallbackStub.reset(); outerRefCallbackStub.reset(); }); it("should not call any listeners if element didn't had click event", () => { render(<Component />); expect(innerRefCallbackStub).to.not.be.called; }); it("should call click listener based on internal ref if element has been clicked", () => { render(<Component />); const element = screen.getByText("Lorem ipsum dolor sit amet"); act(() => fireEvent.click(element)); expect(innerRefCallbackStub).to.be.calledOnce; }); it("it should call both listeners if ref prop was passed and element has been clicked", () => { const propRef = {}; render(<Component ref={propRef} />); propRef.current.addEventListener("click", outerRefCallbackStub); const element = screen.getByText("Lorem ipsum dolor sit amet"); act(() => { fireEvent.click(element); }); propRef.current.removeEventListener("click", outerRefCallbackStub); expect(innerRefCallbackStub).to.be.calledOnce; expect(outerRefCallbackStub).to.be.calledOnce; }); it("it should not call any listener if ref prop was passed and element has not been clicked", () => { const propRef = {}; render(<Component ref={propRef} />); propRef.current.addEventListener("click", outerRefCallbackStub); propRef.current.removeEventListener("click", outerRefCallbackStub); expect(innerRefCallbackStub).to.not.be.called; expect(outerRefCallbackStub).to.not.be.called; }); }); });