import React from 'react';
import {mount, shallow} from 'enzyme';
import STATUS from '../../src/constants';
import {Notification, className} from '../../src/components/Notification/Notification';

describe('Notification', () => {
  // a default notification
  const notification = {
    id: 123123123,
    title: 'title',
    message: 'message',
    dismissible: false,
    dismissAfter: 3333,
    status: STATUS.info,
    onAdd: function() {
    },
    onRemove: function() {
    }
  };

  // default props for Notification component
  const defaultProps = {
    removeNotification: function() {}
  };

  /**
   * Return expected Notifications JSX
   * @param {Object} props
   * @returns {XML}
   */
  /* eslint-disable "react/prop-types" */
  function expectedNotificationJSX(notification) {
    const {title, message, status, dismissible} = notification;
    let titleDiv = null;
    if (title) {
      titleDiv = <p className={className.title}>{title}</p>;
    }
    return (
      <div className={`${className.main} ${className.status(status)}`}
           onClick={dismissible ? this._remove : ''}>
        <i className={className.icon}></i>
        {titleDiv}
        {message}
      </div>
    );
  }

  /* eslint-enable "react/prop-types" */

  it('should render JSX and HTML correctly (with title)', () => {
    const wrapper = shallow(<Notification key={notification.id} className={className}
      {...notification} {...defaultProps}/>);
    const expectedComponent = shallow(expectedNotificationJSX(notification));
    expect(wrapper.html()).toEqual(expectedComponent.html());
    expect(wrapper.debug()).toEqual(expectedComponent.debug());
  });

  it('should render JSX and HTML correctly (without title)', () => {
    const _notification = Object.assign({}, notification);
    // remove title
    delete _notification.title;
    const wrapper = shallow(<Notification key={_notification.id} className={className}
      {..._notification} {...defaultProps}/>);
    const expectedComponent = shallow(expectedNotificationJSX(_notification));
    expect(wrapper.html()).toEqual(expectedComponent.html());
    expect(wrapper.debug()).toEqual(expectedComponent.debug());
  });

  it('should mount with passed props', () => {
    const wrapper = mount(<Notification key={notification.id} className={className}
      {...notification} {...defaultProps}/>);
    expect(wrapper.props().removeNotification).toEqual(defaultProps.removeNotification);
    expect(wrapper.props().id).toEqual(notification.id);
    expect(wrapper.props().title).toEqual(notification.title);
    expect(wrapper.props().message).toEqual(notification.message);
    expect(wrapper.props().status).toEqual(notification.status);
    expect(wrapper.props().dismissible).toEqual(notification.dismissible);
    expect(wrapper.props().dismissAfter).toEqual(notification.dismissAfter);
    expect(wrapper.props().onAdd()).toEqual(notification.onAdd());
    expect(wrapper.props().onRemove()).toEqual(notification.onRemove());
  });
});

@@ -589,18 +589,23 @@
 tion() %7B
+%0A    
 %7D%0A
-
   %7D;%0A%0A  
@@ -629,16 +629,23 @@
 xpected 
+JSX of 
 Notifica
@@ -652,13 +652,18 @@
 tion
-s JSX
+ component
 %0A   
@@ -1220,17 +1220,16 @@
  );%0A  %7D%0A
-%0A
   /* esl
@@ -2930,24 +2930,24 @@
 n.onAdd());%0A
-
     expect(w
@@ -3012,13 +3012,1377 @@
 );%0A  %7D);
+%0A%0A  it('should run onAdd() callback at componentDidMount() lifecycle', () =%3E %7B%0A    const errorMessage = 'onAdd() callback';%0A    const _notification = Object.assign(%7B%7D, notification, %7B%0A      // here we throw an error to capture where%0A      // the code has been executed before error was thrown%0A      onAdd: function() %7B%0A        throw new Error(errorMessage);%0A      %7D%0A    %7D);%0A    try %7B%0A      mount(%3CNotification key=%7B_notification.id%7D className=%7BclassName%7D%0A        %7B..._notification%7D %7B...defaultProps%7D/%3E);%0A    %7D%0A    catch (error) %7B%0A      expect(error.stack).toMatch(/onAdd%5CncomponentDidMount/);%0A      expect(error.message).toEqual(errorMessage);%0A    %7D%0A  %7D);%0A%0A  it('should run onRemove() callback at componentWillUnmount() lifecycle', () =%3E %7B%0A    const errorMessage = 'onRemove() callback';%0A    const _notification = Object.assign(%7B%7D, notification, %7B%0A      // here we throw an error to capture where%0A      // the code has been executed before error was thrown%0A      onRemove: function() %7B%0A        throw new Error(errorMessage);%0A      %7D%0A    %7D);%0A    const wrapper = mount(%3CNotification key=%7B_notification.id%7D className=%7BclassName%7D%0A      %7B..._notification%7D %7B...defaultProps%7D/%3E);%0A    try %7B%0A      wrapper.unmount()%0A    %7D%0A    catch (error) %7B%0A      expect(error.stack).toMatch(/onRemove%5CncomponentWillUnmount/);%0A      expect(error.message).toEqual(errorMessage);%0A    %7D%0A  %7D);
 %0A%7D);%0A

add test for onAdd() and onRemove() callbacks