// @flow
import React from 'react';
import {
  mountWrappedComponent,
  shallowWrappedComponent,
  renderSnapshot,
} from '../../../../utils/tests';

import type { RadioButtonProps } from './radio-button.proptypes';
import { RadioButton } from './index';

const DEFAULT_PROPS: RadioButtonProps = {
  id: 'test-id',
  name: 'radiobtn',
  selected: false,
  text: 'great label',
  onClick: jest.fn(),
};

describe('RadioButton', () => {
  describe('snapshot', () => {
    it('matches the previous snapshot', () => {
      const radioButton = renderSnapshot(<RadioButton {...DEFAULT_PROPS} />);

      expect(radioButton).toMatchSnapshot();
    });
  });

  it('renders a clickable container', () => {
    const radioButton = shallowWrappedComponent(
      <RadioButton {...DEFAULT_PROPS} />,
    ).dive();

    expect(radioButton.find('RadioButtonContainer').props()).toEqual({
      stacked: 'row',
      align: 'center',
      onClick: expect.any(Function),
      children: expect.anything(),
    });
  });

  it('calls onClick with given id', () => {
    const handleOnClick = jest.fn();
    const radioButton = shallowWrappedComponent(
      <RadioButton {...DEFAULT_PROPS} onClick={handleOnClick} />,
    ).dive();

    expect(handleOnClick).toHaveBeenCalledTimes(0);

    const clickable = radioButton.find('RadioButtonContainer');
    clickable.simulate('click');

    expect(handleOnClick).toHaveBeenCalledTimes(1);
    expect(handleOnClick).toHaveBeenCalledWith(DEFAULT_PROPS.id);
  });

  it('renders a label if given text', () => {
    const text = 'example text';
    const radioButton = shallowWrappedComponent(
      <RadioButton {...DEFAULT_PROPS} text={text} />,
    ).dive();

    expect(radioButton.contains(text)).toBe(true);
  });

  it('does not render a label if not given text', () => {
    const text = 'example text';
    const radioButton = shallowWrappedComponent(
      <RadioButton {...DEFAULT_PROPS} text={undefined} />,
    ).dive();

    expect(radioButton.contains(text)).toBe(false);
  });

  it('renders an invisible input', () => {
    const radioButton = mountWrappedComponent(
      <RadioButton {...DEFAULT_PROPS} />,
    );

    const invisibleInput = radioButton.find('input');

    expect(invisibleInput.props()).toEqual({
      type: 'radio',
      className: expect.any(String),
      id: expect.any(String),
      readOnly: true,
      checked: DEFAULT_PROPS.selected,
      name: DEFAULT_PROPS.name,
    });

    expect(invisibleInput).toHaveStyleRule('opacity', '0');
  });

  it('selects both the invisible and visible inputs', () => {
    const selectedState = [true, false];

    selectedState.forEach(state => {
      const radioButton = mountWrappedComponent(
        <RadioButton {...DEFAULT_PROPS} selected={state} />,
      );

      const invisibleInput = radioButton.find('input');
      expect(invisibleInput.prop('checked')).toBe(state);

      const visibleInput = radioButton.find('StyledRadioOption');
      expect(visibleInput.prop('checked')).toEqual(state);
    });
  });
});
