import { mount, shallow } from 'enzyme';
import React, { Component } from 'react';

import Site from '.';
import { getDisplayName } from '../../lib';
import { Site as MockSite } from '../../../tests/storyshare';
import { siteHocFactory } from './siteHocFactory';

describe('siteHocFactory HOC', () => {
  class WrappedComponent extends Component {
    render = () => <div>Test component</div>;
  }

  let EnhancedComponent;

  const OPTIONS_FIXTURE = { };

  const SITE_FIXTURE = new MockSite();

  let wrapper;

  beforeEach(() => {
    EnhancedComponent = siteHocFactory('site')(WrappedComponent);
    wrapper = mount(
      <Site
        options={ OPTIONS_FIXTURE }
        site={ SITE_FIXTURE }
      >
        <EnhancedComponent testProp="value" />
      </Site>
    );
  });

  it('renders', () => {
    expect(wrapper).toExist();
  });

  it('renders the wrapped component', () => {
    expect(wrapper.find(WrappedComponent)).toExist();
  });

  it('passes site to the wrapped component', () => {
    expect(wrapper.find(WrappedComponent))
      .toHaveProp('site', SITE_FIXTURE);
  });

  it('passes the site to the wrapped component', () => {
    expect(wrapper.find(WrappedComponent)).toHaveProp('site', SITE_FIXTURE);
  });

  it('passes any props through to the wrapped component', () => {
    expect(wrapper.find(WrappedComponent)).toHaveProp('testProp', 'value');
  });

  it("uses the wrapped component's display name", () => {
    expect(getDisplayName(EnhancedComponent)).toBe('WrappedComponent');
  });

  it('throws if it cannot find a site', () => {
    const render = shallow(<EnhancedComponent />).prop('children');
    expect(render).toThrowError('Cannot find <Site> to access with DataLayer');
  });

  it('passes options to wrapped component if its propName', () => {
    EnhancedComponent = siteHocFactory('options')(WrappedComponent);
    wrapper = mount(
      <Site
        options={ OPTIONS_FIXTURE }
        site={ SITE_FIXTURE }
      >
        <EnhancedComponent testProp="value" />
      </Site>
    );
    expect(wrapper.find(WrappedComponent))
      .toHaveProp('options', OPTIONS_FIXTURE);
  });
});
