diff --git a/src/composables/downloadFile.js b/src/composables/downloadFile.js index 12639dcd6..ef1a1093e 100644 --- a/src/composables/downloadFile.js +++ b/src/composables/downloadFile.js @@ -1,11 +1,24 @@ import { useSession } from 'src/composables/useSession'; import { getUrl } from './getUrl'; +import axios from 'axios'; +import { exportFile } from 'quasar'; const { getTokenMultimedia } = useSession(); const token = getTokenMultimedia(); export async function downloadFile(id, model = 'dms', urlPath = '/downloadFile', url) { - let appUrl = await getUrl('', 'lilium'); - appUrl = appUrl.replace('/#/', ''); - window.open(url ?? `${appUrl}/api/${model}/${id}${urlPath}?access_token=${token}`); + const appUrl = (await getUrl('', 'lilium')).replace('/#/', ''); + const response = await axios.get( + url ?? `${appUrl}/${model}/${id}${urlPath}?access_token=${token}`, + { responseType: 'blob' } + ); + + const contentDisposition = response.headers['content-disposition']; + const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDisposition); + const filename = + matches != null && matches[1] + ? matches[1].replace(/['"]/g, '') + : 'downloaded-file'; + + exportFile(filename, response.data); } diff --git a/test/vitest/__tests__/composables/downloadFile.spec.js b/test/vitest/__tests__/composables/downloadFile.spec.js index f611479bf..8d480fcef 100644 --- a/test/vitest/__tests__/composables/downloadFile.spec.js +++ b/test/vitest/__tests__/composables/downloadFile.spec.js @@ -1,25 +1,36 @@ -import { vi, describe, expect, it } from 'vitest'; +import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest'; import { axios } from 'app/test/vitest/helper'; import { downloadFile } from 'src/composables/downloadFile'; import { useSession } from 'src/composables/useSession'; - const session = useSession(); const token = session.getToken(); describe('downloadFile', () => { + const baseUrl = 'http://localhost:9000'; + let defaulCreateObjectURL; + + beforeAll(() => { + defaulCreateObjectURL = window.URL.createObjectURL; + window.URL.createObjectURL = vi.fn(() => 'blob:http://localhost:9000/blob-id'); + }); + + afterAll(() => (window.URL.createObjectURL = defaulCreateObjectURL)); + it('should open a new window to download the file', async () => { - const url = 'http://localhost:9000'; - - vi.spyOn(axios, 'get').mockResolvedValueOnce({ data: url }); - - const mockWindowOpen = vi.spyOn(window, 'open'); + const res = { + data: new Blob(['file content'], { type: 'application/octet-stream' }), + headers: { 'content-disposition': 'attachment; filename="test-file.txt"' }, + }; + vi.spyOn(axios, 'get').mockImplementation((url) => { + if (url == 'Urls/getUrl') return Promise.resolve({ data: baseUrl }); + else if (url.includes('downloadFile')) return Promise.resolve(res); + }); await downloadFile(1); - expect(mockWindowOpen).toHaveBeenCalledWith( - `${url}/api/dms/1/downloadFile?access_token=${token}` + expect(axios.get).toHaveBeenCalledWith( + `${baseUrl}/dms/1/downloadFile?access_token=${token}`, + { responseType: 'blob' } ); - - mockWindowOpen.mockRestore(); }); });