Skip to content

Commit

Permalink
feat: update react-dnd to 14.0.2 (#729)
Browse files Browse the repository at this point in the history
* Updated to react-dnd@9.4.0

* upgrade to react-dnd@14.0.2

* fix example and code

* fix

* tests: remove react-dnd-testing-backend and use @testing-library/reac

* Add specs

* fix

* fix

Co-authored-by: Hajnal Benjámin <hajnalbenjamin@gmail.com>
  • Loading branch information
ad1992 and hajnalben committed Jun 5, 2021
1 parent ee727fd commit 44f5341
Show file tree
Hide file tree
Showing 11 changed files with 506 additions and 530 deletions.
1 change: 1 addition & 0 deletions __tests__/__snapshots__/reactTags.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Object {
],
"handleAddition": [Function],
"handleDelete": [Function],
"handleDrag": [Function],
"inline": true,
"inputFieldPosition": "inline",
"inputProps": Object {},
Expand Down
141 changes: 118 additions & 23 deletions __tests__/reactTags.test.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
import React from 'react';
import { expect } from 'chai';
import { mount, shallow } from 'enzyme';
import { spy, stub } from 'sinon';
import { spy, stub, createSandbox } from 'sinon';

import { WithContext as ReactTags } from '../src/components/ReactTags';
import {
WithContext as ReactTags,
WithOutContext as PureReactTags,
} from '../src/components/ReactTags';

import { INPUT_FIELD_POSITIONS } from '../src/components/constants';
import { fireEvent, render } from '@testing-library/react';

/* eslint-disable no-console */

const defaults = {
tags: [{ id: 'Apple', text: 'Apple' }],
suggestions: [
{ id: 'Banana', text: 'Banana' },
{ id: 'Apple', text: 'Apple' },
{ id: 'Apricot', text: 'Apricot' },
{ id: 'Pear', text: 'Pear' },
{ id: 'Peach', text: 'Peach' },
],
};
let defaults;
const sandbox = createSandbox();
let handleDragStub;
beforeAll(() => {
handleDragStub = sandbox.stub();
defaults = {
tags: [{ id: 'Apple', text: 'Apple' }],
suggestions: [
{ id: 'Banana', text: 'Banana' },
{ id: 'Apple', text: 'Apple' },
{ id: 'Apricot', text: 'Apricot' },
{ id: 'Pear', text: 'Pear' },
{ id: 'Peach', text: 'Peach' },
],
handleDrag: handleDragStub,
};
});

beforeEach(() => {
sandbox.resetHistory();
});

afterAll(() => {
sandbox.restore();
});
const DOWN_ARROW_KEY_CODE = 40;
const ENTER_ARROW_KEY_CODE = 13;

Expand Down Expand Up @@ -263,8 +281,9 @@ describe('Test ReactTags', () => {
},
})
);

expect($el.instance().props.tags).to.have.deep.members(defaults.tags);
expect($el.find(PureReactTags).instance().props.tags).to.have.deep.members(
defaults.tags
);
const $input = $el.find('.ReactTags__tagInputField');
$input.simulate('change', { target: { value: 'Apple' } });

Expand All @@ -283,7 +302,9 @@ describe('Test ReactTags', () => {
})
);

expect($el.instance().props.tags).to.have.members(defaults.tags);
expect($el.find(PureReactTags).instance().props.tags).to.have.members(
defaults.tags
);

const $input = $el.find('.ReactTags__tagInputField');
$input.simulate('keyDown', { keyCode: DOWN_ARROW_KEY_CODE });
Expand Down Expand Up @@ -354,7 +375,9 @@ describe('Test ReactTags', () => {
tags: modifiedTags,
})
);
expect($el.instance().props.tags).to.have.members(modifiedTags);
expect($el.find(PureReactTags).instance().props.tags).to.have.members(
modifiedTags
);
});

test('allow adding tag which is not in the list', () => {
Expand Down Expand Up @@ -390,7 +413,7 @@ describe('Test ReactTags', () => {
describe('autocomplete/suggestions filtering', () => {
test('updates suggestions state if the suggestions prop changes', () => {
const $el = mount(mockItem());
const ReactTagsInstance = $el.instance().getDecoratedComponentInstance();
const ReactTagsInstance = $el.find(PureReactTags).instance();
const $input = $el.find('.ReactTags__tagInputField');

$input.simulate('change', { target: { value: 'ap' } });
Expand All @@ -413,7 +436,7 @@ describe('Test ReactTags', () => {

test('updates suggestions state as expected based on default filter logic', () => {
const $el = mount(mockItem());
const ReactTagsInstance = $el.instance().getDecoratedComponentInstance();
const ReactTagsInstance = $el.find(PureReactTags).instance();
const $input = $el.find('.ReactTags__tagInputField');

expect(ReactTagsInstance.state.suggestions).to.have.members(
Expand Down Expand Up @@ -448,7 +471,7 @@ describe('Test ReactTags', () => {
},
})
);
const ReactTagsInstance = $el.instance().getDecoratedComponentInstance();
const ReactTagsInstance = $el.find(PureReactTags).instance();
const $input = $el.find('.ReactTags__tagInputField');

expect(ReactTagsInstance.state.suggestions).to.have.members(
Expand Down Expand Up @@ -481,7 +504,7 @@ describe('Test ReactTags', () => {
},
})
);
const ReactTagsInstance = $el.instance().getDecoratedComponentInstance();
const ReactTagsInstance = $el.find(PureReactTags).instance();
const $input = $el.find('.ReactTags__tagInputField');

expect(ReactTagsInstance.state.suggestions).to.have.deep.members(
Expand Down Expand Up @@ -627,7 +650,9 @@ describe('Test ReactTags', () => {
})
);

expect($el.instance().props.tags).to.have.deep.members(defaults.tags);
expect($el.find(PureReactTags).instance().props.tags).to.have.deep.members(
defaults.tags
);
const $input = $el.find('.ReactTags__tagInputField');
$input.simulate('change', { target: { value: 'Apple' } });
$input.simulate('keyDown', { keyCode: ENTER_ARROW_KEY_CODE });
Expand Down Expand Up @@ -695,8 +720,6 @@ describe('Test ReactTags', () => {
'[Deprecation] The inline attribute is deprecated and will be removed in v7.x.x, please use inputFieldPosition instead.'
)
).to.be.true;

consoleWarnStub.restore();
});
});

Expand All @@ -710,4 +733,76 @@ describe('Test ReactTags', () => {
);
expect($el.find('[data-automation="input"]').props().disabled).to.be.true;
});

describe('Test drag and drop', () => {
test('should be draggable', () => {
const root = render(
mockItem({
tags: [
...defaults.tags,
{ id: 'Litchi', text: 'Litchi' },
{ id: 'Mango', text: 'Mango' },
],
})
);
const src = root.getByText('Apple');
const dest = root.getByText('Mango');
fireEvent.dragStart(src);
const styles = getComputedStyle(src);
expect(styles.cursor).to.equal('move');
fireEvent.dragEnter(dest);
fireEvent.drop(dest);
fireEvent.dragLeave(dest);
fireEvent.dragEnd(dest);

const dragTag = defaults.tags[0];
const dragIndex = 0;
const hoverIndex = 2;
expect(handleDragStub.calledWithExactly(dragTag, dragIndex, hoverIndex))
.to.be.true;
});

test('should not be draggable when drag and drop index is same', () => {
const root = render(mockItem());
const src = root.getByText('Apple');
fireEvent.dragStart(src);
fireEvent.dragEnter(src);
fireEvent.drop(src);
fireEvent.dragLeave(src);
fireEvent.dragEnd(src);

expect(handleDragStub.called).to.be.false;
});

[
{ overrideProps: { readOnly: true }, title: 'readOnly is true' },
{
overrideProps: { allowDragDrop: false },
title: 'allowDragDrop is false',
},
].forEach((data) => {
const { title, overrideProps } = data;
test(`should not be draggable when ${title}`, () => {
const root = render(
mockItem({
...overrideProps,
tags: [
...defaults.tags,
{ id: 'Litchi', text: 'Litchi' },
{ id: 'Mango', text: 'Mango' },
],
})
);
const src = root.getByText('Apple');
const dest = root.getByText('Mango');
fireEvent.dragStart(src);
fireEvent.dragEnter(dest);
fireEvent.dragLeave(dest);
fireEvent.dragEnd(dest);
expect(handleDragStub.called).to.be.false;
const styles = getComputedStyle(src);
expect(styles.cursor).to.equal('auto');
});
});
});
});
69 changes: 10 additions & 59 deletions __tests__/tag.test.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
import React, { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { expect } from 'chai';
import { DragDropContext } from 'react-dnd';
import TestBackend from 'react-dnd-test-backend';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

import { mount } from 'enzyme';
import sinon from 'sinon';
import TestUtils from 'react-dom/test-utils';
import noop from 'lodash/noop';
import Tag from '../src/components/Tag';
import RemoveComponent from '../src/components/RemoveComponent';

function wrapInTestContext(DecoratedComponent) {
class DecoratedComponentWrapper extends Component {
constructor(props) {
super(props);
}
render() {
return <DecoratedComponent {...this.props} />;
}
}
return DragDropContext(TestBackend)(DecoratedComponentWrapper);
}

function mockItem(overrides) {
const props = Object.assign(
{},
Expand All @@ -35,11 +23,15 @@ function mockItem(overrides) {
tag: 'tag',
remove: 'remove',
},
index: 0,
},
overrides
);
const TagContext = wrapInTestContext(Tag);
return <TagContext {...props} />;
return (
<DndProvider backend={HTML5Backend}>
<Tag {...props} />
</DndProvider>
);
}

describe('Tag', () => {
Expand Down Expand Up @@ -110,45 +102,4 @@ describe('Tag', () => {
$el.find('span').simulate('touchStart');
expect(onTagClickedStub.calledOnce).to.be.true;
});

test('should be draggable', () => {
const root = TestUtils.renderIntoDocument(mockItem());
const backend = root.getManager().getBackend();
const tag = TestUtils.findRenderedComponentWithType(root, Tag);
backend.simulateBeginDrag([
tag.getDecoratedComponentInstance().getHandlerId(),
]);
expect(tag.getDecoratedComponentInstance().state.isDragging).to.be.true;
const el = TestUtils.findRenderedDOMComponentWithTag(root, 'span');
const { _values: styleAttributes } = el.style;
expect(styleAttributes.opacity).to.equal('0');
expect(styleAttributes.cursor).to.equal('move');
backend.simulateEndDrag();
expect(styleAttributes.opacity).to.equal('1');
expect(tag.getDecoratedComponentInstance().state.isDragging).to.be.false;
});

[
{ overrideProps: { readOnly: true }, title: 'readOnly is true' },
{
overrideProps: { allowDragDrop: false },
title: 'allowDragDrop is false',
},
].forEach((data) => {
const { title, overrideProps } = data;
test(`should not be draggable when ${title}`, () => {
const root = TestUtils.renderIntoDocument(mockItem({ ...overrideProps }));
const backend = root.getManager().getBackend();
const tag = TestUtils.findRenderedComponentWithType(root, Tag);
backend.simulateBeginDrag([
tag.getDecoratedComponentInstance().getHandlerId(),
]);
const el = TestUtils.scryRenderedDOMComponentsWithClass(
root,
'cursor-move'
);
expect(el.length).eq(0);
expect(tag.getDecoratedComponentInstance().state.isDragging).to.be.false;
});
});
});
4 changes: 1 addition & 3 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@
alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_left_darkblue_121621.png"></a>
<div class='container'>
<hr/>
<h4>React Tags</h4>
<p>What countries have you visited?</p>
<div id='app'></div>
</div>
<!-- include dependancies -->
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-dnd@2/dist/ReactDnD.min.js"></script>
<script src="https://unpkg.com/react-dnd@14.0.2/dist/umd/ReactDnD.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<!-- webpack dev scripts -->
<script type="text/javascript" src="../ReactTags.min.js"></script>
Expand Down
Loading

0 comments on commit 44f5341

Please sign in to comment.