[ARVADOS-WORKBENCH2] created: 1.4.1-265-g6d1f423a

Git user git at public.arvados.org
Wed Feb 5 21:06:40 UTC 2020


        at  6d1f423a0c753f84562aa3efafaaa110062cfdad (commit)


commit 6d1f423a0c753f84562aa3efafaaa110062cfdad
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Wed Feb 5 18:05:08 2020 -0300

    16067: Ignores certain fields on create & update api calls.
    
    Some fields like 'etag', 'kind', 'uuid' and others are read-only, so
    they shouldn't be sent to the API server.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/services/collection-service/collection-service.ts b/src/services/collection-service/collection-service.ts
index 6eb9b5ba..f7955fba 100644
--- a/src/services/collection-service/collection-service.ts
+++ b/src/services/collection-service/collection-service.ts
@@ -15,7 +15,11 @@ export type UploadProgress = (fileId: number, loaded: number, total: number, cur
 
 export class CollectionService extends TrashableResourceService<CollectionResource> {
     constructor(serverApi: AxiosInstance, private webdavClient: WebDAV, private authService: AuthService, actions: ApiActions) {
-        super(serverApi, "collections", actions);
+        super(serverApi, "collections", actions, [
+            'unsignedManifestText',
+            'storageClassesConfirmed',
+            'storageClassesConfirmedAt'
+        ]);
     }
 
     async files(uuid: string) {
diff --git a/src/services/common-service/common-resource-service.test.ts b/src/services/common-service/common-resource-service.test.ts
index 2a18ce23..038c6943 100644
--- a/src/services/common-service/common-resource-service.test.ts
+++ b/src/services/common-service/common-resource-service.test.ts
@@ -48,6 +48,22 @@ describe("CommonResourceService", () => {
         expect(axiosInstance.post).toHaveBeenCalledWith("/resource", {owner_uuid: "ownerUuidValue"});
     });
 
+    it("#create ignores fields listed as readonly", async () => {
+        axiosInstance.post = jest.fn(() => Promise.resolve({data: {}}));
+        const commonResourceService = new CommonResourceService(axiosInstance, "resource", actions);
+        // UUID fields are read-only on all resources.
+        await commonResourceService.create({ uuid: "this should be ignored", ownerUuid: "ownerUuidValue" });
+        expect(axiosInstance.post).toHaveBeenCalledWith("/resource", {owner_uuid: "ownerUuidValue"});
+    });
+
+    it("#update ignores fields listed as readonly", async () => {
+        axiosInstance.put = jest.fn(() => Promise.resolve({data: {}}));
+        const commonResourceService = new CommonResourceService(axiosInstance, "resource", actions);
+        // UUID fields are read-only on all resources.
+        await commonResourceService.update('resource-uuid', { uuid: "this should be ignored", ownerUuid: "ownerUuidValue" });
+        expect(axiosInstance.put).toHaveBeenCalledWith("/resource/resource-uuid", {owner_uuid: "ownerUuidValue"});
+    });
+
     it("#delete", async () => {
         axiosMock
             .onDelete("/resource/uuid")
diff --git a/src/services/common-service/common-resource-service.ts b/src/services/common-service/common-resource-service.ts
index d29ea156..bc24f227 100644
--- a/src/services/common-service/common-resource-service.ts
+++ b/src/services/common-service/common-resource-service.ts
@@ -17,8 +17,26 @@ export enum CommonResourceServiceError {
 }
 
 export class CommonResourceService<T extends Resource> extends CommonService<T> {
-   constructor(serverApi: AxiosInstance, resourceType: string, actions: ApiActions) {
-        super(serverApi, resourceType, actions);
+    constructor(serverApi: AxiosInstance, resourceType: string, actions: ApiActions, readOnlyFields: string[] = []) {
+        super(serverApi, resourceType, actions, readOnlyFields.concat([
+            'uuid',
+            'etag',
+            'kind'
+        ]));
+    }
+
+    create(data?: Partial<T>) {
+        if (data !== undefined) {
+            this.readOnlyFields.forEach( field => delete data[field] );
+        }
+        return super.create(data);
+    }
+
+    update(uuid: string, data: Partial<T>) {
+        if (data !== undefined) {
+            this.readOnlyFields.forEach( field => delete data[field] );
+        }
+        return super.update(uuid, data);
     }
 }
 
diff --git a/src/services/common-service/common-service.ts b/src/services/common-service/common-service.ts
index d8117821..44233eb1 100644
--- a/src/services/common-service/common-service.ts
+++ b/src/services/common-service/common-service.ts
@@ -36,11 +36,13 @@ export class CommonService<T> {
     protected serverApi: AxiosInstance;
     protected resourceType: string;
     protected actions: ApiActions;
+    protected readOnlyFields: string[];
 
-    constructor(serverApi: AxiosInstance, resourceType: string, actions: ApiActions) {
+    constructor(serverApi: AxiosInstance, resourceType: string, actions: ApiActions, readOnlyFields: string[] = []) {
         this.serverApi = serverApi;
         this.resourceType = '/' + resourceType;
         this.actions = actions;
+        this.readOnlyFields = readOnlyFields;
     }
 
     static mapResponseKeys = (response: { data: any }) =>
diff --git a/src/services/common-service/trashable-resource-service.ts b/src/services/common-service/trashable-resource-service.ts
index 5746bffb..63be3ab8 100644
--- a/src/services/common-service/trashable-resource-service.ts
+++ b/src/services/common-service/trashable-resource-service.ts
@@ -10,8 +10,8 @@ import { ApiActions } from "~/services/api/api-actions";
 
 export class TrashableResourceService<T extends TrashableResource> extends CommonResourceService<T> {
 
-    constructor(serverApi: AxiosInstance, resourceType: string, actions: ApiActions) {
-        super(serverApi, resourceType, actions);
+    constructor(serverApi: AxiosInstance, resourceType: string, actions: ApiActions, readOnlyFields: string[] = []) {
+        super(serverApi, resourceType, actions, readOnlyFields);
     }
 
     trash(uuid: string): Promise<T> {
diff --git a/src/store/collections/collection-copy-actions.ts b/src/store/collections/collection-copy-actions.ts
index b13d08aa..cf87f3f1 100644
--- a/src/store/collections/collection-copy-actions.ts
+++ b/src/store/collections/collection-copy-actions.ts
@@ -28,13 +28,9 @@ export const copyCollection = (resource: CopyFormDialogData) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         dispatch(startSubmit(COLLECTION_COPY_FORM_NAME));
         try {
-            dispatch(progressIndicatorActions.START_WORKING(COLLECTION_COPY_FORM_NAME));
             const collection = await services.collectionService.get(resource.uuid);
-            const uuidKey = 'uuid';
-            delete collection[uuidKey];
             const newCollection = await services.collectionService.create({ ...collection, ownerUuid: resource.ownerUuid, name: resource.name });
             dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_COPY_FORM_NAME }));
-            dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_COPY_FORM_NAME));
             return newCollection;
         } catch (e) {
             const error = getCommonResourceServiceError(e);
@@ -47,7 +43,8 @@ export const copyCollection = (resource: CopyFormDialogData) =>
                 dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_COPY_FORM_NAME }));
                 throw new Error('Could not copy the collection.');
             }
-            dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_COPY_FORM_NAME));
             return;
+        } finally {
+            dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_COPY_FORM_NAME));
         }
     };

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list