import React from 'react';
import PropTypes from 'prop-types';
import { shallow, configure } from 'enzyme';
import { spy } from 'sinon';
import Adapter from 'enzyme-adapter-react-16';
import { OpenProvider } from '../src/OpenProvider';

configure({ adapter: new Adapter() });

const shallowRender = (props) => {
  const requiredProps = {
    children: () => {}
  };

  const mergedProps = Object.assign({}, requiredProps, props);
  const wrapper = shallow(<OpenProvider { ...mergedProps } />);

  return {
    mergedProps,
    wrapper
  }
};

describe('OpenProvider', () => {
  it('should be closed initially', () => {
    const { wrapper, mergedProps } = shallowRender();

    expect(wrapper.state('open')).toBe(false);
  });

  describe('handleClickOutside(..)', () => {
    describe('when the state is open', () => {
      const { wrapper, mergedProps } = shallowRender();
      const instance = wrapper.instance();

      instance.setState({ open: true });

      it('should set the open state to false', () => {
          instance.handleClickOutside();
          expect(instance.state.open).toBe(false);
      });
    });
  });

  describe('toggle(..)', () => {
    describe('initial state', () => {
      const { wrapper } = shallowRender();
      const instance = wrapper.instance();

      it('should have open state set to false', () => {
        expect(instance.state.open).toBe(false);
      });
    });

    describe('when the open state is false', () => {
      const { wrapper } = shallowRender();
      const instance = wrapper.instance();

      instance.toggle();

      it('should set the open state to true', () => {
        expect(instance.state.open).toBe(true);
      });
    });

    describe('when the open state is true', () => {
      const { wrapper } = shallowRender();
      const instance = wrapper.instance();

      instance.setState({ open: true })
      instance.toggle();

      it('should set the open state to false', () => {
        expect(instance.state.open).toBe(false);
      });
    });
  });

  describe('children', () => {
    it('should pass the correct arguments to the children function', () => {
      const { wrapper, mergedProps } = shallowRender({ children: spy() });
      const instance = wrapper.instance();

      expect(mergedProps.children.calledWith(
        instance.state.open,
        instance.toggle
      )).toBe(true);
    })
  });
});
