import React from 'react'; import { mount } from 'enzyme'; import Upload from '..'; import Form from '../../form'; import { errorRequest, successRequest } from './requests'; import { setup, teardown } from './mock'; const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout)); const fileList = [{ uid: '-1', name: 'xxx.png', status: 'done', url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', thumbUrl: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png', }, { uid: '-2', name: 'yyy.png', status: 'done', url: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png', thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', }]; describe('Upload List', () => { beforeEach(() => setup()); afterEach(() => teardown()); // https://github.com/ant-design/ant-design/issues/4653 it('should use file.thumbUrl for in priority', () => { const wrapper = mount( ); fileList.forEach((file, i) => { const linkNode = wrapper.find('.ant-upload-list-item-thumbnail').at(i); const imgNode = wrapper.find('.ant-upload-list-item-thumbnail img').at(i); expect(linkNode.prop('href')).toBe(file.url); expect(imgNode.prop('src')).toBe(file.thumbUrl); }); }); // https://github.com/ant-design/ant-design/issues/7269 it('should remove correct item when uid is 0', async () => { const list = [{ uid: '0', name: 'xxx.png', status: 'done', url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', thumbUrl: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png', }, { uid: '1', name: 'xxx.png', status: 'done', url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', thumbUrl: 'https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png', }]; const wrapper = mount( ); expect(wrapper.find('.ant-upload-list-item').length).toBe(2); wrapper.find('.ant-upload-list-item').at(0).find('.anticon-cross').simulate('click'); await delay(400); wrapper.update(); expect(wrapper.find('.ant-upload-list-item').hostNodes().length).toBe(1); }); it('should be uploading when upload a file', (done) => { let wrapper; const onChange = ({ file }) => { if (file.status === 'uploading') { expect(wrapper.render()).toMatchSnapshot(); } if (file.status === 'done') { expect(wrapper.render()).toMatchSnapshot(); done(); } }; wrapper = mount( ); wrapper.find('input').simulate('change', { target: { files: [ { name: 'foo.png' }, ], }, }); }); it('handle error', (done) => { let wrapper; const onChange = ({ file }) => { if (file.status !== 'uploading') { expect(wrapper.render()).toMatchSnapshot(); done(); } }; wrapper = mount( ); wrapper.find('input').simulate('change', { target: { files: [ { name: 'foo.png' }, ], }, }); }); it('does concat filelist when beforeUpload returns false', () => { const handleChange = jest.fn(); const wrapper = mount( false} > ); wrapper.find('input').simulate('change', { target: { files: [ { name: 'foo.png' }, ], }, }); expect(wrapper.state().fileList.length).toBe(fileList.length + 1); expect(handleChange.mock.calls[0][0].fileList).toHaveLength(3); }); // https://github.com/ant-design/ant-design/issues/7762 it('work with form validation', () => { let errors; class TestForm extends React.Component { handleSubmit = () => { const { form: { validateFields } } = this.props; validateFields((err) => { errors = err; }); } render() { const { form: { getFieldDecorator } } = this.props; return (
{getFieldDecorator('file', { valuePropname: 'fileList', getValueFromEvent: e => e.fileList, rules: [ { required: true, validator: (rule, value, callback) => { if (!value || value.length === 0) { callback('file required'); } else { callback(); } }, }, ], })( false} > )}
); } } const App = Form.create()(TestForm); const wrapper = mount(); wrapper.find(Form).simulate('submit'); expect(errors.file.errors).toEqual([{ message: 'file required', field: 'file' }]); wrapper.find('input').simulate('change', { target: { files: [ { name: 'foo.png' }, ], }, }); wrapper.find(Form).simulate('submit'); expect(errors).toBeNull(); }); it('should support onPreview', () => { const handlePreview = jest.fn(); const wrapper = mount( ); wrapper.find('.anticon-eye-o').at(0).simulate('click'); expect(handlePreview).toBeCalledWith(fileList[0]); wrapper.find('.anticon-eye-o').at(1).simulate('click'); expect(handlePreview).toBeCalledWith(fileList[1]); }); it('should support onRemove', async () => { const handleRemove = jest.fn(); const handleChange = jest.fn(); const wrapper = mount( ); wrapper.find('.anticon-delete').at(0).simulate('click'); expect(handleRemove).toBeCalledWith(fileList[0]); wrapper.find('.anticon-delete').at(1).simulate('click'); expect(handleRemove).toBeCalledWith(fileList[1]); await delay(0); expect(handleChange.mock.calls.length).toBe(2); }); it('should generate thumbUrl from file', async () => { const handlePreview = jest.fn(); const newFileList = [...fileList]; const newFile = { ...fileList[0], uid: '-3', originFileObj: new File([], 'xxx.png') }; delete newFile.thumbUrl; newFileList.push(newFile); const wrapper = mount( ); wrapper.setState({}); await delay(0); expect(wrapper.state().fileList[2].thumbUrl).not.toBe(undefined); }); it('should non-image format file preview', () => { const list = [ { name: 'not-image', status: 'done', uid: '-3', url: 'https://cdn.xxx.com/aaa.zip', thumbUrl: 'data:application/zip;base64,UEsDBAoAAAAAADYZYkwAAAAAAAAAAAAAAAAdAAk', originFileObj: new File([], 'aaa.zip'), }, { name: 'image', status: 'done', uid: '-4', url: 'https://cdn.xxx.com/aaa', }, { name: 'not-image', status: 'done', uid: '-5', url: 'https://cdn.xxx.com/aaa.xx', }, { name: 'not-image', status: 'done', uid: '-6', url: 'https://cdn.xxx.com/aaa.png/xx.xx', }, { name: 'image', status: 'done', uid: '-7', url: 'https://cdn.xxx.com/xx.xx/aaa.png', }, { name: 'image', status: 'done', uid: '-8', url: 'https://cdn.xxx.com/xx.xx/aaa.png', thumbUrl: 'data:image/png;base64,UEsDBAoAAAAAADYZYkwAAAAAAAAAAAAAAAAdAAk', }, { name: 'image', status: 'done', uid: '-9', url: 'https://cdn.xxx.com/xx.xx/aaa.png?query=123', }, { name: 'image', status: 'done', uid: '-10', url: 'https://cdn.xxx.com/xx.xx/aaa.png#anchor', }, { name: 'image', status: 'done', uid: '-11', url: 'https://cdn.xxx.com/xx.xx/aaa.png?query=some.query.with.dot', }, { name: 'image', status: 'done', uid: '-12', url: 'https://publish-pic-cpu.baidu.com/1296beb3-50d9-4276-885f-52645cbb378e.jpeg@w_228%2ch_152', type: 'image', }, ]; const wrapper = mount( ); expect(wrapper.render()).toMatchSnapshot(); }); });