import { shallow, mount } from 'enzyme';
import sinon from 'sinon';
import React from 'react';
import ReactDOM from 'react-dom';
import { TextArea } from 'web-foundation';

describe('<TextArea />', function() {
    it('should make an element', function() {
        const wrapper = shallow(<TextArea />);

        expect(wrapper.hasClass('text-area')).to.be.true;
        expect(wrapper.find('textarea')).to.have.length(1);
        expect(wrapper.find('label')).to.have.length(0);

        wrapper.find('textarea').simulate('focus');
        wrapper.find('textarea').simulate('blur');
    });

    it('should allow for a label', function() {
        const wrapper = shallow(
            <TextArea
                label="This is a label" />
        );

        expect(wrapper.find('label')).to.have.length(1);
        expect(wrapper.find('label').text()).to.equal('This is a label');
    });

    it('should show the placeholder in the textarea', function() {
        const wrapper = shallow(
            <TextArea
                placeholder="This is a placeholder" />
        );

        expect(wrapper.find('textarea').prop('placeholder'))
            .to.equal('This is a placeholder');
    });

    it('should show the alt placeholder on focus', function() {
        const blurCallback = sinon.spy(),
            wrapper = shallow(
                <TextArea
                    altPlaceholder="This is an alt placeholder"
                    blur={ blurCallback } />
            );

        expect(wrapper.find('textarea').prop('placeholder'))
            .to.equal('');

        wrapper.find('textarea').simulate('focus');

        expect(wrapper.find('textarea').prop('placeholder'))
            .to.equal('This is an alt placeholder');

        wrapper.find('textarea').simulate('blur');

        expect(wrapper.find('textarea').prop('placeholder'))
            .to.equal('');
        expect(blurCallback.calledOnce).to.be.true;
    });

    it('should display a value', function() {
        const wrapper = mount(
                <TextArea value="test value" />
            ),
            node = ReactDOM.findDOMNode(wrapper.instance());

        expect(node.getElementsByTagName('textarea')[0].value)
            .to.equal('test value');
    });

    it('should apply a \'disabled\' class', function() {
        const wrapper = shallow(<TextArea disabled />);

        expect(wrapper.hasClass('disabled')).to.be.true;
    });

    // currently this is untestable through dom manipulation
    it('should update the value', function() {
        const updateSpy = sinon.spy(),
            wrapperOne = mount(
                <TextArea value="test value"
                    update={ updateSpy } />
            ),
            wrapperTwo = mount(
                <TextArea value="test value" />
            );

        wrapperOne.instance().update({ value() { return 'beans'; } });
        wrapperTwo.instance().update({ value() { return 'beans'; } });
        expect(updateSpy.callCount).to.equal(1);
    });

    it('should allow a value rewrite through props', function() {
        const updateSpy = sinon.spy(),
            wrapper = mount(
                <TextArea value="test value"
                    update={ updateSpy } />
            ),
            node = ReactDOM.findDOMNode(wrapper.instance());

        wrapper.setProps({ value: 'beans' });

        expect(updateSpy.callCount).to.equal(0);
        expect(node.getElementsByTagName('textarea')[0].value)
            .to.equal('beans');
    });

    it('should ignore that if it has focus', function() {
        const updateSpy = sinon.spy(),
            wrapper = mount(
                <TextArea value="test value"
                    update={ updateSpy } />
            ),
            node = ReactDOM.findDOMNode(wrapper.instance());

        wrapper.find('textarea').simulate('focus');
        wrapper.setProps({ value: 'beans' });

        expect(updateSpy.callCount).to.equal(0);
        expect(node.getElementsByTagName('textarea')[0].value)
            .to.equal('test value');
    });

    it('should initialize with focus if told to', function() {
        let wrapper = mount(
            <TextArea value="test value" />
        );

        expect(wrapper.state('focused')).to.be.false;

        wrapper = mount(
            <TextArea value="test value"
                setFocus />
        );

        expect(wrapper.state('focused')).to.be.true;
    });

    it('should acknowledge an error through props', function() {
        const wrapper = shallow(
                <TextArea
                    error="error message" />
            );

        expect(wrapper.hasClass('has-error')).to.be.true;
    });
});
