ant-design/components/upload/__tests__/upload.test.js
Saeed Rahimi 676de29eb4 feat: added rtl direction to all of ant-design components (#19380)
* rtl demo change en-us description

* change bundlesize css limit

* RTL: modal component (exclude confirm)

* RTL: table component

* RTL: pagination component

* cleanup rtl demo

* fix pagination.tsx compile error

* RTL: button and button-group

* RTL: Steps component

* fix rtl demo style

* fix input suffix icon alignment

* fix select component arrow issue

* RTL: form component

* add pagination rtl test

* fix test lint error

* RTL: rate component

* RTL: radio and radio group components

* RTL: tree-select component

* some fixes to RTL components

* RTL: badge component

* fix rtl issue in inline form

* fix input component rtl padding issue

* fix switch component text rtl issue

* fix table grouped header text-align

* add rtl support to whole demo with RTL button

* Update rtl demo responsive

* RTL: page-header component

* RTL: typography component

* RTL: Dropdown (Partial)

* update config-provider doc

* RTL: input component

* RTL: select component

* RTL: switch component

* RTL: tree component

* fix rtl demo lint

* rtl demo change en-us description

* RTL: modal component (exclude confirm)

* RTL: table component

* RTL: pagination component

* cleanup rtl demo

* RTL: button and button-group

* RTL: Steps component

* fix rtl demo style

* fix input suffix icon alignment

* RTL: form component

* RTL: rate component

* RTL: radio and radio group components

* RTL: tree-select component

* RTL: badge component

* fix rtl issue in inline form

* fix input component rtl padding issue

* add rtl support to whole demo with RTL button

* fix lost changes after rebase

* fix lint errors

* RTL: Transfer Component

* RTL: upload component

* RTL: update avatar demo

* RTL: comment component

* RTL: collapse component

* RTL: carousel component

* update snapshots

* RTL: Card component

* RTL: descriptions component

* RTL:  Empty component

* RTL: list component

* RTL: slider component

* slider component import/order

* add shared rtlTest

* RTL: Statistic component

* RTL: tooltip components

* RTL: popover component

* RTL: timeline component

* RTL: tag component

* RTL: alert component

* RTL: drawer component

* RTL: Tab component

* change direction definition

* RTL: progress component

* input.tsx, remove duplicate after rebase

* fix demo.less after rebase

* fix ant-row-rtl after rebase

* fix upload issues in rtl

* badge rtl demo margin fix

* fix: tabs with icon margin

* fix: radio-wrapper margin

* fix: table component after rebase

* fix: centered modal text-align

* update slider snapshot

* RTL: popconfirm component

* RTL: back-top component

* RTL: spin component

* RTL: result component

* RTL: skeleton component

* RTL: menu component

* RTL: time-picker component

* RTL: calendar component

* RTL: date-picker component

* RTL: home page

* update snapshots

* test: add auto-complete rtl test

* test: add avatar component rtl tests

* test: add badge component rtl tests

* test: add breadcrumb component rtl tests

* test: add button components rtl tests

* test: add card component rtl tests

* test: add carousel component rtl tests

* test: add cascader component rtl tests

* test: add checkbox component rtl tests

* test: add collapse component rtl tests

* test: add comment component rtl tests

* test: add dropdown component rtl tests

* test: add empty component rtl tests

* test: add form component rtl tests

* test: add grid component rtl tests

* test: add input component rtl tests

* test: add search component rtl tests

* test: add input-number component rtl tests

* test: add layout component rtl tests

* test: add list component rtl tests

* test: add mentions component rtl tests

* test: add modal component rtl tests

* test: add page-header component rtl tests

* test: add pagination component rtl tests

* test: add radio component rtl tests

* test: add rate component rtl tests

* test: add select component rtl tests

* test: add slider component rtl tests

* test: add steps component rtl tests

* test: add switch component rtl tests

* test: add table component rtl tests

* test: add transfer component rtl tests

* test: add tree component rtl tests

* test: add tree-select component rtl tests

* test: add typography component rtl tests

* test: add upload component rtl tests

* test: add affix component rtl tests

* update calendar tests

* increase css file maxSize

* update snapshots

* remove workflows to allow push

* remove duplicate reverse prop from slider

* fix: remove table demo from config-provider

* fix: remove table demo from config-provider

* fix lint error

* Added direction property to ConfigProvider

* cascader rtl tests added

* update config-provider doc

* RTL: grid system

* RTL: input component

* RTL: switch component

* fix rtl demo lint

* RTL: modal component (exclude confirm)

* RTL: table component

* RTL: pagination component

* cleanup rtl demo

* fix pagination.tsx compile error

* RTL: button and button-group

* RTL: Steps component

* fix rtl demo style

* RTL: form component

* add pagination rtl test

* RTL: rate component

* RTL: radio and radio group components

* RTL: tree-select component

* RTL: badge component

* fix rtl issue in inline form

* fix input component rtl padding issue

* add rtl support to whole demo with RTL button

* RTL: input component

* RTL: select component

* RTL: switch component

* RTL: tree component

* fix rtl demo lint

* rtl demo change en-us description

* RTL: modal component (exclude confirm)

* RTL: table component

* RTL: pagination component

* cleanup rtl demo

* RTL: button and button-group

* RTL: Steps component

* fix rtl demo style

* fix input suffix icon alignment

* RTL: form component

* RTL: rate component

* RTL: radio and radio group components

* RTL: tree-select component

* RTL: badge component

* fix rtl issue in inline form

* fix input component rtl padding issue

* add rtl support to whole demo with RTL button

* input.tsx, remove duplicate after rebase

* fix ant-row-rtl after rebase

* update snapshots

* test: add cascader component rtl tests

* test: add pagination component rtl tests

* update calendar tests

* update snapshots

* fix: remove table demo from config-provider

* fix: remove table demo from config-provider

* fix lint error

* update direction.md icons

* dropdown and cascader default placement in rtl

* update snapshots

* fix lint errors

* remove duplicate import

* update snapshots

* update snapshot

* update calendar snapshot

* update snapshots

* integrate with new rc-picker

* update snapshots

* fix lint errors

* update snapshot

* update snapshots

* update snapshots

* update snapshots :|

* update snapshots

* fix compile error.

* fix typo after rebase

* update snapshots

* remove workflows to allow push

* update snapshots

* update snapshots

* fix dist error

* front-page css fix

* update snapshots

* fix lint and test issues

* restore cascader index.less

* update snapshots

* fix logo in rtl and demo controls

* ci errors

* resolve steps/index.tsx conflicts

* tooltip family demo remove inline style

* resolve table/Table.tsx conflicts

* resolve modal/Modal.tsx conflicts

* resolve cascader/index.tsx conflicts

* add workflows from upstream

* update snapshots

* revert logo to default

* fix codebox demo direction of placements

* resolve tooltip overlayClassName conflicts

* update snapshots

* update popover test

* fix: cascader miss popupClassName

* fix: fix select missing dropdownClassName

* chore: Update snapshot

* chore: Adjust menu use rtl logic

* docs: Update demo line color

Co-authored-by: 二货机器人 <smith3816@gmail.com>
2020-01-02 19:10:16 +08:00

502 lines
13 KiB
JavaScript

/* eslint-disable react/no-string-refs, react/prefer-es6-class */
import React from 'react';
import { mount } from 'enzyme';
import Upload from '..';
import Form from '../../form';
import { T, fileToObject, getFileItem, removeFileItem } from '../utils';
import { setup, teardown } from './mock';
import { resetWarned } from '../../_util/warning';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
describe('Upload', () => {
mountTest(Upload);
rtlTest(Upload);
beforeEach(() => setup());
afterEach(() => teardown());
// https://github.com/react-component/upload/issues/36
it('should get refs inside Upload in componentDidMount', () => {
let ref;
class App extends React.Component {
componentDidMount() {
ref = this.refs.input;
}
render() {
return (
<Upload supportServerRender={false}>
<input ref="input" />
</Upload>
);
}
}
mount(<App />);
expect(ref).toBeDefined();
});
it('return promise in beforeUpload', done => {
const data = jest.fn();
const props = {
action: 'http://upload.com',
beforeUpload: () => new Promise(resolve => setTimeout(() => resolve('success'), 100)),
data,
onChange: ({ file }) => {
if (file.status !== 'uploading') {
expect(data).toHaveBeenCalled();
done();
}
},
};
const wrapper = mount(
<Upload {...props}>
<button type="button">upload</button>
</Upload>,
);
wrapper.find('input').simulate('change', {
target: {
files: [{ file: 'foo.png' }],
},
});
});
it('beforeUpload can be falsy', done => {
const props = {
action: 'http://upload.com',
beforeUpload: false,
onChange: ({ file }) => {
if (file.status !== 'uploading') {
done();
}
},
};
const wrapper = mount(
<Upload {...props}>
<button type="button">upload</button>
</Upload>,
);
wrapper.find('input').simulate('change', {
target: {
files: [{ file: 'foo.png' }],
},
});
});
it('upload promise return file in beforeUpload', done => {
const data = jest.fn();
const props = {
action: 'http://upload.com',
beforeUpload: file =>
new Promise(resolve =>
setTimeout(() => {
const result = file;
result.name = 'test.png';
resolve(result);
}, 100),
),
data,
onChange: ({ file }) => {
if (file.status !== 'uploading') {
expect(data).toHaveBeenCalled();
expect(file.name).toEqual('test.png');
done();
}
},
};
const wrapper = mount(
<Upload {...props}>
<button type="button">upload</button>
</Upload>,
);
wrapper.find('input').simulate('change', {
target: {
files: [{ file: 'foo.png' }],
},
});
});
it('should not stop upload when return value of beforeUpload is false', done => {
const fileList = [
{
uid: 'bar',
name: 'bar.png',
},
];
const mockFile = new File(['foo'], 'foo.png', {
type: 'image/png',
});
const data = jest.fn();
const props = {
action: 'http://upload.com',
fileList,
beforeUpload: () => false,
data,
onChange: ({ file, fileList: updatedFileList }) => {
expect(file instanceof File).toBe(true);
expect(updatedFileList.map(f => f.name)).toEqual(['bar.png', 'foo.png']);
expect(data).not.toHaveBeenCalled();
done();
},
};
const wrapper = mount(
<Upload {...props}>
<button type="button">upload</button>
</Upload>,
);
wrapper.find('input').simulate('change', {
target: {
files: [mockFile],
},
});
});
it('should not stop upload when return value of beforeUpload is not false', done => {
const data = jest.fn();
const props = {
action: 'http://upload.com',
beforeUpload() {},
data,
onChange: () => {
expect(data).toHaveBeenCalled();
done();
},
};
const wrapper = mount(
<Upload {...props}>
<button type="button">upload</button>
</Upload>,
);
wrapper.find('input').simulate('change', {
target: {
files: [{ file: 'foo.png' }],
},
});
});
// https://github.com/ant-design/ant-design/issues/14779
it('should contain input file control if upload button is hidden', () => {
const wrapper = mount(
<Upload action="http://upload.com">
<button type="button">upload</button>
</Upload>,
);
expect(wrapper.find('input[type="file"]').length).toBe(1);
wrapper.setProps({ children: null });
expect(wrapper.find('input[type="file"]').length).toBe(1);
});
// https://github.com/ant-design/ant-design/issues/14298
it('should not have id if upload children is null, avoid being triggered by label', () => {
// eslint-disable-next-line
const Demo = ({ children }) => (
<Form>
<Form.Item name="upload" label="Upload" valuePropName="fileList">
<Upload>{children}</Upload>
</Form.Item>
</Form>
);
const wrapper = mount(
<Demo>
<div>upload</div>
</Demo>,
);
expect(wrapper.find('input#upload').length).toBe(1);
wrapper.setProps({ children: null });
expect(wrapper.find('input#upload').length).toBe(0);
});
// https://github.com/ant-design/ant-design/issues/16478
it('should not have id if upload is disabled, avoid being triggered by label', () => {
// eslint-disable-next-line
const Demo = ({ disabled }) => (
<Form>
<Form.Item name="upload" label="Upload" valuePropName="fileList">
<Upload disabled={disabled}>
<div>upload</div>
</Upload>
</Form.Item>
</Form>
);
const wrapper = mount(<Demo />);
expect(wrapper.find('input#upload').length).toBe(1);
wrapper.setProps({ disabled: true });
expect(wrapper.find('input#upload').length).toBe(0);
});
it('should be controlled by fileList', () => {
const fileList = [
{
uid: '-1',
name: 'foo.png',
status: 'done',
url: 'http://www.baidu.com/xxx.png',
},
];
const wrapper = mount(<Upload />);
expect(wrapper.instance().state.fileList).toEqual([]);
wrapper.setProps({ fileList });
expect(wrapper.instance().state.fileList).toEqual(fileList);
});
describe('util', () => {
// https://github.com/react-component/upload/issues/36
it('should T() return true', () => {
const res = T();
expect(res).toBe(true);
});
it('should be able to copy file instance', () => {
const file = new File([], 'aaa.zip');
const copiedFile = fileToObject(file);
['uid', 'lastModified', 'lastModifiedDate', 'name', 'size', 'type'].forEach(key => {
expect(key in copiedFile).toBe(true);
});
});
it('should be able to get fileItem', () => {
const file = { uid: '-1', name: 'item.jpg' };
const fileList = [
{
uid: '-1',
name: 'item.jpg',
},
];
const targetItem = getFileItem(file, fileList);
expect(targetItem).toBe(fileList[0]);
});
it('should be able to remove fileItem', () => {
const file = { uid: '-1', name: 'item.jpg' };
const fileList = [
{
uid: '-1',
name: 'item.jpg',
},
{
uid: '-2',
name: 'item2.jpg',
},
];
const targetItem = removeFileItem(file, fileList);
expect(targetItem).toEqual(fileList.slice(1));
});
it('should not be able to remove fileItem', () => {
const file = { uid: '-3', name: 'item.jpg' };
const fileList = [
{
uid: '-1',
name: 'item.jpg',
},
{
uid: '-2',
name: 'item2.jpg',
},
];
const targetItem = removeFileItem(file, fileList);
expect(targetItem).toBe(null);
});
});
it('should support linkProps as object', () => {
const fileList = [
{
uid: '-1',
name: 'foo.png',
status: 'done',
url: 'http://www.baidu.com/xxx.png',
linkProps: {
download: 'image',
rel: 'noopener',
},
},
];
const wrapper = mount(<Upload fileList={fileList} />);
const linkNode = wrapper.find('a.ant-upload-list-item-name');
expect(linkNode.props().download).toBe('image');
expect(linkNode.props().rel).toBe('noopener');
});
it('should support linkProps as json stringify', () => {
const linkPropsString = JSON.stringify({
download: 'image',
rel: 'noopener',
});
const fileList = [
{
uid: '-1',
name: 'foo.png',
status: 'done',
url: 'http://www.baidu.com/xxx.png',
linkProps: linkPropsString,
},
];
const wrapper = mount(<Upload fileList={fileList} />);
const linkNode = wrapper.find('a.ant-upload-list-item-name');
expect(linkNode.props().download).toBe('image');
expect(linkNode.props().rel).toBe('noopener');
});
it('should not stop remove when return value of onRemove is false', done => {
const mockRemove = jest.fn(() => false);
const props = {
onRemove: mockRemove,
fileList: [
{
uid: '-1',
name: 'foo.png',
status: 'done',
url: 'http://www.baidu.com/xxx.png',
},
],
};
const wrapper = mount(<Upload {...props} />);
wrapper.find('div.ant-upload-list-item .anticon-delete').simulate('click');
setImmediate(() => {
wrapper.update();
expect(mockRemove).toHaveBeenCalled();
expect(props.fileList).toHaveLength(1);
expect(props.fileList[0].status).toBe('done');
done();
});
});
// https://github.com/ant-design/ant-design/issues/18902
it('should not abort uploading until return value of onRemove is resolved as true', done => {
let wrapper;
const props = {
onRemove: () =>
new Promise(
resolve =>
setTimeout(() => {
wrapper.update();
expect(props.fileList).toHaveLength(1);
expect(props.fileList[0].status).toBe('uploading');
resolve(true);
}),
100,
),
fileList: [
{
uid: '-1',
name: 'foo.png',
status: 'uploading',
url: 'http://www.baidu.com/xxx.png',
},
],
onChange: () => {
expect(props.fileList).toHaveLength(1);
expect(props.fileList[0].status).toBe('removed');
done();
},
};
wrapper = mount(<Upload {...props} />);
wrapper.find('div.ant-upload-list-item .anticon-delete').simulate('click');
});
it('should not stop download when return use onDownload', done => {
const mockRemove = jest.fn(() => false);
const props = {
onRemove: mockRemove,
fileList: [
{
uid: '-1',
name: 'foo.png',
status: 'done',
url: 'http://www.baidu.com/xxx.png',
},
],
};
const wrapper = mount(<Upload {...props} onDownload={() => {}} />);
wrapper.find('div.ant-upload-list-item .anticon-download').simulate('click');
setImmediate(() => {
wrapper.update();
expect(props.fileList).toHaveLength(1);
expect(props.fileList[0].status).toBe('done');
done();
});
});
// https://github.com/ant-design/ant-design/issues/14439
it('should allow call abort function through upload instance', () => {
const wrapper = mount(
<Upload>
<button type="button">upload</button>
</Upload>,
);
expect(typeof wrapper.instance().upload.abort).toBe('function');
});
it('unmount', () => {
const wrapper = mount(
<Upload>
<button type="button">upload</button>
</Upload>,
);
const clearIntervalSpy = jest.spyOn(global, 'clearInterval');
expect(clearIntervalSpy).not.toHaveBeenCalled();
wrapper.unmount();
expect(clearIntervalSpy).toHaveBeenCalled();
clearIntervalSpy.mockRestore();
});
it('correct dragCls when type is drag', () => {
const fileList = [{ status: 'uploading', uid: 'file' }];
const wrapper = mount(
<Upload type="drag" fileList={fileList}>
<button type="button">upload</button>
</Upload>,
);
expect(wrapper.find('.ant-upload-drag-uploading').length).toBe(1);
});
it('return when targetItem is null', () => {
const fileList = [{ uid: 'file' }];
const wrapper = mount(
<Upload type="drag" fileList={fileList}>
<button type="button">upload</button>
</Upload>,
).instance();
expect(wrapper.onSuccess('', { uid: 'fileItem' })).toBe(undefined);
expect(wrapper.onProgress('', { uid: 'fileItem' })).toBe(undefined);
expect(wrapper.onError('', '', { uid: 'fileItem' })).toBe(undefined);
});
it('warning if set `value`', () => {
resetWarned();
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
mount(<Upload value={[]} />);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Upload] `value` is not validate prop, do you mean `fileList`?',
);
errorSpy.mockRestore();
});
});