prakhar1989/react-tags

View on GitHub
__tests__/SingleTag.test.tsx

Summary

Maintainability
A
1 hr
Test Coverage
import React from 'react';
import PropTypes from 'prop-types';
import { expect } from 'chai';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

import { mount } from 'enzyme';
import sinon from 'sinon';
import noop from 'lodash/noop';
import { SingleTag } from '../src/components/SingleTag';
import RemoveComponent from '../src/components/RemoveComponent';

function mockItem(overrides) {
  const props = Object.assign(
    {},
    {
      tag: { id: '1', text: 'FooBar', className: 'action' },
      onDelete: noop,
      readOnly: false,
      allowDragDrop: true,
      moveTag: noop,
      classNames: {
        tag: 'tag',
        remove: 'remove',
      },
      index: 0,
    },
    overrides
  );
  return (
    <DndProvider backend={HTML5Backend}>
      <SingleTag {...props} />
    </DndProvider>
  );
}

describe('Tag', () => {
  test('shows the classnames of children properly', () => {
    const $el = mount(mockItem());
    expect($el.find('.tag').length).to.equal(1);
    expect($el.text()).to.have.string('FooBar');
  });

  test('should show cross for removing tag when read-only is false', () => {
    const $el = mount(mockItem());
    expect($el.find(RemoveComponent).length).to.equal(1);
  });

  test('should not show cross for removing tag when read-only is true', () => {
    const $el = mount(mockItem({ readOnly: true }));
    expect($el.find('a.remove').length).to.equal(0);
  });

  test('renders passed in removed component correctly', () => {
    const CustomRemoveComponent = function () {
      return <a className="remove">delete me</a>;
    };
    const $el = mount(mockItem({ removeComponent: CustomRemoveComponent }));
    expect($el.find('a.remove').length).to.equal(1);
    expect($el.text()).to.have.string('delete me');
  });

  test('renders conditional passed in removed component correctly', () => {
    const CustomConditionRemoveComponent = function (props) {
      return props.tag.id === '1' ? null : <a className="removeTag">x</a>;
    };
    CustomConditionRemoveComponent.propTypes = {
      tag: PropTypes.shape({
        id: PropTypes.string.isRequired,
      }),
    };
    const $el = mount(
      mockItem({ removeComponent: CustomConditionRemoveComponent })
    );
    expect($el.find('.removeTag').length).to.equal(0);
  });

  test('calls the delete handler correctly', () => {
    const spy = sinon.spy();
    const $el = mount(mockItem({ onDelete: spy }));
    $el.find(RemoveComponent).simulate('click');
    expect(spy.calledOnce).to.be.true;
    spy.resetHistory();
  });

  test('should add className passed in tags to the tag', () => {
    const $el = mount(mockItem());
    expect($el.find('.action').length).to.equal(1);
  });

  test('calls the tag click handler correctly', () => {
    const spy = sinon.spy();
    const $el = mount(mockItem({ onTagClicked: spy }));
    $el.find('span').simulate('click');
    expect(spy.calledOnce).to.be.true;
    spy.resetHistory();
  });

  test('should trigger the tag click handler on touchStart', () => {
    const onTagClickedStub = sinon.stub();
    const $el = mount(mockItem({ onTagClicked: onTagClickedStub }));
    $el.find('span').simulate('touchStart');
    expect(onTagClickedStub.calledOnce).to.be.true;
  });
});