17337: Added more tests, fixed whitespace issue
authorDaniel Kutyła <daniel.kutyla@contractors.roche.com>
Thu, 25 Feb 2021 20:34:41 +0000 (21:34 +0100)
committerDaniel Kutyła <daniel.kutyla@contractors.roche.com>
Thu, 25 Feb 2021 20:38:23 +0000 (21:38 +0100)
Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła <daniel.kutyla@contractors.roche.com>

cypress/integration/collection.spec.js
src/common/url.ts
src/common/webdav.ts
src/services/collection-service/collection-service-files-response.test.ts
src/services/collection-service/collection-service-files-response.ts

index 8f614591127d0d055c8ef167d1d4b23c1de6d337..6ac65497458c2bae7883518440dba889ff086c45 100644 (file)
@@ -138,7 +138,7 @@ describe('Collection panel tests', function () {
                             }
                         });
                         cy.get('[data-cy=collection-files-panel]')
-                            .contains(fileName).rightclick();
+                            .contains(fileName).rightclick({ force: true });
                         cy.get('[data-cy=context-menu]')
                             .should('contain', 'Download')
                             .and('contain', 'Open in new tab')
@@ -370,6 +370,12 @@ describe('Collection panel tests', function () {
                 cy.get('[data-cy=context-menu]').contains('Remove selected').click();
                 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
                 cy.get('[data-cy=collection-files-panel]').contains('#foo').should('not.exist');
+
+                cy.get('[data-cy=collection-files-panel]').contains('bar').rightclick();
+                cy.get('[data-cy=context-menu]').contains('Rename').click();
+                cy.get('input[name=path]').type('bar 123 321 bar');
+                cy.get('[data-cy=form-submit-btn]').click();
+                cy.get('[data-cy=collection-files-panel]').contains('barbar 123 321 bar').should('exist');
             });
     });
 
index 9789b65effb6b47d6ed14c0589cb39b2b032c2a4..6223485eabee6908fa363ea94e7345c1c54d7822 100644 (file)
@@ -1,3 +1,7 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
 export function getUrlParameter(search: string, name: string) {
     const safeName = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
     const regex = new RegExp('[\\?&]' + safeName + '=([^&#]*)');
@@ -13,3 +17,10 @@ export function normalizeURLPath(url: string) {
     }
     return u.toString();
 }
+
+export const escapeHashIfRequired = (name: string, defaultTransformation?: Function) =>
+    name.indexOf('#') > -1 ?
+        encodeURIComponent(name) :
+        defaultTransformation ?
+            defaultTransformation(name) :
+            name;
\ No newline at end of file
index e896a207e7c5708c7b9948592606cf6ae3fbae7d..54601f16d2e5a380b315e8d8eb9834d2228bcb38 100644 (file)
@@ -2,6 +2,8 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
+import { escapeHashIfRequired } from "./url";
+
 export class WebDAV {
 
     defaults: WebDAVDefaults = {
@@ -75,7 +77,7 @@ export class WebDAV {
             r.open(config.method,
                 `${this.defaults.baseURL
                     ? this.defaults.baseURL+'/'
-                    : ''}${encodeURIComponent(config.url)}`);
+                    : ''}${escapeHashIfRequired(config.url, encodeURI)}`);
             const headers = { ...this.defaults.headers, ...config.headers };
             Object
                 .keys(headers)
index 06c8662b165fb3a64fc92d68d162f0a47b07945d..ad75f572aa6d44836acc47a69cf4b5161062824f 100644 (file)
@@ -3,16 +3,32 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { CollectionFile } from '~/models/collection-file';
-import { getFileFullPath } from './collection-service-files-response';
+import { getFileFullPath, extractFilesData } from './collection-service-files-response';
 
 describe('collection-service-files-response', () => {
+
+    describe('extractFilesData', () => {
+        it('should extract', () => {
+            // given
+            const xmlString = '<D:multistatus xmlns:D="DAV:"><D:response><D:href>/c=xxxxx-zzzzz-vvvvvvvvvvvvvvv/</D:href><D:propstat><D:prop><D:resourcetype><D:collection xmlns:D="DAV:"/></D:resourcetype><D:getlastmodified>Wed, 24 Feb 2021 22:16:19 GMT</D:getlastmodified><D:supportedlock><D:lockentry xmlns:D="DAV:"><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry></D:supportedlock><D:displayname></D:displayname></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response><D:response><D:href>/c=zzzzz-xxxxx-vvvvvvvvvvvvvvv/2</D:href><D:propstat><D:prop><D:getcontentlength>1582976</D:getcontentlength><D:getetag>"1666cee048aa7f98182780"</D:getetag><D:resourcetype></D:resourcetype><D:displayname>2</D:displayname><D:getlastmodified>Wed, 24 Feb 2021 22:16:19 GMT</D:getlastmodified><D:getcontenttype>text/plain; charset=utf-8</D:getcontenttype><D:supportedlock><D:lockentry xmlns:D="DAV:"><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry></D:supportedlock></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response><D:response><D:href>/c=zzzzz-xxxxx-vvvvvvvvvvvvvvv/table%201%202%203</D:href><D:propstat><D:prop><D:resourcetype></D:resourcetype><D:getcontentlength>133352</D:getcontentlength><D:getetag>"1666cee048aa7f98208e8"</D:getetag><D:displayname>table 1 2 3</D:displayname><D:getlastmodified>Wed, 24 Feb 2021 22:16:19 GMT</D:getlastmodified><D:getcontenttype>text/plain; charset=utf-8</D:getcontenttype><D:supportedlock><D:lockentry xmlns:D="DAV:"><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry></D:supportedlock></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response></D:multistatus>';
+            const parser = new DOMParser();
+            const xmlDoc = parser.parseFromString(xmlString, "text/xml");
+
+            // when
+            const result = extractFilesData(xmlDoc);
+
+            // then
+            expect(result).toEqual([{ id: "zzzzz-xxxxx-vvvvvvvvvvvvvvv/2", name: "2", path: "", size: 1582976, type: "file", url: "/c=zzzzz-xxxxx-vvvvvvvvvvvvvvv/2" }, { id: "zzzzz-xxxxx-vvvvvvvvvvvvvvv/table 1 2 3", name: "table 1 2 3", path: "", size: 133352, type: "file", url: "/c=zzzzz-xxxxx-vvvvvvvvvvvvvvv/table 1 2 3" }]);
+        });
+    });
+
     describe('getFileFullPath', () => {
         it('should encode weird names', async () => {
             // given
-            const file = { 
+            const file = {
                 name: '#test',
                 path: 'http://localhost',
-             } as CollectionFile;
+            } as CollectionFile;
 
             // when
             const result = getFileFullPath(file);
index c1176cd5645967c99a4af78f770268c2c2d14048..6f8b3de3a9b99bc0aac4ecb1100b95f71d6af309 100644 (file)
@@ -5,6 +5,7 @@
 import { CollectionDirectory, CollectionFile, CollectionFileType, createCollectionDirectory, createCollectionFile } from "../../models/collection-file";
 import { getTagValue } from "~/common/xml";
 import { getNodeChildren, Tree, mapTree } from '~/models/tree';
+import { escapeHashIfRequired } from "~/common/url";
 
 export const sortFilesTree = (tree: Tree<CollectionDirectory | CollectionFile>) => {
     return mapTree<CollectionDirectory | CollectionFile>(node => {
@@ -28,7 +29,7 @@ export const extractFilesData = (document: Document) => {
             const name = getTagValue(element, 'D:displayname', '');
             const size = parseInt(getTagValue(element, 'D:getcontentlength', '0'), 10);
             const url = getTagValue(element, 'D:href', '');
-            const nameSuffix = `/${encodeURIComponent(name) || ''}`;
+            const nameSuffix = `/${escapeHashIfRequired(name) || ''}`;
             const collectionUuidMatch = collectionUrlPrefix.exec(url);
             const collectionUuid = collectionUuidMatch ? collectionUuidMatch.pop() : '';
             const directory = url