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() {
|
render() {
|
||||||
const { permission } = this.state;
|
const { permission } = this.state;
|
||||||
const { t, loading, error } = this.props;
|
const { t, loading, error } = this.props;
|
||||||
const types = ["READ", "OWNER", "GROUP"];
|
const types = ["READ", "OWNER", "WRITE"];
|
||||||
const deleteButton = this.props.permission._links.delete ? (
|
const deleteButton = this.props.permission._links.delete ? (
|
||||||
<DeleteButton label={t("edit-permission.delete-button")} />
|
<DeleteButton label={t("edit-permission.delete-button")} />
|
||||||
) : null;
|
) : null;
|
||||||
@@ -99,7 +99,10 @@ class SinglePermission extends React.Component<Props, State> {
|
|||||||
<Checkbox checked={permission ? permission.groupPermission : false} />
|
<Checkbox checked={permission ? permission.groupPermission : false} />
|
||||||
</td>
|
</td>
|
||||||
{typeSelector}
|
{typeSelector}
|
||||||
<td>{deleteButton}</td> {errorNotification}
|
<td>
|
||||||
|
{deleteButton}
|
||||||
|
{errorNotification}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,14 @@ import type { Action } from "../../types/Action";
|
|||||||
import type { PermissionCollection, Permission } from "../types/Permissions";
|
import type { PermissionCollection, Permission } from "../types/Permissions";
|
||||||
import { isPending } from "../../modules/pending";
|
import { isPending } from "../../modules/pending";
|
||||||
import { getFailure } from "../../modules/failure";
|
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 = "scm/permissions/FETCH_PERMISSIONS";
|
||||||
export const FETCH_PERMISSIONS_PENDING = `${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}_${
|
export const MODIFY_PERMISSION_RESET = `${MODIFY_PERMISSION}_${
|
||||||
types.RESET_SUFFIX
|
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 REPOS_URL = "repositories";
|
||||||
const PERMISSIONS_URL = "permissions";
|
const PERMISSIONS_URL = "permissions";
|
||||||
const CONTENT_TYPE = "application/vnd.scmm-permission+json";
|
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
|
// reducer
|
||||||
export default function reducer(
|
export default function reducer(
|
||||||
state: Object = {},
|
state: Object = {},
|
||||||
@@ -195,17 +283,23 @@ export default function reducer(
|
|||||||
case FETCH_PERMISSIONS_SUCCESS:
|
case FETCH_PERMISSIONS_SUCCESS:
|
||||||
return {
|
return {
|
||||||
...state,
|
...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:
|
case MODIFY_PERMISSION_SUCCESS:
|
||||||
const positionOfPermission = action.payload.position;
|
const positionOfPermission = action.payload.position;
|
||||||
const newPermission = newPermissions(
|
const newPermission = newPermissions(
|
||||||
state[action.payload.position],
|
state[action.payload.position].entries,
|
||||||
action.payload.permission
|
action.payload.permission
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[positionOfPermission]: newPermission
|
[positionOfPermission]: {
|
||||||
|
...state[positionOfPermission],
|
||||||
|
entries: newPermission
|
||||||
|
}
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
@@ -220,7 +314,7 @@ export function getPermissionsOfRepo(
|
|||||||
name: string
|
name: string
|
||||||
) {
|
) {
|
||||||
if (state.permissions && state.permissions[namespace + "/" + name]) {
|
if (state.permissions && state.permissions[namespace + "/" + name]) {
|
||||||
const permissions = state.permissions[namespace + "/" + name];
|
const permissions = state.permissions[namespace + "/" + name].entries;
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import reducer, {
|
|||||||
modifyPermissionSuccess,
|
modifyPermissionSuccess,
|
||||||
getModifyPermissionFailure,
|
getModifyPermissionFailure,
|
||||||
isModifyPermissionPending,
|
isModifyPermissionPending,
|
||||||
|
createPermission,
|
||||||
MODIFY_PERMISSION_FAILURE,
|
MODIFY_PERMISSION_FAILURE,
|
||||||
MODIFY_PERMISSION_PENDING,
|
MODIFY_PERMISSION_PENDING,
|
||||||
FETCH_PERMISSIONS,
|
FETCH_PERMISSIONS,
|
||||||
@@ -19,7 +20,12 @@ import reducer, {
|
|||||||
FETCH_PERMISSIONS_SUCCESS,
|
FETCH_PERMISSIONS_SUCCESS,
|
||||||
FETCH_PERMISSIONS_FAILURE,
|
FETCH_PERMISSIONS_FAILURE,
|
||||||
MODIFY_PERMISSION_SUCCESS,
|
MODIFY_PERMISSION_SUCCESS,
|
||||||
MODIFY_PERMISSION
|
MODIFY_PERMISSION,
|
||||||
|
CREATE_PERMISSION,
|
||||||
|
CREATE_PERMISSION_PENDING,
|
||||||
|
CREATE_PERMISSION_SUCCESS,
|
||||||
|
CREATE_PERMISSION_FAILURE,
|
||||||
|
createPermissionSuccess
|
||||||
} from "./permissions";
|
} from "./permissions";
|
||||||
import type { Permission, PermissionCollection } from "../types/Permissions";
|
import type { Permission, PermissionCollection } from "../types/Permissions";
|
||||||
|
|
||||||
@@ -71,6 +77,11 @@ const hitchhiker_puzzle42Permissions: PermissionCollection = [
|
|||||||
const hitchhiker_puzzle42RepoPermissions = {
|
const hitchhiker_puzzle42RepoPermissions = {
|
||||||
_embedded: {
|
_embedded: {
|
||||||
permissions: hitchhiker_puzzle42Permissions
|
permissions: hitchhiker_puzzle42Permissions
|
||||||
|
},
|
||||||
|
_links: {
|
||||||
|
create: {
|
||||||
|
link: "link"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -203,6 +214,83 @@ describe("permission fetch", () => {
|
|||||||
expect(actions[1].payload).toBeDefined();
|
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", () => {
|
describe("permissions reducer", () => {
|
||||||
@@ -230,19 +318,23 @@ describe("permissions reducer", () => {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(newState["hitchhiker/puzzle42"]).toBe(
|
expect(newState["hitchhiker/puzzle42"].entries).toBe(
|
||||||
hitchhiker_puzzle42Permissions
|
hitchhiker_puzzle42Permissions
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should update permission", () => {
|
it("should update permission", () => {
|
||||||
const oldState = {
|
const oldState = {
|
||||||
"hitchhiker/puzzle42": [hitchhiker_puzzle42Permission_user_eins]
|
"hitchhiker/puzzle42": {
|
||||||
|
entries: [hitchhiker_puzzle42Permission_user_eins]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let permissionEdited = { ...hitchhiker_puzzle42Permission_user_eins };
|
let permissionEdited = { ...hitchhiker_puzzle42Permission_user_eins };
|
||||||
permissionEdited.type = "OWNER";
|
permissionEdited.type = "OWNER";
|
||||||
let expectedState = {
|
let expectedState = {
|
||||||
"hitchhiker/puzzle42": [permissionEdited]
|
"hitchhiker/puzzle42": {
|
||||||
|
entries: [permissionEdited]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const newState = reducer(
|
const newState = reducer(
|
||||||
oldState,
|
oldState,
|
||||||
@@ -260,7 +352,9 @@ describe("permissions selectors", () => {
|
|||||||
it("should return the permissions of one repository", () => {
|
it("should return the permissions of one repository", () => {
|
||||||
const state = {
|
const state = {
|
||||||
permissions: {
|
permissions: {
|
||||||
"hitchhiker/puzzle42": hitchhiker_puzzle42Permissions
|
"hitchhiker/puzzle42": {
|
||||||
|
entries: hitchhiker_puzzle42Permissions
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user