From: Daniel Kutyła Date: Mon, 12 Oct 2020 17:58:47 +0000 (+0200) Subject: Merge branch '16037-download-selected-functionality-messes-up-file-names' X-Git-Tag: 2.1.1~11 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/f4bc382beb99c86c71462c3cd7329ef1b5fda617?hp=dbd29b580dbb01ab045284bd2446b47e1285f3d3 Merge branch '16037-download-selected-functionality-messes-up-file-names' Closes #16037 Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła --- diff --git a/cypress/integration/collection-panel.spec.js b/cypress/integration/collection-panel.spec.js index 6fc2d565..c14101d8 100644 --- a/cypress/integration/collection-panel.spec.js +++ b/cypress/integration/collection-panel.spec.js @@ -103,8 +103,8 @@ describe('Collection panel tests', function() { cy.get('[data-cy=collection-files-panel-options-btn]') .click() cy.get('[data-cy=context-menu]') - .should('contain', 'Download selected') - .and(`${isWritable ? '' : 'not.'}contain`, 'Remove selected') + // .should('contain', 'Download selected') + .should(`${isWritable ? '' : 'not.'}contain`, 'Remove selected') .type('{esc}'); // Collapse the options menu // File item 'more options' button cy.get('[data-cy=file-item-options-btn') @@ -117,4 +117,4 @@ describe('Collection panel tests', function() { }) }) }) -}) \ No newline at end of file +}) diff --git a/src/views-components/context-menu/action-sets/collection-files-action-set.ts b/src/views-components/context-menu/action-sets/collection-files-action-set.ts index fc0139c8..7e885615 100644 --- a/src/views-components/context-menu/action-sets/collection-files-action-set.ts +++ b/src/views-components/context-menu/action-sets/collection-files-action-set.ts @@ -5,7 +5,7 @@ import { ContextMenuActionSet } from "~/views-components/context-menu/context-menu-action-set"; import { collectionPanelFilesAction, openMultipleFilesRemoveDialog } from "~/store/collection-panel/collection-panel-files/collection-panel-files-actions"; import { openCollectionPartialCopyDialog, openCollectionPartialCopyToSelectedCollectionDialog } from '~/store/collections/collection-partial-copy-actions'; -import { DownloadCollectionFileAction } from "~/views-components/context-menu/actions/download-collection-file-action"; +// import { DownloadCollectionFileAction } from "~/views-components/context-menu/actions/download-collection-file-action"; export const readOnlyCollectionFilesActionSet: ContextMenuActionSet = [[ { @@ -20,10 +20,10 @@ export const readOnlyCollectionFilesActionSet: ContextMenuActionSet = [[ dispatch(collectionPanelFilesAction.UNSELECT_ALL_COLLECTION_FILES()); } }, - { - component: DownloadCollectionFileAction, - execute: () => { return; } - }, + // { // Disabled for now as we need to create backend version of this feature which will be less buggy + // component: DownloadCollectionFileAction, + // execute: () => { return; } + // }, { name: "Create a new collection with selected", execute: dispatch => { diff --git a/src/views-components/context-menu/actions/download-action.test.tsx b/src/views-components/context-menu/actions/download-action.test.tsx new file mode 100644 index 00000000..88791d4b --- /dev/null +++ b/src/views-components/context-menu/actions/download-action.test.tsx @@ -0,0 +1,73 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import * as React from 'react'; +import axios from 'axios'; +import { configure, shallow } from "enzyme"; +import * as Adapter from 'enzyme-adapter-react-16'; +import { ListItem } from '@material-ui/core'; +import * as JSZip from 'jszip'; +import { DownloadAction } from './download-action'; + +configure({ adapter: new Adapter() }); + +jest.mock('axios'); + +jest.mock('file-saver', () => ({ + saveAs: jest.fn(), +})); + +const mock = { + file: jest.fn(), + generateAsync: jest.fn().mockImplementation(() => Promise.resolve('test')), +}; + +jest.mock('jszip', () => jest.fn().mockImplementation(() => mock)); + +describe('', () => { + let props; + let zip; + + beforeEach(() => { + props = {}; + zip = new JSZip(); + (axios as any).get.mockImplementationOnce(() => Promise.resolve({ data: '1234' })); + }); + + it('should return null if missing href or kind of file in props', () => { + // when + const wrapper = shallow(); + + // then + expect(wrapper.html()).toBeNull(); + }); + + it('should return a element', () => { + // setup + props.href = '#'; + + // when + const wrapper = shallow(); + + // then + expect(wrapper.html()).not.toBeNull(); + }); + + it('should handle download', () => { + // setup + props = { + href: ['file1'], + kind: 'files', + download: [], + currentCollectionUuid: '123412-123123' + }; + const wrapper = shallow(); + + // when + wrapper.find(ListItem).simulate('click'); + + // then + expect(axios.get).toHaveBeenCalledWith(props.href[0]); + }); +}); \ No newline at end of file diff --git a/src/views-components/context-menu/actions/download-action.tsx b/src/views-components/context-menu/actions/download-action.tsx index 7fcf7c2c..7468954f 100644 --- a/src/views-components/context-menu/actions/download-action.tsx +++ b/src/views-components/context-menu/actions/download-action.tsx @@ -2,10 +2,10 @@ // // SPDX-License-Identifier: AGPL-3.0 -import * as React from "react"; -import { ListItemIcon, ListItemText, ListItem } from "@material-ui/core"; -import { DownloadIcon } from "../../../components/icon/icon"; -import * as JSZip from "jszip"; +import * as React from 'react'; +import { ListItemIcon, ListItemText, ListItem } from '@material-ui/core'; +import { DownloadIcon } from '../../../components/icon/icon'; +import * as JSZip from 'jszip'; import * as FileSaver from 'file-saver'; import axios from 'axios'; @@ -13,28 +13,35 @@ export const DownloadAction = (props: { href?: any, download?: any, onClick?: () const downloadProps = props.download ? { download: props.download } : {}; const createZip = (fileUrls: string[], download: string[]) => { - const zip = new JSZip(); let id = 1; - fileUrls.map((href: string) => { - axios.get(href).then(response => response).then(({ data }: any) => { - const splittedByDot = href.split('.'); - if (splittedByDot[splittedByDot.length - 1] !== 'json') { - if (fileUrls.length === id) { - zip.file(download[id - 1], data); - zip.generateAsync({ type: 'blob' }).then((content) => { - FileSaver.saveAs(content, `download-${props.currentCollectionUuid}.zip`); - }); + const zip = new JSZip(); + const filteredFileUrls = fileUrls + .filter((href: string) => { + const letter = href.split('').pop(); + return letter !== '/'; + }); + + filteredFileUrls + .map((href: string) => { + axios.get(href).then(response => response).then(({ data }: any) => { + const splittedByDot = href.split('.'); + if (splittedByDot[splittedByDot.length - 1] !== 'json') { + if (filteredFileUrls.length === id) { + zip.file(download[id - 1], data); + zip.generateAsync({ type: 'blob' }).then((content) => { + FileSaver.saveAs(content, `download-${props.currentCollectionUuid}.zip`); + }); + } else { + zip.file(download[id - 1], data); + zip.generateAsync({ type: 'blob' }); + } } else { - zip.file(download[id - 1], data); + zip.file(download[id - 1], JSON.stringify(data)); zip.generateAsync({ type: 'blob' }); } - } else { - zip.file(download[id - 1], JSON.stringify(data)); - zip.generateAsync({ type: 'blob' }); - } - id++; + id++; + }); }); - }); }; return props.href || props.kind === 'files'