import {shallow} from 'enzyme';
import React from 'react';

import * as ErrorBoundaryView from 'src/main/views/ErrorBoundaryView';

describe('src/main/views/ErrorBoundaryView', () => {
  describe('ErrorBoundaryView', () => {
    let fakeError = null;

    beforeEach(() => {
      fakeError = new Error('FIAL');
    });

    describe('constructor', () => {
      it('initializes the state', () => {
        // Given
        const component = shallow(
          <ErrorBoundaryView.ErrorBoundaryView>
            <span>It works!</span>
          </ErrorBoundaryView.ErrorBoundaryView>
        );

        // Then
        expect(component.state('error')).toBe(null);
      });
    });

    describe('componentDidCatch', () => {
      it('updates the state with error', () => {
        // Given
        const component = shallow(
          <ErrorBoundaryView.ErrorBoundaryView>
            <span>It works!</span>
          </ErrorBoundaryView.ErrorBoundaryView>
        );

        // When
        component.instance().componentDidCatch(fakeError);

        // Then
        expect(component.state('error')).toEqual(fakeError);
      });
    });

    describe('render', () => {
      let fakeChildren = null;

      beforeEach(() => {
        fakeChildren = <span>It works!</span>;
      });

      it('renders the children when error is null', () => {
        // Given
        const component = shallow(
          <ErrorBoundaryView.ErrorBoundaryView>
            {fakeChildren}
          </ErrorBoundaryView.ErrorBoundaryView>
        );

        // When
        component.setState({error: null});

        // Then
        expect(component.contains(fakeChildren)).toBe(true);
        expect(component.contains('.ErrorBoundaryView')).toBe(false);
      });

      it('renders the error view when error is not null', () => {
        // Given
        const component = shallow(
          <ErrorBoundaryView.ErrorBoundaryView>
            {fakeChildren}
          </ErrorBoundaryView.ErrorBoundaryView>
        );

        // When
        component.setState({error: fakeError});

        // Then
        expect(component.contains(fakeChildren)).toBe(false);
        expect(component.hasClass('ErrorBoundaryView')).toBe(true);
        expect(component.find('p').at(1).text()).toMatch(fakeError.message);
      });
    });
  });
});
