/*
Copyright (c) 2018 Uber Technologies, Inc.

This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/

/* eslint-env browser */
import React from 'react';
import ReactDOM from 'react-dom';
import { mount } from 'enzyme';
import { Modal, ModalHeader, ModalFooter, ModalBody, StyledBackdrop, StyledClose, StyledDialog, CLOSE_SOURCE } from '../index.js';
jest.useFakeTimers(); // Mock React 16 portals in a way that makes them easy to test

var originalCreatePortal = ReactDOM.createPortal; // Mock document.addEventListener

var originalDocumentAddListener = document.addEventListener;
describe('Modal', function () {
  var wrapper;
  beforeAll(function () {
    // $FlowFixMe
    ReactDOM.createPortal = jest.fn(function (e) {
      return React.createElement("div", {
        "is-portal": "true",
        key: "portal"
      }, e);
    }); // $FlowFixMe

    document.addEventListener = jest.fn();
  });
  afterEach(function () {
    ReactDOM.createPortal.mockClear();
    document.addEventListener.mockClear();
    wrapper && wrapper.unmount();
  });
  afterAll(function () {
    // $FlowFixMe
    ReactDOM.createPortal = originalCreatePortal; // $FlowFixMe

    document.addEventListener = originalDocumentAddListener;
  });
  test('renders nothing when closed', function () {
    wrapper = mount(React.createElement(Modal, {
      isOpen: false
    }, React.createElement(ModalBody, null, "Hello world")));
    expect(wrapper).toBeEmptyRender();
  });
  test('renders portal when open', function () {
    wrapper = mount(React.createElement(Modal, {
      isOpen: true
    }, React.createElement(ModalHeader, null, "Hello world"), React.createElement(ModalBody, null, "Modal Body"), React.createElement(ModalFooter, null, "Footer")));
    expect(wrapper).toMatchSnapshot('Rendered Modal');
  });
  test('close button triggers close', function () {
    var onClose = jest.fn();
    wrapper = mount(React.createElement(Modal, {
      isOpen: true,
      onClose: onClose
    }, React.createElement(ModalBody, null, "Modal Body")));
    wrapper.find(StyledClose).simulate('click');
    expect(onClose).toHaveBeenCalledTimes(1);
    expect(onClose).toHaveBeenLastCalledWith({
      closeSource: CLOSE_SOURCE.closeButton
    });
  });
  test('backdrop triggers close', function () {
    var onClose = jest.fn();
    wrapper = mount(React.createElement(Modal, {
      isOpen: true,
      onClose: onClose
    }, React.createElement(ModalBody, null, "Modal Body")));
    wrapper.find(StyledBackdrop).simulate('click');
    expect(onClose).toHaveBeenCalledTimes(1);
    expect(onClose).toHaveBeenLastCalledWith({
      closeSource: CLOSE_SOURCE.backdrop
    });
  });
  test('disable closeable', function () {
    var onClose = jest.fn();
    wrapper = mount(React.createElement(Modal, {
      isOpen: true,
      closeable: false,
      onClose: onClose
    }, React.createElement(ModalBody, null, "Modal Body")));
    expect(wrapper.find(StyledClose)).not.toExist();
    wrapper.find(StyledBackdrop).simulate('click');
    expect(onClose).not.toHaveBeenCalled();
  });
  test('prevents scroll on mount node', function () {
    var onClose = jest.fn();
    wrapper = mount(React.createElement(Modal, {
      onClose: onClose
    }, React.createElement(ModalBody, null, "Modal Body")));
    var body = document.body;
    expect(body.style.overflow).toBe('');
    wrapper.setProps({
      isOpen: true
    });
    expect(body.style.overflow).toBe('hidden');
    wrapper.setProps({
      isOpen: false
    });
    expect(body.style.overflow).toBe('');
  });
  test('override components', function () {
    var mock = function mock() {
      return jest.fn().mockImplementation(function (_ref) {
        var children = _ref.children;
        return React.createElement("div", null, children);
      });
    };

    var Root = mock();
    var Backdrop = mock();
    var DialogContainer = mock();
    var Dialog = mock();
    var Close = mock();
    wrapper = mount(React.createElement(Modal, {
      isOpen: true,
      overrides: {
        // $FlowFixMe
        Root: Root,
        // $FlowFixMe
        Backdrop: Backdrop,
        // $FlowFixMe
        DialogContainer: DialogContainer,
        // $FlowFixMe
        Dialog: Dialog,
        // $FlowFixMe
        Close: Close
      }
    }, React.createElement(ModalBody, null, "Modal Body")));
    expect(wrapper.find(Root)).toExist();
    expect(wrapper.find(Backdrop)).toExist();
    expect(wrapper.find(DialogContainer)).toExist();
    expect(wrapper.find(Dialog)).toExist();
    expect(wrapper.find(Close)).toExist();
  });
  test('role', function () {
    wrapper = mount( // eslint-disable-next-line jsx-a11y/aria-role
    React.createElement(Modal, {
      role: "mycustomrole",
      isOpen: true
    }, React.createElement(ModalBody, null, "Modal Body")));
    expect(wrapper.find(StyledDialog)).toHaveProp('role', 'mycustomrole');
  });
});