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

@@ -1,13 +1,13 @@
import React from 'react';
import { User } from '@scm-manager/ui-types';
import React from "react";
import { User } from "@scm-manager/ui-types";
import {
SubmitButton,
Notification,
ErrorNotification,
PasswordConfirmation,
} from '@scm-manager/ui-components';
import { translate } from 'react-i18next';
import { setPassword } from './setPassword';
PasswordConfirmation
} from "@scm-manager/ui-components";
import { translate } from "react-i18next";
import { setPassword } from "./setPassword";
type Props = {
user: User;
@@ -27,20 +27,20 @@ class SetUserPassword extends React.Component<Props, State> {
super(props);
this.state = {
password: '',
password: "",
loading: false,
passwordConfirmationError: false,
validatePasswordError: false,
validatePassword: '',
validatePassword: "",
passwordChanged: false,
passwordValid: false,
passwordValid: false
};
}
setLoadingState = () => {
this.setState({
...this.state,
loading: true,
loading: true
});
};
@@ -48,7 +48,7 @@ class SetUserPassword extends React.Component<Props, State> {
this.setState({
...this.state,
error: error,
loading: false,
loading: false
});
};
@@ -57,7 +57,7 @@ class SetUserPassword extends React.Component<Props, State> {
...this.state,
loading: false,
passwordChanged: true,
password: '',
password: ""
});
};
@@ -88,8 +88,8 @@ class SetUserPassword extends React.Component<Props, State> {
if (passwordChanged) {
message = (
<Notification
type={'success'}
children={t('singleUserPassword.setPasswordSuccessful')}
type={"success"}
children={t("singleUserPassword.setPasswordSuccessful")}
onClose={() => this.onClose()}
/>
);
@@ -102,14 +102,14 @@ class SetUserPassword extends React.Component<Props, State> {
{message}
<PasswordConfirmation
passwordChanged={this.passwordChanged}
key={this.state.passwordChanged ? 'changed' : 'unchanged'}
key={this.state.passwordChanged ? "changed" : "unchanged"}
/>
<div className="columns">
<div className="column">
<SubmitButton
disabled={!this.state.passwordValid}
loading={loading}
label={t('singleUserPassword.button')}
label={t("singleUserPassword.button")}
/>
</div>
</div>
@@ -121,16 +121,16 @@ class SetUserPassword extends React.Component<Props, State> {
this.setState({
...this.state,
password,
passwordValid: !!password && passwordValid,
passwordValid: !!password && passwordValid
});
};
onClose = () => {
this.setState({
...this.state,
passwordChanged: false,
passwordChanged: false
});
};
}
export default translate('users')(SetUserPassword);
export default translate("users")(SetUserPassword);

View File

@@ -1,15 +1,15 @@
import React from 'react';
import { translate } from 'react-i18next';
import { User } from '@scm-manager/ui-types';
import React from "react";
import { translate } from "react-i18next";
import { User } from "@scm-manager/ui-types";
import {
Subtitle,
Checkbox,
InputField,
PasswordConfirmation,
SubmitButton,
validation as validator,
} from '@scm-manager/ui-components';
import * as userValidator from './userValidation';
validation as validator
} from "@scm-manager/ui-components";
import * as userValidator from "./userValidation";
type Props = {
submitForm: (p: User) => void;
@@ -32,17 +32,17 @@ class UserForm extends React.Component<Props, State> {
this.state = {
user: {
name: '',
displayName: '',
mail: '',
password: '',
name: "",
displayName: "",
mail: "",
password: "",
active: true,
_links: {},
_links: {}
},
mailValidationError: false,
displayNameValidationError: false,
nameValidationError: false,
passwordValid: false,
passwordValid: false
};
}
@@ -51,8 +51,8 @@ class UserForm extends React.Component<Props, State> {
if (user) {
this.setState({
user: {
...user,
},
...user
}
});
}
}
@@ -121,12 +121,12 @@ class UserForm extends React.Component<Props, State> {
nameField = (
<div className="column is-half">
<InputField
label={t('user.name')}
label={t("user.name")}
onChange={this.handleUsernameChange}
value={user ? user.name : ''}
value={user ? user.name : ""}
validationError={this.state.nameValidationError}
errorMessage={t('validation.name-invalid')}
helpText={t('help.usernameHelpText')}
errorMessage={t("validation.name-invalid")}
helpText={t("help.usernameHelpText")}
/>
</div>
);
@@ -136,7 +136,7 @@ class UserForm extends React.Component<Props, State> {
);
} else {
// edit existing user
subtitle = <Subtitle subtitle={t('userForm.subtitle')} />;
subtitle = <Subtitle subtitle={t("userForm.subtitle")} />;
}
return (
<>
@@ -146,22 +146,22 @@ class UserForm extends React.Component<Props, State> {
{nameField}
<div className="column is-half">
<InputField
label={t('user.displayName')}
label={t("user.displayName")}
onChange={this.handleDisplayNameChange}
value={user ? user.displayName : ''}
value={user ? user.displayName : ""}
validationError={this.state.displayNameValidationError}
errorMessage={t('validation.displayname-invalid')}
helpText={t('help.displayNameHelpText')}
errorMessage={t("validation.displayname-invalid")}
helpText={t("help.displayNameHelpText")}
/>
</div>
<div className="column is-half">
<InputField
label={t('user.mail')}
label={t("user.mail")}
onChange={this.handleEmailChange}
value={user ? user.mail : ''}
value={user ? user.mail : ""}
validationError={this.state.mailValidationError}
errorMessage={t('validation.mail-invalid')}
helpText={t('help.mailHelpText')}
errorMessage={t("validation.mail-invalid")}
helpText={t("help.mailHelpText")}
/>
</div>
</div>
@@ -169,10 +169,10 @@ class UserForm extends React.Component<Props, State> {
<div className="columns">
<div className="column">
<Checkbox
label={t('user.active')}
label={t("user.active")}
onChange={this.handleActiveChange}
checked={user ? user.active : false}
helpText={t('help.activeHelpText')}
helpText={t("help.activeHelpText")}
/>
</div>
</div>
@@ -181,7 +181,7 @@ class UserForm extends React.Component<Props, State> {
<SubmitButton
disabled={!this.isValid()}
loading={loading}
label={t('userForm.button')}
label={t("userForm.button")}
/>
</div>
</div>
@@ -195,20 +195,20 @@ class UserForm extends React.Component<Props, State> {
nameValidationError: !validator.isNameValid(name),
user: {
...this.state.user,
name,
},
name
}
});
};
handleDisplayNameChange = (displayName: string) => {
this.setState({
displayNameValidationError: !userValidator.isDisplayNameValid(
displayName,
displayName
),
user: {
...this.state.user,
displayName,
},
displayName
}
});
};
@@ -217,8 +217,8 @@ class UserForm extends React.Component<Props, State> {
mailValidationError: !validator.isMailValid(mail),
user: {
...this.state.user,
mail,
},
mail
}
});
};
@@ -226,9 +226,9 @@ class UserForm extends React.Component<Props, State> {
this.setState({
user: {
...this.state.user,
password,
password
},
passwordValid: !this.isFalsy(password) && passwordValid,
passwordValid: !this.isFalsy(password) && passwordValid
});
};
@@ -236,10 +236,10 @@ class UserForm extends React.Component<Props, State> {
this.setState({
user: {
...this.state.user,
active,
},
active
}
});
};
}
export default translate('users')(UserForm);
export default translate("users")(UserForm);

View File

@@ -1,27 +1,27 @@
import React from 'react';
import { shallow } from 'enzyme';
import '@scm-manager/ui-tests/enzyme';
import '@scm-manager/ui-tests/i18n';
import EditUserNavLink from './EditUserNavLink';
import React from "react";
import { shallow } from "enzyme";
import "@scm-manager/ui-tests/enzyme";
import "@scm-manager/ui-tests/i18n";
import EditUserNavLink from "./EditUserNavLink";
it('should render nothing, if the edit link is missing', () => {
it("should render nothing, if the edit link is missing", () => {
const user = {
_links: {},
_links: {}
};
const navLink = shallow(<EditUserNavLink user={user} editUrl="/user/edit" />);
expect(navLink.text()).toBe('');
expect(navLink.text()).toBe("");
});
it('should render the navLink', () => {
it("should render the navLink", () => {
const user = {
_links: {
update: {
href: '/users',
},
},
href: "/users"
}
}
};
const navLink = shallow(<EditUserNavLink user={user} editUrl="/user/edit" />);
expect(navLink.text()).not.toBe('');
expect(navLink.text()).not.toBe("");
});

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { User } from '@scm-manager/ui-types';
import { NavLink } from '@scm-manager/ui-components';
import { translate } from 'react-i18next';
import React from "react";
import { User } from "@scm-manager/ui-types";
import { NavLink } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
type Props = {
user: User;
@@ -20,8 +20,8 @@ class EditUserNavLink extends React.Component<Props> {
if (!this.isEditable()) {
return null;
}
return <NavLink to={editUrl} label={t('singleUser.menu.generalNavLink')} />;
return <NavLink to={editUrl} label={t("singleUser.menu.generalNavLink")} />;
}
}
export default translate('users')(EditUserNavLink);
export default translate("users")(EditUserNavLink);

View File

@@ -1,31 +1,31 @@
import React from 'react';
import { shallow } from 'enzyme';
import '@scm-manager/ui-tests/enzyme';
import '@scm-manager/ui-tests/i18n';
import ChangePasswordNavLink from './SetPasswordNavLink';
import React from "react";
import { shallow } from "enzyme";
import "@scm-manager/ui-tests/enzyme";
import "@scm-manager/ui-tests/i18n";
import ChangePasswordNavLink from "./SetPasswordNavLink";
it('should render nothing, if the password link is missing', () => {
it("should render nothing, if the password link is missing", () => {
const user = {
_links: {},
_links: {}
};
const navLink = shallow(
<ChangePasswordNavLink user={user} passwordUrl="/user/password" />,
<ChangePasswordNavLink user={user} passwordUrl="/user/password" />
);
expect(navLink.text()).toBe('');
expect(navLink.text()).toBe("");
});
it('should render the navLink', () => {
it("should render the navLink", () => {
const user = {
_links: {
password: {
href: '/password',
},
},
href: "/password"
}
}
};
const navLink = shallow(
<ChangePasswordNavLink user={user} passwordUrl="/user/password" />,
<ChangePasswordNavLink user={user} passwordUrl="/user/password" />
);
expect(navLink.text()).not.toBe('');
expect(navLink.text()).not.toBe("");
});

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { translate } from 'react-i18next';
import { User } from '@scm-manager/ui-types';
import { NavLink } from '@scm-manager/ui-components';
import React from "react";
import { translate } from "react-i18next";
import { User } from "@scm-manager/ui-types";
import { NavLink } from "@scm-manager/ui-components";
type Props = {
t: (p: string) => string;
@@ -19,7 +19,7 @@ class ChangePasswordNavLink extends React.Component<Props> {
return (
<NavLink
to={passwordUrl}
label={t('singleUser.menu.setPasswordNavLink')}
label={t("singleUser.menu.setPasswordNavLink")}
/>
);
}
@@ -29,4 +29,4 @@ class ChangePasswordNavLink extends React.Component<Props> {
};
}
export default translate('users')(ChangePasswordNavLink);
export default translate("users")(ChangePasswordNavLink);

View File

@@ -1,31 +1,31 @@
import React from 'react';
import '@scm-manager/ui-tests/enzyme';
import '@scm-manager/ui-tests/i18n';
import SetPermissionsNavLink from './SetPermissionsNavLink';
import { shallow } from 'enzyme';
import React from "react";
import "@scm-manager/ui-tests/enzyme";
import "@scm-manager/ui-tests/i18n";
import SetPermissionsNavLink from "./SetPermissionsNavLink";
import { shallow } from "enzyme";
it('should render nothing, if the permissions link is missing', () => {
it("should render nothing, if the permissions link is missing", () => {
const user = {
_links: {},
_links: {}
};
const navLink = shallow(
<SetPermissionsNavLink user={user} permissionsUrl="/user/permissions" />,
<SetPermissionsNavLink user={user} permissionsUrl="/user/permissions" />
);
expect(navLink.text()).toBe('');
expect(navLink.text()).toBe("");
});
it('should render the navLink', () => {
it("should render the navLink", () => {
const user = {
_links: {
permissions: {
href: '/permissions',
},
},
href: "/permissions"
}
}
};
const navLink = shallow(
<SetPermissionsNavLink user={user} permissionsUrl="/user/permissions" />,
<SetPermissionsNavLink user={user} permissionsUrl="/user/permissions" />
);
expect(navLink.text()).not.toBe('');
expect(navLink.text()).not.toBe("");
});

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { translate } from 'react-i18next';
import { User } from '@scm-manager/ui-types';
import { NavLink } from '@scm-manager/ui-components';
import React from "react";
import { translate } from "react-i18next";
import { User } from "@scm-manager/ui-types";
import { NavLink } from "@scm-manager/ui-components";
type Props = {
t: (p: string) => string;
@@ -19,7 +19,7 @@ class ChangePermissionNavLink extends React.Component<Props> {
return (
<NavLink
to={permissionsUrl}
label={t('singleUser.menu.setPermissionsNavLink')}
label={t("singleUser.menu.setPermissionsNavLink")}
/>
);
}
@@ -29,4 +29,4 @@ class ChangePermissionNavLink extends React.Component<Props> {
};
}
export default translate('users')(ChangePermissionNavLink);
export default translate("users")(ChangePermissionNavLink);

View File

@@ -1,3 +1,3 @@
export { default as EditUserNavLink } from './EditUserNavLink';
export { default as SetPasswordNavLink } from './SetPasswordNavLink';
export { default as SetPermissionsNavLink } from './SetPermissionsNavLink';
export { default as EditUserNavLink } from "./EditUserNavLink";
export { default as SetPasswordNavLink } from "./SetPasswordNavLink";
export { default as SetPermissionsNavLink } from "./SetPermissionsNavLink";

View File

@@ -1,20 +1,20 @@
import fetchMock from 'fetch-mock';
import { CONTENT_TYPE_PASSWORD_OVERWRITE, setPassword } from './setPassword';
import fetchMock from "fetch-mock";
import { CONTENT_TYPE_PASSWORD_OVERWRITE, setPassword } from "./setPassword";
describe('password change', () => {
const SET_PASSWORD_URL = '/users/testuser/password';
const newPassword = 'testpw123';
describe("password change", () => {
const SET_PASSWORD_URL = "/users/testuser/password";
const newPassword = "testpw123";
afterEach(() => {
fetchMock.reset();
fetchMock.restore();
});
it('should set password', done => {
fetchMock.put('/api/v2' + SET_PASSWORD_URL, 204, {
it("should set password", done => {
fetchMock.put("/api/v2" + SET_PASSWORD_URL, 204, {
headers: {
'content-type': CONTENT_TYPE_PASSWORD_OVERWRITE,
},
"content-type": CONTENT_TYPE_PASSWORD_OVERWRITE
}
});
setPassword(SET_PASSWORD_URL, newPassword).then(content => {

View File

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

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { User } from '@scm-manager/ui-types';
import { translate } from 'react-i18next';
import { Checkbox, MailLink, DateFromNow } from '@scm-manager/ui-components';
import React from "react";
import { User } from "@scm-manager/ui-types";
import { translate } from "react-i18next";
import { Checkbox, MailLink, DateFromNow } from "@scm-manager/ui-components";
type Props = {
user: User;
@@ -15,37 +15,37 @@ class Details extends React.Component<Props> {
<table className="table">
<tbody>
<tr>
<th>{t('user.name')}</th>
<th>{t("user.name")}</th>
<td>{user.name}</td>
</tr>
<tr>
<th>{t('user.displayName')}</th>
<th>{t("user.displayName")}</th>
<td>{user.displayName}</td>
</tr>
<tr>
<th>{t('user.mail')}</th>
<th>{t("user.mail")}</th>
<td>
<MailLink address={user.mail} />
</td>
</tr>
<tr>
<th>{t('user.active')}</th>
<th>{t("user.active")}</th>
<td>
<Checkbox checked={user.active} />
</td>
</tr>
<tr>
<th>{t('user.type')}</th>
<th>{t("user.type")}</th>
<td>{user.type}</td>
</tr>
<tr>
<th>{t('user.creationDate')}</th>
<th>{t("user.creationDate")}</th>
<td>
<DateFromNow date={user.creationDate} />
</td>
</tr>
<tr>
<th>{t('user.lastModified')}</th>
<th>{t("user.lastModified")}</th>
<td>
<DateFromNow date={user.lastModified} />
</td>
@@ -56,4 +56,4 @@ class Details extends React.Component<Props> {
}
}
export default translate('users')(Details);
export default translate("users")(Details);

View File

@@ -1,8 +1,8 @@
import React from 'react';
import { translate } from 'react-i18next';
import { Link } from 'react-router-dom';
import { User } from '@scm-manager/ui-types';
import { Icon } from '@scm-manager/ui-components';
import React from "react";
import { translate } from "react-i18next";
import { Link } from "react-router-dom";
import { User } from "@scm-manager/ui-types";
import { Icon } from "@scm-manager/ui-components";
type Props = {
user: User;
@@ -20,13 +20,13 @@ class UserRow extends React.Component<Props> {
const { user, t } = this.props;
const to = `/user/${user.name}`;
const iconType = user.active ? (
<Icon title={t('user.active')} name="user" />
<Icon title={t("user.active")} name="user" />
) : (
<Icon title={t('user.inactive')} name="user-slash" />
<Icon title={t("user.inactive")} name="user-slash" />
);
return (
<tr className={user.active ? 'border-is-green' : 'border-is-yellow'}>
<tr className={user.active ? "border-is-green" : "border-is-yellow"}>
<td>
{iconType} {this.renderLink(to, user.name)}
</td>
@@ -41,4 +41,4 @@ class UserRow extends React.Component<Props> {
}
}
export default translate('users')(UserRow);
export default translate("users")(UserRow);

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { translate } from 'react-i18next';
import UserRow from './UserRow';
import { User } from '@scm-manager/ui-types';
import React from "react";
import { translate } from "react-i18next";
import UserRow from "./UserRow";
import { User } from "@scm-manager/ui-types";
type Props = {
t: (p: string) => string;
@@ -15,9 +15,9 @@ class UserTable extends React.Component<Props> {
<table className="card-table table is-hoverable is-fullwidth">
<thead>
<tr>
<th className="is-hidden-mobile">{t('user.name')}</th>
<th>{t('user.displayName')}</th>
<th>{t('user.mail')}</th>
<th className="is-hidden-mobile">{t("user.name")}</th>
<th>{t("user.displayName")}</th>
<th>{t("user.mail")}</th>
</tr>
</thead>
<tbody>
@@ -30,4 +30,4 @@ class UserTable extends React.Component<Props> {
}
}
export default translate('users')(UserTable);
export default translate("users")(UserTable);

View File

@@ -1,3 +1,3 @@
export { default as Details } from './Details';
export { default as UserRow } from './UserRow';
export { default as UserTable } from './UserTable';
export { default as Details } from "./Details";
export { default as UserRow } from "./UserRow";
export { default as UserTable } from "./UserTable";

View File

@@ -1,18 +1,18 @@
import * as validator from './userValidation';
import * as validator from "./userValidation";
describe('test displayName validation', () => {
it('should return false', () => {
expect(validator.isDisplayNameValid('')).toBe(false);
describe("test displayName validation", () => {
it("should return false", () => {
expect(validator.isDisplayNameValid("")).toBe(false);
});
it('should return true', () => {
it("should return true", () => {
// valid names taken from ValidationUtilTest.java
const validNames = [
'Arthur Dent',
'Tricia.McMillan@hitchhiker.com',
'Ford Prefect (ford.prefect@hitchhiker.com)',
'Zaphod Beeblebrox <zaphod.beeblebrox@hitchhiker.com>',
'Marvin, der depressive Roboter',
"Arthur Dent",
"Tricia.McMillan@hitchhiker.com",
"Ford Prefect (ford.prefect@hitchhiker.com)",
"Zaphod Beeblebrox <zaphod.beeblebrox@hitchhiker.com>",
"Marvin, der depressive Roboter"
];
for (let name of validNames) {
expect(validator.isDisplayNameValid(name)).toBe(true);
@@ -20,18 +20,18 @@ describe('test displayName validation', () => {
});
});
describe('test password validation', () => {
it('should return false', () => {
describe("test password validation", () => {
it("should return false", () => {
// invalid taken from ValidationUtilTest.java
const invalid = ['', 'abc', 'aaabbbcccdddeeefffggghhhiiijjjkkk'];
const invalid = ["", "abc", "aaabbbcccdddeeefffggghhhiiijjjkkk"];
for (let password of invalid) {
expect(validator.isPasswordValid(password)).toBe(false);
}
});
it('should return true', () => {
it("should return true", () => {
// valid taken from ValidationUtilTest.java
const valid = ['secret123', 'mySuperSecretPassword'];
const valid = ["secret123", "mySuperSecretPassword"];
for (let password of valid) {
expect(validator.isPasswordValid(password)).toBe(true);
}

View File

@@ -1,4 +1,4 @@
import { validation } from '@scm-manager/ui-components';
import { validation } from "@scm-manager/ui-components";
const { isNameValid, isMailValid, isPathValid } = validation;

View File

@@ -1,17 +1,17 @@
import React from 'react';
import { connect } from 'react-redux';
import UserForm from '../components/UserForm';
import { User } from '@scm-manager/ui-types';
import { History } from 'history';
import React from "react";
import { connect } from "react-redux";
import UserForm from "../components/UserForm";
import { User } from "@scm-manager/ui-types";
import { History } from "history";
import {
createUser,
createUserReset,
isCreateUserPending,
getCreateUserFailure,
} from '../modules/users';
import { Page } from '@scm-manager/ui-components';
import { translate } from 'react-i18next';
import { getUsersLink } from '../../modules/indexResource';
getCreateUserFailure
} from "../modules/users";
import { Page } from "@scm-manager/ui-components";
import { translate } from "react-i18next";
import { getUsersLink } from "../../modules/indexResource";
type Props = {
loading?: boolean;
@@ -34,12 +34,12 @@ class CreateUser extends React.Component<Props> {
userCreated = (user: User) => {
const { history } = this.props;
history.push('/user/' + user.name);
history.push("/user/" + user.name);
};
createUser = (user: User) => {
this.props.addUser(this.props.usersLink, user, () =>
this.userCreated(user),
this.userCreated(user)
);
};
@@ -48,8 +48,8 @@ class CreateUser extends React.Component<Props> {
return (
<Page
title={t('createUser.title')}
subtitle={t('createUser.subtitle')}
title={t("createUser.title")}
subtitle={t("createUser.subtitle")}
error={error}
showContentOnError={true}
>
@@ -69,7 +69,7 @@ const mapDispatchToProps = dispatch => {
},
resetForm: () => {
dispatch(createUserReset());
},
}
};
};
@@ -80,11 +80,11 @@ const mapStateToProps = (state, ownProps) => {
return {
usersLink,
loading,
error,
error
};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(translate('users')(CreateUser));
mapDispatchToProps
)(translate("users")(CreateUser));

View File

@@ -1,20 +1,20 @@
import React from 'react';
import { translate } from 'react-i18next';
import { User } from '@scm-manager/ui-types';
import React from "react";
import { translate } from "react-i18next";
import { User } from "@scm-manager/ui-types";
import {
Subtitle,
DeleteButton,
confirmAlert,
ErrorNotification,
} from '@scm-manager/ui-components';
ErrorNotification
} from "@scm-manager/ui-components";
import {
deleteUser,
getDeleteUserFailure,
isDeleteUserPending,
} from '../modules/users';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { History } from 'history';
isDeleteUserPending
} from "../modules/users";
import { connect } from "react-redux";
import { withRouter } from "react-router-dom";
import { History } from "history";
type Props = {
loading: boolean;
@@ -30,11 +30,11 @@ type Props = {
class DeleteUser extends React.Component<Props> {
static defaultProps = {
confirmDialog: true,
confirmDialog: true
};
userDeleted = () => {
this.props.history.push('/users/');
this.props.history.push("/users/");
};
deleteUser = () => {
@@ -44,18 +44,18 @@ class DeleteUser extends React.Component<Props> {
confirmDelete = () => {
const { t } = this.props;
confirmAlert({
title: t('deleteUser.confirmAlert.title'),
message: t('deleteUser.confirmAlert.message'),
title: t("deleteUser.confirmAlert.title"),
message: t("deleteUser.confirmAlert.message"),
buttons: [
{
label: t('deleteUser.confirmAlert.submit'),
onClick: () => this.deleteUser(),
label: t("deleteUser.confirmAlert.submit"),
onClick: () => this.deleteUser()
},
{
label: t('deleteUser.confirmAlert.cancel'),
onClick: () => null,
},
],
label: t("deleteUser.confirmAlert.cancel"),
onClick: () => null
}
]
});
};
@@ -73,12 +73,12 @@ class DeleteUser extends React.Component<Props> {
return (
<>
<Subtitle subtitle={t('deleteUser.subtitle')} />
<Subtitle subtitle={t("deleteUser.subtitle")} />
<ErrorNotification error={error} />
<div className="columns">
<div className="column">
<DeleteButton
label={t('deleteUser.button')}
label={t("deleteUser.button")}
action={action}
loading={loading}
/>
@@ -94,7 +94,7 @@ const mapStateToProps = (state, ownProps) => {
const error = getDeleteUserFailure(state, ownProps.user.name);
return {
loading,
error,
error
};
};
@@ -102,11 +102,11 @@ const mapDispatchToProps = dispatch => {
return {
deleteUser: (user: User, callback?: () => void) => {
dispatch(deleteUser(user, callback));
},
}
};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(withRouter(translate('users')(DeleteUser)));
mapDispatchToProps
)(withRouter(translate("users")(DeleteUser)));

View File

@@ -1,17 +1,17 @@
import React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import UserForm from '../components/UserForm';
import DeleteUser from './DeleteUser';
import { User } from '@scm-manager/ui-types';
import React from "react";
import { connect } from "react-redux";
import { withRouter } from "react-router-dom";
import UserForm from "../components/UserForm";
import DeleteUser from "./DeleteUser";
import { User } from "@scm-manager/ui-types";
import {
modifyUser,
isModifyUserPending,
getModifyUserFailure,
modifyUserReset,
} from '../modules/users';
import { History } from 'history';
import { ErrorNotification } from '@scm-manager/ui-components';
modifyUserReset
} from "../modules/users";
import { History } from "history";
import { ErrorNotification } from "@scm-manager/ui-components";
type Props = {
loading: boolean;
@@ -62,7 +62,7 @@ const mapStateToProps = (state, ownProps) => {
const error = getModifyUserFailure(state, ownProps.user.name);
return {
loading,
error,
error
};
};
@@ -73,11 +73,11 @@ const mapDispatchToProps = dispatch => {
},
modifyUserReset: (user: User) => {
dispatch(modifyUserReset(user));
},
}
};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
mapDispatchToProps
)(withRouter(EditUser));

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { connect } from 'react-redux';
import React from "react";
import { connect } from "react-redux";
import {
Page,
Loading,
@@ -7,29 +7,29 @@ import {
SubNavigation,
Section,
NavLink,
ErrorPage,
} from '@scm-manager/ui-components';
import { Route } from 'react-router-dom';
import { Details } from './../components/table';
import EditUser from './EditUser';
import { User } from '@scm-manager/ui-types';
import { History } from 'history';
ErrorPage
} from "@scm-manager/ui-components";
import { Route } from "react-router-dom";
import { Details } from "./../components/table";
import EditUser from "./EditUser";
import { User } from "@scm-manager/ui-types";
import { History } from "history";
import {
fetchUserByName,
getUserByName,
isFetchUserPending,
getFetchUserFailure,
} from '../modules/users';
getFetchUserFailure
} from "../modules/users";
import {
EditUserNavLink,
SetPasswordNavLink,
SetPermissionsNavLink,
} from './../components/navLinks';
import { translate } from 'react-i18next';
import { getUsersLink } from '../../modules/indexResource';
import SetUserPassword from '../components/SetUserPassword';
import SetPermissions from '../../permissions/components/SetPermissions';
import { ExtensionPoint } from '@scm-manager/ui-extensions';
SetPermissionsNavLink
} from "./../components/navLinks";
import { translate } from "react-i18next";
import { getUsersLink } from "../../modules/indexResource";
import SetUserPassword from "../components/SetUserPassword";
import SetPermissions from "../../permissions/components/SetPermissions";
import { ExtensionPoint } from "@scm-manager/ui-extensions";
type Props = {
name: string;
@@ -53,7 +53,7 @@ class SingleUser extends React.Component<Props> {
}
stripEndingSlash = (url: string) => {
if (url.endsWith('/')) {
if (url.endsWith("/")) {
return url.substring(0, url.length - 2);
}
return url;
@@ -69,8 +69,8 @@ class SingleUser extends React.Component<Props> {
if (error) {
return (
<ErrorPage
title={t('singleUser.errorTitle')}
subtitle={t('singleUser.errorSubtitle')}
title={t("singleUser.errorTitle")}
subtitle={t("singleUser.errorSubtitle")}
error={error}
/>
);
@@ -84,7 +84,7 @@ class SingleUser extends React.Component<Props> {
const extensionProps = {
user,
url,
url
};
return (
@@ -116,15 +116,15 @@ class SingleUser extends React.Component<Props> {
</div>
<div className="column">
<Navigation>
<Section label={t('singleUser.menu.navigationLabel')}>
<Section label={t("singleUser.menu.navigationLabel")}>
<NavLink
to={`${url}`}
icon="fas fa-info-circle"
label={t('singleUser.menu.informationNavLink')}
label={t("singleUser.menu.informationNavLink")}
/>
<SubNavigation
to={`${url}/settings/general`}
label={t('singleUser.menu.settingsNavLink')}
label={t("singleUser.menu.settingsNavLink")}
>
<EditUserNavLink
user={user}
@@ -164,7 +164,7 @@ const mapStateToProps = (state, ownProps) => {
name,
user,
loading,
error,
error
};
};
@@ -172,11 +172,11 @@ const mapDispatchToProps = dispatch => {
return {
fetchUserByName: (link: string, name: string) => {
dispatch(fetchUserByName(link, name));
},
}
};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(translate('users')(SingleUser));
mapDispatchToProps
)(translate("users")(SingleUser));

View File

@@ -1,16 +1,16 @@
import React from 'react';
import { connect } from 'react-redux';
import { translate } from 'react-i18next';
import { History } from 'history';
import { User, PagedCollection } from '@scm-manager/ui-types';
import React from "react";
import { connect } from "react-redux";
import { translate } from "react-i18next";
import { History } from "history";
import { User, PagedCollection } from "@scm-manager/ui-types";
import {
fetchUsersByPage,
getUsersFromState,
selectListAsCollection,
isPermittedToCreateUsers,
isFetchUsersPending,
getFetchUsersFailure,
} from '../modules/users';
getFetchUsersFailure
} from "../modules/users";
import {
Page,
PageActions,
@@ -18,10 +18,10 @@ import {
Notification,
LinkPaginator,
urls,
CreateButton,
} from '@scm-manager/ui-components';
import { UserTable } from './../components/table';
import { getUsersLink } from '../../modules/indexResource';
CreateButton
} from "@scm-manager/ui-components";
import { UserTable } from "./../components/table";
import { getUsersLink } from "../../modules/indexResource";
type Props = {
users: User[];
@@ -47,7 +47,7 @@ class Users extends React.Component<Props> {
fetchUsersByPage(
usersLink,
page,
urls.getQueryStringFromLocation(location),
urls.getQueryStringFromLocation(location)
);
}
@@ -58,7 +58,7 @@ class Users extends React.Component<Props> {
page,
usersLink,
location,
fetchUsersByPage,
fetchUsersByPage
} = this.props;
if (list && page && !loading) {
const statePage: number = list.page + 1;
@@ -66,7 +66,7 @@ class Users extends React.Component<Props> {
fetchUsersByPage(
usersLink,
page,
urls.getQueryStringFromLocation(location),
urls.getQueryStringFromLocation(location)
);
}
}
@@ -76,8 +76,8 @@ class Users extends React.Component<Props> {
const { users, loading, error, canAddUsers, t } = this.props;
return (
<Page
title={t('users.title')}
subtitle={t('users.subtitle')}
title={t("users.title")}
subtitle={t("users.subtitle")}
loading={loading || !users}
error={error}
>
@@ -87,7 +87,7 @@ class Users extends React.Component<Props> {
<OverviewPageActions
showCreateButton={canAddUsers}
link="users"
label={t('users.createButton')}
label={t("users.createButton")}
/>
</PageActions>
</Page>
@@ -108,14 +108,14 @@ class Users extends React.Component<Props> {
</>
);
}
return <Notification type="info">{t('users.noUsers')}</Notification>;
return <Notification type="info">{t("users.noUsers")}</Notification>;
}
renderCreateButton() {
const { canAddUsers, t } = this.props;
if (canAddUsers) {
return (
<CreateButton label={t('users.createButton')} link="/users/create" />
<CreateButton label={t("users.createButton")} link="/users/create" />
);
}
return null;
@@ -139,7 +139,7 @@ const mapStateToProps = (state, ownProps) => {
canAddUsers,
list,
page,
usersLink,
usersLink
};
};
@@ -147,11 +147,11 @@ const mapDispatchToProps = dispatch => {
return {
fetchUsersByPage: (link: string, page: number, filter?: string) => {
dispatch(fetchUsersByPage(link, page, filter));
},
}
};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(translate('users')(Users));
mapDispatchToProps
)(translate("users")(Users));

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_USERS,
@@ -45,53 +45,53 @@ import reducer, {
deleteUserSuccess,
getDeleteUserFailure,
selectListAsCollection,
isPermittedToCreateUsers,
} from './users';
isPermittedToCreateUsers
} from "./users";
const userZaphod = {
active: true,
admin: true,
creationDate: '2018-07-11T12:23:49.027Z',
displayName: 'Z. Beeblebrox',
mail: 'president@heartofgold.universe',
name: 'zaphod',
password: '',
type: 'xml',
creationDate: "2018-07-11T12:23:49.027Z",
displayName: "Z. Beeblebrox",
mail: "president@heartofgold.universe",
name: "zaphod",
password: "",
type: "xml",
properties: {},
_links: {
self: {
href: 'http://localhost:8081/api/v2/users/zaphod',
href: "http://localhost:8081/api/v2/users/zaphod"
},
delete: {
href: 'http://localhost:8081/api/v2/users/zaphod',
href: "http://localhost:8081/api/v2/users/zaphod"
},
update: {
href: 'http://localhost:8081/api/v2/users/zaphod',
},
},
href: "http://localhost:8081/api/v2/users/zaphod"
}
}
};
const userFord = {
active: true,
admin: false,
creationDate: '2018-07-06T13:21:18.459Z',
displayName: 'F. Prefect',
mail: 'ford@prefect.universe',
name: 'ford',
password: '',
type: 'xml',
creationDate: "2018-07-06T13:21:18.459Z",
displayName: "F. Prefect",
mail: "ford@prefect.universe",
name: "ford",
password: "",
type: "xml",
properties: {},
_links: {
self: {
href: 'http://localhost:8081/api/v2/users/ford',
href: "http://localhost:8081/api/v2/users/ford"
},
delete: {
href: 'http://localhost:8081/api/v2/users/ford',
href: "http://localhost:8081/api/v2/users/ford"
},
update: {
href: 'http://localhost:8081/api/v2/users/ford',
},
},
href: "http://localhost:8081/api/v2/users/ford"
}
}
};
const responseBody = {
@@ -99,54 +99,54 @@ const responseBody = {
pageTotal: 1,
_links: {
self: {
href: 'http://localhost:3000/api/v2/users/?page=0&pageSize=10',
href: "http://localhost:3000/api/v2/users/?page=0&pageSize=10"
},
first: {
href: 'http://localhost:3000/api/v2/users/?page=0&pageSize=10',
href: "http://localhost:3000/api/v2/users/?page=0&pageSize=10"
},
last: {
href: 'http://localhost:3000/api/v2/users/?page=0&pageSize=10',
href: "http://localhost:3000/api/v2/users/?page=0&pageSize=10"
},
create: {
href: 'http://localhost:3000/api/v2/users/',
},
href: "http://localhost:3000/api/v2/users/"
}
},
_embedded: {
users: [userZaphod, userFord],
},
users: [userZaphod, userFord]
}
};
const response = {
headers: {
'content-type': 'application/json',
"content-type": "application/json"
},
responseBody,
responseBody
};
const URL = 'users';
const USERS_URL = '/api/v2/users';
const USER_ZAPHOD_URL = 'http://localhost:8081/api/v2/users/zaphod';
const URL = "users";
const USERS_URL = "/api/v2/users";
const USER_ZAPHOD_URL = "http://localhost:8081/api/v2/users/zaphod";
const error = new Error('KAPUTT');
const error = new Error("KAPUTT");
describe('users fetch()', () => {
describe("users fetch()", () => {
const mockStore = configureMockStore([thunk]);
afterEach(() => {
fetchMock.reset();
fetchMock.restore();
});
it('should successfully fetch users', () => {
it("should successfully fetch users", () => {
fetchMock.getOnce(USERS_URL, response);
const expectedActions = [
{
type: FETCH_USERS_PENDING,
type: FETCH_USERS_PENDING
},
{
type: FETCH_USERS_SUCCESS,
payload: response,
},
payload: response
}
];
const store = mockStore({});
@@ -156,9 +156,9 @@ describe('users fetch()', () => {
});
});
it('should fail getting users on HTTP 500', () => {
it("should fail getting users on HTTP 500", () => {
fetchMock.getOnce(USERS_URL, {
status: 500,
status: 500
});
const store = mockStore({});
@@ -170,11 +170,11 @@ describe('users fetch()', () => {
});
});
it('should sucessfully fetch single user by name', () => {
fetchMock.getOnce(USERS_URL + '/zaphod', userZaphod);
it("should sucessfully fetch single user by name", () => {
fetchMock.getOnce(USERS_URL + "/zaphod", userZaphod);
const store = mockStore({});
return store.dispatch(fetchUserByName(URL, 'zaphod')).then(() => {
return store.dispatch(fetchUserByName(URL, "zaphod")).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(FETCH_USER_PENDING);
expect(actions[1].type).toEqual(FETCH_USER_SUCCESS);
@@ -182,13 +182,13 @@ describe('users fetch()', () => {
});
});
it('should fail fetching single user by name on HTTP 500', () => {
fetchMock.getOnce(USERS_URL + '/zaphod', {
status: 500,
it("should fail fetching single user by name on HTTP 500", () => {
fetchMock.getOnce(USERS_URL + "/zaphod", {
status: 500
});
const store = mockStore({});
return store.dispatch(fetchUserByName(URL, 'zaphod')).then(() => {
return store.dispatch(fetchUserByName(URL, "zaphod")).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(FETCH_USER_PENDING);
expect(actions[1].type).toEqual(FETCH_USER_FAILURE);
@@ -196,7 +196,7 @@ describe('users fetch()', () => {
});
});
it('should sucessfully fetch single user', () => {
it("should sucessfully fetch single user", () => {
fetchMock.getOnce(USER_ZAPHOD_URL, userZaphod);
const store = mockStore({});
@@ -208,9 +208,9 @@ describe('users fetch()', () => {
});
});
it('should fail fetching single user on HTTP 500', () => {
it("should fail fetching single user on HTTP 500", () => {
fetchMock.getOnce(USER_ZAPHOD_URL, {
status: 500,
status: 500
});
const store = mockStore({});
@@ -222,10 +222,10 @@ describe('users fetch()', () => {
});
});
it('should add a user successfully', () => {
it("should add a user successfully", () => {
// unmatched
fetchMock.postOnce(USERS_URL, {
status: 204,
status: 204
});
// after create, the users are fetched again
@@ -239,9 +239,9 @@ describe('users fetch()', () => {
});
});
it('should fail adding a user on HTTP 500', () => {
it("should fail adding a user on HTTP 500", () => {
fetchMock.postOnce(USERS_URL, {
status: 500,
status: 500
});
const store = mockStore({});
@@ -253,27 +253,27 @@ describe('users fetch()', () => {
});
});
it('should call the callback after user successfully created', () => {
it("should call the callback after user successfully created", () => {
// unmatched
fetchMock.postOnce(USERS_URL, {
status: 204,
status: 204
});
let callMe = 'not yet';
let callMe = "not yet";
const callback = () => {
callMe = 'yeah';
callMe = "yeah";
};
const store = mockStore({});
return store.dispatch(createUser(URL, userZaphod, callback)).then(() => {
expect(callMe).toBe('yeah');
expect(callMe).toBe("yeah");
});
});
it('successfully update user', () => {
it("successfully update user", () => {
fetchMock.putOnce(USER_ZAPHOD_URL, {
status: 204,
status: 204
});
fetchMock.getOnce(USER_ZAPHOD_URL, userZaphod);
@@ -287,9 +287,9 @@ describe('users fetch()', () => {
});
});
it('should call callback, after successful modified user', () => {
it("should call callback, after successful modified user", () => {
fetchMock.putOnce(USER_ZAPHOD_URL, {
status: 204,
status: 204
});
fetchMock.getOnce(USER_ZAPHOD_URL, userZaphod);
@@ -304,9 +304,9 @@ describe('users fetch()', () => {
});
});
it('should fail updating user on HTTP 500', () => {
it("should fail updating user on HTTP 500", () => {
fetchMock.putOnce(USER_ZAPHOD_URL, {
status: 500,
status: 500
});
const store = mockStore({});
@@ -318,9 +318,9 @@ describe('users fetch()', () => {
});
});
it('should delete successfully user zaphod', () => {
it("should delete successfully user zaphod", () => {
fetchMock.deleteOnce(USER_ZAPHOD_URL, {
status: 204,
status: 204
});
const store = mockStore({});
@@ -333,9 +333,9 @@ describe('users fetch()', () => {
});
});
it('should call the callback, after successful delete', () => {
it("should call the callback, after successful delete", () => {
fetchMock.deleteOnce(USER_ZAPHOD_URL, {
status: 204,
status: 204
});
let called = false;
@@ -349,9 +349,9 @@ describe('users fetch()', () => {
});
});
it('should fail to delete user zaphod', () => {
it("should fail to delete user zaphod", () => {
fetchMock.deleteOnce(USER_ZAPHOD_URL, {
status: 500,
status: 500
});
const store = mockStore({});
@@ -365,325 +365,325 @@ describe('users fetch()', () => {
});
});
describe('users reducer', () => {
it('should update state correctly according to FETCH_USERS_SUCCESS action', () => {
describe("users reducer", () => {
it("should update state correctly according to FETCH_USERS_SUCCESS action", () => {
const newState = reducer({}, fetchUsersSuccess(responseBody));
expect(newState.list).toEqual({
entries: ['zaphod', 'ford'],
entries: ["zaphod", "ford"],
entry: {
userCreatePermission: true,
page: 0,
pageTotal: 1,
_links: responseBody._links,
},
_links: responseBody._links
}
});
expect(newState.byNames).toEqual({
zaphod: userZaphod,
ford: userFord,
ford: userFord
});
expect(newState.list.entry.userCreatePermission).toBeTruthy();
});
it('should set userCreatePermission to true if update link is present', () => {
it("should set userCreatePermission to true if update link is present", () => {
const newState = reducer({}, fetchUsersSuccess(responseBody));
expect(newState.list.entry.userCreatePermission).toBeTruthy();
});
it('should not replace whole byNames map when fetching users', () => {
it("should not replace whole byNames map when fetching users", () => {
const oldState = {
byNames: {
ford: userFord,
},
ford: userFord
}
};
const newState = reducer(oldState, fetchUsersSuccess(responseBody));
expect(newState.byNames['zaphod']).toBeDefined();
expect(newState.byNames['ford']).toBeDefined();
expect(newState.byNames["zaphod"]).toBeDefined();
expect(newState.byNames["ford"]).toBeDefined();
});
it('should remove user from state when delete succeeds', () => {
it("should remove user from state when delete succeeds", () => {
const state = {
list: {
entries: ['ford', 'zaphod'],
entries: ["ford", "zaphod"]
},
byNames: {
zaphod: userZaphod,
ford: userFord,
},
ford: userFord
}
};
const newState = reducer(state, deleteUserSuccess(userFord));
expect(newState.byNames['zaphod']).toBeDefined();
expect(newState.byNames['ford']).toBeFalsy();
expect(newState.list.entries).toEqual(['zaphod']);
expect(newState.byNames["zaphod"]).toBeDefined();
expect(newState.byNames["ford"]).toBeFalsy();
expect(newState.list.entries).toEqual(["zaphod"]);
});
it('should set userCreatePermission to true if create link is present', () => {
it("should set userCreatePermission to true if create link is present", () => {
const newState = reducer({}, fetchUsersSuccess(responseBody));
expect(newState.list.entry.userCreatePermission).toBeTruthy();
expect(newState.list.entries).toEqual(['zaphod', 'ford']);
expect(newState.byNames['ford']).toBeTruthy();
expect(newState.byNames['zaphod']).toBeTruthy();
expect(newState.list.entries).toEqual(["zaphod", "ford"]);
expect(newState.byNames["ford"]).toBeTruthy();
expect(newState.byNames["zaphod"]).toBeTruthy();
});
it('should update state according to FETCH_USER_SUCCESS action', () => {
it("should update state according to FETCH_USER_SUCCESS action", () => {
const newState = reducer({}, fetchUserSuccess(userFord));
expect(newState.byNames['ford']).toBe(userFord);
expect(newState.byNames["ford"]).toBe(userFord);
});
it('should affect users state nor the state of other users', () => {
it("should affect users state nor the state of other users", () => {
const newState = reducer(
{
list: {
entries: ['zaphod'],
},
entries: ["zaphod"]
}
},
fetchUserSuccess(userFord),
fetchUserSuccess(userFord)
);
expect(newState.byNames['ford']).toBe(userFord);
expect(newState.list.entries).toEqual(['zaphod']);
expect(newState.byNames["ford"]).toBe(userFord);
expect(newState.list.entries).toEqual(["zaphod"]);
});
});
describe('selector tests', () => {
it('should return an empty object', () => {
describe("selector tests", () => {
it("should return an empty object", () => {
expect(selectListAsCollection({})).toEqual({});
expect(
selectListAsCollection({
users: {
a: 'a',
},
}),
a: "a"
}
})
).toEqual({});
});
it('should return a state slice collection', () => {
it("should return a state slice collection", () => {
const collection = {
page: 3,
totalPages: 42,
totalPages: 42
};
const state = {
users: {
list: {
entry: collection,
},
},
entry: collection
}
}
};
expect(selectListAsCollection(state)).toBe(collection);
});
it('should return false', () => {
it("should return false", () => {
expect(isPermittedToCreateUsers({})).toBe(false);
expect(
isPermittedToCreateUsers({
users: {
list: {
entry: {},
},
},
}),
entry: {}
}
}
})
).toBe(false);
expect(
isPermittedToCreateUsers({
users: {
list: {
entry: {
userCreatePermission: false,
},
},
},
}),
userCreatePermission: false
}
}
}
})
).toBe(false);
});
it('should return true', () => {
it("should return true", () => {
const state = {
users: {
list: {
entry: {
userCreatePermission: true,
},
},
},
userCreatePermission: true
}
}
}
};
expect(isPermittedToCreateUsers(state)).toBe(true);
});
it('should get users from state', () => {
it("should get users from state", () => {
const state = {
users: {
list: {
entries: ['a', 'b'],
entries: ["a", "b"]
},
byNames: {
a: {
name: 'a',
name: "a"
},
b: {
name: 'b',
},
},
},
name: "b"
}
}
}
};
expect(getUsersFromState(state)).toEqual([
{
name: 'a',
name: "a"
},
{
name: 'b',
},
name: "b"
}
]);
});
it('should return true, when fetch users is pending', () => {
it("should return true, when fetch users is pending", () => {
const state = {
pending: {
[FETCH_USERS]: true,
},
[FETCH_USERS]: true
}
};
expect(isFetchUsersPending(state)).toEqual(true);
});
it('should return false, when fetch users is not pending', () => {
it("should return false, when fetch users is not pending", () => {
expect(isFetchUsersPending({})).toEqual(false);
});
it('should return error when fetch users did fail', () => {
it("should return error when fetch users did fail", () => {
const state = {
failure: {
[FETCH_USERS]: error,
},
[FETCH_USERS]: error
}
};
expect(getFetchUsersFailure(state)).toEqual(error);
});
it('should return undefined when fetch users did not fail', () => {
it("should return undefined when fetch users did not fail", () => {
expect(getFetchUsersFailure({})).toBe(undefined);
});
it('should return true if create user is pending', () => {
it("should return true if create user is pending", () => {
const state = {
pending: {
[CREATE_USER]: true,
},
[CREATE_USER]: true
}
};
expect(isCreateUserPending(state)).toBe(true);
});
it('should return false if create user is not pending', () => {
it("should return false if create user is not pending", () => {
const state = {
pending: {
[CREATE_USER]: false,
},
[CREATE_USER]: false
}
};
expect(isCreateUserPending(state)).toBe(false);
});
it('should return error when create user did fail', () => {
it("should return error when create user did fail", () => {
const state = {
failure: {
[CREATE_USER]: error,
},
[CREATE_USER]: error
}
};
expect(getCreateUserFailure(state)).toEqual(error);
});
it('should return undefined when create user did not fail', () => {
it("should return undefined when create user did not fail", () => {
expect(getCreateUserFailure({})).toBe(undefined);
});
it('should return user ford', () => {
it("should return user ford", () => {
const state = {
users: {
byNames: {
ford: userFord,
},
},
ford: userFord
}
}
};
expect(getUserByName(state, 'ford')).toEqual(userFord);
expect(getUserByName(state, "ford")).toEqual(userFord);
});
it('should return true, when fetch user zaphod is pending', () => {
it("should return true, when fetch user zaphod is pending", () => {
const state = {
pending: {
[FETCH_USER + '/zaphod']: true,
},
[FETCH_USER + "/zaphod"]: true
}
};
expect(isFetchUserPending(state, 'zaphod')).toEqual(true);
expect(isFetchUserPending(state, "zaphod")).toEqual(true);
});
it('should return false, when fetch user zaphod is not pending', () => {
expect(isFetchUserPending({}, 'zaphod')).toEqual(false);
it("should return false, when fetch user zaphod is not pending", () => {
expect(isFetchUserPending({}, "zaphod")).toEqual(false);
});
it('should return error when fetch user zaphod did fail', () => {
it("should return error when fetch user zaphod did fail", () => {
const state = {
failure: {
[FETCH_USER + '/zaphod']: error,
},
[FETCH_USER + "/zaphod"]: error
}
};
expect(getFetchUserFailure(state, 'zaphod')).toEqual(error);
expect(getFetchUserFailure(state, "zaphod")).toEqual(error);
});
it('should return undefined when fetch user zaphod did not fail', () => {
expect(getFetchUserFailure({}, 'zaphod')).toBe(undefined);
it("should return undefined when fetch user zaphod did not fail", () => {
expect(getFetchUserFailure({}, "zaphod")).toBe(undefined);
});
it('should return true, when modify user ford is pending', () => {
it("should return true, when modify user ford is pending", () => {
const state = {
pending: {
[MODIFY_USER + '/ford']: true,
},
[MODIFY_USER + "/ford"]: true
}
};
expect(isModifyUserPending(state, 'ford')).toEqual(true);
expect(isModifyUserPending(state, "ford")).toEqual(true);
});
it('should return false, when modify user ford is not pending', () => {
expect(isModifyUserPending({}, 'ford')).toEqual(false);
it("should return false, when modify user ford is not pending", () => {
expect(isModifyUserPending({}, "ford")).toEqual(false);
});
it('should return error when modify user ford did fail', () => {
it("should return error when modify user ford did fail", () => {
const state = {
failure: {
[MODIFY_USER + '/ford']: error,
},
[MODIFY_USER + "/ford"]: error
}
};
expect(getModifyUserFailure(state, 'ford')).toEqual(error);
expect(getModifyUserFailure(state, "ford")).toEqual(error);
});
it('should return undefined when modify user ford did not fail', () => {
expect(getModifyUserFailure({}, 'ford')).toBe(undefined);
it("should return undefined when modify user ford did not fail", () => {
expect(getModifyUserFailure({}, "ford")).toBe(undefined);
});
it('should return true, when delete user zaphod is pending', () => {
it("should return true, when delete user zaphod is pending", () => {
const state = {
pending: {
[DELETE_USER + '/zaphod']: true,
},
[DELETE_USER + "/zaphod"]: true
}
};
expect(isDeleteUserPending(state, 'zaphod')).toEqual(true);
expect(isDeleteUserPending(state, "zaphod")).toEqual(true);
});
it('should return false, when delete user zaphod is not pending', () => {
expect(isDeleteUserPending({}, 'zaphod')).toEqual(false);
it("should return false, when delete user zaphod is not pending", () => {
expect(isDeleteUserPending({}, "zaphod")).toEqual(false);
});
it('should return error when delete user zaphod did fail', () => {
it("should return error when delete user zaphod did fail", () => {
const state = {
failure: {
[DELETE_USER + '/zaphod']: error,
},
[DELETE_USER + "/zaphod"]: error
}
};
expect(getDeleteUserFailure(state, 'zaphod')).toEqual(error);
expect(getDeleteUserFailure(state, "zaphod")).toEqual(error);
});
it('should return undefined when delete user zaphod did not fail', () => {
expect(getDeleteUserFailure({}, 'zaphod')).toBe(undefined);
it("should return undefined when delete user zaphod did not fail", () => {
expect(getDeleteUserFailure({}, "zaphod")).toBe(undefined);
});
});

View File

@@ -1,38 +1,38 @@
import { apiClient } from '@scm-manager/ui-components';
import { isPending } from '../../modules/pending';
import { getFailure } from '../../modules/failure';
import * as types from '../../modules/types';
import { combineReducers, Dispatch } from 'redux';
import { User, Action, PagedCollection } from '@scm-manager/ui-types';
import { apiClient } from "@scm-manager/ui-components";
import { isPending } from "../../modules/pending";
import { getFailure } from "../../modules/failure";
import * as types from "../../modules/types";
import { combineReducers, Dispatch } from "redux";
import { User, Action, PagedCollection } from "@scm-manager/ui-types";
export const FETCH_USERS = 'scm/users/FETCH_USERS';
export const FETCH_USERS = "scm/users/FETCH_USERS";
export const FETCH_USERS_PENDING = `${FETCH_USERS}_${types.PENDING_SUFFIX}`;
export const FETCH_USERS_SUCCESS = `${FETCH_USERS}_${types.SUCCESS_SUFFIX}`;
export const FETCH_USERS_FAILURE = `${FETCH_USERS}_${types.FAILURE_SUFFIX}`;
export const FETCH_USER = 'scm/users/FETCH_USER';
export const FETCH_USER = "scm/users/FETCH_USER";
export const FETCH_USER_PENDING = `${FETCH_USER}_${types.PENDING_SUFFIX}`;
export const FETCH_USER_SUCCESS = `${FETCH_USER}_${types.SUCCESS_SUFFIX}`;
export const FETCH_USER_FAILURE = `${FETCH_USER}_${types.FAILURE_SUFFIX}`;
export const CREATE_USER = 'scm/users/CREATE_USER';
export const CREATE_USER = "scm/users/CREATE_USER";
export const CREATE_USER_PENDING = `${CREATE_USER}_${types.PENDING_SUFFIX}`;
export const CREATE_USER_SUCCESS = `${CREATE_USER}_${types.SUCCESS_SUFFIX}`;
export const CREATE_USER_FAILURE = `${CREATE_USER}_${types.FAILURE_SUFFIX}`;
export const CREATE_USER_RESET = `${CREATE_USER}_${types.RESET_SUFFIX}`;
export const MODIFY_USER = 'scm/users/MODIFY_USER';
export const MODIFY_USER = "scm/users/MODIFY_USER";
export const MODIFY_USER_PENDING = `${MODIFY_USER}_${types.PENDING_SUFFIX}`;
export const MODIFY_USER_SUCCESS = `${MODIFY_USER}_${types.SUCCESS_SUFFIX}`;
export const MODIFY_USER_FAILURE = `${MODIFY_USER}_${types.FAILURE_SUFFIX}`;
export const MODIFY_USER_RESET = `${MODIFY_USER}_${types.RESET_SUFFIX}`;
export const DELETE_USER = 'scm/users/DELETE_USER';
export const DELETE_USER = "scm/users/DELETE_USER";
export const DELETE_USER_PENDING = `${DELETE_USER}_${types.PENDING_SUFFIX}`;
export const DELETE_USER_SUCCESS = `${DELETE_USER}_${types.SUCCESS_SUFFIX}`;
export const DELETE_USER_FAILURE = `${DELETE_USER}_${types.FAILURE_SUFFIX}`;
const CONTENT_TYPE_USER = 'application/vnd.scmm-user+json;v=2';
const CONTENT_TYPE_USER = "application/vnd.scmm-user+json;v=2";
// TODO i18n for error messages
@@ -46,7 +46,7 @@ export function fetchUsersByPage(link: string, page: number, filter?: string) {
// backend start counting by 0
if (filter) {
return fetchUsersByLink(
`${link}?page=${page - 1}&q=${decodeURIComponent(filter)}`,
`${link}?page=${page - 1}&q=${decodeURIComponent(filter)}`
);
}
return fetchUsersByLink(`${link}?page=${page - 1}`);
@@ -69,14 +69,14 @@ export function fetchUsersByLink(link: string) {
export function fetchUsersPending(): Action {
return {
type: FETCH_USERS_PENDING,
type: FETCH_USERS_PENDING
};
}
export function fetchUsersSuccess(users: any): Action {
return {
type: FETCH_USERS_SUCCESS,
payload: users,
payload: users
};
}
@@ -85,14 +85,14 @@ export function fetchUsersFailure(url: string, error: Error): Action {
type: FETCH_USERS_FAILURE,
payload: {
error,
url,
},
url
}
};
}
//fetch user
export function fetchUserByName(link: string, name: string) {
const userUrl = link.endsWith('/') ? link + name : link + '/' + name;
const userUrl = link.endsWith("/") ? link + name : link + "/" + name;
return fetchUser(userUrl, name);
}
@@ -121,7 +121,7 @@ export function fetchUserPending(name: string): Action {
return {
type: FETCH_USER_PENDING,
payload: name,
itemId: name,
itemId: name
};
}
@@ -129,7 +129,7 @@ export function fetchUserSuccess(user: any): Action {
return {
type: FETCH_USER_SUCCESS,
payload: user,
itemId: user.name,
itemId: user.name
};
}
@@ -138,9 +138,9 @@ export function fetchUserFailure(name: string, error: Error): Action {
type: FETCH_USER_FAILURE,
payload: {
name,
error,
error
},
itemId: name,
itemId: name
};
}
@@ -164,26 +164,26 @@ export function createUser(link: string, user: User, callback?: () => void) {
export function createUserPending(user: User): Action {
return {
type: CREATE_USER_PENDING,
user,
user
};
}
export function createUserSuccess(): Action {
return {
type: CREATE_USER_SUCCESS,
type: CREATE_USER_SUCCESS
};
}
export function createUserFailure(error: Error): Action {
return {
type: CREATE_USER_FAILURE,
payload: error,
payload: error
};
}
export function createUserReset() {
return {
type: CREATE_USER_RESET,
type: CREATE_USER_RESET
};
}
@@ -213,7 +213,7 @@ export function modifyUserPending(user: User): Action {
return {
type: MODIFY_USER_PENDING,
payload: user,
itemId: user.name,
itemId: user.name
};
}
@@ -221,7 +221,7 @@ export function modifyUserSuccess(user: User): Action {
return {
type: MODIFY_USER_SUCCESS,
payload: user,
itemId: user.name,
itemId: user.name
};
}
@@ -230,16 +230,16 @@ export function modifyUserFailure(user: User, error: Error): Action {
type: MODIFY_USER_FAILURE,
payload: {
error,
user,
user
},
itemId: user.name,
itemId: user.name
};
}
export function modifyUserReset(user: User): Action {
return {
type: MODIFY_USER_RESET,
itemId: user.name,
itemId: user.name
};
}
@@ -266,7 +266,7 @@ export function deleteUserPending(user: User): Action {
return {
type: DELETE_USER_PENDING,
payload: user,
itemId: user.name,
itemId: user.name
};
}
@@ -274,7 +274,7 @@ export function deleteUserSuccess(user: User): Action {
return {
type: DELETE_USER_SUCCESS,
payload: user,
itemId: user.name,
itemId: user.name
};
}
@@ -283,16 +283,16 @@ export function deleteUserFailure(user: User, error: Error): Action {
type: DELETE_USER_FAILURE,
payload: {
error,
user,
user
},
itemId: user.name,
itemId: user.name
};
}
function extractUsersByNames(
users: User[],
userNames: string[],
oldUsersByNames: object,
oldUsersByNames: object
) {
const usersByNames = {};
@@ -325,7 +325,7 @@ function deleteUserInEntries(users: [], userName: string) {
const reducerByName = (state: any, username: string, newUserState: any) => {
return {
...state,
[username]: newUserState,
[username]: newUserState
};
};
@@ -341,19 +341,19 @@ function listReducer(state: any = {}, action: any = {}) {
userCreatePermission: !!action.payload._links.create,
page: action.payload.page,
pageTotal: action.payload.pageTotal,
_links: action.payload._links,
},
_links: action.payload._links
}
};
// Delete single user actions
case DELETE_USER_SUCCESS:
const newUserEntries = deleteUserInEntries(
state.entries,
action.payload.name,
action.payload.name
);
return {
...state,
entries: newUserEntries,
entries: newUserEntries
};
default:
return state;
@@ -368,7 +368,7 @@ function byNamesReducer(state: any = {}, action: any = {}) {
const userNames = users.map(user => user.name);
const byNames = extractUsersByNames(users, userNames, state.byNames);
return {
...byNames,
...byNames
};
// Fetch single user actions
@@ -385,7 +385,7 @@ function byNamesReducer(state: any = {}, action: any = {}) {
export default combineReducers({
list: listReducer,
byNames: byNamesReducer,
byNames: byNamesReducer
});
// selectors