From d96555fa9cfe785897b6ad772d15671ce5fda5d5 Mon Sep 17 00:00:00 2001 From: Jianjun Yu <49601167+jianjunyuu@users.noreply.github.com> Date: Fri, 8 Sep 2023 15:57:05 +0800 Subject: [PATCH] feat(components): [upload] support async data (#14015) * feat(components): [upload] support async data * feat(components): [upload] support async data * fix(components): [upload] unit test * fix(components): [upload] unit test * feat(components): [upload] update data docs * fix(components): [upload] unit test * chore: add version --------- Co-authored-by: Hefty --- docs/en-US/component/upload.md | 2 +- .../upload/__tests__/upload.test.tsx | 112 ++++++++++++++++++ .../components/upload/src/upload-content.vue | 32 +++-- packages/components/upload/src/upload.ts | 9 +- 4 files changed, 145 insertions(+), 10 deletions(-) diff --git a/docs/en-US/component/upload.md b/docs/en-US/component/upload.md index 82bafe3ee3..5a9b351339 100644 --- a/docs/en-US/component/upload.md +++ b/docs/en-US/component/upload.md @@ -99,7 +99,7 @@ upload/manual | `headers` | request headers. | `Headers \| Record` | — | No | | `method` | set upload request method. | `string` | `'post'` | No | | `multiple` | whether uploading multiple files is permitted. | `boolean` | `false` | No | -| `data` | additions options of request. | `Record` | — | No | +| `data` | additions options of request. support `Awaitable` data and `Function` since v3.3.13 | `Record \| Awaitable> \| ((rawFile: UploadRawFile) => Awaitable>)` | — | No | | `name` | key name for uploaded file. | `string` | `'file'` | No | | `with-credentials` | whether cookies are sent. | `boolean` | `false` | No | | `show-file-list` | whether to show the uploaded file list. | `boolean` | `true` | No | diff --git a/packages/components/upload/__tests__/upload.test.tsx b/packages/components/upload/__tests__/upload.test.tsx index 21a7b733d2..150b0f40a2 100644 --- a/packages/components/upload/__tests__/upload.test.tsx +++ b/packages/components/upload/__tests__/upload.test.tsx @@ -5,6 +5,7 @@ import { afterEach, describe, expect, test, vi } from 'vitest' import { EVENT_CODE } from '@element-plus/constants' import Upload from '../src/upload.vue' import UploadContent from '../src/upload-content.vue' +import type { UploadRawFile } from '../src/upload' const AXIOM = 'Rem is the best girl' @@ -203,6 +204,117 @@ describe('', () => { expect(keyList).toEqual(['test-file.txt', 'test-file2.txt']) }) + test('data support receive promise', async () => { + const onSuccess = vi.fn() + const onError = vi.fn() + const onRemove = vi.fn() + let requestData: any = {} + + const httpRequest = vi.fn((val) => { + requestData = val?.data + return Promise.resolve() + }) + + const data = ref(Promise.resolve({ type: 'promise' })) + + const wrapper = mount(() => ( + + )) + + const fileList = [new File(['content'], 'test-file.txt')] + mockGetFile(wrapper.find('input').element, fileList) + + await wrapper.find('input').trigger('change') + + await flushPromises() + + expect(requestData).toEqual(await data.value) + expect(onSuccess).toHaveBeenCalled() + expect(onError).not.toHaveBeenCalled() + + vi.clearAllMocks() + + data.value = Promise.reject({ type: 'error promise' }) + await expect(data.value).rejects.toThrowError(undefined) + await nextTick() + await nextTick() + await wrapper.find('input').trigger('change') + + await flushPromises() + expect(onSuccess).not.toHaveBeenCalled() + expect(onError).not.toHaveBeenCalled() + expect(onRemove).toHaveBeenCalled() + }) + + test('data support receive function', async () => { + const keyList: string[] = [] + const httpRequest = vi.fn((val) => { + keyList.push(val?.data?.key) + return Promise.resolve() + }) + + const data = vi.fn((file: UploadRawFile) => ({ key: file.name })) + + const wrapper = mount(() => ( + + )) + + const fileList = [ + new File(['content'], 'test-file.txt'), + new File(['content2'], 'test-file2.txt'), + ] + mockGetFile(wrapper.find('input').element, fileList) + + await wrapper.find('input').trigger('change') + + await flushPromises() + await flushPromises() + await nextTick() + + expect(keyList).toEqual(['test-file.txt', 'test-file2.txt']) + }) + + test('data support receive async function', async () => { + const keyList: string[] = [] + const httpRequest = vi.fn(() => Promise.resolve()) + + const dataFN = vi.fn(async (file: UploadRawFile) => { + return new Promise((resolve) => { + keyList.push(file.name) + resolve({ key: file.name }) + }) + }) + + const wrapper = mount(() => ( + + )) + + const fileList = [ + new File(['content'], 'test-file.txt'), + new File(['content2'], 'test-file2.txt'), + ] + mockGetFile(wrapper.find('input').element, fileList) + + await wrapper.find('input').trigger('change') + + await flushPromises() + + expect(dataFN).toHaveBeenCalledTimes(2) + + expect(keyList).toEqual(['test-file.txt', 'test-file2.txt']) + }) + test('upload files and save keyList', async () => { const keyList: string[] = [] const beforeUpload = vi.fn((file: File) => { diff --git a/packages/components/upload/src/upload-content.vue b/packages/components/upload/src/upload-content.vue index eb52778155..dbbff511ef 100644 --- a/packages/components/upload/src/upload-content.vue +++ b/packages/components/upload/src/upload-content.vue @@ -28,10 +28,10 @@