From 029503e7a3c00699d1dbacfb476703aa47ae2a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maren=20S=C3=BCwer?= Date: Thu, 30 Aug 2018 08:50:15 +0200 Subject: [PATCH] add delete functionality --- scm-ui/src/permissions/modules/permissions.js | 107 +++++++++++++++- .../permissions/modules/permissions.test.js | 119 +++++++++++++++++- 2 files changed, 223 insertions(+), 3 deletions(-) diff --git a/scm-ui/src/permissions/modules/permissions.js b/scm-ui/src/permissions/modules/permissions.js index 45b142ee91..8eaac31250 100644 --- a/scm-ui/src/permissions/modules/permissions.js +++ b/scm-ui/src/permissions/modules/permissions.js @@ -34,12 +34,22 @@ export const CREATE_PERMISSION = "scm/permissions/CREATE_PERMISSION"; export const CREATE_PERMISSION_PENDING = `${CREATE_PERMISSION}_${ types.PENDING_SUFFIX }`; -export const CREATE_PERMISSION_SUCCESS = `$CREATE_PERMISSION}_${ +export const CREATE_PERMISSION_SUCCESS = `${CREATE_PERMISSION}_${ types.SUCCESS_SUFFIX }`; export const CREATE_PERMISSION_FAILURE = `${CREATE_PERMISSION}_${ types.FAILURE_SUFFIX }`; +export const DELETE_PERMISSION = "scm/permissions/DELETE_PERMISSION"; +export const DELETE_PERMISSION_PENDING = `${DELETE_PERMISSION}_${ + types.PENDING_SUFFIX +}`; +export const DELETE_PERMISSION_SUCCESS = `${DELETE_PERMISSION}_${ + types.SUCCESS_SUFFIX +}`; +export const DELETE_PERMISSION_FAILURE = `${DELETE_PERMISSION}_${ + types.FAILURE_SUFFIX +}`; const REPOS_URL = "repositories"; const PERMISSIONS_URL = "permissions"; @@ -263,6 +273,88 @@ export function createPermissionFailure( }; } +// delete permission + +export function deletePermission( + permission: Permission, + namespace: string, + name: string, + callback?: () => void +) { + return function(dispatch: any) { + dispatch(deletePermissionPending(permission, namespace, name)); + return apiClient + .delete(permission._links.delete.href) + .then(() => { + dispatch(deletePermissionSuccess(permission, namespace, name)); + if (callback) { + callback(); + } + }) + .catch(cause => { + const error = new Error( + `could not delete permission ${permission.name}: ${cause.message}` + ); + dispatch(deletePermissionFailure(permission, namespace, name, error)); + }); + }; +} + +export function deletePermissionPending( + permission: Permission, + namespace: string, + name: string +): Action { + return { + type: DELETE_PERMISSION_PENDING, + payload: permission, + itemId: namespace + "/" + name + "/" + permission.name + }; +} + +export function deletePermissionSuccess( + permission: Permission, + namespace: string, + name: string +): Action { + return { + type: DELETE_PERMISSION_SUCCESS, + payload: { + permission, + position: namespace + "/" + name + }, + itemId: namespace + "/" + name + "/" + permission.name + }; +} + +export function deletePermissionFailure( + permission: Permission, + namespace: string, + name: string, + error: Error +): Action { + return { + type: DELETE_PERMISSION_FAILURE, + payload: { + error, + permission + }, + itemId: namespace + "/" + name + "/" + permission.name + }; +} + +function deletePermissionFromState( + oldPermissions: PermissionCollection, + permission: Permission +) { + for (let i = 0; i < oldPermissions.length; i++) { + if (oldPermissions[i] === permission) { + oldPermissions.splice(i, 1); + } + } + return oldPermissions; +} + // reducer export default function reducer( state: Object = {}, @@ -294,6 +386,19 @@ export default function reducer( entries: newPermission } }; + case DELETE_PERMISSION_SUCCESS: + const permissionPosition = action.payload.position; + const new_Permissions = deletePermissionFromState( + state[action.payload.position].entries, + action.payload.permission + ); + return { + ...state, + [permissionPosition]: { + ...state[permissionPosition], + entries: new_Permissions + } + }; default: return state; } diff --git a/scm-ui/src/permissions/modules/permissions.test.js b/scm-ui/src/permissions/modules/permissions.test.js index c999c16b41..245fa39541 100644 --- a/scm-ui/src/permissions/modules/permissions.test.js +++ b/scm-ui/src/permissions/modules/permissions.test.js @@ -14,6 +14,8 @@ import reducer, { isModifyPermissionPending, createPermission, hasCreatePermission, + deletePermission, + deletePermissionSuccess, MODIFY_PERMISSION_FAILURE, MODIFY_PERMISSION_PENDING, FETCH_PERMISSIONS, @@ -22,11 +24,12 @@ import reducer, { FETCH_PERMISSIONS_FAILURE, MODIFY_PERMISSION_SUCCESS, MODIFY_PERMISSION, - CREATE_PERMISSION, CREATE_PERMISSION_PENDING, CREATE_PERMISSION_SUCCESS, CREATE_PERMISSION_FAILURE, - createPermissionSuccess + DELETE_PERMISSION_PENDING, + DELETE_PERMISSION_SUCCESS, + DELETE_PERMISSION_FAILURE } from "./permissions"; import type { Permission, PermissionCollection } from "../types/Permissions"; @@ -292,6 +295,89 @@ describe("permission fetch", () => { expect(callMe).toBe("yeah"); }); }); + it("should delete successfully permission user_eins", () => { + fetchMock.deleteOnce( + hitchhiker_puzzle42Permission_user_eins._links.delete.href, + { + status: 204 + } + ); + + const store = mockStore({}); + return store + .dispatch( + deletePermission( + hitchhiker_puzzle42Permission_user_eins, + "hitchhiker", + "puzzle42" + ) + ) + .then(() => { + const actions = store.getActions(); + expect(actions.length).toBe(2); + expect(actions[0].type).toEqual(DELETE_PERMISSION_PENDING); + expect(actions[0].payload).toBe( + hitchhiker_puzzle42Permission_user_eins + ); + expect(actions[1].type).toEqual(DELETE_PERMISSION_SUCCESS); + }); + }); + + it("should call the callback, after successful delete", () => { + fetchMock.deleteOnce( + hitchhiker_puzzle42Permission_user_eins._links.delete.href, + { + status: 204 + } + ); + + let called = false; + const callMe = () => { + called = true; + }; + + const store = mockStore({}); + return store + .dispatch( + deletePermission( + hitchhiker_puzzle42Permission_user_eins, + "hitchhiker", + "puzzle42", + callMe + ) + ) + .then(() => { + expect(called).toBeTruthy(); + }); + }); + + it("should fail to delete permission", () => { + fetchMock.deleteOnce( + hitchhiker_puzzle42Permission_user_eins._links.delete.href, + { + status: 500 + } + ); + + const store = mockStore({}); + return store + .dispatch( + deletePermission( + hitchhiker_puzzle42Permission_user_eins, + "hitchhiker", + "puzzle42" + ) + ) + .then(() => { + const actions = store.getActions(); + expect(actions[0].type).toEqual(DELETE_PERMISSION_PENDING); + expect(actions[0].payload).toBe( + hitchhiker_puzzle42Permission_user_eins + ); + expect(actions[1].type).toEqual(DELETE_PERMISSION_FAILURE); + expect(actions[1].payload).toBeDefined(); + }); + }); }); describe("permissions reducer", () => { @@ -345,6 +431,35 @@ describe("permissions reducer", () => { expectedState["hitchhiker/puzzle42"] ); }); + + it("should remove permission from state when delete succeeds", () => { + const state = { + "hitchhiker/puzzle42": { + entries: [ + hitchhiker_puzzle42Permission_user_eins, + hitchhiker_puzzle42Permission_user_zwei + ] + } + }; + + const expectedState = { + "hitchhiker/puzzle42": { + entries: [hitchhiker_puzzle42Permission_user_zwei] + } + }; + + const newState = reducer( + state, + deletePermissionSuccess( + hitchhiker_puzzle42Permission_user_eins, + "hitchhiker", + "puzzle42" + ) + ); + expect(newState["hitchhiker/puzzle42"]).toEqual( + expectedState["hitchhiker/puzzle42"] + ); + }); }); describe("permissions selectors", () => {