Files
vant/src/uploader/test/index.spec.ts
nemo-shen dcd5f08b3b test(Uploader): add test cases (#8318)
* test(Uploader): add test cases

* test(Uploader): add test cases

* test(Uploader): add test cases

* test(Uploader): 修复类型错误

Co-authored-by: nemo-shen <1034131477@qq.com>
2021-03-10 11:25:16 +08:00

575 lines
15 KiB
TypeScript

import Uploader, { UploaderFileListItem } from '..';
import { mount, later, triggerDrag } from '../../../test';
import { nextTick } from 'vue';
const mockFileDataUrl = 'data:image/test';
const mockFile = new File([new ArrayBuffer(10000)], 'test.jpg');
const IMAGE = 'https://img01.yzcdn.cn/vant/cat.jpeg';
const PDF = 'https://img01.yzcdn.cn/vant/test.pdf';
(window.FileReader as any) = function (this: any) {
(this as any).readAsText = function () {
this.onload &&
this.onload({
target: {
result: mockFileDataUrl,
},
});
};
this.readAsDataURL = this.readAsText;
};
test('disabled', async () => {
const afterRead = jest.fn();
const wrapper = mount(Uploader, {
props: {
disabled: true,
afterRead,
},
});
await later();
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
await later();
expect(afterRead).toHaveBeenCalledTimes(0);
});
test('result-type as text', async (done) => {
const wrapper = mount(Uploader, {
props: {
resultType: 'text',
afterRead(readFile: UploaderFileListItem | UploaderFileListItem[]) {
expect((readFile as UploaderFileListItem).content).toEqual(
mockFileDataUrl
);
done();
},
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
});
test('result-type as file', (done) => {
const wrapper = mount(Uploader, {
props: {
resultType: 'file',
afterRead: (readFile: UploaderFileListItem | UploaderFileListItem[]) => {
expect((readFile as UploaderFileListItem).file).toBeTruthy();
expect((readFile as UploaderFileListItem).content).toBeFalsy();
done();
},
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
});
test('set input name', (done) => {
const wrapper = mount(Uploader, {
props: {
name: 'uploader',
beforeRead: (
file: File | File[],
detail: { name: string | number; index: number }
) => {
expect(detail.name).toEqual('uploader');
return file;
},
afterRead: (
readFile: UploaderFileListItem | UploaderFileListItem[],
detail: { name: string | number; index: number }
) => {
expect(detail.name).toEqual('uploader');
done();
},
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
});
test('unknown resultType', async () => {
const afterRead = jest.fn();
const wrapper = mount(Uploader, {
props: {
afterRead,
},
});
await wrapper.setProps({ resultType: 'xxxx' });
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
await later();
expect(afterRead).toHaveBeenCalledTimes(0);
});
test('before read return false', async () => {
const afterRead = jest.fn();
const wrapper = mount(Uploader, {
props: {
beforeRead: () => undefined,
afterRead,
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
await later();
expect(afterRead).toHaveBeenCalledTimes(0);
expect(input.element.value).toEqual('');
});
test('before read return promise and resolve', async () => {
const afterRead = jest.fn();
const wrapper = mount(Uploader, {
props: {
beforeRead: (file: File | File[]) =>
new Promise<File | File[] | undefined>((resolve) => {
resolve(file);
}),
afterRead,
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
await later();
expect(afterRead).toHaveBeenCalledTimes(1);
});
test('before read return promise and resolve no value', async () => {
const afterRead = jest.fn();
const wrapper = mount(Uploader, {
props: {
beforeRead: () =>
new Promise<undefined>((resolve) => {
resolve(undefined);
}),
afterRead,
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
await later();
expect(afterRead).toHaveBeenCalledTimes(1);
expect(input.element.value).toEqual('');
});
test('before read return promise and reject', async () => {
const afterRead = jest.fn();
const wrapper = mount(Uploader, {
props: {
beforeRead: () =>
new Promise<undefined>((resolve, reject) => {
reject();
}),
afterRead,
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
await later();
expect(afterRead).toHaveBeenCalledTimes(0);
expect(input.element.value).toEqual('');
});
test('file size overlimit', async () => {
const wrapper = mount(Uploader, {
props: {
maxSize: 1,
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
let fileList = [mockFile];
Object.defineProperty(input.element, 'files', {
get: () => jest.fn().mockReturnValue(fileList)(),
});
await input.trigger('change');
fileList = [mockFile, mockFile];
await input.trigger('change');
await later();
expect(wrapper.emitted<[File]>('oversize')![0]).toBeTruthy();
expect(wrapper.emitted<[File]>('oversize')![1]).toBeTruthy();
await wrapper.setProps({ maxSize: 100000 });
fileList = [mockFile];
await input.trigger('change');
await later();
expect(wrapper.emitted<[File]>('oversize')![2]).toBeFalsy();
});
test('render upload-text', () => {
const uploadText = 'Text';
const wrapper = mount(Uploader, {
props: {
uploadText,
},
});
const text = wrapper.find<HTMLSpanElement>('.van-uploader__upload-text');
expect(text?.text()).toEqual(uploadText);
});
test('render preview image', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [
{ url: 'https://img01.yzcdn.cn/vant/cat.jpeg' },
{ url: 'https://img01.yzcdn.cn/vant/test.pdf' },
{ file: mockFile },
],
},
});
expect(wrapper.html()).toMatchSnapshot();
});
test('image-fit prop', () => {
const wrapper = mount(Uploader, {
props: {
imageFit: 'contain',
modelValue: [{ url: 'https://img01.yzcdn.cn/vant/cat.jpeg' }],
},
});
expect(wrapper.html()).toMatchSnapshot();
});
test('upload-icon prop', () => {
const wrapper = mount(Uploader, {
props: {
uploadIcon: 'add',
},
});
expect(wrapper.html()).toMatchSnapshot();
});
test('disable preview image', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [],
previewImage: false,
},
});
await wrapper.setProps({ modelValue: [{ file: mockFile }] });
expect(wrapper.html()).toMatchSnapshot();
await wrapper.setProps({ previewImage: true });
expect(wrapper.html()).toMatchSnapshot();
});
test('max-count prop', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [],
maxCount: 1,
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile, mockFile]),
});
input.trigger('change');
await later();
expect(
wrapper.emitted<[File | File[]]>('update:modelValue')![0][0]
).toHaveLength(1);
});
test('preview-size prop', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [],
previewSize: 30,
},
});
await wrapper.setProps({ modelValue: [{ file: mockFile }] });
expect(wrapper.html()).toMatchSnapshot();
});
test('deletable prop', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }],
},
});
expect(wrapper.find('.van-uploader__preview-delete').exists()).toBeTruthy();
await wrapper.setProps({ deletable: false });
expect(wrapper.find('.van-uploader__preview-delete').exists()).toBeFalsy();
});
test('delete preview image', () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }],
previewSize: 30,
},
});
wrapper.find('.van-uploader__preview-delete').trigger('click');
expect(wrapper.emitted<[File]>('update:modelValue')![0][0]).toHaveLength(0);
expect(wrapper.html()).toMatchSnapshot();
expect(wrapper.emitted<[File]>('delete')![0]).toBeTruthy();
});
test('before-delete prop return false', () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }],
beforeDelete: () => false,
},
});
wrapper.find('.van-uploader__preview-delete').trigger('click');
expect(wrapper.emitted('delete')).toBeFalsy();
});
test('before-delete prop return true', () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }],
beforeDelete: () => true,
},
});
wrapper.find('.van-uploader__preview-delete').trigger('click');
expect(wrapper.emitted('delete')).toBeTruthy();
});
test('before-delete prop resolved', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }],
beforeDelete: () => new Promise<boolean>((resolve) => resolve(true)),
},
});
wrapper.find('.van-uploader__preview-delete').trigger('click');
await later();
expect(wrapper.emitted('delete')).toBeTruthy();
});
test('before-delete prop rejected', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }],
beforeDelete: () => new Promise<boolean>((resolve, reject) => reject()),
},
});
wrapper.find('.van-uploader__preview-delete').trigger('click');
await later();
expect(wrapper.emitted('delete')).toBeFalsy();
});
test('click to preview image', async () => {
const wrapper = mount(Uploader, {
props: {
previewFullImage: false,
modelValue: [{ url: IMAGE }, { url: PDF }],
},
});
wrapper.find('.van-image').trigger('click');
await later();
expect(document.querySelector('.van-image-preview')).toBeFalsy();
await wrapper.setProps({ previewFullImage: true });
wrapper.find('.van-image').trigger('click');
await later();
expect(document.querySelector('.van-image-preview')).toBeTruthy();
const images = document.querySelectorAll<HTMLImageElement>(
'.van-image-preview .van-image-preview__image'
);
expect(images).toHaveLength(1);
});
test('preview-options prop', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }],
previewOptions: {
images: [],
closeable: true,
},
},
});
wrapper.find('.van-image').trigger('click');
await later();
const closeIcon = document.querySelectorAll('.van-image-preview__close-icon');
expect(closeIcon).toHaveLength(1);
});
test('closeImagePreview method', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }],
},
});
await nextTick();
await (wrapper.vm as Record<string, any>).closeImagePreview();
expect(wrapper.emitted('close-preview')).toBeFalsy();
wrapper.find('.van-image').trigger('click');
await (wrapper.vm as Record<string, any>).closeImagePreview();
expect(wrapper.emitted('close-preview')).toBeTruthy();
});
test('click-preview event', () => {
const wrapper = mount(Uploader, {
props: {
previewFullImage: false,
modelValue: [{ url: IMAGE }, { url: PDF }],
},
});
wrapper.find('.van-image').trigger('click');
expect(wrapper.emitted<[File]>('click-preview')![0][0]).toEqual({
url: IMAGE,
});
expect(
wrapper.emitted<[File, { name: string; index: number }]>(
'click-preview'
)![0][1]
).toEqual({
name: '',
index: 0,
});
});
test('close-preview event', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }],
},
});
await later();
wrapper.find('.van-image').trigger('click');
const preview = document.querySelector<HTMLDivElement>('.van-image-preview');
const swipe = preview?.querySelector<HTMLDivElement>(
'.van-swipe-item'
) as HTMLDivElement;
triggerDrag(swipe, 0, 0);
await later(300);
expect(wrapper.emitted('close-preview')).toBeTruthy();
});
test('show-upload prop', async () => {
const wrapper = mount(Uploader);
expect(wrapper.find('.van-uploader__upload').exists()).toBeTruthy();
await wrapper.setProps({ showUpload: false });
expect(wrapper.find('.van-uploader__upload').exists()).toBeFalsy();
});
test('file message should be reactive', async (done) => {
const wrapper = mount(Uploader, {
props: {
modelValue: [],
afterRead(file: UploaderFileListItem | UploaderFileListItem[]) {
if (Array.isArray(file)) return;
file.status = 'uploading';
file.message = '1';
setTimeout(() => {
file.message = '2';
expect(wrapper.html()).toMatchSnapshot();
done();
});
},
},
});
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile]),
});
input.trigger('change');
});
test('multiFile upload filter max-size file', async () => {
const wrapper = mount(Uploader, {
props: {
maxSize: 1000,
},
});
const smallFile = new File([new ArrayBuffer(100)], 'small.jpg');
const input = wrapper.find<HTMLInputElement>('.van-uploader__input');
Object.defineProperty(input.element, 'files', {
get: jest.fn().mockReturnValue([mockFile, smallFile]),
});
input.trigger('change');
await later();
expect(wrapper.emitted<[File]>('oversize')![0]).toBeTruthy();
});
test('preview-cover slot', async () => {
const wrapper = mount(Uploader, {
props: {
modelValue: [{ url: IMAGE }, { url: IMAGE }],
},
slots: {
'preview-cover': 'Custom Preview Cover',
},
});
expect(wrapper.html()).toMatchSnapshot();
});