import sleep from '@douyinfe/semi-ui/_test_/utils/function/sleep';
import { IconUser } from '@douyinfe/semi-icons';
import { Upload, Button } from '../../index';
import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
let action = 'https://semi.bytendance.com';
const PROGRESS_COEFFICIENT = 0.95;
function getUpload(props, formProps = {}) {
if (!props.children) {
props.children = (
} theme="light">
点击上传
);
}
if (!props.action) {
props.action = action;
}
return mount();
}
function trigger(upload, event) {
const input = upload.find(`.${BASE_CLASS_PREFIX}-upload-hidden-input`);
input.simulate('change', event);
}
const file = new File(['(⌐□_□)'], 'chucknorris.png', { type: 'image/png' });
const createFile = (size = 44320, name = 'semi-logo.png', type = 'image/png') => {
return new File([new ArrayBuffer(size)], name, {
type: type,
});
};
const createEvent = file => {
let event = { target: { files: [file] } };
return event;
};
const defaultFileList = [
{
uid: '1',
name: 'vigo.png',
status: 'success',
size: '130KB',
preview: true,
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
},
{
uid: '2',
name: 'test.jpeg',
status: 'uploadFail',
size: '222KB',
preview: false,
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
},
];
// TODO
/**
* 1、unitTest无法测试点击Upload Children自动弹出文件浏览器的case,需要在e2e里完成
* 2、multiple 属性无法测试,理由同上
* 3、disabled时点击不弹出文件浏览器的行为无法测试,理由同上
*/
describe('Upload', () => {
let requests;
let xhr;
window.URL.createObjectURL = jest.fn();
beforeEach(() => {
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCreate = req => requests.push(req);
window.URL.createObjectURL.mockReset();
});
afterEach(() => {
xhr.restore();
});
it('className & style', () => {
let props = {
className: 'test',
style: { color: 'red' },
action: '',
};
const upload = getUpload(props);
expect(upload.find('div.test').length).toEqual(1);
});
it('action / withCredentials', () => {
let props = {
action,
withCredentials: true,
data: { semiKey: 123456 },
};
const upload = getUpload(props);
let event = { target: { files: [file] } };
trigger(upload, event);
expect(requests[0].url).toEqual(action);
expect(requests[0].withCredentials).toEqual(true);
});
it('data / headers / name', () => {
let headers = { 'x-tt-header': 'semi' };
let name = 'bytedance.jpeg';
let props = {
data: { semiKey: 123456 },
name,
headers,
};
const upload = getUpload(props);
let event = { target: { files: [file] } };
trigger(upload, event);
let requestBody = Array.from(requests[0].requestBody);
expect(requestBody[0][0]).toEqual('semiKey');
expect(requestBody[0][1]).toEqual('123456');
let requestHeaders = requests[0].requestHeaders;
expect(requestHeaders).toEqual(headers);
expect(requestBody[1][0]).toEqual(name);
});
it('data / headrs : function', () => {
let headers = { 'x-tt-header': 'semi' };
let data = { semiKey: 123456 };
let getHeaders = file => {
return headers;
};
let getData = file => {
return data;
};
let spyGetData = sinon.spy(getData);
let spyGetHeaders = sinon.spy(getHeaders);
let props = {
data: spyGetData,
headers: spyGetHeaders,
};
const upload = getUpload(props);
let event = { target: { files: [file] } };
trigger(upload, event);
// test data
let requestBody = Array.from(requests[0].requestBody);
expect(requestBody[0][0]).toEqual('semiKey');
expect(requestBody[0][1]).toEqual('123456');
expect(spyGetData.calledOnce).toEqual(true);
expect(spyGetData.calledWithMatch(file)).toEqual(true);
// test headers
let requestHeaders = requests[0].requestHeaders;
expect(requestHeaders).toEqual(headers);
expect(spyGetHeaders.calledOnce).toEqual(true);
expect(spyGetHeaders.calledWithMatch(file)).toEqual(true);
});
it('accept', () => {
let accept = 'application/pdf,image/png,image/jpeg';
let props = {
accept,
};
const upload = getUpload(props);
expect(upload.find(`input.${BASE_CLASS_PREFIX}-upload-hidden-input`).instance().accept).toEqual(accept);
});
it('minSize / maxSize / onSizeError', () => {
let kb1 = 1024 * 1024;
let onSizeError = (file, fileList) => {};
let spyOnSizeError = sinon.spy(onSizeError);
let props = {
maxSize: kb1 * 3,
minSize: kb1 * 2,
onSizeError: spyOnSizeError,
};
const upload = getUpload(props);
const bigFile = createFile(kb1 * 4, 'bigSemi.jpeg');
const smallFile = createFile(kb1, 'smallSemi.jpeg');
let bigEvent = { target: { files: [bigFile] } };
let smallEvent = { target: { files: [smallFile] } };
// choose file over maxSize
trigger(upload, bigEvent);
// choose file below minSize
trigger(upload, smallEvent);
expect(spyOnSizeError.callCount).toEqual(2);
let firstCall = spyOnSizeError.getCall(0);
let secondCall = spyOnSizeError.getCall(1);
let firstArgs = firstCall.args;
let secondArgs = secondCall.args;
// 如果是calledWithMatch({}, []) 这种写法,即使放空object,和空数组也能过,可能只判断了类型?但实际上第一个参数是File
// 这里借助文件name来判断一下
expect(firstArgs[0] instanceof File).toEqual(true);
expect(firstArgs[0].name).toEqual('bigSemi.jpeg');
expect(Array.isArray(firstArgs[1]) && firstArgs[1].length === 0).toEqual(true);
// expect(firstCall.calledWithMatch({}, [])).toEqual(true);
expect(secondArgs[0] instanceof File).toEqual(true);
expect(secondArgs[0].name).toEqual('smallSemi.jpeg');
expect(
Array.isArray(secondArgs[1]) && secondArgs[1].length === 1 && secondArgs[1][0].name === 'bigSemi.jpeg'
).toEqual(true);
});
it('prompt / promptPosition', () => {
let prompt = 'Some info for extra text';
let props = {
prompt,
promptPosition: 'right',
};
const upload = getUpload(props);
expect(upload.find(`.${BASE_CLASS_PREFIX}-upload-prompt`).text()).toEqual(prompt);
expect(upload.find(`.${BASE_CLASS_PREFIX}-upload`).instance().getAttribute('x-prompt-pos')).toEqual('right');
upload.setProps({ promptPosition: 'bottom' });
upload.update();
expect(upload.find(`.${BASE_CLASS_PREFIX}-upload`).instance().getAttribute('x-prompt-pos')).toEqual('bottom');
upload.setProps({ promptPosition: 'left' });
upload.update();
expect(upload.find(`.${BASE_CLASS_PREFIX}-upload`).instance().getAttribute('x-prompt-pos')).toEqual('left');
});
it('limit / onExceed', () => {
let onExceed = (file, fileList) => {
// debugger;
};
let spyOnExceed = sinon.spy(onExceed);
let props = {
limit: 2,
onExceed: spyOnExceed,
};
const upload = getUpload(props);
let fileA = createFile(1024, 'fileA');
let fileB = createFile(1024, 'fileB');
let fileC = createFile(1024, 'fileC');
let files = [fileA, fileB, fileC];
let event = {
target: { files },
};
trigger(upload, event);
expect(spyOnExceed.calledOnce).toEqual(true);
// expect(spyOnExceed.calledWithMatch(fileC, files)).toEqual(true);
});
it('beforeUpload - return boolean', () => {
let beforeUpload = ({ file, fileList }) => {
if (file.name === 'pass.jpg') {
return true;
}
return false;
};
let spyBefore = sinon.spy(beforeUpload);
const props = {
beforeUpload: spyBefore,
};
const upload = getUpload(props);
let event = createEvent(createFile(10, 'pass.jpg'));
trigger(upload, event);
expect(upload.state().fileList[0].name).toEqual('pass.jpg');
event = createEvent(createFile(20, 'fail.jpg'));
trigger(upload, event);
const fileList = upload.state().fileList;
expect(fileList.length).toEqual(2);
expect(fileList[0].status === 'uploading').toEqual(true);
expect(fileList[1].status === 'validateFail').toEqual(true);
expect(spyBefore.callCount).toEqual(2);
});
it('beforeUpload - return object sync', () => {
// beforeUploadResult:
// {
// fileInstance?: File,
// status?: 'success' | 'uploadFail' | 'validateFail' | 'validating' | 'uploading' | 'wait',
// validateMessage?: React.ReactNode | string, // 文件的校验信息
// shouldUpload: boolean, // 是否需要上传。默认为true,如果为false,该fileItem只会被展示在列表中,不会触发上传操作
// autoRemove?: boolean, // 是否从fileList中移除该文件,默认为false
// }
let beforeUpload = ({ file, fileList }) => {
let result = {
shouldUpload: false,
autoRemove: false,
};
if (file.name === 'pass.jpg') {
result.shouldUpload = true;
}
if (file.name === 'invalid.jpg') {
result.validateMessage = 'not valid file';
result.status = 'validateFail';
}
if (file.name === 'autoRemove.jpg') {
result.autoRemove = true;
}
return result;
};
let spyBefore = sinon.spy(beforeUpload);
const props = {
beforeUpload: spyBefore,
};
const upload = getUpload(props);
// pass a file will pass validate
let eventA = createEvent(createFile(10, 'pass.jpg'));
trigger(upload, eventA);
expect(upload.state().fileList[0].name).toEqual('pass.jpg');
// pass a file invalid & change it's validateMessage & status
let eventB = createEvent(createFile(20, 'invalid.jpg'));
trigger(upload, eventB);
// pass a file invalid & auto remove this file from fileList
let eventC = createEvent(createFile(30, 'autoRemove.jpg'));
trigger(upload, eventC);
const fileList = upload.state().fileList;
expect(fileList.length).toEqual(2);
expect(fileList[0].status === 'uploading').toEqual(true);
expect(fileList[1].status === 'validateFail').toEqual(true);
expect(fileList[1].validateMessage === 'not valid file').toEqual(true);
expect(fileList.every(item => item !== 'autoRemove.jpg')).toEqual(true);
expect(spyBefore.callCount).toEqual(3);
});
// 1、promise reject:not upload file
// 2、promise resolve: upload file
// 3、promise reslove / reject object
it('beforeUpload - return promise', async () => {
function selectFile(filename, upload) {
let file = createFile(50, filename);
let event = createEvent(file);
trigger(upload, event);
}
let beforeUpload = ({ file, fileList }) => {
let result;
switch (file.name) {
case 'reject.jpg':
result = new Promise((resolve, reject) => setTimeout(reject, 10));
break;
case 'resolve.jpg':
result = new Promise((resolve, reject) => setTimeout(resolve, 10));
break;
case 'resloveObject.jpg':
let pro = new Promise((resolve, reject) => {
let newFile = createFile(200, 'afterProcess.jpg');
let result = {
fileInstance: newFile,
// shouldUpload: true,
};
setTimeout(() => resolve(result), 10);
});
result = pro;
break;
case 'rejectObject.jpg':
let pro2 = new Promise((resolve, reject) => {
let result = {
status: 'validateFail',
validateMessage: 'not valid',
// shouldUpload: false,
};
setTimeout(() => reject(result), 10);
});
result = pro2;
break;
default:
break;
}
return result;
};
let spyBefore = sinon.spy(beforeUpload);
const props = {
beforeUpload: spyBefore,
};
const upload = getUpload(props);
selectFile('reject.jpg', upload);
await sleep(60);
selectFile('resolve.jpg', upload);
await sleep(60);
selectFile('resloveObject.jpg', upload);
await sleep(60);
selectFile('rejectObject.jpg', upload);
await sleep(100);
expect(spyBefore.callCount).toEqual(4);
const fileList = upload.state().fileList;
expect(fileList.length).toEqual(4);
expect(fileList[0].status === 'validateFail').toEqual(true);
expect(fileList[1].status === 'uploading').toEqual(true);
expect(fileList[2].status === 'uploading' && fileList[2].fileInstance.name === 'afterProcess.jpg').toEqual(
true
);
expect(fileList[3].status === 'validateFail' && fileList[3].validateMessage === 'not valid').toEqual(true);
});
it('onFileChange', () => {
let onFileChange = files => {};
let spyOnFileChange = sinon.spy(onFileChange);
const props = {
onFileChange: spyOnFileChange,
};
const upload = getUpload(props);
let event = { target: { files: [file] } };
trigger(upload, event);
expect(spyOnFileChange.calledOnce).toEqual(true);
expect(spyOnFileChange.calledWithMatch([file])).toEqual(true);
});
it('onProgress', () => {
let onProgress = (percent, file, fileList) => {};
let spyProgress = sinon.spy(onProgress);
let props = {
onProgress: spyProgress,
};
const server = sinon.fakeServer.create();
const upload = getUpload(props);
let event = { target: { files: [file] } };
trigger(upload, event);
server.requests[0].uploadProgress({ loaded: 40, total: 100 });
server.requests[0].uploadProgress({ loaded: 80, total: 100 });
expect(spyProgress.callCount).toEqual(2);
expect(spyProgress.getCall(0).calledWithMatch(40 * PROGRESS_COEFFICIENT)).toEqual(true);
expect(spyProgress.getCall(1).calledWithMatch(80 * PROGRESS_COEFFICIENT)).toEqual(true);
});
it('onError', () => {
let onError = (responseBody, file, fileList, xhr) => {};
let spyOnError = sinon.spy(onError);
const props = {
onError: spyOnError,
};
const upload = getUpload(props);
let event = { target: { files: [file] } };
trigger(upload, event);
requests[0].respond(404, { 'Content-Type': 'application/json' }, '[{ "id": 12, "comment": "Hey there" }]');
expect(spyOnError.calledOnce).toEqual(true);
const [error, fileInstance, fileList, xhr] = spyOnError.args[0];
expect(error.method).toEqual('post');
expect(fileInstance instanceof File).toEqual(true);
expect(Array.isArray(fileList)).toEqual(true);
expect(xhr instanceof XMLHttpRequest).toEqual(true);
});
it('onRetry', () => {
const onRetry = f => {};
const spyOnRetry = sinon.spy(onRetry);
const fileInstance = createFile(200, 'semi.jpg');
const file = {
uid: '2',
name: 'test.jpeg',
status: 'uploadFail',
size: '222KB',
preview: true,
fileInstance,
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
};
const props = {
fileList: [file],
onRetry: spyOnRetry,
};
const upload = getUpload(props);
upload.find(`.${BASE_CLASS_PREFIX}-upload-file-card-info-retry`).simulate('click');
expect(spyOnRetry.calledOnce).toEqual(true);
const [f] = spyOnRetry.args[0];
expect(f.fileInstance instanceof File).toEqual(true);
});
it('onOpenFileDialog', () => {
const onOpenFileDialog = () => {};
const spyOnOpenFileDialog = sinon.spy(onOpenFileDialog);
const props = {
onOpenFileDialog: spyOnOpenFileDialog,
};
const upload = getUpload(props);
upload.find(`div.${BASE_CLASS_PREFIX}-upload-add`).simulate('click');
expect(spyOnOpenFileDialog.calledOnce).toEqual(true);
});
it('onSuccess', () => {
let body = [{ id: 12, comment: 'Hey there' }];
let onSuccess = (responseBody, file, fileList) => {
console.log(body);
// debugger;
};
let spyOnSuccess = sinon.spy(onSuccess);
const props = {
onSuccess: spyOnSuccess,
};
const upload = getUpload(props);
let event = { target: { files: [file] } };
trigger(upload, event);
requests[0].respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(body));
expect(spyOnSuccess.calledOnce).toEqual(true);
// TODO check argument,凡是涉及到fileList的都会failed
expect(spyOnSuccess.calledWith([{ id: 12, comment: 'Hey there' }], file)).toEqual(true);
});
it('onRemove', () => {
let onRemove = (file, fileList) => {};
const spyOnRemove = sinon.spy(onRemove);
let fileInstance = createFile(200, 'semi.jpg');
let file = {
uid: '2',
name: 'test.jpeg',
status: 'error',
size: '222KB',
preview: true,
fileInstance,
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
};
let props = {
defaultFileList: [file],
onRemove: spyOnRemove,
};
const upload = getUpload(props);
upload.find(`button.${BASE_CLASS_PREFIX}-upload-file-card-close`).simulate('click', {});
setTimeout(() => {
expect(spyOnRemove.calledOnce).toEqual(true);
expect(spyOnRemove.calledOnceWith(fileInstance, [])).toEqual(true);
});
});
it('defaultFileList', () => {
let props = {
defaultFileList,
};
const upload = getUpload(props);
expect(upload.find(`.${BASE_CLASS_PREFIX}-upload-file-list`).children().length).toEqual(2);
// TODO check item name, size, preview
});
it('showUploadList', () => {
let props = {
showUploadList: false,
defaultFileList: [
{
uid: '2',
name: 'test.jpeg',
status: 'error',
size: '222KB',
preview: true,
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
},
],
};
const upload = getUpload(props);
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload-file-list`)).toEqual(false);
});
it('listType', () => {
let props = {
listType: 'picture',
};
const upload = getUpload(props);
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload.${BASE_CLASS_PREFIX}-upload-picture`)).toEqual(true);
});
it('previewFile', () => {
let specificContent =
2
;
let previewFile = () => specificContent;
let spyPreview = sinon.spy(previewFile);
let props = {
previewFile: spyPreview,
};
const upload = getUpload(props);
let event = { target: { files: [file] } };
trigger(upload, event);
requests[0].respond(200, { 'Content-Type': 'application/json' }, 'success');
const previewContent = upload.find(`.${BASE_CLASS_PREFIX}-upload-file-card-preview`);
expect(previewContent.contains(specificContent)).toEqual(true);
upload.unmount();
});
it('afterUpload', () => {
// afterUploadResult:
// {
// status?: 'success' | 'uploadFail' | 'validateFail' | 'validating' | 'uploading' | 'wait',
// validateMessage?: React.ReactNode | string, // 文件的校验信息
// autoRemove: boolean, // 是否从fileList中移除该文件,默认为false
// name: string,
// }
let codeStatusMaps = {
0: 'success',
1: 'uploadFail',
2: 'validateFail',
};
let afterUpload = ({ response, file, fileList }) => {
let result = {};
result.status = codeStatusMaps[response.code];
if (response.message) {
result.validateMessage = response.message;
}
if (response.autoRemove) {
result.autoRemove = true;
}
if (response.newName) {
result.name = response.newName;
}
return result;
};
let spyAfterUpload = sinon.spy(afterUpload);
let props = {
afterUpload: spyAfterUpload,
};
const upload = getUpload(props);
// test status-success
let eventA = { target: { files: [createFile(234, 'uploadSuccess.jpg')] } };
let resA = { code: 0 };
trigger(upload, eventA);
requests[0].respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(resA));
// test status-uploadFail & validateMessage
let eventB = { target: { files: [createFile(123, 'uploadFail.jpg')] } };
trigger(upload, eventB);
let uploadFailMessage = 'upload request fail';
let resB = { code: 1, message: uploadFailMessage };
requests[1].respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(resB));
// test status-validateFail & validateMessage
let eventC = { target: { files: [createFile(123, 'validateFail.jpg')] } };
trigger(upload, eventC);
let validateFailMessage = 'what u upload is invalid';
let resC = { code: 2, message: validateFailMessage };
requests[2].respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(resC));
// test autoRemove, should auto remove this file
let eventD = { target: { files: [createFile(123, 'remove.jpg')] } };
trigger(upload, eventD);
let resD = { code: 2, autoRemove: true };
requests[3].respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(resD));
// test rename
let eventE = { target: { files: [createFile(123, 'semi.jpg')] } };
trigger(upload, eventE);
let rename = 'renameByAfterUpload.jpg';
let resE = { code: 1, newName: rename };
requests[4].respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(resE));
const stateFileList = upload.state().fileList;
expect(stateFileList.length).toEqual(4);
expect(stateFileList[0].status === 'success').toEqual(true);
expect(
stateFileList[1].status === 'uploadFail' && stateFileList[1].validateMessage === uploadFailMessage
).toEqual(true);
expect(
stateFileList[2].status === 'validateFail' && stateFileList[2].validateMessage === validateFailMessage
).toEqual(true);
expect(stateFileList.every(item => item.name !== 'remove.jpg')).toEqual(true);
expect(stateFileList[3].status === 'uploadFail' && stateFileList[3].name === rename).toEqual(true);
upload.unmount();
});
it('uploadTrigger', () => {
let props = {
uploadTrigger: 'custom',
};
const upload = getUpload(props);
let eventA = { target: { files: [createFile(234, 'semi.jpg')] } };
trigger(upload, eventA);
expect(upload.state().fileList.length).toEqual(1);
console.log(requests);
expect(requests.length).toEqual(0);
upload.instance().upload();
// only new XHR after trigger upload instance (by ref) method: upload()
expect(requests.length).toEqual(1);
});
it('auto hide trigger when limit & listType="picture"', () => {
let props = {
limit: 2,
listType: 'picture',
defaultFileList,
};
const upload = getUpload(props);
expect(upload.find(`.${BASE_CLASS_PREFIX}-upload-file-list-main`).children().length).toEqual(2);
});
it('showClear', () => {
let props = {
defaultFileList,
showClear: false,
};
const upload = getUpload(props);
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload-file-list-title-clear`)).toEqual(false);
let props2 = {
defaultFileList,
};
const upload2 = getUpload(props2);
expect(upload2.exists(`.${BASE_CLASS_PREFIX}-upload-file-list-title-clear`)).toEqual(true);
});
it('showRetry', () => {
let props = {
defaultFileList,
showRetry: false,
};
const upload = getUpload(props);
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload-file-card-info-retry`)).toEqual(false);
});
it('validateMessage', () => {
let props = {
defaultFileList,
validateMessage: 'test',
};
const upload = getUpload(props);
expect(upload.find(`.${BASE_CLASS_PREFIX}-upload-validate-message`).text()).toEqual('test');
});
it('renderFileItem', () => {
let props = {
defaultFileList,
renderFileItem: fileItem => {fileItem.name}
,
};
const upload = getUpload(props);
expect(upload.find('.customRender').length).toEqual(2);
expect(upload.find('.customRender').at(0).text()).toEqual(defaultFileList[0].name);
expect(upload.find('.customRender').at(1).text()).toEqual(defaultFileList[1].name);
});
it('limit=1,file replace', () => {
let props = {
limit: 1,
defaultFileList,
};
const upload = getUpload(props);
const file = createFile(100, 'a.png');
const event = createEvent(file);
trigger(upload, event);
expect(upload.state().fileList.length).toEqual(1);
expect(upload.state().fileList[0].name).toEqual('a.png');
});
it('onAcceptInvalid when file change', () => {
const fakeOnAcceptInvalid = sinon.spy();
let props = {
accept: 'image/png',
onAcceptInvalid: fakeOnAcceptInvalid,
};
const upload = getUpload(props);
const input = upload.find(`.${BASE_CLASS_PREFIX}-upload-hidden-input`).at(0);
const file = createFile(100, 'a.jpg', 'image/jpg');
const event = { target: { files: [file] } };
input.simulate('change', event);
const arg = fakeOnAcceptInvalid.firstCall.args[0];
expect(fakeOnAcceptInvalid.calledOnce).toEqual(true);
expect(Array.isArray(arg)).toEqual(true);
expect(arg.length === 1).toEqual(true);
expect(arg[0].name === 'a.jpg').toEqual(true);
});
it('onAcceptInvalid when file replace', () => {
const fakeOnAcceptInvalid = sinon.spy();
let props = {
defaultFileList: [
{
uid: '1',
name: 'vigo.png',
status: 'success',
size: '130KB',
preview: true,
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
},
],
showReplace: true,
accept: 'image/png',
onAcceptInvalid: fakeOnAcceptInvalid,
};
const upload = getUpload(props);
const input = upload.find(`.${BASE_CLASS_PREFIX}-upload-hidden-input-replace`).at(0);
const file = createFile(100, 'a.jpg', 'image/jpg');
const event = { target: { files: [file] } };
upload.setState({ replaceIdx: 0 }, () => {
input.simulate('change', event);
const arg = fakeOnAcceptInvalid.firstCall.args[0];
expect(fakeOnAcceptInvalid.calledOnce).toEqual(true);
expect(Array.isArray(arg)).toEqual(true);
expect(arg.length === 1).toEqual(true);
expect(arg[0].name === 'a.jpg').toEqual(true);
});
});
it('beforeRemove effects', () => {
const props = {
fileList: [
{
uid: '1',
name: 'vigo.png',
status: 'success',
size: '130KB',
preview: true,
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
},
],
};
const spyOnChange = sinon.spy();
const spyOnRemove = sinon.spy();
const spyOnChangePass = sinon.spy();
const spyOnRemovePass = sinon.spy();
const upload = getUpload({
...props,
beforeRemove: () => false,
onChange: spyOnChange,
onRemove: spyOnRemove,
});
const uploadPass = getUpload({
...props,
beforeRemove: () => true,
onChange: spyOnChangePass,
onRemove: spyOnRemovePass,
});
const removeBtn = upload.find(`.${BASE_CLASS_PREFIX}-upload-file-card-close`).at(0);
const removeBtnPass = uploadPass.find(`.${BASE_CLASS_PREFIX}-upload-file-card-close`).at(0);
const event = { target: {} };
removeBtn.simulate('click', event);
removeBtnPass.simulate('click', event);
setTimeout(() => {
expect(spyOnChange.callCount).toEqual(0);
expect(spyOnRemove.callCount).toEqual(0);
expect(spyOnChangePass.callCount).toEqual(1);
expect(Array.isArray(spyOnChangePass.firstCall.args[0].fileList)).toEqual(true);
expect(spyOnChangePass.firstCall.args[0].fileList.length).toEqual(0);
expect(spyOnRemovePass.callCount).toEqual(1);
expect(spyOnRemovePass.firstCall.args[0].uid).toEqual('1');
});
});
it('beforeClear effects', () => {
const props = {
fileList: [
{
uid: '1',
name: 'vigo.png',
status: 'success',
size: '130KB',
preview: true,
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg',
},
],
};
const spyOnChange = sinon.spy();
const spyOnClear = sinon.spy();
const spyOnChangePass = sinon.spy();
const spyOnClearPass = sinon.spy();
const spyOnChangeReject = sinon.spy();
const spyOnClearReject = sinon.spy();
const upload = getUpload({
...props,
beforeClear: () => Promise.resolve(false),
onChange: spyOnChange,
onClear: spyOnClear,
});
const uploadPass = getUpload({
...props,
beforeClear: () => Promise.resolve(true),
onChange: spyOnChangePass,
onClear: spyOnClearPass,
});
const uploadReject = getUpload({
...props,
beforeClear: () => Promise.reject(),
onChange: spyOnChangeReject,
onClear: spyOnClearReject,
});
const clearBtn = upload.find(`.${BASE_CLASS_PREFIX}-upload-file-list-title-clear`).at(0);
const clearBtnPass = uploadPass.find(`.${BASE_CLASS_PREFIX}-upload-file-list-title-clear`).at(0);
const clearBtnReject = uploadReject.find(`.${BASE_CLASS_PREFIX}-upload-file-list-title-clear`).at(0);
const event = { target: {} };
clearBtn.simulate('click', event);
clearBtnPass.simulate('click', event);
clearBtnReject.simulate('click', event);
setTimeout(() => {
expect(spyOnChange.callCount).toEqual(0);
expect(spyOnClear.callCount).toEqual(0);
expect(spyOnChangePass.callCount).toEqual(1);
expect(Array.isArray(spyOnChangePass.firstCall.args[0].fileList)).toEqual(true);
expect(spyOnChangePass.firstCall.args[0].fileList.length).toEqual(0);
expect(spyOnChangeReject.callCount).toEqual(0);
expect(spyOnClearReject.callCount).toEqual(0);
});
});
it('insert method', () => {
const props = {
defaultFileList: [],
};
const upload = getUpload(props);
const uploadInstance = upload.instance();
const file_0 = new File([new ArrayBuffer(1024)], 'chucknorris_0.png', { type: 'image/png' });
const file_1 = new File([new ArrayBuffer(1024)], 'chucknorris_1.png', { type: 'image/png' });
const file_2 = new File([new ArrayBuffer(1024)], 'chucknorris_2.png', { type: 'image/png' });
expect(uploadInstance instanceof Upload).toEqual(true);
expect(Object.prototype.hasOwnProperty.call(uploadInstance, 'insert')).toEqual(true);
/**
* test fileList state should be [] => [file_0] => [file_1, file_0] => [file_1, file_2, file_0]
*/
upload.instance().insert([file_0]);
upload.instance().insert([file_1], 0);
upload.instance().insert([file_2], 1);
expect(Array.isArray(upload.state('fileList'))).toEqual(true);
expect(upload.state('fileList').length).toEqual(3);
expect(upload.state('fileList')[0].name).toEqual('chucknorris_1.png');
expect(upload.state('fileList')[1].name).toEqual('chucknorris_2.png');
expect(upload.state('fileList')[2].name).toEqual('chucknorris_0.png');
});
it('showPicInfo works', () => {
const props = {
listType: 'picture',
defaultFileList: [
{
uid: '1',
name: 'jiafang1.jpeg',
status: 'success',
size: '130kb',
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg',
},
],
showPicInfo: true,
};
const upload = getUpload(props);
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload`)).toEqual(true);
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload-file-list-main`)).toEqual(true);
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload-picture-file-card-pic-info`)).toEqual(true);
});
});