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

// Components
import TutorialStep from '.';
import { Button, Input, Textarea } from '@ui/components';

import { PermissionContext } from '@ui/compositions/Tutorials/Modal';

// Constants
import { DEFAULT_STEP } from '@ui/compositions/Tutorials/Modal/constants/stepDefaults';

describe('TutorialStep', () => {
  let node;
  let props;

  beforeEach(() => {
    props = {
      step: DEFAULT_STEP,
      index: 1,
      lastIndex: 2,
      shiftOrder: jest.fn(),
      navStep: jest.fn(),
      handleClick: jest.fn(),
      deleteStep: jest.fn(),
      updateStep: jest.fn(),
    };
    node = mount(
      <PermissionContext.Provider value={false}>
        <TutorialStep {...props} />
      </PermissionContext.Provider>
    );
  });

  it('should display the TutorialCard component', () => {
    expect(node.find('.TutorialStep').find('header')).toHaveLength(1);
  });

  it('should display a footer in readonly view while open', () => {
    const n2 = mount(<TutorialStep {...props} />);
    expect(n2.find('.TutorialStep').find('footer')).toHaveLength(1);
  });

  describe('component prop events', () => {
    describe('updateStep()', () => {
      it('should call updateStep with title key on title input', () => {
        const event = { target: { name: 'test', value: true, id: 'title-status' } };
        const input = node.find('.TutorialStep').find(Input).find('.Input');
        input.simulate('change', event);

        expect(props.updateStep).toHaveBeenCalledWith({ status: true });
      });

      it('should call updateStep with body key on body input', () => {
        const event = { target: { name: 'test', value: true, id: 'body-status' } };
        const ta = node.find('.TutorialStep').find(Textarea).find('.TextArea');
        ta.simulate('change', event);

        expect(props.updateStep).toHaveBeenCalledWith({ status: true });
      });
    });

    describe('shiftOrder()', () => {
      it('should be called with -1 when up arrow is selected', () => {
        const button = node.find('.TutorialStep').find(Button).find('button').first();
        button.simulate('click');

        expect(props.shiftOrder).toHaveBeenCalledWith(-1);
      });

      it('should be called with 1 when down arrow is selected', () => {
        const button = node.find('.TutorialStep').find(Button).find('button').at(1);
        button.simulate('click');

        expect(props.shiftOrder).toHaveBeenCalledWith(1);
      });

      it('should call handleClick while selecting a closed step', () => {
        const props2 = {
          step: {
            ...DEFAULT_STEP,
            isOpen: false,
          },
          index: 1,
          lastIndex: 2,
          shiftOrder: jest.fn(),
          navStep: jest.fn(),
          handleClick: jest.fn(),
          deleteStep: jest.fn(),
          updateStep: jest.fn(),
        };
        const n2 = mount(
          <PermissionContext.Provider value={false}>
            <TutorialStep {...props2} />
          </PermissionContext.Provider>
        );
        const event = { target: { name: 'test', value: '', nodeName: 'Button' } };
        const button = n2.find('.TutorialStep').find(Button).find('button').first();
        button.simulate('click', event);

        expect(props2.handleClick).toHaveBeenCalled();
      });
    });

    it('should call deleteStep() with index', () => {
      const button = node.find('.TutorialStep').find(Button).find('button').at(2);
      button.simulate('click');

      expect(props.deleteStep).toHaveBeenCalledWith(1);
    });

    describe('readonly events', () => {
      let node2;

      beforeEach(() => {
        node2 = mount(<TutorialStep {...props} />);
      });

      it('should call navStep with 1 while navigating next', () => {
        const button = node2.find('.TutorialStep').find('footer').find('button').last();
        button.simulate('click');

        expect(props.navStep).toHaveBeenCalledWith(1);
      });
    });
  });
});
