From dcd5f08b3b757bfeb351ce25080aad00c1474215 Mon Sep 17 00:00:00 2001 From: nemo-shen Date: Wed, 10 Mar 2021 11:25:16 +0800 Subject: [PATCH] test(Uploader): add test cases (#8318) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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> --- .../test/__snapshots__/index.legacy.js.snap | 173 ------ .../test/__snapshots__/index.spec.ts.snap | 282 +++++++++ src/uploader/test/index.legacy.js | 539 ---------------- src/uploader/test/index.spec.ts | 574 ++++++++++++++++++ .../test/{utils.legacy.js => utils.spec.ts} | 8 +- 5 files changed, 862 insertions(+), 714 deletions(-) delete mode 100644 src/uploader/test/__snapshots__/index.legacy.js.snap create mode 100644 src/uploader/test/__snapshots__/index.spec.ts.snap delete mode 100644 src/uploader/test/index.legacy.js create mode 100644 src/uploader/test/index.spec.ts rename src/uploader/test/{utils.legacy.js => utils.spec.ts} (80%) diff --git a/src/uploader/test/__snapshots__/index.legacy.js.snap b/src/uploader/test/__snapshots__/index.legacy.js.snap deleted file mode 100644 index 6421e923c..000000000 --- a/src/uploader/test/__snapshots__/index.legacy.js.snap +++ /dev/null @@ -1,173 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`delete preview image 1`] = ` -
-
-
-
-
-
-`; - -exports[`disable preview image 1`] = ` -
-
-
-
-
-
-`; - -exports[`file message should be reactive 1`] = ` -
-
-
-
-
-
-
-
-
-
2
-
-
-
-
-
-
-`; - -exports[`image-fit prop 1`] = ` -
-
-
-
-
-
-
-
-
-
-
-
-
-
-`; - -exports[`max-count prop 1`] = ` -
-
-
-
-
-
-
-
-
-
-
-
-`; - -exports[`preview-cover slot 1`] = ` -
-
-
-
-
-
-
url: https://img.yzcdn.cn/vant/cat.jpeg, index: 0
-
-
-
-
-
-
-
-
-
url: https://img.yzcdn.cn/vant/cat.jpeg, index: 1
-
-
-
-
-
-
-
-
-`; - -exports[`preview-size prop 1`] = ` -
-
-
-
-
-
-
-
-
-
-
-
-
-
-`; - -exports[`render preview image 1`] = ` -
-
-
-
-
-
-
-
-
-
-
-
- -
https://img.yzcdn.cn/vant/test.pdf
-
-
-
-
-
-
- -
test.pdf
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`; - -exports[`render upload-text 1`] = ` -
-
-
- Text
-
-
-`; - -exports[`upload-icon prop 1`] = ` -
-
-
-
-
-
-`; diff --git a/src/uploader/test/__snapshots__/index.spec.ts.snap b/src/uploader/test/__snapshots__/index.spec.ts.snap new file mode 100644 index 000000000..52809c25f --- /dev/null +++ b/src/uploader/test/__snapshots__/index.spec.ts.snap @@ -0,0 +1,282 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`delete preview image 1`] = ` +
+
+
+
+ +
+ + +
+
+
+ + +
+
+
+ + + +
+
+
+`; + +exports[`disable preview image 1`] = ` +
+
+
+ + + +
+
+
+`; + +exports[`disable preview image 2`] = ` +
+
+
+
+ + +
+ test.jpg +
+
+
+ + +
+
+
+ + + +
+
+
+`; + +exports[`file message should be reactive 1`] = ` +
+
+
+ + + +
+
+
+`; + +exports[`image-fit prop 1`] = ` +
+
+
+
+ +
+ + +
+
+
+ + +
+
+
+ + + +
+
+
+`; + +exports[`preview-cover slot 1`] = ` +
+
+
+
+ +
+ + +
+
+ Custom Preview Cover +
+
+
+ + +
+
+
+
+ +
+ + +
+
+ Custom Preview Cover +
+
+
+ + +
+
+
+ + + +
+
+
+`; + +exports[`preview-size prop 1`] = ` +
+
+
+
+ + +
+ test.jpg +
+
+
+ + +
+
+
+ + + +
+
+
+`; + +exports[`render preview image 1`] = ` +
+
+
+
+ +
+ + +
+
+
+ + +
+
+
+
+ + +
+ https://img01.yzcdn.cn/vant/test.pdf +
+
+
+ + +
+
+
+
+ + +
+ test.jpg +
+
+
+ + +
+
+
+ + + +
+
+
+`; + +exports[`upload-icon prop 1`] = ` +
+
+
+ + + +
+
+
+`; diff --git a/src/uploader/test/index.legacy.js b/src/uploader/test/index.legacy.js deleted file mode 100644 index 9ed3bfee4..000000000 --- a/src/uploader/test/index.legacy.js +++ /dev/null @@ -1,539 +0,0 @@ -import { Uploader } from '..'; -import { mount, later, triggerDrag } from '../../../test'; - -window.File = function () { - this.size = 10000; -}; - -const mockFileDataUrl = 'data:image/test'; -const mockFile = new File([], 'test.jpg'); -const file = { target: { files: [mockFile] } }; -const multiFile = { target: { files: [mockFile, mockFile] } }; -const IMAGE = 'https://img.yzcdn.cn/vant/cat.jpeg'; -const PDF = 'https://img.yzcdn.cn/vant/test.pdf'; - -window.FileReader = function () { - this.readAsText = function () { - this.onload && - this.onload({ - target: { - result: mockFileDataUrl, - }, - }); - }; - this.readAsDataURL = this.readAsText; -}; - -test('disabled', () => { - const afterRead = jest.fn(); - const wrapper = mount(Uploader, { - props: { - disabled: true, - afterRead, - }, - }); - - wrapper.vm.onChange(file); - expect(afterRead).toHaveBeenCalledTimes(0); -}); - -test('result-type as text', (done) => { - const wrapper = mount(Uploader, { - props: { - resultType: 'text', - afterRead: (readFile) => { - expect(readFile.content).toEqual(mockFileDataUrl); - done(); - }, - }, - }); - - wrapper.vm.onChange(file); -}); - -test('result-type as file', (done) => { - const wrapper = mount(Uploader, { - props: { - resultType: 'file', - afterRead: (readFile) => { - expect(readFile.file).toBeTruthy(); - expect(readFile.content).toBeFalsy(); - done(); - }, - }, - }); - - wrapper.vm.onChange(file); -}); - -test('set input name', (done) => { - const wrapper = mount(Uploader, { - props: { - name: 'uploader', - beforeRead: (readFile, detail) => { - expect(detail.name).toEqual('uploader'); - return true; - }, - afterRead: (readFile, detail) => { - expect(detail.name).toEqual('uploader'); - done(); - }, - }, - }); - - wrapper.vm.onChange(file); -}); - -test('unknown resultType', () => { - const afterRead = jest.fn(); - const wrapper = mount(Uploader, { - props: { - resultType: 'xxxx', - afterRead, - }, - }); - wrapper.vm.onChange(file); - expect(afterRead).toHaveBeenCalledTimes(0); -}); - -test('before read return false', () => { - const afterRead = jest.fn(); - const wrapper = mount(Uploader, { - props: { - beforeRead: () => false, - afterRead, - }, - }); - - const input = wrapper.find('input'); - - wrapper.vm.onChange(file); - 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: () => - new Promise((resolve) => { - resolve(file); - }), - afterRead, - }, - }); - - wrapper.vm.onChange(file); - - 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((resolve) => { - resolve(); - }), - afterRead, - }, - }); - - const input = wrapper.find('input'); - wrapper.vm.onChange(file); - 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((resolve, reject) => { - reject(); - }), - afterRead, - }, - }); - - const input = wrapper.find('input'); - wrapper.vm.onChange(file); - - await later(); - expect(afterRead).toHaveBeenCalledTimes(0); - expect(input.element.value).toEqual(''); -}); - -test('file size overlimit', async () => { - const wrapper = mount(Uploader, { - props: { - maxSize: 1, - }, - }); - wrapper.vm.onChange(file); - wrapper.vm.onChange(multiFile); - - await later(); - expect(wrapper.emitted('oversize')[0]).toBeTruthy(); - expect(wrapper.emitted('oversize')[1]).toBeTruthy(); - - wrapper.vm.maxSize = 100000; - wrapper.vm.onChange(multiFile); - - await later(); - expect(wrapper.emitted('oversize')[2]).toBeFalsy(); -}); - -test('render upload-text', () => { - const wrapper = mount(Uploader, { - props: { - uploadText: 'Text', - }, - }); - - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('render preview image', async () => { - const wrapper = mount(Uploader, { - props: { - fileList: [ - { url: 'https://img.yzcdn.cn/vant/cat.jpeg' }, - { url: 'https://img.yzcdn.cn/vant/test.pdf' }, - { file: { name: 'test.pdf' } }, - ], - }, - listeners: { - input(fileList) { - wrapper.setProps({ fileList }); - }, - }, - }); - - wrapper.vm.onChange(file); - await later(); - - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('image-fit prop', () => { - const wrapper = mount(Uploader, { - props: { - imageFit: 'contain', - fileList: [{ url: 'https://img.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: { - fileList: [], - previewImage: false, - }, - listeners: { - input(fileList) { - wrapper.setProps({ fileList }); - }, - }, - }); - - wrapper.vm.onChange(file); - await later(); - - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('max-count prop', async () => { - const wrapper = mount(Uploader, { - props: { - fileList: [], - maxCount: 1, - }, - listeners: { - input(fileList) { - wrapper.setProps({ fileList }); - }, - }, - }); - - wrapper.vm.onChange(multiFile); - await later(); - - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('preview-size prop', async () => { - const wrapper = mount(Uploader, { - props: { - fileList: [], - previewSize: 30, - }, - listeners: { - input(fileList) { - wrapper.setProps({ fileList }); - }, - }, - }); - - wrapper.vm.onChange(file); - await later(); - - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('deletable prop', () => { - const wrapper = mount(Uploader, { - props: { - fileList: [{ url: IMAGE }], - }, - }); - - expect(wrapper.find('.van-uploader__preview-delete').element).toBeTruthy(); - - wrapper.setProps({ deletable: false }); - expect(wrapper.find('.van-uploader__preview-delete').element).toBeFalsy(); -}); - -test('delete preview image', () => { - const wrapper = mount(Uploader, { - props: { - fileList: [{ url: IMAGE }], - previewSize: 30, - }, - listeners: { - input(fileList) { - wrapper.setProps({ fileList }); - }, - }, - }); - - wrapper.find('.van-uploader__preview-delete').trigger('click'); - expect(wrapper.vm.fileList.length).toEqual(0); - - expect(wrapper.html()).toMatchSnapshot(); - expect(wrapper.emitted('delete')[0]).toBeTruthy(); -}); - -test('before-delete prop return false', () => { - const wrapper = mount(Uploader, { - props: { - fileList: [{ 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: { - fileList: [{ 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: { - fileList: [{ url: IMAGE }], - beforeDelete: () => new Promise((resolve) => resolve()), - }, - }); - - 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: { - fileList: [{ url: IMAGE }], - beforeDelete: () => new Promise((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, - fileList: [{ url: IMAGE }, { url: PDF }], - }, - }); - - wrapper.find('.van-image').trigger('click'); - const imagePreviewNode = document.querySelector('.van-image-preview'); - expect(imagePreviewNode).toBeFalsy(); - - wrapper.setProps({ previewFullImage: true }); - wrapper.find('.van-image').trigger('click'); - - await later(); - - const imagePreviewNode2 = document.querySelector('.van-image-preview'); - const images = imagePreviewNode2.querySelectorAll( - '.van-image-preview__image' - ); - expect(images.length).toEqual(1); -}); - -test('preview-options prop', async () => { - const wrapper = mount(Uploader, { - props: { - fileList: [{ url: IMAGE }], - previewOptions: { - closeable: true, - }, - }, - }); - - wrapper.find('.van-image').trigger('click'); - await later(); - - const closeIcon = document.querySelectorAll('.van-image-preview__close-icon'); - expect(closeIcon.length).toEqual(1); -}); - -test('closeImagePreview method', () => { - const close = jest.fn(); - const wrapper = mount(Uploader, { - mocks: { - imagePreview: { - close, - }, - }, - }); - - wrapper.vm.closeImagePreview(); - expect(close).toHaveBeenCalledTimes(1); - - // should not throw error - const wrapper2 = mount(Uploader); - wrapper2.vm.closeImagePreview(); -}); - -test('click-preview event', () => { - const wrapper = mount(Uploader, { - props: { - previewFullImage: false, - fileList: [{ url: IMAGE }, { url: PDF }], - }, - }); - - wrapper.find('.van-image').trigger('click'); - expect(wrapper.emitted('click-preview')[0][0]).toEqual({ url: IMAGE }); - expect(wrapper.emitted('click-preview')[0][1]).toEqual({ - name: '', - index: 0, - }); -}); - -test('close-preview event', async () => { - const wrapper = mount(Uploader, { - props: { - fileList: [{ url: IMAGE }], - }, - }); - - wrapper.find('.van-image').trigger('click'); - - const preview = document.querySelector('.van-image-preview'); - const swipe = preview.querySelector('.van-swipe-item'); - triggerDrag(swipe, 0, 0); - - await later(300); - expect(wrapper.emitted('close-preview')).toBeTruthy(); -}); - -test('show-upload prop', () => { - const wrapper = mount(Uploader); - expect(wrapper.contains('.van-uploader__upload')).toBeTruthy(); - wrapper.setProps({ showUpload: false }); - expect(wrapper.contains('.van-uploader__upload')).toBeFalsy(); -}); - -test('file message should be reactive', (done) => { - const wrapper = mount(Uploader, { - props: { - fileList: [], - afterRead(file) { - file.status = 'uploading'; - file.message = 1; - setTimeout(() => { - file.message = 2; - expect(wrapper.html()).toMatchSnapshot(); - done(); - }); - }, - }, - listeners: { - input(fileList) { - wrapper.setProps({ fileList }); - }, - }, - }); - - wrapper.vm.onChange(file); -}); - -test('multiFile upload filter max-size file', async () => { - const SmallFile = function () { - this.size = 100; - }; - const multiFiles = { - target: { files: [mockFile, new SmallFile([], 'small-test.jpg')] }, - }; - - const wrapper = mount(Uploader, { - props: { - maxSize: 1000, - }, - }); - wrapper.vm.onChange(multiFiles); - - await later(); - - expect(wrapper.emitted('oversize')[0]).toBeTruthy(); -}); - -test('preview-cover slot', () => { - const wrapper = mount(Uploader, { - props: { - fileList: [{ url: IMAGE }, { url: IMAGE }], - }, - slots: { - 'preview-cover': (item) => `url: ${item.url}, index: ${item.index}`, - }, - }); - - expect(wrapper.html()).toMatchSnapshot(); -}); diff --git a/src/uploader/test/index.spec.ts b/src/uploader/test/index.spec.ts new file mode 100644 index 000000000..b255ef725 --- /dev/null +++ b/src/uploader/test/index.spec.ts @@ -0,0 +1,574 @@ +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('.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('.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('.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('.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('.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('.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((resolve) => { + resolve(file); + }), + afterRead, + }, + }); + + const input = wrapper.find('.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((resolve) => { + resolve(undefined); + }), + afterRead, + }, + }); + + const input = wrapper.find('.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((resolve, reject) => { + reject(); + }), + afterRead, + }, + }); + + const input = wrapper.find('.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('.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('.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('.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((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((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( + '.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).closeImagePreview(); + expect(wrapper.emitted('close-preview')).toBeFalsy(); + + wrapper.find('.van-image').trigger('click'); + await (wrapper.vm as Record).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('.van-image-preview'); + const swipe = preview?.querySelector( + '.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('.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('.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(); +}); diff --git a/src/uploader/test/utils.legacy.js b/src/uploader/test/utils.spec.ts similarity index 80% rename from src/uploader/test/utils.legacy.js rename to src/uploader/test/utils.spec.ts index 58435c82b..55847e8ef 100644 --- a/src/uploader/test/utils.legacy.js +++ b/src/uploader/test/utils.spec.ts @@ -10,8 +10,12 @@ test('isImageFile', () => { expect(isImageFile({ url: 'https://a.jfif' })).toBeTruthy(); expect(isImageFile({ url: 'https://a.bmp' })).toBeTruthy(); expect(isImageFile({ url: 'https://a.dpg' })).toBeTruthy(); - expect(isImageFile({ file: { type: 'image/jpg' } })).toBeTruthy(); - expect(isImageFile({ file: { type: 'application/pdf' } })).toBeFalsy(); + expect( + isImageFile({ file: new File([], 'foo.jpg', { type: 'image/jpg' }) }) + ).toBeTruthy(); + expect( + isImageFile({ file: new File([], 'bar.pdf', { type: 'application/pdf' }) }) + ).toBeFalsy(); expect(isImageFile({ content: 'data:image/xxx' })).toBeTruthy(); expect(isImageFile({ content: 'data:application/xxx' })).toBeFalsy(); expect(isImageFile({ isImage: true })).toBeTruthy();