move permissions to repo

This commit is contained in:
Maren Süwer
2018-09-11 16:00:15 +02:00
parent a31914f7ca
commit fe33e55bef
11 changed files with 15 additions and 15 deletions

View File

@@ -0,0 +1,625 @@
// @flow
import { apiClient } from "../../../../../scm-ui-components/packages/ui-components/src/index";
import * as types from "../../../modules/types";
import type { Action } from "../../../../../scm-ui-components/packages/ui-types/src/index";
import type {
PermissionCollection,
Permission,
PermissionEntry
} from "../types/Permissions";
import { isPending } from "../../../modules/pending";
import { getFailure } from "../../../modules/failure";
import { Dispatch } from "redux";
export const FETCH_PERMISSIONS = "scm/permissions/FETCH_PERMISSIONS";
export const FETCH_PERMISSIONS_PENDING = `${FETCH_PERMISSIONS}_${
types.PENDING_SUFFIX
}`;
export const FETCH_PERMISSIONS_SUCCESS = `${FETCH_PERMISSIONS}_${
types.SUCCESS_SUFFIX
}`;
export const FETCH_PERMISSIONS_FAILURE = `${FETCH_PERMISSIONS}_${
types.FAILURE_SUFFIX
}`;
export const MODIFY_PERMISSION = "scm/permissions/MODFIY_PERMISSION";
export const MODIFY_PERMISSION_PENDING = `${MODIFY_PERMISSION}_${
types.PENDING_SUFFIX
}`;
export const MODIFY_PERMISSION_SUCCESS = `${MODIFY_PERMISSION}_${
types.SUCCESS_SUFFIX
}`;
export const MODIFY_PERMISSION_FAILURE = `${MODIFY_PERMISSION}_${
types.FAILURE_SUFFIX
}`;
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
}`;
export const CREATE_PERMISSION_RESET = `${CREATE_PERMISSION}_${
types.RESET_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
}`;
export const DELETE_PERMISSION_RESET = `${DELETE_PERMISSION}_${
types.RESET_SUFFIX
}`;
const REPOS_URL = "repositories";
const PERMISSIONS_URL = "permissions";
const CONTENT_TYPE = "application/vnd.scmm-permission+json";
// fetch permissions
export function fetchPermissions(namespace: string, repoName: string) {
return function(dispatch: any) {
dispatch(fetchPermissionsPending(namespace, repoName));
return apiClient
.get(`${REPOS_URL}/${namespace}/${repoName}/${PERMISSIONS_URL}`)
.then(response => response.json())
.then(permissions => {
dispatch(fetchPermissionsSuccess(permissions, namespace, repoName));
})
.catch(err => {
dispatch(fetchPermissionsFailure(namespace, repoName, err));
});
};
}
export function fetchPermissionsPending(
namespace: string,
repoName: string
): Action {
return {
type: FETCH_PERMISSIONS_PENDING,
payload: {
namespace,
repoName
},
itemId: namespace + "/" + repoName
};
}
export function fetchPermissionsSuccess(
permissions: any,
namespace: string,
repoName: string
): Action {
return {
type: FETCH_PERMISSIONS_SUCCESS,
payload: permissions,
itemId: namespace + "/" + repoName
};
}
export function fetchPermissionsFailure(
namespace: string,
repoName: string,
error: Error
): Action {
return {
type: FETCH_PERMISSIONS_FAILURE,
payload: {
namespace,
repoName,
error
},
itemId: namespace + "/" + repoName
};
}
// modify permission
export function modifyPermission(
permission: Permission,
namespace: string,
repoName: string,
callback?: () => void
) {
return function(dispatch: any) {
dispatch(modifyPermissionPending(permission, namespace, repoName));
return apiClient
.put(permission._links.update.href, permission, CONTENT_TYPE)
.then(() => {
dispatch(modifyPermissionSuccess(permission, namespace, repoName));
if (callback) {
callback();
}
})
.catch(cause => {
const error = new Error(
`failed to modify permission: ${cause.message}`
);
dispatch(
modifyPermissionFailure(permission, error, namespace, repoName)
);
});
};
}
export function modifyPermissionPending(
permission: Permission,
namespace: string,
repoName: string
): Action {
return {
type: MODIFY_PERMISSION_PENDING,
payload: permission,
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function modifyPermissionSuccess(
permission: Permission,
namespace: string,
repoName: string
): Action {
return {
type: MODIFY_PERMISSION_SUCCESS,
payload: {
permission,
position: namespace + "/" + repoName
},
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function modifyPermissionFailure(
permission: Permission,
error: Error,
namespace: string,
repoName: string
): Action {
return {
type: MODIFY_PERMISSION_FAILURE,
payload: { error, permission },
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
function newPermissions(
oldPermissions: PermissionCollection,
newPermission: Permission
) {
for (let i = 0; i < oldPermissions.length; i++) {
if (oldPermissions[i].name === newPermission.name) {
oldPermissions.splice(i, 1, newPermission);
return oldPermissions;
}
}
}
export function modifyPermissionReset(namespace: string, repoName: string) {
return {
type: MODIFY_PERMISSION_RESET,
payload: {
namespace,
repoName
},
itemId: namespace + "/" + repoName
};
}
// create permission
export function createPermission(
permission: PermissionEntry,
namespace: string,
repoName: string,
callback?: () => void
) {
return function(dispatch: Dispatch) {
dispatch(createPermissionPending(permission, namespace, repoName));
return apiClient
.post(
`${REPOS_URL}/${namespace}/${repoName}/${PERMISSIONS_URL}`,
permission,
CONTENT_TYPE
)
.then(response => {
const location = response.headers.get("Location");
return apiClient.get(location);
})
.then(response => response.json())
.then(createdPermission => {
dispatch(
createPermissionSuccess(createdPermission, namespace, repoName)
);
if (callback) {
callback();
}
})
.catch(err =>
dispatch(
createPermissionFailure(
new Error(
`failed to add permission ${permission.name}: ${err.message}`
),
namespace,
repoName
)
)
);
};
}
export function createPermissionPending(
permission: PermissionEntry,
namespace: string,
repoName: string
): Action {
return {
type: CREATE_PERMISSION_PENDING,
payload: permission,
itemId: namespace + "/" + repoName
};
}
export function createPermissionSuccess(
permission: PermissionEntry,
namespace: string,
repoName: string
): Action {
return {
type: CREATE_PERMISSION_SUCCESS,
payload: {
permission,
position: namespace + "/" + repoName
},
itemId: namespace + "/" + repoName
};
}
export function createPermissionFailure(
error: Error,
namespace: string,
repoName: string
): Action {
return {
type: CREATE_PERMISSION_FAILURE,
payload: error,
itemId: namespace + "/" + repoName
};
}
export function createPermissionReset(namespace: string, repoName: string) {
return {
type: CREATE_PERMISSION_RESET,
itemId: namespace + "/" + repoName
};
}
// delete permission
export function deletePermission(
permission: Permission,
namespace: string,
repoName: string,
callback?: () => void
) {
return function(dispatch: any) {
dispatch(deletePermissionPending(permission, namespace, repoName));
return apiClient
.delete(permission._links.delete.href)
.then(() => {
dispatch(deletePermissionSuccess(permission, namespace, repoName));
if (callback) {
callback();
}
})
.catch(cause => {
const error = new Error(
`could not delete permission ${permission.name}: ${cause.message}`
);
dispatch(
deletePermissionFailure(permission, namespace, repoName, error)
);
});
};
}
export function deletePermissionPending(
permission: Permission,
namespace: string,
repoName: string
): Action {
return {
type: DELETE_PERMISSION_PENDING,
payload: permission,
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function deletePermissionSuccess(
permission: Permission,
namespace: string,
repoName: string
): Action {
return {
type: DELETE_PERMISSION_SUCCESS,
payload: {
permission,
position: namespace + "/" + repoName
},
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function deletePermissionFailure(
permission: Permission,
namespace: string,
repoName: string,
error: Error
): Action {
return {
type: DELETE_PERMISSION_FAILURE,
payload: {
error,
permission
},
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function deletePermissionReset(namespace: string, repoName: string) {
return {
type: DELETE_PERMISSION_RESET,
payload: {
namespace,
repoName
},
itemId: namespace + "/" + repoName
};
}
function deletePermissionFromState(
oldPermissions: PermissionCollection,
permission: Permission
) {
let newPermission = [];
for (let i = 0; i < oldPermissions.length; i++) {
if (oldPermissions[i] !== permission) {
newPermission.push(oldPermissions[i]);
}
}
return newPermission;
}
// reducer
export default function reducer(
state: Object = {},
action: Action = { type: "UNKNOWN" }
): Object {
if (!action.payload) {
return state;
}
switch (action.type) {
case FETCH_PERMISSIONS_SUCCESS:
return {
...state,
[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].entries,
action.payload.permission
);
return {
...state,
[positionOfPermission]: {
...state[positionOfPermission],
entries: newPermission
}
};
case CREATE_PERMISSION_SUCCESS:
// return state;
const position = action.payload.position;
const permissions = state[action.payload.position].entries;
permissions.push(action.payload.permission);
return {
...state,
[position]: {
...state[position],
entries: permissions
}
};
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;
}
}
// selectors
export function getPermissionsOfRepo(
state: Object,
namespace: string,
repoName: string
) {
if (state.permissions && state.permissions[namespace + "/" + repoName]) {
const permissions = state.permissions[namespace + "/" + repoName].entries;
return permissions;
}
}
export function isFetchPermissionsPending(
state: Object,
namespace: string,
repoName: string
) {
return isPending(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
}
export function getFetchPermissionsFailure(
state: Object,
namespace: string,
repoName: string
) {
return getFailure(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
}
export function isModifyPermissionPending(
state: Object,
namespace: string,
repoName: string,
permissionname: string
) {
return isPending(
state,
MODIFY_PERMISSION,
namespace + "/" + repoName + "/" + permissionname
);
}
export function getModifyPermissionFailure(
state: Object,
namespace: string,
repoName: string,
permissionname: string
) {
return getFailure(
state,
MODIFY_PERMISSION,
namespace + "/" + repoName + "/" + permissionname
);
}
export function hasCreatePermission(
state: Object,
namespace: string,
repoName: string
) {
if (state.permissions && state.permissions[namespace + "/" + repoName])
return state.permissions[namespace + "/" + repoName].createPermission;
else return null;
}
export function isCreatePermissionPending(
state: Object,
namespace: string,
repoName: string
) {
return isPending(state, CREATE_PERMISSION, namespace + "/" + repoName);
}
export function getCreatePermissionFailure(
state: Object,
namespace: string,
repoName: string
) {
return getFailure(state, CREATE_PERMISSION, namespace + "/" + repoName);
}
export function isDeletePermissionPending(
state: Object,
namespace: string,
repoName: string,
permissionname: string
) {
return isPending(
state,
DELETE_PERMISSION,
namespace + "/" + repoName + "/" + permissionname
);
}
export function getDeletePermissionFailure(
state: Object,
namespace: string,
repoName: string,
permissionname: string
) {
return getFailure(
state,
DELETE_PERMISSION,
namespace + "/" + repoName + "/" + permissionname
);
}
export function getDeletePermissionsFailure(
state: Object,
namespace: string,
repoName: string
) {
const permissions =
state.permissions && state.permissions[namespace + "/" + repoName]
? state.permissions[namespace + "/" + repoName].entries
: null;
if (permissions == null) return undefined;
for (let i = 0; i < permissions.length; i++) {
if (
getDeletePermissionFailure(
state,
namespace,
repoName,
permissions[i].name
)
) {
return getFailure(
state,
DELETE_PERMISSION,
namespace + "/" + repoName + "/" + permissions[i].name
);
}
}
return null;
}
export function getModifyPermissionsFailure(
state: Object,
namespace: string,
repoName: string
) {
const permissions =
state.permissions && state.permissions[namespace + "/" + repoName]
? state.permissions[namespace + "/" + repoName].entries
: null;
if (permissions == null) return undefined;
for (let i = 0; i < permissions.length; i++) {
if (
getModifyPermissionFailure(
state,
namespace,
repoName,
permissions[i].name
)
) {
return getFailure(
state,
MODIFY_PERMISSION,
namespace + "/" + repoName + "/" + permissions[i].name
);
}
}
return null;
}

View File

@@ -0,0 +1,732 @@
// @flow
import configureMockStore from "redux-mock-store";
import thunk from "redux-thunk";
import fetchMock from "fetch-mock";
import reducer, {
fetchPermissions,
fetchPermissionsSuccess,
getPermissionsOfRepo,
isFetchPermissionsPending,
getFetchPermissionsFailure,
modifyPermission,
modifyPermissionSuccess,
getModifyPermissionFailure,
isModifyPermissionPending,
createPermission,
hasCreatePermission,
deletePermission,
deletePermissionSuccess,
getDeletePermissionFailure,
isDeletePermissionPending,
getModifyPermissionsFailure,
MODIFY_PERMISSION_FAILURE,
MODIFY_PERMISSION_PENDING,
FETCH_PERMISSIONS,
FETCH_PERMISSIONS_PENDING,
FETCH_PERMISSIONS_SUCCESS,
FETCH_PERMISSIONS_FAILURE,
MODIFY_PERMISSION_SUCCESS,
MODIFY_PERMISSION,
CREATE_PERMISSION_PENDING,
CREATE_PERMISSION_SUCCESS,
CREATE_PERMISSION_FAILURE,
DELETE_PERMISSION,
DELETE_PERMISSION_PENDING,
DELETE_PERMISSION_SUCCESS,
DELETE_PERMISSION_FAILURE,
CREATE_PERMISSION,
createPermissionSuccess,
getCreatePermissionFailure,
isCreatePermissionPending,
getDeletePermissionsFailure
} from "./permissions";
import type { Permission, PermissionCollection } from "../types/Permissions";
const namespace = "hitchhiker";
const repoName = "puzzle42";
const hitchhiker_puzzle42Permission_user_eins: Permission = {
name: "user_eins",
type: "READ",
groupPermission: true,
_links: {
self: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
},
delete: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
},
update: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_eins"
}
}
};
const hitchhiker_puzzle42Permission_user_zwei: Permission = {
name: "user_zwei",
type: "WRITE",
groupPermission: true,
_links: {
self: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
},
delete: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
},
update: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions/user_zwei"
}
}
};
const hitchhiker_puzzle42Permissions: PermissionCollection = [
hitchhiker_puzzle42Permission_user_eins,
hitchhiker_puzzle42Permission_user_zwei
];
const hitchhiker_puzzle42RepoPermissions = {
_embedded: {
permissions: hitchhiker_puzzle42Permissions
},
_links: {
create: {
href:
"http://localhost:8081/scm/api/rest/v2/repositories/hitchhiker/puzzle42/permissions"
}
}
};
describe("permission fetch", () => {
const REPOS_URL = "/api/rest/v2/repositories";
const mockStore = configureMockStore([thunk]);
afterEach(() => {
fetchMock.reset();
fetchMock.restore();
});
it("should successfully fetch permissions to repo hitchhiker/puzzle42", () => {
fetchMock.getOnce(
REPOS_URL + "/hitchhiker/puzzle42/permissions",
hitchhiker_puzzle42RepoPermissions
);
const expectedActions = [
{
type: FETCH_PERMISSIONS_PENDING,
payload: {
namespace: "hitchhiker",
repoName: "puzzle42"
},
itemId: "hitchhiker/puzzle42"
},
{
type: FETCH_PERMISSIONS_SUCCESS,
payload: hitchhiker_puzzle42RepoPermissions,
itemId: "hitchhiker/puzzle42"
}
];
const store = mockStore({});
return store
.dispatch(fetchPermissions("hitchhiker", "puzzle42"))
.then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it("should dispatch FETCH_PERMISSIONS_FAILURE, it the request fails", () => {
fetchMock.getOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", {
status: 500
});
const store = mockStore({});
return store
.dispatch(fetchPermissions("hitchhiker", "puzzle42"))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(FETCH_PERMISSIONS_PENDING);
expect(actions[1].type).toEqual(FETCH_PERMISSIONS_FAILURE);
expect(actions[1].payload).toBeDefined();
});
});
it("should successfully modify user_eins permission", () => {
fetchMock.putOnce(
hitchhiker_puzzle42Permission_user_eins._links.update.href,
{
status: 204
}
);
let editedPermission = { ...hitchhiker_puzzle42Permission_user_eins };
editedPermission.type = "OWNER";
const store = mockStore({});
return store
.dispatch(modifyPermission(editedPermission, "hitchhiker", "puzzle42"))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
expect(actions[1].type).toEqual(MODIFY_PERMISSION_SUCCESS);
});
});
it("should successfully modify user_eins permission and call the callback", () => {
fetchMock.putOnce(
hitchhiker_puzzle42Permission_user_eins._links.update.href,
{
status: 204
}
);
let editedPermission = { ...hitchhiker_puzzle42Permission_user_eins };
editedPermission.type = "OWNER";
const store = mockStore({});
let called = false;
const callback = () => {
called = true;
};
return store
.dispatch(
modifyPermission(editedPermission, "hitchhiker", "puzzle42", callback)
)
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
expect(actions[1].type).toEqual(MODIFY_PERMISSION_SUCCESS);
expect(called).toBe(true);
});
});
it("should fail modifying on HTTP 500", () => {
fetchMock.putOnce(
hitchhiker_puzzle42Permission_user_eins._links.update.href,
{
status: 500
}
);
let editedPermission = { ...hitchhiker_puzzle42Permission_user_eins };
editedPermission.type = "OWNER";
const store = mockStore({});
return store
.dispatch(modifyPermission(editedPermission, "hitchhiker", "puzzle42"))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(MODIFY_PERMISSION_PENDING);
expect(actions[1].type).toEqual(MODIFY_PERMISSION_FAILURE);
expect(actions[1].payload).toBeDefined();
});
});
it("should add a permission successfully", () => {
// unmatched
fetchMock.postOnce(REPOS_URL + "/hitchhiker/puzzle42/permissions", {
status: 204,
headers: {
location: "/hitchhiker/puzzle42/permissions/user_eins"
}
});
fetchMock.getOnce(
REPOS_URL + "/hitchhiker/puzzle42/permissions/user_eins",
hitchhiker_puzzle42Permission_user_eins
);
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,
headers: {
location: "/hitchhiker/puzzle42/permissions/user_eins"
}
});
fetchMock.getOnce(
REPOS_URL + "/hitchhiker/puzzle42/permissions/user_eins",
hitchhiker_puzzle42Permission_user_eins
);
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");
});
});
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", () => {
it("should return empty object, if state and action is undefined", () => {
expect(reducer()).toEqual({});
});
it("should return the same state, if the action is undefined", () => {
const state = { x: true };
expect(reducer(state)).toBe(state);
});
it("should return the same state, if the action is unknown to the reducer", () => {
const state = { x: true };
expect(reducer(state, { type: "EL_SPECIALE" })).toBe(state);
});
it("should store the permissions on FETCH_PERMISSION_SUCCESS", () => {
const newState = reducer(
{},
fetchPermissionsSuccess(
hitchhiker_puzzle42RepoPermissions,
"hitchhiker",
"puzzle42"
)
);
expect(newState["hitchhiker/puzzle42"].entries).toBe(
hitchhiker_puzzle42Permissions
);
});
it("should update permission", () => {
const oldState = {
"hitchhiker/puzzle42": {
entries: [hitchhiker_puzzle42Permission_user_eins]
}
};
let permissionEdited = { ...hitchhiker_puzzle42Permission_user_eins };
permissionEdited.type = "OWNER";
let expectedState = {
"hitchhiker/puzzle42": {
entries: [permissionEdited]
}
};
const newState = reducer(
oldState,
modifyPermissionSuccess(permissionEdited, "hitchhiker", "puzzle42")
);
expect(newState["hitchhiker/puzzle42"]).toEqual(
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"]
);
});
it("should add permission", () => {
//changing state had to be removed because of errors
const oldState = {
"hitchhiker/puzzle42": {
entries: [hitchhiker_puzzle42Permission_user_eins]
}
};
let expectedState = {
"hitchhiker/puzzle42": {
entries: [
hitchhiker_puzzle42Permission_user_eins,
hitchhiker_puzzle42Permission_user_zwei
]
}
};
const newState = reducer(
oldState,
createPermissionSuccess(
hitchhiker_puzzle42Permission_user_zwei,
"hitchhiker",
"puzzle42"
)
);
expect(newState["hitchhiker/puzzle42"]).toEqual(
expectedState["hitchhiker/puzzle42"]
);
});
});
describe("permissions selectors", () => {
const error = new Error("something goes wrong");
it("should return the permissions of one repository", () => {
const state = {
permissions: {
"hitchhiker/puzzle42": {
entries: hitchhiker_puzzle42Permissions
}
}
};
const repoPermissions = getPermissionsOfRepo(
state,
"hitchhiker",
"puzzle42"
);
expect(repoPermissions).toEqual(hitchhiker_puzzle42Permissions);
});
it("should return true, when fetch permissions is pending", () => {
const state = {
pending: {
[FETCH_PERMISSIONS + "/hitchhiker/puzzle42"]: true
}
};
expect(isFetchPermissionsPending(state, "hitchhiker", "puzzle42")).toEqual(
true
);
});
it("should return false, when fetch permissions is not pending", () => {
expect(isFetchPermissionsPending({}, "hitchiker", "puzzle42")).toEqual(
false
);
});
it("should return error when fetch permissions did fail", () => {
const state = {
failure: {
[FETCH_PERMISSIONS + "/hitchhiker/puzzle42"]: error
}
};
expect(getFetchPermissionsFailure(state, "hitchhiker", "puzzle42")).toEqual(
error
);
});
it("should return undefined when fetch permissions did not fail", () => {
expect(getFetchPermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(
undefined
);
});
it("should return true, when modify permission is pending", () => {
const state = {
pending: {
[MODIFY_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: true
}
};
expect(
isModifyPermissionPending(state, "hitchhiker", "puzzle42", "user_eins")
).toEqual(true);
});
it("should return false, when modify permission is not pending", () => {
expect(
isModifyPermissionPending({}, "hitchiker", "puzzle42", "user_eins")
).toEqual(false);
});
it("should return error when modify permission did fail", () => {
const state = {
failure: {
[MODIFY_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
}
};
expect(
getModifyPermissionFailure(state, "hitchhiker", "puzzle42", "user_eins")
).toEqual(error);
});
it("should return undefined when modify permission did not fail", () => {
expect(
getModifyPermissionFailure({}, "hitchhiker", "puzzle42", "user_eins")
).toBe(undefined);
});
it("should return error when one of the modify permissions did fail", () => {
const state = {
permissions: {
"hitchhiker/puzzle42": { entries: hitchhiker_puzzle42Permissions }
},
failure: {
[MODIFY_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
}
};
expect(
getModifyPermissionsFailure(state, "hitchhiker", "puzzle42")
).toEqual(error);
});
it("should return undefined when no modify permissions did not fail", () => {
expect(getModifyPermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(
undefined
);
});
it("should return true, when createPermission is true", () => {
const state = {
permissions: {
["hitchhiker/puzzle42"]: {
createPermission: true
}
}
};
expect(hasCreatePermission(state, "hitchhiker", "puzzle42")).toBe(true);
});
it("should return false, when createPermission is false", () => {
const state = {
permissions: {
["hitchhiker/puzzle42"]: {
createPermission: false
}
}
};
expect(hasCreatePermission(state, "hitchhiker", "puzzle42")).toEqual(false);
});
it("should return true, when delete permission is pending", () => {
const state = {
pending: {
[DELETE_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: true
}
};
expect(
isDeletePermissionPending(state, "hitchhiker", "puzzle42", "user_eins")
).toEqual(true);
});
it("should return false, when delete permission is not pending", () => {
expect(
isDeletePermissionPending({}, "hitchiker", "puzzle42", "user_eins")
).toEqual(false);
});
it("should return error when delete permission did fail", () => {
const state = {
failure: {
[DELETE_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
}
};
expect(
getDeletePermissionFailure(state, "hitchhiker", "puzzle42", "user_eins")
).toEqual(error);
});
it("should return undefined when delete permission did not fail", () => {
expect(
getDeletePermissionFailure({}, "hitchhiker", "puzzle42", "user_eins")
).toBe(undefined);
});
it("should return error when one of the delete permissions did fail", () => {
const state = {
permissions: {
"hitchhiker/puzzle42": { entries: hitchhiker_puzzle42Permissions }
},
failure: {
[DELETE_PERMISSION + "/hitchhiker/puzzle42/user_eins"]: error
}
};
expect(
getDeletePermissionsFailure(state, "hitchhiker", "puzzle42")
).toEqual(error);
});
it("should return undefined when no delete permissions did not fail", () => {
expect(getDeletePermissionsFailure({}, "hitchhiker", "puzzle42")).toBe(
undefined
);
});
it("should return true, when create permission is pending", () => {
const state = {
pending: {
[CREATE_PERMISSION + "/hitchhiker/puzzle42"]: true
}
};
expect(isCreatePermissionPending(state, "hitchhiker", "puzzle42")).toEqual(
true
);
});
it("should return false, when create permissions is not pending", () => {
expect(isCreatePermissionPending({}, "hitchiker", "puzzle42")).toEqual(
false
);
});
it("should return error when create permissions did fail", () => {
const state = {
failure: {
[CREATE_PERMISSION + "/hitchhiker/puzzle42"]: error
}
};
expect(getCreatePermissionFailure(state, "hitchhiker", "puzzle42")).toEqual(
error
);
});
it("should return undefined when create permissions did not fail", () => {
expect(getCreatePermissionFailure({}, "hitchhiker", "puzzle42")).toBe(
undefined
);
});
});