/* eslint-disable react/prop-types */
import * as React from "react";
import { View } from "react-native";

import { render, fireEvent, cleanup } from "@testing-library/react-native";

import { DimensionsContext, DimensionsProvider } from "../";

describe("Dimensions Provider", () => {
  const windowWidth = 100;
  const windowHeight = 200;

  const TestComponent = (props) => {
    const { width, height } = React.useContext(DimensionsContext);

    React.useLayoutEffect(() => {
      props?.onLayout({ width, height });
    }, [height, width]);

    return <View style={{ width, height }} testID={"test-component-view"} />;
  };

  const TestingMule = ({ onLayout = () => null } = {}) => (
    <View testID="root-view">
      <DimensionsProvider>
        <TestComponent onLayout={onLayout} />
      </DimensionsProvider>
    </View>
  );

  afterEach(() => {
    cleanup();
  });

  afterAll(() => {
    jest.clearAllMocks();
  });

  it("Return correct dimensions", async () => {
    const wrapper = render(<TestingMule />);

    const onLayoutView = wrapper.getByTestId("on-layout-view");

    fireEvent(onLayoutView, "layout", {
      nativeEvent: {
        layout: {
          width: windowWidth,
          height: windowHeight,
        },
      },
    });

    const testComponentView = wrapper.getByTestId("test-component-view");

    expect(testComponentView.props.style.width).toBe(windowWidth);
    expect(testComponentView.props.style.height).toBe(windowHeight);
  });

  it("Notifies listener on dimensions change", () => {
    const onLayout = jest.fn();
    const wrapper = render(<TestingMule onLayout={onLayout} />);

    const onLayoutView = wrapper.getByTestId("on-layout-view");

    fireEvent(onLayoutView, "layout", {
      nativeEvent: {
        layout: {
          width: windowWidth,
          height: windowHeight,
        },
      },
    });

    expect(onLayout).toBeCalledWith(
      expect.objectContaining({
        width: windowWidth,
        height: windowHeight,
      })
    );
  });
});
