import { shallow } from 'enzyme';
import React from 'react';
import { Message } from 'semantic-ui-react';

import createMessageComponent from './createMessageComponent';

describe('createMessageComponent function', () => {
  const Context = React.createContext();

  let Component;

  let wrapper;

  beforeEach(() => {
    Component = createMessageComponent(
      'DisplayName',
      Context,
      'testName',
      'test expected',
      { extra: 'prop' }
    );
    wrapper = shallow(<Component />);
  });

  const getMessageFromState = (state) => {
    const children = wrapper.find(Context.Consumer).prop('children');
    return shallow(<div>{ children(state) }</div>).find('Message');
  };

  const getMessage = () => getMessageFromState({ testName: 'test expected' });

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

  it('renders a Consumer to retrieve the context', () => {
    expect(wrapper.find(Context.Consumer)).toExist();
  });

  it('renders nothing if the field is missing', () => {
    expect(getMessageFromState({ })).not.toExist();
  });

  it('renders nothing if the field is null', () => {
    expect(getMessageFromState({ testName: null })).not.toExist();
  });

  it('renders nothing if the field has an unexpected value', () => {
    expect(getMessageFromState({ testName: 'other' })).not.toExist();
  });

  it('renders a Message', () => {
    expect(getMessage()).toExist();
  });

  it('passes props down to the Message', () => {
    wrapper.setProps({ size: 'small' });
    expect(getMessage()).toHaveProp('size', 'small');
  });

  it('copies propTypes from the Message', () => {
    expect(Component.propTypes).toBe(Message.propTypes);
  });

  it('adds extra props', () => {
    expect(getMessage()).toHaveProp('extra', 'prop');
  });

  it('ignores attempts to change the extra props', () => {
    wrapper.setProps({ extra: 'other' });
    expect(getMessage()).toHaveProp('extra', 'prop');
  });

  it('copes if no extra props are supplied', () => {
    Component = createMessageComponent(
      'DisplayName',
      Context,
      'testName',
      'test expected'
    );
    // Test succeeds if no errors
  });

  it('sets the component display name', () => {
    expect(Component.displayName).toBe('DisplayName');
  });
});
