From: Daniel Kutyła Date: Fri, 26 Nov 2021 08:05:56 +0000 (+0100) Subject: Merge branch '18169-cancel-button-not-working' into main X-Git-Tag: 2.4.0~29 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/6e4b23e9a99ab64e25c60a128e6beb4fa8636374?hp=6e0bfefd885bb7ebb445f60f3985bbbfca361935 Merge branch '18169-cancel-button-not-working' into main closes #18169 Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła --- diff --git a/.licenseignore b/.licenseignore index 853135fc..9b943a1f 100644 --- a/.licenseignore +++ b/.licenseignore @@ -14,3 +14,4 @@ public/* .npmrc src/lib/cwl-svg/* tools/arvados_config.yml +cypress/fixtures/files/5mb.bin diff --git a/cypress/fixtures/files/5mb.bin b/cypress/fixtures/files/5mb.bin new file mode 100644 index 00000000..d52f252e Binary files /dev/null and b/cypress/fixtures/files/5mb.bin differ diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js index 3e06d7e5..eb06a06c 100644 --- a/cypress/integration/collection.spec.js +++ b/cypress/integration/collection.spec.js @@ -793,4 +793,83 @@ describe('Collection panel tests', function () { .contains(adminUser.user.uuid); }); }); + + describe('file upload', () => { + beforeEach(() => { + cy.createCollection(adminUser.token, { + name: `Test collection ${Math.floor(Math.random() * 999999)}`, + owner_uuid: activeUser.user.uuid, + manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n" + }) + .as('testCollection1'); + }); + + it('allows to cancel running upload', () => { + cy.getAll('@testCollection1') + .then(function([testCollection1]) { + cy.loginAs(activeUser); + + cy.goToPath(`/collections/${testCollection1.uuid}`); + + cy.get('[data-cy=upload-button]').click(); + + cy.fixture('files/5mb.bin', 'base64').then(content => { + cy.get('[data-cy=drag-and-drop]').upload(content, '5mb_a.bin'); + cy.get('[data-cy=drag-and-drop]').upload(content, '5mb_b.bin'); + + cy.get('[data-cy=form-submit-btn]').click(); + + cy.get('button').contains('Cancel').click(); + + cy.get('[data-cy=form-submit-btn]').should('not.exist'); + }); + }); + }); + + it('allows to cancel single file from the running upload', () => { + cy.getAll('@testCollection1') + .then(function([testCollection1]) { + cy.loginAs(activeUser); + + cy.goToPath(`/collections/${testCollection1.uuid}`); + + cy.get('[data-cy=upload-button]').click(); + + cy.fixture('files/5mb.bin', 'base64').then(content => { + cy.get('[data-cy=drag-and-drop]').upload(content, '5mb_a.bin'); + cy.get('[data-cy=drag-and-drop]').upload(content, '5mb_b.bin'); + + cy.get('[data-cy=form-submit-btn]').click(); + + cy.get('button[aria-label=Remove]').eq(1).click(); + + cy.get('[data-cy=form-submit-btn]').should('not.exist'); + + cy.get('[data-cy=collection-files-panel]').contains('5mb_a.bin').should('exist'); + }); + }); + }); + + it('allows to cancel all files from the running upload', () => { + cy.getAll('@testCollection1') + .then(function([testCollection1]) { + cy.loginAs(activeUser); + + cy.goToPath(`/collections/${testCollection1.uuid}`); + + cy.get('[data-cy=upload-button]').click(); + + cy.fixture('files/5mb.bin', 'base64').then(content => { + cy.get('[data-cy=drag-and-drop]').upload(content, '5mb_a.bin'); + cy.get('[data-cy=drag-and-drop]').upload(content, '5mb_b.bin'); + + cy.get('[data-cy=form-submit-btn]').click(); + + cy.get('button[aria-label=Remove]').click({ multiple: true }); + + cy.get('[data-cy=form-submit-btn]').should('not.exist'); + }); + }); + }); + }); }) diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 069ed96d..07290e55 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -280,4 +280,42 @@ Cypress.Commands.add('createProject', ({ cy.addToFavorites(user.token, user.user.uuid, project.uuid); } }); -}); \ No newline at end of file +}); + +Cypress.Commands.add( + 'upload', + { + prevSubject: 'element', + }, + (subject, file, fileName) => { + cy.window().then(window => { + const blob = b64toBlob(file, '', 512); + const testFile = new window.File([blob], fileName); + + cy.wrap(subject).trigger('drop', { + dataTransfer: { files: [testFile] }, + }); + }) + } +) + +function b64toBlob(b64Data, contentType = '', sliceSize = 512) { + const byteCharacters = atob(b64Data) + const byteArrays = [] + + for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { + const slice = byteCharacters.slice(offset, offset + sliceSize); + + const byteNumbers = new Array(slice.length); + for (let i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + + const byteArray = new Uint8Array(byteNumbers); + + byteArrays.push(byteArray); + } + + const blob = new Blob(byteArrays, { type: contentType }); + return blob +} \ No newline at end of file diff --git a/src/common/webdav.ts b/src/common/webdav.ts index 758a5e18..93ec21cb 100644 --- a/src/common/webdav.ts +++ b/src/common/webdav.ts @@ -84,6 +84,15 @@ export class WebDAV { .keys(headers) .forEach(key => r.setRequestHeader(key, headers[key])); + if (!(window as any).cancelTokens) { + Object.assign(window, { cancelTokens: {} }); + } + + (window as any).cancelTokens[config.url] = () => { + resolve(r); + r.abort(); + } + if (config.onUploadProgress) { r.upload.addEventListener('progress', config.onUploadProgress); } diff --git a/src/components/collection-panel-files/collection-panel-files.tsx b/src/components/collection-panel-files/collection-panel-files.tsx index 97cbc8ce..a7001a61 100644 --- a/src/components/collection-panel-files/collection-panel-files.tsx +++ b/src/components/collection-panel-files/collection-panel-files.tsx @@ -517,7 +517,12 @@ export const CollectionPanelFiles = withStyles(styles)(connect((state: RootState