mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 15:35:49 +01:00
add handling of create link and createPermission handling
This commit is contained in:
@@ -70,7 +70,7 @@ class SinglePermission extends React.Component<Props, State> {
|
||||
render() {
|
||||
const { permission } = this.state;
|
||||
const { t, loading, error } = this.props;
|
||||
const types = ["READ", "OWNER", "GROUP"];
|
||||
const types = ["READ", "OWNER", "WRITE"];
|
||||
const deleteButton = this.props.permission._links.delete ? (
|
||||
<DeleteButton label={t("edit-permission.delete-button")} />
|
||||
) : null;
|
||||
@@ -99,7 +99,10 @@ class SinglePermission extends React.Component<Props, State> {
|
||||
<Checkbox checked={permission ? permission.groupPermission : false} />
|
||||
</td>
|
||||
{typeSelector}
|
||||
<td>{deleteButton}</td> {errorNotification}
|
||||
<td>
|
||||
{deleteButton}
|
||||
{errorNotification}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,14 @@ import type { Action } from "../../types/Action";
|
||||
import type { PermissionCollection, Permission } from "../types/Permissions";
|
||||
import { isPending } from "../../modules/pending";
|
||||
import { getFailure } from "../../modules/failure";
|
||||
import type { User } from "../../users/types/User";
|
||||
import { Dispatch } from "redux";
|
||||
import {
|
||||
CREATE_USER_FAILURE,
|
||||
CREATE_USER_PENDING,
|
||||
CREATE_USER_RESET,
|
||||
CREATE_USER_SUCCESS
|
||||
} from "../../users/modules/users";
|
||||
|
||||
export const FETCH_PERMISSIONS = "scm/permissions/FETCH_PERMISSIONS";
|
||||
export const FETCH_PERMISSIONS_PENDING = `${FETCH_PERMISSIONS}_${
|
||||
@@ -29,6 +37,17 @@ export const MODIFY_PERMISSION_FAILURE = `${MODIFY_PERMISSION}_${
|
||||
export const MODIFY_PERMISSION_RESET = `${MODIFY_PERMISSION}_${
|
||||
types.RESET_SUFFIX
|
||||
}`;
|
||||
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}_${
|
||||
types.SUCCESS_SUFFIX
|
||||
}`;
|
||||
export const CREATE_PERMISSION_FAILURE = `${CREATE_PERMISSION}_${
|
||||
types.FAILURE_SUFFIX
|
||||
}`;
|
||||
|
||||
const REPOS_URL = "repositories";
|
||||
const PERMISSIONS_URL = "permissions";
|
||||
const CONTENT_TYPE = "application/vnd.scmm-permission+json";
|
||||
@@ -182,6 +201,75 @@ export function modifyPermissionReset(
|
||||
};
|
||||
}
|
||||
|
||||
// create permission
|
||||
export function createPermission(
|
||||
permission: Permission,
|
||||
namespace: string,
|
||||
name: string,
|
||||
callback?: () => void
|
||||
) {
|
||||
return function(dispatch: Dispatch) {
|
||||
dispatch(createPermissionPending(permission, namespace, name));
|
||||
return apiClient
|
||||
.post(
|
||||
`${REPOS_URL}/${namespace}/${name}/${PERMISSIONS_URL}`,
|
||||
permission,
|
||||
CONTENT_TYPE
|
||||
)
|
||||
.then(() => {
|
||||
dispatch(createPermissionSuccess(namespace, name));
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
.catch(err =>
|
||||
dispatch(
|
||||
createPermissionFailure(
|
||||
new Error(
|
||||
`failed to add permission ${permission.name}: ${err.message}`
|
||||
),
|
||||
namespace,
|
||||
name
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function createPermissionPending(
|
||||
permission: Permission,
|
||||
namespace: string,
|
||||
name: string
|
||||
): Action {
|
||||
return {
|
||||
type: CREATE_PERMISSION_PENDING,
|
||||
payload: permission,
|
||||
itemId: namespace + "/" + name
|
||||
};
|
||||
}
|
||||
|
||||
export function createPermissionSuccess(
|
||||
namespace: string,
|
||||
name: string
|
||||
): Action {
|
||||
return {
|
||||
type: CREATE_PERMISSION_SUCCESS,
|
||||
itemId: namespace + "/" + name
|
||||
};
|
||||
}
|
||||
|
||||
export function createPermissionFailure(
|
||||
error: Error,
|
||||
namespace: string,
|
||||
name: string
|
||||
): Action {
|
||||
return {
|
||||
type: CREATE_PERMISSION_FAILURE,
|
||||
payload: error,
|
||||
itemId: namespace + "/" + name
|
||||
};
|
||||
}
|
||||
|
||||
// reducer
|
||||
export default function reducer(
|
||||
state: Object = {},
|
||||
@@ -195,17 +283,23 @@ export default function reducer(
|
||||
case FETCH_PERMISSIONS_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
[action.itemId]: action.payload._embedded.permissions
|
||||
[action.itemId]: {
|
||||
entries: action.payload._embedded.permissions,
|
||||
createPermission: action.payload._links.create ? true : false
|
||||
}
|
||||
};
|
||||
case MODIFY_PERMISSION_SUCCESS:
|
||||
const positionOfPermission = action.payload.position;
|
||||
const newPermission = newPermissions(
|
||||
state[action.payload.position],
|
||||
state[action.payload.position].entries,
|
||||
action.payload.permission
|
||||
);
|
||||
return {
|
||||
...state,
|
||||
[positionOfPermission]: newPermission
|
||||
[positionOfPermission]: {
|
||||
...state[positionOfPermission],
|
||||
entries: newPermission
|
||||
}
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
@@ -220,7 +314,7 @@ export function getPermissionsOfRepo(
|
||||
name: string
|
||||
) {
|
||||
if (state.permissions && state.permissions[namespace + "/" + name]) {
|
||||
const permissions = state.permissions[namespace + "/" + name];
|
||||
const permissions = state.permissions[namespace + "/" + name].entries;
|
||||
return permissions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import reducer, {
|
||||
modifyPermissionSuccess,
|
||||
getModifyPermissionFailure,
|
||||
isModifyPermissionPending,
|
||||
createPermission,
|
||||
MODIFY_PERMISSION_FAILURE,
|
||||
MODIFY_PERMISSION_PENDING,
|
||||
FETCH_PERMISSIONS,
|
||||
@@ -19,7 +20,12 @@ import reducer, {
|
||||
FETCH_PERMISSIONS_SUCCESS,
|
||||
FETCH_PERMISSIONS_FAILURE,
|
||||
MODIFY_PERMISSION_SUCCESS,
|
||||
MODIFY_PERMISSION
|
||||
MODIFY_PERMISSION,
|
||||
CREATE_PERMISSION,
|
||||
CREATE_PERMISSION_PENDING,
|
||||
CREATE_PERMISSION_SUCCESS,
|
||||
CREATE_PERMISSION_FAILURE,
|
||||
createPermissionSuccess
|
||||
} from "./permissions";
|
||||
import type { Permission, PermissionCollection } from "../types/Permissions";
|
||||
|
||||
@@ -71,6 +77,11 @@ const hitchhiker_puzzle42Permissions: PermissionCollection = [
|
||||
const hitchhiker_puzzle42RepoPermissions = {
|
||||
_embedded: {
|
||||
permissions: hitchhiker_puzzle42Permissions
|
||||
},
|
||||
_links: {
|
||||
create: {
|
||||
link: "link"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -203,6 +214,83 @@ describe("permission fetch", () => {
|
||||
expect(actions[1].payload).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("should add a permission successfully", () => {
|
||||
// unmatched
|
||||
fetchMock.postOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", {
|
||||
status: 204
|
||||
});
|
||||
|
||||
// after create, the users are fetched again
|
||||
fetchMock.getOnce(
|
||||
REPOS_URL + "/hitchhiker/puzzle42",
|
||||
hitchhiker_puzzle42RepoPermissions
|
||||
);
|
||||
|
||||
const store = mockStore({});
|
||||
return store
|
||||
.dispatch(
|
||||
createPermission(
|
||||
hitchhiker_puzzle42Permission_user_eins,
|
||||
"hitchhiker",
|
||||
"puzzle42"
|
||||
)
|
||||
)
|
||||
.then(() => {
|
||||
const actions = store.getActions();
|
||||
expect(actions[0].type).toEqual(CREATE_PERMISSION_PENDING);
|
||||
expect(actions[1].type).toEqual(CREATE_PERMISSION_SUCCESS);
|
||||
});
|
||||
});
|
||||
|
||||
it("should fail adding a permission on HTTP 500", () => {
|
||||
fetchMock.postOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", {
|
||||
status: 500
|
||||
});
|
||||
|
||||
const store = mockStore({});
|
||||
return store
|
||||
.dispatch(
|
||||
createPermission(
|
||||
hitchhiker_puzzle42Permission_user_eins,
|
||||
"hitchhiker",
|
||||
"puzzle42"
|
||||
)
|
||||
)
|
||||
.then(() => {
|
||||
const actions = store.getActions();
|
||||
expect(actions[0].type).toEqual(CREATE_PERMISSION_PENDING);
|
||||
expect(actions[1].type).toEqual(CREATE_PERMISSION_FAILURE);
|
||||
expect(actions[1].payload).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("should call the callback after permission successfully created", () => {
|
||||
// unmatched
|
||||
fetchMock.postOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", {
|
||||
status: 204
|
||||
});
|
||||
|
||||
let callMe = "not yet";
|
||||
|
||||
const callback = () => {
|
||||
callMe = "yeah";
|
||||
};
|
||||
|
||||
const store = mockStore({});
|
||||
return store
|
||||
.dispatch(
|
||||
createPermission(
|
||||
hitchhiker_puzzle42Permission_user_eins,
|
||||
"hitchhiker",
|
||||
"puzzle42",
|
||||
callback
|
||||
)
|
||||
)
|
||||
.then(() => {
|
||||
expect(callMe).toBe("yeah");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("permissions reducer", () => {
|
||||
@@ -230,19 +318,23 @@ describe("permissions reducer", () => {
|
||||
)
|
||||
);
|
||||
|
||||
expect(newState["hitchhiker/puzzle42"]).toBe(
|
||||
expect(newState["hitchhiker/puzzle42"].entries).toBe(
|
||||
hitchhiker_puzzle42Permissions
|
||||
);
|
||||
});
|
||||
|
||||
it("should update permission", () => {
|
||||
const oldState = {
|
||||
"hitchhiker/puzzle42": [hitchhiker_puzzle42Permission_user_eins]
|
||||
"hitchhiker/puzzle42": {
|
||||
entries: [hitchhiker_puzzle42Permission_user_eins]
|
||||
}
|
||||
};
|
||||
let permissionEdited = { ...hitchhiker_puzzle42Permission_user_eins };
|
||||
permissionEdited.type = "OWNER";
|
||||
let expectedState = {
|
||||
"hitchhiker/puzzle42": [permissionEdited]
|
||||
"hitchhiker/puzzle42": {
|
||||
entries: [permissionEdited]
|
||||
}
|
||||
};
|
||||
const newState = reducer(
|
||||
oldState,
|
||||
@@ -260,7 +352,9 @@ describe("permissions selectors", () => {
|
||||
it("should return the permissions of one repository", () => {
|
||||
const state = {
|
||||
permissions: {
|
||||
"hitchhiker/puzzle42": hitchhiker_puzzle42Permissions
|
||||
"hitchhiker/puzzle42": {
|
||||
entries: hitchhiker_puzzle42Permissions
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user