apply prettier, removed flow related config and added tsconfig

This commit is contained in:
Sebastian Sdorra
2019-10-20 18:02:52 +02:00
parent 0e017dcadd
commit 490418d06e
231 changed files with 5771 additions and 30386 deletions

View File

@@ -29,62 +29,62 @@ import reducer, {
LOGOUT_REDIRECT,
LOGOUT_SUCCESS,
logoutSuccess,
redirectAfterLogout,
} from './auth';
redirectAfterLogout
} from "./auth";
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import fetchMock from 'fetch-mock';
import configureMockStore from "redux-mock-store";
import thunk from "redux-thunk";
import fetchMock from "fetch-mock";
import {
FETCH_INDEXRESOURCES_PENDING,
FETCH_INDEXRESOURCES_SUCCESS,
} from './indexResource';
FETCH_INDEXRESOURCES_SUCCESS
} from "./indexResource";
const me = {
name: 'tricia',
displayName: 'Tricia McMillian',
mail: 'trillian@heartofgold.universe',
name: "tricia",
displayName: "Tricia McMillian",
mail: "trillian@heartofgold.universe"
};
describe('auth reducer', () => {
it('should set me and login on successful fetch of me', () => {
describe("auth reducer", () => {
it("should set me and login on successful fetch of me", () => {
const state = reducer(undefined, fetchMeSuccess(me));
expect(state.me).toBe(me);
});
it('should set authenticated to false', () => {
it("should set authenticated to false", () => {
const initialState = {
me,
me
};
const state = reducer(initialState, fetchMeUnauthenticated());
expect(state.me.name).toBeUndefined();
});
it('should reset the state after logout', () => {
it("should reset the state after logout", () => {
const initialState = {
me,
me
};
const state = reducer(initialState, logoutSuccess());
expect(state.me).toBeUndefined();
expect(state.authenticated).toBeUndefined();
});
it('should keep state and set redirecting to true', () => {
it("should keep state and set redirecting to true", () => {
const initialState = {
me,
me
};
const state = reducer(initialState, redirectAfterLogout());
expect(state.me).toBe(initialState.me);
expect(state.redirecting).toBe(true);
});
it('should set state authenticated and me after login', () => {
it("should set state authenticated and me after login", () => {
const state = reducer(undefined, loginSuccess(me));
expect(state.me).toBe(me);
});
});
describe('auth actions', () => {
describe("auth actions", () => {
const mockStore = configureMockStore([thunk]);
afterEach(() => {
@@ -92,72 +92,72 @@ describe('auth actions', () => {
fetchMock.restore();
});
it('should dispatch login success and dispatch fetch me', () => {
fetchMock.postOnce('/api/v2/auth/access_token', {
it("should dispatch login success and dispatch fetch me", () => {
fetchMock.postOnce("/api/v2/auth/access_token", {
body: {
cookie: true,
grant_type: 'password',
username: 'tricia',
password: 'secret123',
grant_type: "password",
username: "tricia",
password: "secret123"
},
headers: {
'content-type': 'application/json',
},
"content-type": "application/json"
}
});
fetchMock.getOnce('/api/v2/me', {
fetchMock.getOnce("/api/v2/me", {
body: me,
headers: {
'content-type': 'application/json',
},
"content-type": "application/json"
}
});
const meLink = {
me: {
href: '/me',
},
href: "/me"
}
};
fetchMock.getOnce('/api/v2/', {
_links: meLink,
fetchMock.getOnce("/api/v2/", {
_links: meLink
});
const expectedActions = [
{
type: LOGIN_PENDING,
type: LOGIN_PENDING
},
{
type: FETCH_INDEXRESOURCES_PENDING,
type: FETCH_INDEXRESOURCES_PENDING
},
{
type: FETCH_INDEXRESOURCES_SUCCESS,
payload: {
_links: meLink,
},
_links: meLink
}
},
{
type: LOGIN_SUCCESS,
payload: me,
},
payload: me
}
];
const store = mockStore({});
return store
.dispatch(login('/auth/access_token', 'tricia', 'secret123'))
.dispatch(login("/auth/access_token", "tricia", "secret123"))
.then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it('should dispatch login failure', () => {
fetchMock.postOnce('/api/v2/auth/access_token', {
status: 400,
it("should dispatch login failure", () => {
fetchMock.postOnce("/api/v2/auth/access_token", {
status: 400
});
const store = mockStore({});
return store
.dispatch(login('/auth/access_token', 'tricia', 'secret123'))
.dispatch(login("/auth/access_token", "tricia", "secret123"))
.then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(LOGIN_PENDING);
@@ -166,38 +166,38 @@ describe('auth actions', () => {
});
});
it('should dispatch fetch me success', () => {
fetchMock.getOnce('/api/v2/me', {
it("should dispatch fetch me success", () => {
fetchMock.getOnce("/api/v2/me", {
body: me,
headers: {
'content-type': 'application/json',
},
"content-type": "application/json"
}
});
const expectedActions = [
{
type: FETCH_ME_PENDING,
type: FETCH_ME_PENDING
},
{
type: FETCH_ME_SUCCESS,
payload: me,
},
payload: me
}
];
const store = mockStore({});
return store.dispatch(fetchMe('me')).then(() => {
return store.dispatch(fetchMe("me")).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it('should dispatch fetch me failure', () => {
fetchMock.getOnce('/api/v2/me', {
status: 500,
it("should dispatch fetch me failure", () => {
fetchMock.getOnce("/api/v2/me", {
status: 500
});
const store = mockStore({});
return store.dispatch(fetchMe('me')).then(() => {
return store.dispatch(fetchMe("me")).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(FETCH_ME_PENDING);
expect(actions[1].type).toEqual(FETCH_ME_FAILURE);
@@ -205,111 +205,111 @@ describe('auth actions', () => {
});
});
it('should dispatch fetch me unauthorized', () => {
fetchMock.getOnce('/api/v2/me', 401);
it("should dispatch fetch me unauthorized", () => {
fetchMock.getOnce("/api/v2/me", 401);
const expectedActions = [
{
type: FETCH_ME_PENDING,
type: FETCH_ME_PENDING
},
{
type: FETCH_ME_UNAUTHORIZED,
resetPending: true,
},
resetPending: true
}
];
const store = mockStore({});
return store.dispatch(fetchMe('me')).then(() => {
return store.dispatch(fetchMe("me")).then(() => {
// return of async actions
expect(store.getActions()).toEqual(expectedActions);
});
});
it('should dispatch logout success', () => {
fetchMock.deleteOnce('/api/v2/auth/access_token', {
status: 204,
it("should dispatch logout success", () => {
fetchMock.deleteOnce("/api/v2/auth/access_token", {
status: 204
});
fetchMock.getOnce('/api/v2/me', {
status: 401,
fetchMock.getOnce("/api/v2/me", {
status: 401
});
fetchMock.getOnce('/api/v2/', {
fetchMock.getOnce("/api/v2/", {
_links: {
login: {
login: '/login',
},
},
login: "/login"
}
}
});
const expectedActions = [
{
type: LOGOUT_PENDING,
type: LOGOUT_PENDING
},
{
type: LOGOUT_SUCCESS,
type: LOGOUT_SUCCESS
},
{
type: FETCH_INDEXRESOURCES_PENDING,
},
type: FETCH_INDEXRESOURCES_PENDING
}
];
const store = mockStore({});
return store.dispatch(logout('/auth/access_token')).then(() => {
return store.dispatch(logout("/auth/access_token")).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it('should dispatch logout success and redirect', () => {
fetchMock.deleteOnce('/api/v2/auth/access_token', {
it("should dispatch logout success and redirect", () => {
fetchMock.deleteOnce("/api/v2/auth/access_token", {
status: 200,
body: {
logoutRedirect: 'http://example.com/cas/logout',
},
logoutRedirect: "http://example.com/cas/logout"
}
});
fetchMock.getOnce('/api/v2/me', {
status: 401,
fetchMock.getOnce("/api/v2/me", {
status: 401
});
fetchMock.getOnce('/api/v2/', {
fetchMock.getOnce("/api/v2/", {
_links: {
login: {
login: '/login',
},
},
login: "/login"
}
}
});
window.location.assign = jest.fn();
const expectedActions = [
{
type: LOGOUT_PENDING,
type: LOGOUT_PENDING
},
{
type: LOGOUT_REDIRECT,
},
type: LOGOUT_REDIRECT
}
];
const store = mockStore({});
return store.dispatch(logout('/auth/access_token')).then(() => {
return store.dispatch(logout("/auth/access_token")).then(() => {
expect(window.location.assign.mock.calls[0][0]).toBe(
'http://example.com/cas/logout',
"http://example.com/cas/logout"
);
expect(store.getActions()).toEqual(expectedActions);
});
});
it('should dispatch logout failure', () => {
fetchMock.deleteOnce('/api/v2/auth/access_token', {
status: 500,
it("should dispatch logout failure", () => {
fetchMock.deleteOnce("/api/v2/auth/access_token", {
status: 500
});
const store = mockStore({});
return store.dispatch(logout('/auth/access_token')).then(() => {
return store.dispatch(logout("/auth/access_token")).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(LOGOUT_PENDING);
expect(actions[1].type).toEqual(LOGOUT_FAILURE);
@@ -318,170 +318,170 @@ describe('auth actions', () => {
});
});
describe('auth selectors', () => {
const error = new Error('yo it failed');
describe("auth selectors", () => {
const error = new Error("yo it failed");
it('should return true if me exist and login Link does not exist', () => {
it("should return true if me exist and login Link does not exist", () => {
expect(
isAuthenticated({
auth: {
me,
me
},
indexResources: {
links: {},
},
}),
links: {}
}
})
).toBe(true);
});
it('should return false if me exist and login Link does exist', () => {
it("should return false if me exist and login Link does exist", () => {
expect(
isAuthenticated({
auth: {
me,
me
},
indexResources: {
links: {
login: {
href: 'login.href',
},
},
},
}),
href: "login.href"
}
}
}
})
).toBe(false);
});
it('should return me', () => {
it("should return me", () => {
expect(
getMe({
auth: {
me,
},
}),
me
}
})
).toBe(me);
});
it('should return undefined, if me is not set', () => {
it("should return undefined, if me is not set", () => {
expect(getMe({})).toBeUndefined();
});
it('should return true, if FETCH_ME is pending', () => {
it("should return true, if FETCH_ME is pending", () => {
expect(
isFetchMePending({
pending: {
[FETCH_ME]: true,
},
}),
[FETCH_ME]: true
}
})
).toBe(true);
});
it('should return false, if FETCH_ME is not in pending state', () => {
it("should return false, if FETCH_ME is not in pending state", () => {
expect(
isFetchMePending({
pending: {},
}),
pending: {}
})
).toBe(false);
});
it('should return true, if LOGIN is pending', () => {
it("should return true, if LOGIN is pending", () => {
expect(
isLoginPending({
pending: {
[LOGIN]: true,
},
}),
[LOGIN]: true
}
})
).toBe(true);
});
it('should return false, if LOGIN is not in pending state', () => {
it("should return false, if LOGIN is not in pending state", () => {
expect(
isLoginPending({
pending: {},
}),
pending: {}
})
).toBe(false);
});
it('should return true, if LOGOUT is pending', () => {
it("should return true, if LOGOUT is pending", () => {
expect(
isLogoutPending({
pending: {
[LOGOUT]: true,
},
}),
[LOGOUT]: true
}
})
).toBe(true);
});
it('should return false, if LOGOUT is not in pending state', () => {
it("should return false, if LOGOUT is not in pending state", () => {
expect(
isLogoutPending({
pending: {},
}),
pending: {}
})
).toBe(false);
});
it('should return the error, if failure state is set for FETCH_ME', () => {
it("should return the error, if failure state is set for FETCH_ME", () => {
expect(
getFetchMeFailure({
failure: {
[FETCH_ME]: error,
},
}),
[FETCH_ME]: error
}
})
).toBe(error);
});
it('should return unknown, if failure state is not set for FETCH_ME', () => {
it("should return unknown, if failure state is not set for FETCH_ME", () => {
expect(getFetchMeFailure({})).toBeUndefined();
});
it('should return the error, if failure state is set for LOGIN', () => {
it("should return the error, if failure state is set for LOGIN", () => {
expect(
getLoginFailure({
failure: {
[LOGIN]: error,
},
}),
[LOGIN]: error
}
})
).toBe(error);
});
it('should return unknown, if failure state is not set for LOGIN', () => {
it("should return unknown, if failure state is not set for LOGIN", () => {
expect(getLoginFailure({})).toBeUndefined();
});
it('should return the error, if failure state is set for LOGOUT', () => {
it("should return the error, if failure state is set for LOGOUT", () => {
expect(
getLogoutFailure({
failure: {
[LOGOUT]: error,
},
}),
[LOGOUT]: error
}
})
).toBe(error);
});
it('should return unknown, if failure state is not set for LOGOUT', () => {
it("should return unknown, if failure state is not set for LOGOUT", () => {
expect(getLogoutFailure({})).toBeUndefined();
});
it('should return false, if redirecting is not set', () => {
it("should return false, if redirecting is not set", () => {
expect(isRedirecting({})).toBe(false);
});
it('should return false, if redirecting is false', () => {
it("should return false, if redirecting is false", () => {
expect(
isRedirecting({
auth: {
redirecting: false,
},
}),
redirecting: false
}
})
).toBe(false);
});
it('should return true, if redirecting is true', () => {
it("should return true, if redirecting is true", () => {
expect(
isRedirecting({
auth: {
redirecting: true,
},
}),
redirecting: true
}
})
).toBe(true);
});
});

View File

@@ -1,31 +1,31 @@
import { Me } from '@scm-manager/ui-types';
import * as types from './types';
import { Me } from "@scm-manager/ui-types";
import * as types from "./types";
import { apiClient, UnauthorizedError } from '@scm-manager/ui-components';
import { isPending } from './pending';
import { getFailure } from './failure';
import { apiClient, UnauthorizedError } from "@scm-manager/ui-components";
import { isPending } from "./pending";
import { getFailure } from "./failure";
import {
callFetchIndexResources,
fetchIndexResources,
fetchIndexResourcesPending,
fetchIndexResourcesSuccess,
getLoginLink,
} from './indexResource';
getLoginLink
} from "./indexResource";
// Action
export const LOGIN = 'scm/auth/LOGIN';
export const LOGIN = "scm/auth/LOGIN";
export const LOGIN_PENDING = `${LOGIN}_${types.PENDING_SUFFIX}`;
export const LOGIN_SUCCESS = `${LOGIN}_${types.SUCCESS_SUFFIX}`;
export const LOGIN_FAILURE = `${LOGIN}_${types.FAILURE_SUFFIX}`;
export const FETCH_ME = 'scm/auth/FETCH_ME';
export const FETCH_ME = "scm/auth/FETCH_ME";
export const FETCH_ME_PENDING = `${FETCH_ME}_${types.PENDING_SUFFIX}`;
export const FETCH_ME_SUCCESS = `${FETCH_ME}_${types.SUCCESS_SUFFIX}`;
export const FETCH_ME_FAILURE = `${FETCH_ME}_${types.FAILURE_SUFFIX}`;
export const FETCH_ME_UNAUTHORIZED = `${FETCH_ME}_UNAUTHORIZED`;
export const LOGOUT = 'scm/auth/LOGOUT';
export const LOGOUT = "scm/auth/LOGOUT";
export const LOGOUT_PENDING = `${LOGOUT}_${types.PENDING_SUFFIX}`;
export const LOGOUT_SUCCESS = `${LOGOUT}_${types.SUCCESS_SUFFIX}`;
export const LOGOUT_FAILURE = `${LOGOUT}_${types.FAILURE_SUFFIX}`;
@@ -38,19 +38,19 @@ const initialState = {};
export default function reducer(
state: object = initialState,
action: object = {
type: 'UNKNOWN',
},
type: "UNKNOWN"
}
) {
switch (action.type) {
case LOGIN_SUCCESS:
case FETCH_ME_SUCCESS:
return {
...state,
me: action.payload,
me: action.payload
};
case FETCH_ME_UNAUTHORIZED:
return {
me: {},
me: {}
};
case LOGOUT_SUCCESS:
return initialState;
@@ -59,7 +59,7 @@ export default function reducer(
// we keep the current state until we are redirected to the new page
return {
...state,
redirecting: true,
redirecting: true
};
}
default:
@@ -71,73 +71,73 @@ export default function reducer(
export const loginPending = () => {
return {
type: LOGIN_PENDING,
type: LOGIN_PENDING
};
};
export const loginSuccess = (me: Me) => {
return {
type: LOGIN_SUCCESS,
payload: me,
payload: me
};
};
export const loginFailure = (error: Error) => {
return {
type: LOGIN_FAILURE,
payload: error,
payload: error
};
};
export const logoutPending = () => {
return {
type: LOGOUT_PENDING,
type: LOGOUT_PENDING
};
};
export const logoutSuccess = () => {
return {
type: LOGOUT_SUCCESS,
type: LOGOUT_SUCCESS
};
};
export const redirectAfterLogout = () => {
return {
type: LOGOUT_REDIRECT,
type: LOGOUT_REDIRECT
};
};
export const logoutFailure = (error: Error) => {
return {
type: LOGOUT_FAILURE,
payload: error,
payload: error
};
};
export const fetchMePending = () => {
return {
type: FETCH_ME_PENDING,
type: FETCH_ME_PENDING
};
};
export const fetchMeSuccess = (me: Me) => {
return {
type: FETCH_ME_SUCCESS,
payload: me,
payload: me
};
};
export const fetchMeUnauthenticated = () => {
return {
type: FETCH_ME_UNAUTHORIZED,
resetPending: true,
resetPending: true
};
};
export const fetchMeFailure = (error: Error) => {
return {
type: FETCH_ME_FAILURE,
payload: error,
payload: error
};
};
@@ -152,13 +152,13 @@ const callFetchMe = (link: string): Promise<Me> => {
export const login = (
loginLink: string,
username: string,
password: string,
password: string
) => {
const login_data = {
cookie: true,
grant_type: 'password',
grant_type: "password",
username,
password,
password
};
return function(dispatch: any) {
dispatch(loginPending());

View File

@@ -1,27 +1,27 @@
import fetchMock from 'fetch-mock';
import { changePassword, CONTENT_TYPE_PASSWORD_CHANGE } from './changePassword';
import fetchMock from "fetch-mock";
import { changePassword, CONTENT_TYPE_PASSWORD_CHANGE } from "./changePassword";
describe('change password', () => {
const CHANGE_PASSWORD_URL = '/me/password';
const oldPassword = 'old';
const newPassword = 'new';
describe("change password", () => {
const CHANGE_PASSWORD_URL = "/me/password";
const oldPassword = "old";
const newPassword = "new";
afterEach(() => {
fetchMock.reset();
fetchMock.restore();
});
it('should update password', done => {
fetchMock.put('/api/v2' + CHANGE_PASSWORD_URL, 204, {
it("should update password", done => {
fetchMock.put("/api/v2" + CHANGE_PASSWORD_URL, 204, {
headers: {
'content-type': CONTENT_TYPE_PASSWORD_CHANGE,
},
"content-type": CONTENT_TYPE_PASSWORD_CHANGE
}
});
changePassword(CHANGE_PASSWORD_URL, oldPassword, newPassword).then(
content => {
done();
},
}
);
});
});

View File

@@ -1,20 +1,20 @@
import { apiClient } from '@scm-manager/ui-components';
import { apiClient } from "@scm-manager/ui-components";
export const CONTENT_TYPE_PASSWORD_CHANGE =
'application/vnd.scmm-passwordChange+json;v=2';
"application/vnd.scmm-passwordChange+json;v=2";
export function changePassword(
url: string,
oldPassword: string,
newPassword: string,
newPassword: string
) {
return apiClient
.put(
url,
{
oldPassword,
newPassword,
newPassword
},
CONTENT_TYPE_PASSWORD_CHANGE,
CONTENT_TYPE_PASSWORD_CHANGE
)
.then(response => {
return response;

View File

@@ -1,158 +1,158 @@
import reducer, { getFailure } from './failure';
import reducer, { getFailure } from "./failure";
const err = new Error('something failed');
const otherErr = new Error('something else failed');
const err = new Error("something failed");
const otherErr = new Error("something else failed");
describe('failure reducer', () => {
it('should set the error for FETCH_ITEMS', () => {
describe("failure reducer", () => {
it("should set the error for FETCH_ITEMS", () => {
const newState = reducer(
{},
{
type: 'FETCH_ITEMS_FAILURE',
payload: err,
},
type: "FETCH_ITEMS_FAILURE",
payload: err
}
);
expect(newState['FETCH_ITEMS']).toBe(err);
expect(newState["FETCH_ITEMS"]).toBe(err);
});
it('should do nothing for unknown action types', () => {
it("should do nothing for unknown action types", () => {
const state = {};
const newState = reducer(state, {
type: 'UNKNOWN',
type: "UNKNOWN"
});
expect(newState).toBe(state);
});
it('should set the error for FETCH_ITEMS, if payload has multiple values', () => {
it("should set the error for FETCH_ITEMS, if payload has multiple values", () => {
const newState = reducer(
{},
{
type: 'FETCH_ITEMS_FAILURE',
type: "FETCH_ITEMS_FAILURE",
payload: {
something: 'something',
error: err,
},
},
something: "something",
error: err
}
}
);
expect(newState['FETCH_ITEMS']).toBe(err);
expect(newState["FETCH_ITEMS"]).toBe(err);
});
it('should set the error for FETCH_ITEMS, but should not affect others', () => {
it("should set the error for FETCH_ITEMS, but should not affect others", () => {
const newState = reducer(
{
FETCH_USERS: otherErr,
FETCH_USERS: otherErr
},
{
type: 'FETCH_ITEMS_FAILURE',
payload: err,
},
type: "FETCH_ITEMS_FAILURE",
payload: err
}
);
expect(newState['FETCH_ITEMS']).toBe(err);
expect(newState['FETCH_USERS']).toBe(otherErr);
expect(newState["FETCH_ITEMS"]).toBe(err);
expect(newState["FETCH_USERS"]).toBe(otherErr);
});
it('should reset FETCH_ITEMS after FETCH_ITEMS_SUCCESS', () => {
it("should reset FETCH_ITEMS after FETCH_ITEMS_SUCCESS", () => {
const newState = reducer(
{
FETCH_ITEMS: err
},
{
type: "FETCH_ITEMS_SUCCESS"
}
);
expect(newState["FETCH_ITEMS"]).toBeFalsy();
});
it("should reset FETCH_ITEMS after FETCH_ITEMS_RESET", () => {
const newState = reducer(
{
FETCH_ITEMS: err
},
{
type: "FETCH_ITEMS_RESET"
}
);
expect(newState["FETCH_ITEMS"]).toBeFalsy();
});
it("should reset FETCH_ITEMS after FETCH_ITEMS_RESET, but should not affect others", () => {
const newState = reducer(
{
FETCH_ITEMS: err,
FETCH_USERS: err
},
{
type: 'FETCH_ITEMS_SUCCESS',
},
type: "FETCH_ITEMS_RESET"
}
);
expect(newState['FETCH_ITEMS']).toBeFalsy();
expect(newState["FETCH_ITEMS"]).toBeFalsy();
expect(newState["FETCH_USERS"]).toBe(err);
});
it('should reset FETCH_ITEMS after FETCH_ITEMS_RESET', () => {
const newState = reducer(
{
FETCH_ITEMS: err,
},
{
type: 'FETCH_ITEMS_RESET',
},
);
expect(newState['FETCH_ITEMS']).toBeFalsy();
});
it('should reset FETCH_ITEMS after FETCH_ITEMS_RESET, but should not affect others', () => {
const newState = reducer(
{
FETCH_ITEMS: err,
FETCH_USERS: err,
},
{
type: 'FETCH_ITEMS_RESET',
},
);
expect(newState['FETCH_ITEMS']).toBeFalsy();
expect(newState['FETCH_USERS']).toBe(err);
});
it('should set the error for a single item of FETCH_ITEM', () => {
it("should set the error for a single item of FETCH_ITEM", () => {
const newState = reducer(
{},
{
type: 'FETCH_ITEM_FAILURE',
type: "FETCH_ITEM_FAILURE",
payload: err,
itemId: 42,
},
itemId: 42
}
);
expect(newState['FETCH_ITEM/42']).toBe(err);
expect(newState["FETCH_ITEM/42"]).toBe(err);
});
it('should reset error for a single item of FETCH_ITEM', () => {
it("should reset error for a single item of FETCH_ITEM", () => {
const newState = reducer(
{
'FETCH_ITEM/42': err,
"FETCH_ITEM/42": err
},
{
type: 'FETCH_ITEM_SUCCESS',
type: "FETCH_ITEM_SUCCESS",
payload: err,
itemId: 42,
},
itemId: 42
}
);
expect(newState['FETCH_ITEM/42']).toBeUndefined();
expect(newState["FETCH_ITEM/42"]).toBeUndefined();
});
});
describe('failure selector', () => {
it('should return failure, if FETCH_ITEMS failure exists', () => {
describe("failure selector", () => {
it("should return failure, if FETCH_ITEMS failure exists", () => {
const failure = getFailure(
{
failure: {
FETCH_ITEMS: err,
},
FETCH_ITEMS: err
}
},
'FETCH_ITEMS',
"FETCH_ITEMS"
);
expect(failure).toBe(err);
});
it('should return undefined, if state has no failure', () => {
const failure = getFailure({}, 'FETCH_ITEMS');
it("should return undefined, if state has no failure", () => {
const failure = getFailure({}, "FETCH_ITEMS");
expect(failure).toBeUndefined();
});
it('should return undefined, if FETCH_ITEMS is not defined', () => {
it("should return undefined, if FETCH_ITEMS is not defined", () => {
const failure = getFailure(
{
failure: {},
failure: {}
},
'FETCH_ITEMS',
"FETCH_ITEMS"
);
expect(failure).toBeFalsy();
});
it('should return failure, if FETCH_ITEM 42 failure exists', () => {
it("should return failure, if FETCH_ITEM 42 failure exists", () => {
const failure = getFailure(
{
failure: {
'FETCH_ITEM/42': err,
},
"FETCH_ITEM/42": err
}
},
'FETCH_ITEM',
42,
"FETCH_ITEM",
42
);
expect(failure).toBe(err);
});

View File

@@ -1,13 +1,13 @@
import { Action } from '@scm-manager/ui-types';
import { Action } from "@scm-manager/ui-types";
const FAILURE_SUFFIX = '_FAILURE';
const FAILURE_SUFFIX = "_FAILURE";
const RESET_PATTERN = /^(.*)_(SUCCESS|RESET)$/;
function extractIdentifierFromFailure(action: Action) {
const type = action.type;
let identifier = type.substring(0, type.length - FAILURE_SUFFIX.length);
if (action.itemId) {
identifier += '/' + action.itemId;
identifier += "/" + action.itemId;
}
return identifier;
}
@@ -15,7 +15,7 @@ function extractIdentifierFromFailure(action: Action) {
function removeAllEntriesOfIdentifierFromState(
state: object,
payload: any,
identifier: string,
identifier: string
) {
const newState = {};
for (let failureType in state) {
@@ -39,8 +39,8 @@ function removeFromState(state: object, identifier: string) {
export default function reducer(
state: object = {},
action: Action = {
type: 'UNKNOWN',
},
type: "UNKNOWN"
}
): object {
const type = action.type;
if (type.endsWith(FAILURE_SUFFIX)) {
@@ -53,20 +53,20 @@ export default function reducer(
}
return {
...state,
[identifier]: payload,
[identifier]: payload
};
} else {
const match = RESET_PATTERN.exec(type);
if (match) {
let identifier = match[1];
if (action.itemId) {
identifier += '/' + action.itemId;
identifier += "/" + action.itemId;
}
if (action.payload)
return removeAllEntriesOfIdentifierFromState(
state,
action.payload,
identifier,
identifier
);
else return removeFromState(state, identifier);
}
@@ -77,12 +77,12 @@ export default function reducer(
export function getFailure(
state: object,
actionType: string,
itemId?: string | number,
itemId?: string | number
) {
if (state.failure) {
let identifier = actionType;
if (itemId) {
identifier += '/' + itemId;
identifier += "/" + itemId;
}
return state.failure[identifier];
}

View File

@@ -1,6 +1,6 @@
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import fetchMock from 'fetch-mock';
import configureMockStore from "redux-mock-store";
import thunk from "redux-thunk";
import fetchMock from "fetch-mock";
import reducer, {
FETCH_INDEXRESOURCES_PENDING,
FETCH_INDEXRESOURCES_SUCCESS,
@@ -24,76 +24,76 @@ import reducer, {
getGroupsLink,
getLinkCollection,
getUserAutoCompleteLink,
getGroupAutoCompleteLink,
} from './indexResource';
getGroupAutoCompleteLink
} from "./indexResource";
const indexResourcesUnauthenticated = {
version: '2.0.0-SNAPSHOT',
version: "2.0.0-SNAPSHOT",
_links: {
self: {
href: 'http://localhost:8081/scm/api/v2/',
href: "http://localhost:8081/scm/api/v2/"
},
uiPlugins: {
href: 'http://localhost:8081/scm/api/v2/ui/plugins',
href: "http://localhost:8081/scm/api/v2/ui/plugins"
},
login: {
href: 'http://localhost:8081/scm/api/v2/auth/access_token',
},
},
href: "http://localhost:8081/scm/api/v2/auth/access_token"
}
}
};
const indexResourcesAuthenticated = {
version: '2.0.0-SNAPSHOT',
version: "2.0.0-SNAPSHOT",
_links: {
self: {
href: 'http://localhost:8081/scm/api/v2/',
href: "http://localhost:8081/scm/api/v2/"
},
uiPlugins: {
href: 'http://localhost:8081/scm/api/v2/ui/plugins',
href: "http://localhost:8081/scm/api/v2/ui/plugins"
},
me: {
href: 'http://localhost:8081/scm/api/v2/me/',
href: "http://localhost:8081/scm/api/v2/me/"
},
logout: {
href: 'http://localhost:8081/scm/api/v2/auth/access_token',
href: "http://localhost:8081/scm/api/v2/auth/access_token"
},
users: {
href: 'http://localhost:8081/scm/api/v2/users/',
href: "http://localhost:8081/scm/api/v2/users/"
},
groups: {
href: 'http://localhost:8081/scm/api/v2/groups/',
href: "http://localhost:8081/scm/api/v2/groups/"
},
config: {
href: 'http://localhost:8081/scm/api/v2/config',
href: "http://localhost:8081/scm/api/v2/config"
},
repositories: {
href: 'http://localhost:8081/scm/api/v2/repositories/',
href: "http://localhost:8081/scm/api/v2/repositories/"
},
hgConfig: {
href: 'http://localhost:8081/scm/api/v2/config/hg',
href: "http://localhost:8081/scm/api/v2/config/hg"
},
gitConfig: {
href: 'http://localhost:8081/scm/api/v2/config/git',
href: "http://localhost:8081/scm/api/v2/config/git"
},
svnConfig: {
href: 'http://localhost:8081/scm/api/v2/config/svn',
href: "http://localhost:8081/scm/api/v2/config/svn"
},
autocomplete: [
{
href: 'http://localhost:8081/scm/api/v2/autocomplete/users',
name: 'users',
href: "http://localhost:8081/scm/api/v2/autocomplete/users",
name: "users"
},
{
href: 'http://localhost:8081/scm/api/v2/autocomplete/groups',
name: 'groups',
},
],
},
href: "http://localhost:8081/scm/api/v2/autocomplete/groups",
name: "groups"
}
]
}
};
describe('index resource', () => {
describe('fetch index resource', () => {
const index_url = '/api/v2/';
describe("index resource", () => {
describe("fetch index resource", () => {
const index_url = "/api/v2/";
const mockStore = configureMockStore([thunk]);
afterEach(() => {
@@ -101,17 +101,17 @@ describe('index resource', () => {
fetchMock.restore();
});
it('should successfully fetch index resources when unauthenticated', () => {
it("should successfully fetch index resources when unauthenticated", () => {
fetchMock.getOnce(index_url, indexResourcesUnauthenticated);
const expectedActions = [
{
type: FETCH_INDEXRESOURCES_PENDING,
type: FETCH_INDEXRESOURCES_PENDING
},
{
type: FETCH_INDEXRESOURCES_SUCCESS,
payload: indexResourcesUnauthenticated,
},
payload: indexResourcesUnauthenticated
}
];
const store = mockStore({});
@@ -120,17 +120,17 @@ describe('index resource', () => {
});
});
it('should successfully fetch index resources when authenticated', () => {
it("should successfully fetch index resources when authenticated", () => {
fetchMock.getOnce(index_url, indexResourcesAuthenticated);
const expectedActions = [
{
type: FETCH_INDEXRESOURCES_PENDING,
type: FETCH_INDEXRESOURCES_PENDING
},
{
type: FETCH_INDEXRESOURCES_SUCCESS,
payload: indexResourcesAuthenticated,
},
payload: indexResourcesAuthenticated
}
];
const store = mockStore({});
@@ -139,9 +139,9 @@ describe('index resource', () => {
});
});
it('should dispatch FETCH_INDEX_RESOURCES_FAILURE if request fails', () => {
it("should dispatch FETCH_INDEX_RESOURCES_FAILURE if request fails", () => {
fetchMock.getOnce(index_url, {
status: 500,
status: 500
});
const store = mockStore({});
@@ -154,338 +154,338 @@ describe('index resource', () => {
});
});
describe('index resources reducer', () => {
it('should return empty object, if state and action is undefined', () => {
describe("index resources 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', () => {
it("should return the same state, if the action is undefined", () => {
const state = {
x: true,
x: true
};
expect(reducer(state)).toBe(state);
});
it('should return the same state, if the action is unknown to the reducer', () => {
it("should return the same state, if the action is unknown to the reducer", () => {
const state = {
x: true,
x: true
};
expect(
reducer(state, {
type: 'EL_SPECIALE',
}),
type: "EL_SPECIALE"
})
).toBe(state);
});
it('should store the index resources on FETCH_INDEXRESOURCES_SUCCESS', () => {
it("should store the index resources on FETCH_INDEXRESOURCES_SUCCESS", () => {
const newState = reducer(
{},
fetchIndexResourcesSuccess(indexResourcesAuthenticated),
fetchIndexResourcesSuccess(indexResourcesAuthenticated)
);
expect(newState.links).toBe(indexResourcesAuthenticated._links);
});
});
describe('index resources selectors', () => {
const error = new Error('something goes wrong');
describe("index resources selectors", () => {
const error = new Error("something goes wrong");
it('should return true, when fetch index resources is pending', () => {
it("should return true, when fetch index resources is pending", () => {
const state = {
pending: {
[FETCH_INDEXRESOURCES]: true,
},
[FETCH_INDEXRESOURCES]: true
}
};
expect(isFetchIndexResourcesPending(state)).toEqual(true);
});
it('should return false, when fetch index resources is not pending', () => {
it("should return false, when fetch index resources is not pending", () => {
expect(isFetchIndexResourcesPending({})).toEqual(false);
});
it('should return error when fetch index resources did fail', () => {
it("should return error when fetch index resources did fail", () => {
const state = {
failure: {
[FETCH_INDEXRESOURCES]: error,
},
[FETCH_INDEXRESOURCES]: error
}
};
expect(getFetchIndexResourcesFailure(state)).toEqual(error);
});
it('should return undefined when fetch index resources did not fail', () => {
it("should return undefined when fetch index resources did not fail", () => {
expect(getFetchIndexResourcesFailure({})).toBe(undefined);
});
it('should return all links', () => {
it("should return all links", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getLinks(state)).toBe(indexResourcesAuthenticated._links);
});
// ui plugins link
it('should return ui plugins link when authenticated and has permission to see it', () => {
it("should return ui plugins link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getUiPluginsLink(state)).toBe(
'http://localhost:8081/scm/api/v2/ui/plugins',
"http://localhost:8081/scm/api/v2/ui/plugins"
);
});
it('should return ui plugins links when unauthenticated and has permission to see it', () => {
it("should return ui plugins links when unauthenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getUiPluginsLink(state)).toBe(
'http://localhost:8081/scm/api/v2/ui/plugins',
"http://localhost:8081/scm/api/v2/ui/plugins"
);
});
// me link
it('should return me link when authenticated and has permission to see it', () => {
it("should return me link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getMeLink(state)).toBe('http://localhost:8081/scm/api/v2/me/');
expect(getMeLink(state)).toBe("http://localhost:8081/scm/api/v2/me/");
});
it('should return undefined for me link when unauthenticated or has not permission to see it', () => {
it("should return undefined for me link when unauthenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getMeLink(state)).toBe(undefined);
});
// logout link
it('should return logout link when authenticated and has permission to see it', () => {
it("should return logout link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getLogoutLink(state)).toBe(
'http://localhost:8081/scm/api/v2/auth/access_token',
"http://localhost:8081/scm/api/v2/auth/access_token"
);
});
it('should return undefined for logout link when unauthenticated or has not permission to see it', () => {
it("should return undefined for logout link when unauthenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getLogoutLink(state)).toBe(undefined);
});
// login link
it('should return login link when unauthenticated and has permission to see it', () => {
it("should return login link when unauthenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getLoginLink(state)).toBe(
'http://localhost:8081/scm/api/v2/auth/access_token',
"http://localhost:8081/scm/api/v2/auth/access_token"
);
});
it('should return undefined for login link when authenticated or has not permission to see it', () => {
it("should return undefined for login link when authenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getLoginLink(state)).toBe(undefined);
});
// users link
it('should return users link when authenticated and has permission to see it', () => {
it("should return users link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getUsersLink(state)).toBe(
'http://localhost:8081/scm/api/v2/users/',
"http://localhost:8081/scm/api/v2/users/"
);
});
it('should return undefined for users link when unauthenticated or has not permission to see it', () => {
it("should return undefined for users link when unauthenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getUsersLink(state)).toBe(undefined);
});
// groups link
it('should return groups link when authenticated and has permission to see it', () => {
it("should return groups link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getGroupsLink(state)).toBe(
'http://localhost:8081/scm/api/v2/groups/',
"http://localhost:8081/scm/api/v2/groups/"
);
});
it('should return undefined for groups link when unauthenticated or has not permission to see it', () => {
it("should return undefined for groups link when unauthenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getGroupsLink(state)).toBe(undefined);
});
// config link
it('should return config link when authenticated and has permission to see it', () => {
it("should return config link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getConfigLink(state)).toBe(
'http://localhost:8081/scm/api/v2/config',
"http://localhost:8081/scm/api/v2/config"
);
});
it('should return undefined for config link when unauthenticated or has not permission to see it', () => {
it("should return undefined for config link when unauthenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getConfigLink(state)).toBe(undefined);
});
// repositories link
it('should return repositories link when authenticated and has permission to see it', () => {
it("should return repositories link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getRepositoriesLink(state)).toBe(
'http://localhost:8081/scm/api/v2/repositories/',
"http://localhost:8081/scm/api/v2/repositories/"
);
});
it('should return config for repositories link when unauthenticated or has not permission to see it', () => {
it("should return config for repositories link when unauthenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getRepositoriesLink(state)).toBe(undefined);
});
// hgConfig link
it('should return hgConfig link when authenticated and has permission to see it', () => {
it("should return hgConfig link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getHgConfigLink(state)).toBe(
'http://localhost:8081/scm/api/v2/config/hg',
"http://localhost:8081/scm/api/v2/config/hg"
);
});
it('should return config for hgConfig link when unauthenticated or has not permission to see it', () => {
it("should return config for hgConfig link when unauthenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getHgConfigLink(state)).toBe(undefined);
});
// gitConfig link
it('should return gitConfig link when authenticated and has permission to see it', () => {
it("should return gitConfig link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getGitConfigLink(state)).toBe(
'http://localhost:8081/scm/api/v2/config/git',
"http://localhost:8081/scm/api/v2/config/git"
);
});
it('should return config for gitConfig link when unauthenticated or has not permission to see it', () => {
it("should return config for gitConfig link when unauthenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getGitConfigLink(state)).toBe(undefined);
});
// svnConfig link
it('should return svnConfig link when authenticated and has permission to see it', () => {
it("should return svnConfig link when authenticated and has permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getSvnConfigLink(state)).toBe(
'http://localhost:8081/scm/api/v2/config/svn',
"http://localhost:8081/scm/api/v2/config/svn"
);
});
it('should return config for svnConfig link when unauthenticated or has not permission to see it', () => {
it("should return config for svnConfig link when unauthenticated or has not permission to see it", () => {
const state = {
indexResources: {
links: indexResourcesUnauthenticated._links,
},
links: indexResourcesUnauthenticated._links
}
};
expect(getSvnConfigLink(state)).toBe(undefined);
});
// Autocomplete links
it('should return link collection', () => {
it("should return link collection", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getLinkCollection(state, 'autocomplete')).toEqual(
indexResourcesAuthenticated._links.autocomplete,
expect(getLinkCollection(state, "autocomplete")).toEqual(
indexResourcesAuthenticated._links.autocomplete
);
});
it('should return user autocomplete link', () => {
it("should return user autocomplete link", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getUserAutoCompleteLink(state)).toEqual(
'http://localhost:8081/scm/api/v2/autocomplete/users',
"http://localhost:8081/scm/api/v2/autocomplete/users"
);
});
it('should return group autocomplete link', () => {
it("should return group autocomplete link", () => {
const state = {
indexResources: {
links: indexResourcesAuthenticated._links,
},
links: indexResourcesAuthenticated._links
}
};
expect(getGroupAutoCompleteLink(state)).toEqual(
'http://localhost:8081/scm/api/v2/autocomplete/groups',
"http://localhost:8081/scm/api/v2/autocomplete/groups"
);
});
});

View File

@@ -1,18 +1,18 @@
import * as types from './types';
import * as types from "./types";
import { apiClient } from '@scm-manager/ui-components';
import { Action, IndexResources, Link } from '@scm-manager/ui-types';
import { isPending } from './pending';
import { getFailure } from './failure';
import { apiClient } from "@scm-manager/ui-components";
import { Action, IndexResources, Link } from "@scm-manager/ui-types";
import { isPending } from "./pending";
import { getFailure } from "./failure";
// Action
export const FETCH_INDEXRESOURCES = 'scm/INDEXRESOURCES';
export const FETCH_INDEXRESOURCES = "scm/INDEXRESOURCES";
export const FETCH_INDEXRESOURCES_PENDING = `${FETCH_INDEXRESOURCES}_${types.PENDING_SUFFIX}`;
export const FETCH_INDEXRESOURCES_SUCCESS = `${FETCH_INDEXRESOURCES}_${types.SUCCESS_SUFFIX}`;
export const FETCH_INDEXRESOURCES_FAILURE = `${FETCH_INDEXRESOURCES}_${types.FAILURE_SUFFIX}`;
const INDEX_RESOURCES_LINK = '/';
const INDEX_RESOURCES_LINK = "/";
export const callFetchIndexResources = (): Promise<IndexResources> => {
return apiClient.get(INDEX_RESOURCES_LINK).then(response => {
@@ -35,21 +35,21 @@ export function fetchIndexResources() {
export function fetchIndexResourcesPending(): Action {
return {
type: FETCH_INDEXRESOURCES_PENDING,
type: FETCH_INDEXRESOURCES_PENDING
};
}
export function fetchIndexResourcesSuccess(resources: IndexResources): Action {
return {
type: FETCH_INDEXRESOURCES_SUCCESS,
payload: resources,
payload: resources
};
}
export function fetchIndexResourcesFailure(err: Error): Action {
return {
type: FETCH_INDEXRESOURCES_FAILURE,
payload: err,
payload: err
};
}
@@ -57,8 +57,8 @@ export function fetchIndexResourcesFailure(err: Error): Action {
export default function reducer(
state: object = {},
action: Action = {
type: 'UNKNOWN',
},
type: "UNKNOWN"
}
): object {
if (!action.payload) {
return state;
@@ -69,7 +69,7 @@ export default function reducer(
return {
...state,
version: action.payload.version,
links: action.payload._links,
links: action.payload._links
};
default:
return state;
@@ -108,89 +108,89 @@ export function getAppVersion(state: object) {
}
export function getUiPluginsLink(state: object) {
return getLink(state, 'uiPlugins');
return getLink(state, "uiPlugins");
}
export function getAvailablePluginsLink(state: object) {
return getLink(state, 'availablePlugins');
return getLink(state, "availablePlugins");
}
export function getInstalledPluginsLink(state: object) {
return getLink(state, 'installedPlugins');
return getLink(state, "installedPlugins");
}
export function getPendingPluginsLink(state: object) {
return getLink(state, 'pendingPlugins');
return getLink(state, "pendingPlugins");
}
export function getMeLink(state: object) {
return getLink(state, 'me');
return getLink(state, "me");
}
export function getLogoutLink(state: object) {
return getLink(state, 'logout');
return getLink(state, "logout");
}
export function getLoginLink(state: object) {
return getLink(state, 'login');
return getLink(state, "login");
}
export function getUsersLink(state: object) {
return getLink(state, 'users');
return getLink(state, "users");
}
export function getRepositoryRolesLink(state: object) {
return getLink(state, 'repositoryRoles');
return getLink(state, "repositoryRoles");
}
export function getRepositoryVerbsLink(state: object) {
return getLink(state, 'repositoryVerbs');
return getLink(state, "repositoryVerbs");
}
export function getGroupsLink(state: object) {
return getLink(state, 'groups');
return getLink(state, "groups");
}
export function getConfigLink(state: object) {
return getLink(state, 'config');
return getLink(state, "config");
}
export function getRepositoriesLink(state: object) {
return getLink(state, 'repositories');
return getLink(state, "repositories");
}
export function getHgConfigLink(state: object) {
return getLink(state, 'hgConfig');
return getLink(state, "hgConfig");
}
export function getGitConfigLink(state: object) {
return getLink(state, 'gitConfig');
return getLink(state, "gitConfig");
}
export function getSvnConfigLink(state: object) {
return getLink(state, 'svnConfig');
return getLink(state, "svnConfig");
}
export function getLoginInfoLink(state: object) {
return getLink(state, 'loginInfo');
return getLink(state, "loginInfo");
}
export function getUserAutoCompleteLink(state: object): string {
const link = getLinkCollection(state, 'autocomplete').find(
i => i.name === 'users',
const link = getLinkCollection(state, "autocomplete").find(
i => i.name === "users"
);
if (link) {
return link.href;
}
return '';
return "";
}
export function getGroupAutoCompleteLink(state: object): string {
const link = getLinkCollection(state, 'autocomplete').find(
i => i.name === 'groups',
const link = getLinkCollection(state, "autocomplete").find(
i => i.name === "groups"
);
if (link) {
return link.href;
}
return '';
return "";
}

View File

@@ -1,168 +1,168 @@
import reducer, { isPending } from './pending';
import reducer, { isPending } from "./pending";
describe('pending reducer', () => {
it('should set pending for FETCH_ITEMS to true', () => {
describe("pending reducer", () => {
it("should set pending for FETCH_ITEMS to true", () => {
const newState = reducer(
{},
{
type: 'FETCH_ITEMS_PENDING',
},
type: "FETCH_ITEMS_PENDING"
}
);
expect(newState['FETCH_ITEMS']).toBe(true);
expect(newState["FETCH_ITEMS"]).toBe(true);
});
it('should do nothing for unknown action types', () => {
it("should do nothing for unknown action types", () => {
const state = {};
const newState = reducer(state, {
type: 'UNKNOWN',
type: "UNKNOWN"
});
expect(newState).toBe(state);
});
it('should set pending for FETCH_ITEMS to true, but should not affect others', () => {
it("should set pending for FETCH_ITEMS to true, but should not affect others", () => {
const newState = reducer(
{
FETCH_USERS: true
},
{
type: "FETCH_ITEMS_PENDING"
}
);
expect(newState["FETCH_ITEMS"]).toBe(true);
expect(newState["FETCH_USERS"]).toBe(true);
});
it("should reset pending state for FETCH_ITEMS after FETCH_ITEMS_SUCCESS", () => {
const newState = reducer(
{
FETCH_ITEMS: true
},
{
type: "FETCH_ITEMS_SUCCESS"
}
);
expect(newState["FETCH_ITEMS"]).toBeFalsy();
});
it("should reset pending state for FETCH_ITEMS after FETCH_ITEMS_FAILURE", () => {
const newState = reducer(
{
FETCH_ITEMS: true
},
{
type: "FETCH_ITEMS_FAILURE"
}
);
expect(newState["FETCH_ITEMS"]).toBeFalsy();
});
it("should reset pending state for FETCH_ITEMS after FETCH_ITEMS_RESET", () => {
const newState = reducer(
{
FETCH_ITEMS: true
},
{
type: "FETCH_ITEMS_RESET"
}
);
expect(newState["FETCH_ITEMS"]).toBeFalsy();
});
it("should reset pending state for FETCH_ITEMS, if resetPending prop is available", () => {
const newState = reducer(
{
FETCH_ITEMS: true
},
{
type: "FETCH_ITEMS_SOMETHING",
resetPending: true
}
);
expect(newState["FETCH_ITEMS"]).toBeFalsy();
});
it("should reset pending state for FETCH_ITEMS after FETCH_ITEMS_SUCCESS, but should not affect others", () => {
const newState = reducer(
{
FETCH_USERS: true,
FETCH_ITEMS: true
},
{
type: 'FETCH_ITEMS_PENDING',
},
type: "FETCH_ITEMS_SUCCESS"
}
);
expect(newState['FETCH_ITEMS']).toBe(true);
expect(newState['FETCH_USERS']).toBe(true);
expect(newState["FETCH_ITEMS"]).toBeFalsy();
expect(newState["FETCH_USERS"]).toBe(true);
});
it('should reset pending state for FETCH_ITEMS after FETCH_ITEMS_SUCCESS', () => {
it("should set pending for a single item", () => {
const newState = reducer(
{
FETCH_ITEMS: true,
"FETCH_USER/42": false
},
{
type: 'FETCH_ITEMS_SUCCESS',
},
type: "FETCH_USER_PENDING",
itemId: 21
}
);
expect(newState['FETCH_ITEMS']).toBeFalsy();
expect(newState["FETCH_USER/21"]).toBe(true);
expect(newState["FETCH_USER/42"]).toBe(false);
});
it('should reset pending state for FETCH_ITEMS after FETCH_ITEMS_FAILURE', () => {
it("should reset pending for a single item", () => {
const newState = reducer(
{
FETCH_ITEMS: true,
"FETCH_USER/42": true
},
{
type: 'FETCH_ITEMS_FAILURE',
},
type: "FETCH_USER_SUCCESS",
itemId: 42
}
);
expect(newState['FETCH_ITEMS']).toBeFalsy();
});
it('should reset pending state for FETCH_ITEMS after FETCH_ITEMS_RESET', () => {
const newState = reducer(
{
FETCH_ITEMS: true,
},
{
type: 'FETCH_ITEMS_RESET',
},
);
expect(newState['FETCH_ITEMS']).toBeFalsy();
});
it('should reset pending state for FETCH_ITEMS, if resetPending prop is available', () => {
const newState = reducer(
{
FETCH_ITEMS: true,
},
{
type: 'FETCH_ITEMS_SOMETHING',
resetPending: true,
},
);
expect(newState['FETCH_ITEMS']).toBeFalsy();
});
it('should reset pending state for FETCH_ITEMS after FETCH_ITEMS_SUCCESS, but should not affect others', () => {
const newState = reducer(
{
FETCH_USERS: true,
FETCH_ITEMS: true,
},
{
type: 'FETCH_ITEMS_SUCCESS',
},
);
expect(newState['FETCH_ITEMS']).toBeFalsy();
expect(newState['FETCH_USERS']).toBe(true);
});
it('should set pending for a single item', () => {
const newState = reducer(
{
'FETCH_USER/42': false,
},
{
type: 'FETCH_USER_PENDING',
itemId: 21,
},
);
expect(newState['FETCH_USER/21']).toBe(true);
expect(newState['FETCH_USER/42']).toBe(false);
});
it('should reset pending for a single item', () => {
const newState = reducer(
{
'FETCH_USER/42': true,
},
{
type: 'FETCH_USER_SUCCESS',
itemId: 42,
},
);
expect(newState['FETCH_USER/42']).toBeFalsy();
expect(newState["FETCH_USER/42"]).toBeFalsy();
});
});
describe('pending selectors', () => {
it('should return true, while FETCH_ITEMS is pending', () => {
describe("pending selectors", () => {
it("should return true, while FETCH_ITEMS is pending", () => {
const result = isPending(
{
pending: {
FETCH_ITEMS: true,
},
FETCH_ITEMS: true
}
},
'FETCH_ITEMS',
"FETCH_ITEMS"
);
expect(result).toBe(true);
});
it('should return false, if pending is not defined', () => {
const result = isPending({}, 'FETCH_ITEMS');
it("should return false, if pending is not defined", () => {
const result = isPending({}, "FETCH_ITEMS");
expect(result).toBe(false);
});
it('should return true, while FETCH_ITEM 42 is pending', () => {
it("should return true, while FETCH_ITEM 42 is pending", () => {
const result = isPending(
{
pending: {
'FETCH_ITEM/42': true,
},
"FETCH_ITEM/42": true
}
},
'FETCH_ITEM',
42,
"FETCH_ITEM",
42
);
expect(result).toBe(true);
});
it('should return true, while FETCH_ITEM 42 is undefined', () => {
it("should return true, while FETCH_ITEM 42 is undefined", () => {
const result = isPending(
{
pending: {
'FETCH_ITEM/21': true,
},
"FETCH_ITEM/21": true
}
},
'FETCH_ITEM',
42,
"FETCH_ITEM",
42
);
expect(result).toBe(false);
});

View File

@@ -1,11 +1,11 @@
import { Action } from '@scm-manager/ui-types';
import * as types from './types';
import { Action } from "@scm-manager/ui-types";
import * as types from "./types";
const PENDING_SUFFIX = '_' + types.PENDING_SUFFIX;
const PENDING_SUFFIX = "_" + types.PENDING_SUFFIX;
const RESET_ACTIONTYPES = [
types.SUCCESS_SUFFIX,
types.FAILURE_SUFFIX,
types.RESET_SUFFIX,
types.RESET_SUFFIX
];
function removeFromState(state: object, identifier: string) {
@@ -21,7 +21,7 @@ function removeFromState(state: object, identifier: string) {
function removeAllEntriesOfIdentifierFromState(
state: object,
payload: any,
identifier: string,
identifier: string
) {
const newState = {};
for (let childType in state) {
@@ -36,7 +36,7 @@ function extractIdentifierFromPending(action: Action) {
const type = action.type;
let identifier = type.substring(0, type.length - PENDING_SUFFIX.length);
if (action.itemId) {
identifier += '/' + action.itemId;
identifier += "/" + action.itemId;
}
return identifier;
}
@@ -44,30 +44,30 @@ function extractIdentifierFromPending(action: Action) {
export default function reducer(
state: object = {},
action: Action = {
type: 'UNKNOWN',
},
type: "UNKNOWN"
}
): object {
const type = action.type;
if (type.endsWith(PENDING_SUFFIX)) {
const identifier = extractIdentifierFromPending(action);
return {
...state,
[identifier]: true,
[identifier]: true
};
} else {
const index = type.lastIndexOf('_');
const index = type.lastIndexOf("_");
if (index > 0) {
const actionType = type.substring(index + 1);
if (RESET_ACTIONTYPES.indexOf(actionType) >= 0 || action.resetPending) {
let identifier = type.substring(0, index);
if (action.itemId) {
identifier += '/' + action.itemId;
identifier += "/" + action.itemId;
}
if (action.payload)
return removeAllEntriesOfIdentifierFromState(
state,
action.payload,
identifier,
identifier
);
else return removeFromState(state, identifier);
}
@@ -79,11 +79,11 @@ export default function reducer(
export function isPending(
state: object,
actionType: string,
itemId?: string | number,
itemId?: string | number
) {
let type = actionType;
if (itemId) {
type += '/' + itemId;
type += "/" + itemId;
}
if (state.pending && state.pending[type]) {
return true;

View File

@@ -1,4 +1,4 @@
export const PENDING_SUFFIX = 'PENDING';
export const SUCCESS_SUFFIX = 'SUCCESS';
export const FAILURE_SUFFIX = 'FAILURE';
export const RESET_SUFFIX = 'RESET';
export const PENDING_SUFFIX = "PENDING";
export const SUCCESS_SUFFIX = "SUCCESS";
export const FAILURE_SUFFIX = "FAILURE";
export const RESET_SUFFIX = "RESET";