diff --git a/__tests__/pages/Organizations/components/OrganizationForm.test.jsx b/__tests__/pages/Organizations/components/OrganizationForm.test.jsx
index e1a4e84048..640845ed20 100644
--- a/__tests__/pages/Organizations/components/OrganizationForm.test.jsx
+++ b/__tests__/pages/Organizations/components/OrganizationForm.test.jsx
@@ -8,11 +8,16 @@ jest.mock('../../../../src/api');
describe('', () => {
const network = {};
-
+ const meConfig = {
+ me: {
+ is_superuser: false
+ }
+ };
const mockData = {
id: 1,
name: 'Foo',
description: 'Bar',
+ max_hosts: 1,
custom_virtualenv: 'Fizz',
related: {
instance_groups: '/api/v2/organizations/1/instance_groups'
@@ -30,6 +35,7 @@ describe('', () => {
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
+ me={meConfig.me}
/>
), {
context: { network },
@@ -55,6 +61,7 @@ describe('', () => {
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
+ me={meConfig.me}
/>
), {
context: { network },
@@ -72,6 +79,7 @@ describe('', () => {
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
+ me={meConfig.me}
/>
);
@@ -98,6 +106,7 @@ describe('', () => {
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
+ me={meConfig.me}
/>
);
@@ -110,6 +119,10 @@ describe('', () => {
target: { value: 'new bar', name: 'description' }
});
expect(form.state('values').description).toEqual('new bar');
+ wrapper.find('input#org-max_hosts').simulate('change', {
+ target: { value: '134', name: 'max_hosts' }
+ });
+ expect(form.state('values').max_hosts).toEqual('134');
});
test('AnsibleSelect component renders if there are virtual environments', () => {
@@ -122,6 +135,7 @@ describe('', () => {
organization={mockData}
handleSubmit={jest.fn()}
handleCancel={jest.fn()}
+ me={meConfig.me}
/>
), {
context: { config },
@@ -138,6 +152,7 @@ describe('', () => {
organization={mockData}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
+ me={meConfig.me}
/>
);
expect(handleSubmit).not.toHaveBeenCalled();
@@ -146,6 +161,7 @@ describe('', () => {
expect(handleSubmit).toHaveBeenCalledWith({
name: 'Foo',
description: 'Bar',
+ max_hosts: 1,
custom_virtualenv: 'Fizz',
}, [], []);
});
@@ -163,6 +179,7 @@ describe('', () => {
const mockDataForm = {
name: 'Foo',
description: 'Bar',
+ max_hosts: 1,
custom_virtualenv: 'Fizz',
};
const handleSubmit = jest.fn();
@@ -175,14 +192,13 @@ describe('', () => {
organization={mockData}
handleSubmit={handleSubmit}
handleCancel={jest.fn()}
+ me={meConfig.me}
/>
), {
- context: { network },
+ context: { network }
}
);
-
await sleep(0);
-
wrapper.find('InstanceGroupsLookup').prop('onChange')([
{ name: 'One', id: 1 },
{ name: 'Three', id: 3 }
@@ -193,13 +209,95 @@ describe('', () => {
expect(handleSubmit).toHaveBeenCalledWith(mockDataForm, [3], [2]);
});
+ test('handleSubmit is called with max_hosts value if it is in range', async () => {
+ const handleSubmit = jest.fn();
+
+ // normal mount
+ const wrapper = mountWithContexts(
+
+ );
+ wrapper.find('button[aria-label="Save"]').simulate('click');
+ await sleep(0);
+ expect(handleSubmit).toHaveBeenCalledWith({
+ name: 'Foo',
+ description: 'Bar',
+ max_hosts: 1,
+ custom_virtualenv: 'Fizz',
+ }, [], []);
+ });
+
+ test('handleSubmit does not get called if max_hosts value is out of range', async () => {
+ const handleSubmit = jest.fn();
+
+ // not mount with Negative value
+ const mockDataNegative = JSON.parse(JSON.stringify(mockData));
+ mockDataNegative.max_hosts = -5;
+ const wrapper1 = mountWithContexts(
+
+ );
+ wrapper1.find('button[aria-label="Save"]').simulate('click');
+ await sleep(0);
+ expect(handleSubmit).not.toHaveBeenCalled();
+
+ // not mount with Out of Range value
+ const mockDataOoR = JSON.parse(JSON.stringify(mockData));
+ mockDataOoR.max_hosts = 999999999999;
+ const wrapper2 = mountWithContexts(
+
+ );
+ wrapper2.find('button[aria-label="Save"]').simulate('click');
+ await sleep(0);
+ expect(handleSubmit).not.toHaveBeenCalled();
+ });
+
+ test('handleSubmit is called and max_hosts value defaults to 0 if input is not a number', async () => {
+ const handleSubmit = jest.fn();
+
+ // mount with String value (default to zero)
+ const mockDataString = JSON.parse(JSON.stringify(mockData));
+ mockDataString.max_hosts = 'Bee';
+ const wrapper = mountWithContexts(
+
+ );
+ wrapper.find('button[aria-label="Save"]').simulate('click');
+ await sleep(0);
+ expect(handleSubmit).toHaveBeenCalledWith({
+ name: 'Foo',
+ description: 'Bar',
+ max_hosts: 0,
+ custom_virtualenv: 'Fizz',
+ }, [], []);
+ });
+
test('calls "handleCancel" when Cancel button is clicked', () => {
const handleCancel = jest.fn();
+
const wrapper = mountWithContexts(
);
expect(handleCancel).not.toHaveBeenCalled();
diff --git a/__tests__/pages/Organizations/screens/Organization/OrganizationDetail.test.jsx b/__tests__/pages/Organizations/screens/Organization/OrganizationDetail.test.jsx
index a4f70f11da..ca7676db42 100644
--- a/__tests__/pages/Organizations/screens/Organization/OrganizationDetail.test.jsx
+++ b/__tests__/pages/Organizations/screens/Organization/OrganizationDetail.test.jsx
@@ -10,6 +10,7 @@ describe('', () => {
name: 'Foo',
description: 'Bar',
custom_virtualenv: 'Fizz',
+ max_hosts: '0',
created: 'Bat',
modified: 'Boo',
summary_fields: {
@@ -71,11 +72,12 @@ describe('', () => {
);
const detailWrapper = wrapper.find('Detail');
- expect(detailWrapper.length).toBe(5);
+ expect(detailWrapper.length).toBe(6);
const nameDetail = detailWrapper.findWhere(node => node.props().label === 'Name');
const descriptionDetail = detailWrapper.findWhere(node => node.props().label === 'Description');
const custom_virtualenvDetail = detailWrapper.findWhere(node => node.props().label === 'Ansible Environment');
+ const max_hostsDetail = detailWrapper.findWhere(node => node.props().label === 'Max Hosts');
const createdDetail = detailWrapper.findWhere(node => node.props().label === 'Created');
const modifiedDetail = detailWrapper.findWhere(node => node.props().label === 'Last Modified');
expect(nameDetail.find('dt').text()).toBe('Name');
@@ -92,6 +94,9 @@ describe('', () => {
expect(modifiedDetail.find('dt').text()).toBe('Last Modified');
expect(modifiedDetail.find('dd').text()).toBe('Boo');
+
+ expect(max_hostsDetail.find('dt').text()).toBe('Max Hosts');
+ expect(max_hostsDetail.find('dd').text()).toBe('0');
});
test('should show edit button for users with edit permission', () => {
diff --git a/src/pages/Organizations/components/OrganizationForm.jsx b/src/pages/Organizations/components/OrganizationForm.jsx
index 1411bc2b4e..5e99e7d484 100644
--- a/src/pages/Organizations/components/OrganizationForm.jsx
+++ b/src/pages/Organizations/components/OrganizationForm.jsx
@@ -6,6 +6,7 @@ import { withRouter } from 'react-router-dom';
import { Formik, Field } from 'formik';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
+
import {
Tooltip,
Form,
@@ -19,7 +20,7 @@ import FormField from '../../../components/FormField';
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
import AnsibleSelect from '../../../components/AnsibleSelect';
import InstanceGroupsLookup from './InstanceGroupsLookup';
-
+import { OrganizationsAPI } from '../../../api';
import { required, minMaxValue } from '../../../util/validators';
class OrganizationForm extends Component {
@@ -28,9 +29,7 @@ class OrganizationForm extends Component {
this.getRelatedInstanceGroups = this.getRelatedInstanceGroups.bind(this);
this.handleInstanceGroupsChange = this.handleInstanceGroupsChange.bind(this);
- this.maxHostsChange = this.maxHostsChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
- this.readUsers = this.readUsers.bind(this);
this.state = {
instanceGroups: [],
@@ -64,14 +63,6 @@ class OrganizationForm extends Component {
return data.results;
}
- async readUsers (queryParams) {
- const { api } = this.props;
- console.log(api.readUsers((queryParams, is_superuser)));
- console.log(api.readUsers((queryParams)));
- return true;
- // return api.readUsers((queryParams));
- }
-
isEditingNewOrganization () {
const { organization } = this.props;
return !organization.id;
@@ -81,10 +72,6 @@ class OrganizationForm extends Component {
this.setState({ instanceGroups });
}
- maxHostsChange (event) {
- console.log('boop');
- }
-
handleSubmit (values) {
const { handleSubmit } = this.props;
const { instanceGroups, initialInstanceGroups } = this.state;
@@ -96,23 +83,25 @@ class OrganizationForm extends Component {
const groupsToDisassociate = [...initialIds]
.filter(x => !updatedIds.includes(x));
+ if (typeof values.max_hosts !== 'number' || values.max_hosts === 'undefined') {
+ values.max_hosts = 0;
+ }
+
handleSubmit(values, groupsToAssociate, groupsToDisassociate);
}
render () {
- const { organization, handleCancel, i18n, is_superuser } = this.props;
+ const { organization, handleCancel, i18n, me } = this.props;
const { instanceGroups, formIsValid, error } = this.state;
const defaultVenv = '/venv/ansible/';
- console.log(organization);
-
return (
(
@@ -136,25 +125,26 @@ class OrganizationForm extends Component {
id="org-max_hosts"
name="max_hosts"
type="number"
- label={
- {i18n._(t`Max Hosts`)}
+ label={
+ (
+
+ {i18n._(t`Max Hosts`)}
{' '}
{(
-
-
-
- )
- }
- }
+
+
+
+ )}
+
+ )
+ }
validate={minMaxValue(0, 2147483647, i18n)}
- onChange={(evt) => this.maxHostsChange(evt)}
- // isDisabled={!is_superuser + console.log(is_superuser)}
- // isDisabled={this.readUsers}
- isDisabled={this.readUsers? true: false}
- />
+ me={me || {}}
+ isDisabled={!me.is_superuser}
+ />
{({ custom_virtualenvs }) => (
custom_virtualenvs && custom_virtualenvs.length > 1 && (
@@ -197,20 +187,14 @@ class OrganizationForm extends Component {
}
FormField.propTypes = {
- //consider changing this in FormField.jsx, as many fields may need tooltips in the label
- label: PropTypes.oneOfType ([
- PropTypes.object,
- PropTypes.string
- ])
-}
-
-console.log()
+ label: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired
+};
OrganizationForm.propTypes = {
organization: PropTypes.shape(),
handleSubmit: PropTypes.func.isRequired,
handleCancel: PropTypes.func.isRequired,
- };
+};
OrganizationForm.defaultProps = {
organization: {
@@ -218,7 +202,7 @@ OrganizationForm.defaultProps = {
description: '',
max_hosts: '0',
custom_virtualenv: '',
- }
+ },
};
OrganizationForm.contextTypes = {
diff --git a/src/pages/Organizations/screens/Organization/OrganizationDetail.jsx b/src/pages/Organizations/screens/Organization/OrganizationDetail.jsx
index b7ec979a9a..6aafd74b45 100644
--- a/src/pages/Organizations/screens/Organization/OrganizationDetail.jsx
+++ b/src/pages/Organizations/screens/Organization/OrganizationDetail.jsx
@@ -78,7 +78,7 @@ class OrganizationDetail extends Component {
/>
-
+
+ {({ me }) => (
+
+ )}
+
{error ? error
: null}
);
diff --git a/src/pages/Organizations/screens/OrganizationAdd.jsx b/src/pages/Organizations/screens/OrganizationAdd.jsx
index 1b5fd2d355..d5a537a633 100644
--- a/src/pages/Organizations/screens/OrganizationAdd.jsx
+++ b/src/pages/Organizations/screens/OrganizationAdd.jsx
@@ -11,6 +11,7 @@ import {
Tooltip,
} from '@patternfly/react-core';
+import { Config } from '../../../contexts/Config';
import { withNetwork } from '../../../contexts/Network';
import CardCloseButton from '../../../components/CardCloseButton';
import OrganizationForm from '../components/OrganizationForm';
@@ -71,10 +72,15 @@ class OrganizationAdd extends React.Component {
-
+
+ {({ me }) => (
+
+ )}
+
{error ? error
: ''}
diff --git a/src/util/validators.jsx b/src/util/validators.jsx
index 5681242d7d..c3da8d4dbe 100644
--- a/src/util/validators.jsx
+++ b/src/util/validators.jsx
@@ -21,7 +21,7 @@ export function maxLength (max, i18n) {
export function minMaxValue (min, max, i18n) {
return value => {
- if (typeof value !== 'number' || value > max || value < min) {
+ if (value < min || value > max) {
return i18n._(t`This field must be a number and have a value between ${min} and ${max}`);
}
return undefined;