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

import {Button, Modal} from 'src/components';
import * as WidgetSettingsModal from 'src/main/components/WidgetSettingsModal';

describe('src/main/components/WidgetSettingsModal', () => {
  describe('WidgetSettingsModal', () => {
    let mockOnCancelButtonClick = null;
    let mockOnClose = null;
    let mockOnSaveButtonClick = null;
    let fakeSettingsView = null;
    let fakeSettingsViewProps = null;

    beforeEach(() => {
      mockOnCancelButtonClick = jasmine.createSpy();
      mockOnClose = jasmine.createSpy();
      mockOnSaveButtonClick = jasmine.createSpy();
      fakeSettingsView = jasmine.createSpy().and.returnValue(
        <span>Settings</span>
      );
      fakeSettingsView.displayName = 'FakeSettingsView';
      fakeSettingsViewProps = {spam: true};
    });

    it('configures and renders the modal', () => {
      // Given
      const component = shallow(
        <WidgetSettingsModal.WidgetSettingsModal
          buttons={[]}
          settingsView={fakeSettingsView}
          settingsViewProps={fakeSettingsViewProps}
          show={false}
          onCancelButtonClick={mockOnCancelButtonClick}
          onClose={mockOnClose}
          onSaveButtonClick={mockOnSaveButtonClick}
        />
      );

      // When
      const modal = component.find(Modal).at(0);

      // Then
      expect(modal.exists()).toBe(true);
      expect(modal.prop('show')).toBe(false);
      expect(modal.prop('onHide')).toEqual(mockOnClose);
    });

    it('configures and renders the settings view', () => {
      // Given
      const component = shallow(
        <WidgetSettingsModal.WidgetSettingsModal
          buttons={[]}
          settingsView={fakeSettingsView}
          settingsViewProps={fakeSettingsViewProps}
          show={false}
          onCancelButtonClick={mockOnCancelButtonClick}
          onClose={mockOnClose}
          onSaveButtonClick={mockOnSaveButtonClick}
        />
      );

      // When
      const settingsView = component.find(fakeSettingsView).at(0);

      // Then
      expect(settingsView.props()).toEqual(fakeSettingsViewProps);
    });

    it('renders the additional buttons', () => {
      // Given
      const button = <Button key="testing">Test</Button>;
      const component = shallow(
        <WidgetSettingsModal.WidgetSettingsModal
          buttons={[button]}
          settingsView={fakeSettingsView}
          settingsViewProps={fakeSettingsViewProps}
          show={false}
          onCancelButtonClick={mockOnCancelButtonClick}
          onClose={mockOnClose}
          onSaveButtonClick={mockOnSaveButtonClick}
        />
      );

      // Then
      expect(component.contains(button)).toBe(true);
    });

    it('configures and renders the cancel button', () => {
      // Given
      const component = shallow(
        <WidgetSettingsModal.WidgetSettingsModal
          buttons={[]}
          settingsView={fakeSettingsView}
          settingsViewProps={fakeSettingsViewProps}
          show={false}
          onCancelButtonClick={mockOnCancelButtonClick}
          onClose={mockOnClose}
          onSaveButtonClick={mockOnSaveButtonClick}
        />
      );

      // When
      const button = component.find('Button[_hint="Cancel"]').at(0);

      // Then
      expect(button.exists()).toBe(true);
      expect(button.prop('onClick')).toEqual(mockOnCancelButtonClick);
    });

    it('configures and renders the save button', () => {
      // Given
      const component = shallow(
        <WidgetSettingsModal.WidgetSettingsModal
          buttons={[]}
          settingsView={fakeSettingsView}
          settingsViewProps={fakeSettingsViewProps}
          show={false}
          onCancelButtonClick={mockOnCancelButtonClick}
          onClose={mockOnClose}
          onSaveButtonClick={mockOnSaveButtonClick}
        />
      );

      // When
      const button = component.find('Button[_hint="Save"]').at(0);

      // Then
      expect(button.exists()).toBe(true);
      expect(button.prop('onClick')).toEqual(mockOnSaveButtonClick);
    });
  });
});
