import React from 'react';

import { shallow, mount, render } from 'enzyme';
import { assert, expect } from 'chai';
import sinon from 'sinon';

import Application from '../lib/components/Application';
import Search from '../lib/components/Search';
import MessageContainer from '../lib/components/MessageContainer';
import Users from '../lib/components/Users';
import Input from '../lib/components/Input';


describe('Application', () => {

  it('renders as a <div>', () => {
    const wrapper = shallow(<Application />)
    assert.equal(wrapper.type(), 'div');
  });

  it('has a className property of application', () => {
    const wrapper = shallow(<Application />)
    expect(wrapper.hasClass('application'));
  })

  it('has a state of messages equal to a blank array', () => {
    const wrapper = shallow(<Application />)
    expect(wrapper.state().messages).to.deep.equal([])
  })

  it('has a state of filteredMessages equal to null', () => {
    const wrapper = shallow(<Application />)
    expect(wrapper.state().filteredMessages).to.equal(null)
  })
  it('has a state of filteredUsers to null', () => {
    const wrapper = shallow(<Application />)
    expect(wrapper.state().filteredUsers).to.equal(null)
  })

  it('has a state of filteredInput to null', () => {
    const wrapper = shallow(<Application />)
    expect(wrapper.state().filteredInput).to.equal(null)
  })

  it('has a state of user equal to null', () => {
    const wrapper = shallow(<Application />)
    expect(wrapper.state().user).to.equal(null)
  })

  it('has a state of allUsers to []', () => {
    const wrapper = shallow(<Application />)
    expect(wrapper.state().allUsers).to.deep.equal([])
  })

  it('has a state of sortMsg to true', () => {
    const wrapper = shallow(<Application />)
    expect(wrapper.state().sortMsg).to.equal(true)
  })

  it('has a state of userSelected to null', () => {
    const wrapper = shallow(<Application />)
    expect(wrapper.state().userSelected).to.equal(null)
  })

  it('calls componentDidMount', () => {
    sinon.spy(Application.prototype, 'componentDidMount');
    const wrapper = mount(<Application />);
    expect(Application.prototype.componentDidMount.calledOnce).to.equal(true);
  });

});

describe('Search', () => {

  it('renders as a <div>', () => {
    const wrapper = shallow(<Search messages/>)
    assert.equal(wrapper.type(), 'div');
 });

  it('should have an input', () => {
    const wrapper = shallow(<Search messages/>)
    expect(wrapper.find('input')).to.have.length(1)
  })

  it('should have an input class of .searchInput', () => {
    const wrapper = shallow(<Search messages />)
    expect(wrapper.find('.searchInput')).to.have.length(1);
  })

  it('should have a button', () => {
    const wrapper = shallow(<Search messages />)
    expect(wrapper.find("button")).to.have.length(1);
  })

  it('should have an button class of .sortButton', () => {
    const wrapper = shallow(<Search messages />)
    expect(wrapper.find('.sortButton')).to.have.length(1);
  })

  it.skip("should have an onClick function on sort button", () => {
    const wrapper = mount(<Search messages />);
    expect(wrapper.props().children[1].props.onClick).to.be.length(1);
  })

  it("should have message props", () => {
    const wrapper = mount(<Search messages={"test"} />);
    expect(wrapper.prop("messages")).to.equal("test");
  })

  it("should have handleChange props", () => {
    const wrapper = mount(<Search messages handleChange={"test"} />);
    expect(wrapper.prop("handleChange")).to.equal("test");
  })

});

describe('MessageContainer', () => {

  it('renders as a <div>', () => {
    const wrapper = shallow(<MessageContainer messages={[]} />)
    assert.equal(wrapper.type(), 'div');
  });

  it('should have a time-and-user class', () => {
    const wrapper = shallow(<MessageContainer messages={[]} />)
    expect(wrapper.hasClass('time-and-user'));
  });

  it('should have a time-stamp class', () => {
    const wrapper = shallow(<MessageContainer messages={[]} />)
    expect(wrapper.hasClass('time-stamp'));
  });

  it('should have a user-stamp class', () => {
    const wrapper = shallow(<MessageContainer messages={[]} />)
    expect(wrapper.hasClass('user-stamp'));
  });

  it('should have a message-stamp class', () => {
    const wrapper = shallow(<MessageContainer messages={[]} />)
    expect(wrapper.hasClass('message-stamp'));
  });

})

describe('Users', () => {

  it('renders as a <p>', () => {
    const wrapper = shallow(<Users users/>)
    assert.equal(wrapper.type(), 'p');
  });

  it("should have message props", () => {
    const wrapper = mount(<Users messages={"test"} />);
    expect(wrapper.prop("messages")).to.equal("test");
  })

  it.skip("should have users props", () => {
    const wrapper = mount(<Users messages users={user} />);
    expect(wrapper.prop("users")).to.equal(user);
  })

  it("should have resetMessages props", () => {
    const wrapper = mount(<Users messages resetMessages={'test'} />);
    expect(wrapper.prop("resetMessages")).to.equal('test');
  })

});

describe('Input', () => {

  it('renders as a <div>', () => {
    const wrapper = shallow(<Input />)
    assert.equal(wrapper.type(), 'div');
  });

  it('should have an input', () => {
    const wrapper = shallow(<Input />)
    expect(wrapper.find("input")).to.have.length(1);
  })

  it('should have an input class of .messageInput', () => {
    const wrapper = shallow(<Input />)
    expect(wrapper.find('.messageInput')).to.have.length(1);
  })

  it('should have 2 buttons', () => {
    const wrapper = shallow(<Input />)
    expect(wrapper.find("button")).to.have.length(2);
  })

  it('should have an button class of .submitMsgBtn', () => {
    const wrapper = shallow(<Input />)
    expect(wrapper.find('.submitMsgBtn')).to.have.length(1);
  })

  it('should have an button class of .clearMsgBtn', () => {
    const wrapper = shallow(<Input />)
    expect(wrapper.find('.clearMsgBtn')).to.have.length(1);
  })

});

@@ -399,17 +399,16 @@
 nput';%0A%0A
-%0A
 describe
@@ -3009,38 +3009,38 @@
 (1);%0A  %7D)%0A%0A  it.
-skip(%22
+only('
 should have an o
@@ -3069,17 +3069,17 @@
 t button
-%22
+'
 , () =%3E 
@@ -3094,121 +3094,236 @@
 nst 
-wrapper = mount(%3CSearch messages /%3E);%0A    expect(wrapper.props().children%5B1%5D.props.onClick).to.be.length(
+handleClick = sinon.spy();%0A    const wrapper = shallow(%0A      %3CSearch messages=%7B%5B%5D%7D handleClick=%7BhandleClick%7D /%3E%0A    );%0A    wrapper.find('button').simulate('click');%0A    expect(handleClick).to.have.property('callCount', 
 1);%0A  %7D)
 %0A%0A  
@@ -3314,24 +3314,25 @@
 t', 1);%0A  %7D)
+;
 %0A%0A  it(%22shou
@@ -4834,13 +4834,8 @@
   it
-.skip
 (%22sh

Add click event test with sinon spy