diff --git a/__tests__/pages/Organizations/components/OrganizationForm.test.jsx b/__tests__/pages/Organizations/components/OrganizationForm.test.jsx
new file mode 100644
index 0000000000..7c1d32dbc0
--- /dev/null
+++ b/__tests__/pages/Organizations/components/OrganizationForm.test.jsx
@@ -0,0 +1,240 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { MemoryRouter } from 'react-router-dom';
+import { I18nProvider } from '@lingui/react';
+import { ConfigContext } from '../../../../src/context';
+import OrganizationForm from '../../../../src/pages/Organizations/components/OrganizationForm';
+
+const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
+
+describe('', () => {
+ let api;
+
+ const mockData = {
+ id: 1,
+ name: 'Foo',
+ description: 'Bar',
+ custom_virtualenv: 'Fizz',
+ related: {
+ instance_groups: '/api/v2/organizations/1/instance_groups'
+ }
+ };
+
+ beforeEach(() => {
+ api = {
+ getInstanceGroups: jest.fn(),
+ };
+ });
+
+ test('should request related instance groups from api', () => {
+ const mockInstanceGroups = [
+ { name: 'One', id: 1 },
+ { name: 'Two', id: 2 }
+ ];
+ api.getOrganizationInstanceGroups = jest.fn(() => (
+ Promise.resolve({ data: { results: mockInstanceGroups } })
+ ));
+ mount(
+
+
+
+
+
+ ).find('OrganizationForm');
+
+ expect(api.getOrganizationInstanceGroups).toHaveBeenCalledTimes(1);
+ });
+
+ test('componentDidMount should set instanceGroups to state', async () => {
+ const mockInstanceGroups = [
+ { name: 'One', id: 1 },
+ { name: 'Two', id: 2 }
+ ];
+ api.getOrganizationInstanceGroups = jest.fn(() => (
+ Promise.resolve({ data: { results: mockInstanceGroups } })
+ ));
+ const wrapper = mount(
+
+
+
+
+
+ ).find('OrganizationForm');
+
+ await wrapper.instance().componentDidMount();
+ expect(wrapper.state().instanceGroups).toEqual(mockInstanceGroups);
+ });
+
+ test('changing instance group successfully sets instanceGroups state', () => {
+ const wrapper = mount(
+
+
+
+
+
+ ).find('OrganizationForm');
+
+ const lookup = wrapper.find('InstanceGroupsLookup');
+ expect(lookup.length).toBe(1);
+
+ lookup.prop('onChange')([
+ {
+ id: 1,
+ name: 'foo'
+ }
+ ], 'instanceGroups');
+ expect(wrapper.state().instanceGroups).toEqual([
+ {
+ id: 1,
+ name: 'foo'
+ }
+ ]);
+ });
+
+ test('changing inputs should update form values', () => {
+ const wrapper = mount(
+
+
+
+
+
+ ).find('OrganizationForm');
+
+ const form = wrapper.find('Formik');
+ wrapper.find('input#edit-org-form-name').simulate('change', {
+ target: { value: 'new foo', name: 'name' }
+ });
+ expect(form.state('values').name).toEqual('new foo');
+ wrapper.find('input#edit-org-form-description').simulate('change', {
+ target: { value: 'new bar', name: 'description' }
+ });
+ expect(form.state('values').description).toEqual('new bar');
+ });
+
+ test('AnsibleSelect component renders if there are virtual environments', () => {
+ const config = {
+ custom_virtualenvs: ['foo', 'bar'],
+ };
+ const wrapper = mount(
+
+
+
+
+
+
+
+ );
+ expect(wrapper.find('FormSelect')).toHaveLength(1);
+ expect(wrapper.find('FormSelectOption')).toHaveLength(2);
+ });
+
+ test('calls handleSubmit when form submitted', async () => {
+ const handleSubmit = jest.fn();
+ const wrapper = mount(
+
+
+
+
+
+ ).find('OrganizationForm');
+ expect(wrapper.prop('handleSubmit')).not.toHaveBeenCalled();
+ wrapper.find('button[aria-label="Save"]').simulate('click');
+ await sleep(1);
+ expect(handleSubmit).toHaveBeenCalledWith({
+ name: 'Foo',
+ description: 'Bar',
+ custom_virtualenv: 'Fizz',
+ }, [], []);
+ });
+
+ test('handleSubmit associates and disassociates instance groups', async () => {
+ const mockInstanceGroups = [
+ { name: 'One', id: 1 },
+ { name: 'Two', id: 2 }
+ ];
+ api.getOrganizationInstanceGroups = jest.fn(() => (
+ Promise.resolve({ data: { results: mockInstanceGroups } })
+ ));
+ const mockDataForm = {
+ name: 'Foo',
+ description: 'Bar',
+ custom_virtualenv: 'Fizz',
+ };
+ const handleSubmit = jest.fn();
+ api.updateOrganizationDetails = jest.fn().mockResolvedValue(1, mockDataForm);
+ api.associateInstanceGroup = jest.fn().mockResolvedValue('done');
+ api.disassociate = jest.fn().mockResolvedValue('done');
+ const wrapper = mount(
+
+
+
+
+
+ ).find('OrganizationForm');
+
+ await wrapper.instance().componentDidMount();
+
+ wrapper.find('InstanceGroupsLookup').prop('onChange')([
+ { name: 'One', id: 1 },
+ { name: 'Three', id: 3 }
+ ], 'instanceGroups');
+
+ wrapper.find('button[aria-label="Save"]').simulate('click');
+ await sleep(0);
+ expect(handleSubmit).toHaveBeenCalledWith(mockDataForm, [3], [2]);
+ });
+
+ test('calls "handleCancel" when Cancel button is clicked', () => {
+ const handleCancel = jest.fn();
+ const wrapper = mount(
+
+
+
+
+
+ );
+ expect(handleCancel).not.toHaveBeenCalled();
+ wrapper.find('button[aria-label="Cancel"]').prop('onClick')();
+ expect(handleCancel).toBeCalled();
+ });
+});
diff --git a/__tests__/pages/Organizations/screens/Organization/OrganizationEdit.test.jsx b/__tests__/pages/Organizations/screens/Organization/OrganizationEdit.test.jsx
index aed7c7687f..f67dc8780d 100644
--- a/__tests__/pages/Organizations/screens/Organization/OrganizationEdit.test.jsx
+++ b/__tests__/pages/Organizations/screens/Organization/OrganizationEdit.test.jsx
@@ -2,8 +2,9 @@ import React from 'react';
import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
-import { ConfigContext } from '../../../../../src/context';
-import OrganizationEdit from '../../../../../src/pages/Organizations/screens/Organization/OrganizationEdit';
+import OrganizationEdit, { OrganizationEditNoRouter } from '../../../../../src/pages/Organizations/screens/Organization/OrganizationEdit';
+
+const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
describe('', () => {
let api;
@@ -21,226 +22,90 @@ describe('', () => {
beforeEach(() => {
api = {
getInstanceGroups: jest.fn(),
+ updateOrganizationDetails: jest.fn(),
+ associateInstanceGroup: jest.fn(),
+ disassociate: jest.fn(),
};
});
- test('should request related instance groups from api', () => {
- const mockInstanceGroups = [
- { name: 'One', id: 1 },
- { name: 'Two', id: 2 }
- ];
- api.getOrganizationInstanceGroups = jest.fn(() => (
- Promise.resolve({ data: { results: mockInstanceGroups } })
- ));
- mount(
-
-
-
-
-
- ).find('OrganizationEdit');
-
- expect(api.getOrganizationInstanceGroups).toHaveBeenCalledTimes(1);
- });
-
- test('componentDidMount should set instanceGroups to state', async () => {
- const mockInstanceGroups = [
- { name: 'One', id: 1 },
- { name: 'Two', id: 2 }
- ];
- api.getOrganizationInstanceGroups = jest.fn(() => (
- Promise.resolve({ data: { results: mockInstanceGroups } })
- ));
- const wrapper = mount(
-
-
-
-
-
- ).find('OrganizationEdit');
-
- await wrapper.instance().componentDidMount();
- expect(wrapper.state().form.instanceGroups.value).toEqual(mockInstanceGroups);
- });
-
- test('changing instance group successfully sets instanceGroups state', () => {
+ test('handleSubmit should call api update', () => {
const wrapper = mount(
-
-
- ).find('OrganizationEdit');
-
- const lookup = wrapper.find('InstanceGroupsLookup');
- expect(lookup.length).toBe(1);
-
- lookup.prop('onChange')([
- {
- id: 1,
- name: 'foo'
- }
- ], 'instanceGroups');
- expect(wrapper.state().form.instanceGroups.value).toEqual([
- {
- id: 1,
- name: 'foo'
- }
- ]);
- });
-
- test('calls "handleFieldChange" when input values change', () => {
- const spy = jest.spyOn(OrganizationEdit.WrappedComponent.prototype, 'handleFieldChange');
- const wrapper = mount(
-
-
-
-
-
- ).find('OrganizationEdit');
-
- expect(spy).not.toHaveBeenCalled();
- wrapper.instance().handleFieldChange('foo', { target: { name: 'name' } });
- wrapper.instance().handleFieldChange('bar', { target: { name: 'description' } });
- expect(spy).toHaveBeenCalledTimes(2);
- });
-
- test('AnsibleSelect component renders if there are virtual environments', () => {
- const config = {
- custom_virtualenvs: ['foo', 'bar'],
- };
- const wrapper = mount(
-
-
-
-
-
-
-
- );
- expect(wrapper.find('FormSelect')).toHaveLength(1);
- expect(wrapper.find('FormSelectOption')).toHaveLength(2);
- });
-
- test('calls handleSubmit when Save button is clicked', () => {
- const spy = jest.spyOn(OrganizationEdit.WrappedComponent.prototype, 'handleSubmit');
- const wrapper = mount(
-
-
-
);
- expect(spy).not.toHaveBeenCalled();
- wrapper.find('button[aria-label="Save"]').prop('onClick')();
- expect(spy).toBeCalled();
+
+ const updatedOrgData = {
+ name: 'new name',
+ description: 'new description',
+ custom_virtualenv: 'Buzz',
+ };
+ wrapper.find('OrganizationForm').prop('handleSubmit')(updatedOrgData, [], []);
+
+ expect(api.updateOrganizationDetails).toHaveBeenCalledWith(
+ 1,
+ updatedOrgData
+ );
});
test('handleSubmit associates and disassociates instance groups', async () => {
- const mockInstanceGroups = [
- { name: 'One', id: 1 },
- { name: 'Two', id: 2 }
- ];
- api.getOrganizationInstanceGroups = jest.fn(() => (
- Promise.resolve({ data: { results: mockInstanceGroups } })
- ));
- const mockDataForm = {
- name: 'Foo',
- description: 'Bar',
- custom_virtualenv: 'Fizz',
- };
- api.updateOrganizationDetails = jest.fn().mockResolvedValue(1, mockDataForm);
- api.associateInstanceGroup = jest.fn().mockResolvedValue('done');
- api.disassociate = jest.fn().mockResolvedValue('done');
- const wrapper = mount(
-
-
-
-
-
- ).find('OrganizationEdit');
-
- await wrapper.instance().componentDidMount();
-
- wrapper.find('InstanceGroupsLookup').prop('onChange')([
- { name: 'One', id: 1 },
- { name: 'Three', id: 3 }
- ], 'instanceGroups');
-
- await wrapper.instance().handleSubmit();
- expect(api.updateOrganizationDetails).toHaveBeenCalledWith(1, mockDataForm);
- expect(api.associateInstanceGroup).toHaveBeenCalledWith('/api/v2/organizations/1/instance_groups', 3);
- expect(api.associateInstanceGroup).not.toHaveBeenCalledWith('/api/v2/organizations/1/instance_groups', 1);
- expect(api.associateInstanceGroup).not.toHaveBeenCalledWith('/api/v2/organizations/1/instance_groups', 2);
-
- expect(api.disassociate).toHaveBeenCalledWith('/api/v2/organizations/1/instance_groups', 2);
- expect(api.disassociate).not.toHaveBeenCalledWith('/api/v2/organizations/1/instance_groups', 1);
- expect(api.disassociate).not.toHaveBeenCalledWith('/api/v2/organizations/1/instance_groups', 3);
- });
-
- test('calls "handleCancel" when Cancel button is clicked', () => {
- const spy = jest.spyOn(OrganizationEdit.WrappedComponent.prototype, 'handleCancel');
const wrapper = mount(
);
- expect(spy).not.toHaveBeenCalled();
+
+ const updatedOrgData = {
+ name: 'new name',
+ description: 'new description',
+ custom_virtualenv: 'Buzz',
+ };
+ wrapper.find('OrganizationForm').prop('handleSubmit')(updatedOrgData, [3, 4], [2]);
+ await sleep(1);
+
+ expect(api.associateInstanceGroup).toHaveBeenCalledWith(
+ '/api/v2/organizations/1/instance_groups',
+ 3
+ );
+ expect(api.associateInstanceGroup).toHaveBeenCalledWith(
+ '/api/v2/organizations/1/instance_groups',
+ 4
+ );
+ expect(api.disassociate).toHaveBeenCalledWith(
+ '/api/v2/organizations/1/instance_groups',
+ 2
+ );
+ });
+
+ test('should navigate to organization detail when cancel is clicked', () => {
+ const history = {
+ push: jest.fn(),
+ };
+ const wrapper = mount(
+
+
+
+
+
+ );
+
+ expect(history.push).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Cancel"]').prop('onClick')();
- expect(spy).toBeCalled();
+
+ expect(history.push).toHaveBeenCalledWith('/organizations/1');
});
});
diff --git a/__tests__/pages/Organizations/screens/OrganizationAdd.test.jsx b/__tests__/pages/Organizations/screens/OrganizationAdd.test.jsx
index 954fa1f2fa..95eb5d631c 100644
--- a/__tests__/pages/Organizations/screens/OrganizationAdd.test.jsx
+++ b/__tests__/pages/Organizations/screens/OrganizationAdd.test.jsx
@@ -1,9 +1,11 @@
import React from 'react';
import { mount } from 'enzyme';
-import { MemoryRouter, Router } from 'react-router-dom';
+import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import { ConfigContext } from '../../../../src/context';
-import OrganizationAdd from '../../../../src/pages/Organizations/screens/OrganizationAdd';
+import OrganizationAdd, { OrganizationAddNoRouter } from '../../../../src/pages/Organizations/screens/OrganizationAdd';
+
+const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
describe('', () => {
let api;
@@ -11,184 +13,140 @@ describe('', () => {
beforeEach(() => {
api = {
getInstanceGroups: jest.fn(),
+ createOrganization: jest.fn(),
+ associateInstanceGroup: jest.fn(),
+ disassociate: jest.fn(),
};
});
- test('initially renders succesfully', () => {
- mount(
-
-
-
-
-
- );
- });
-
- test('calls "handleFieldChange" when input values change', () => {
- const spy = jest.spyOn(OrganizationAdd.WrappedComponent.prototype, 'handleFieldChange');
+ test('handleSubmit should post to api', () => {
const wrapper = mount(
);
- expect(spy).not.toHaveBeenCalled();
- wrapper.find('input#add-org-form-name').simulate('change', { target: { value: 'foo' } });
- wrapper.find('input#add-org-form-description').simulate('change', { target: { value: 'bar' } });
- expect(spy).toHaveBeenCalledTimes(2);
+
+ const updatedOrgData = {
+ name: 'new name',
+ description: 'new description',
+ custom_virtualenv: 'Buzz',
+ };
+ wrapper.find('OrganizationForm').prop('handleSubmit')(updatedOrgData, [], []);
+
+ expect(api.createOrganization).toHaveBeenCalledWith(updatedOrgData);
});
- test('calls "handleSubmit" when Save button is clicked', () => {
- const spy = jest.spyOn(OrganizationAdd.WrappedComponent.prototype, 'handleSubmit');
+ test('should navigate to organizations list when cancel is clicked', () => {
+ const history = {
+ push: jest.fn(),
+ };
const wrapper = mount(
-
);
- expect(spy).not.toHaveBeenCalled();
- wrapper.find('button[aria-label="Save"]').prop('onClick')();
- expect(spy).toBeCalled();
- });
- test('calls "handleCancel" when Cancel button is clicked', () => {
- const spy = jest.spyOn(OrganizationAdd.WrappedComponent.prototype, 'handleCancel');
- const wrapper = mount(
-
-
-
-
-
- );
- expect(spy).not.toHaveBeenCalled();
+ expect(history.push).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Cancel"]').prop('onClick')();
- expect(spy).toBeCalled();
+
+ expect(history.push).toHaveBeenCalledWith('/organizations');
});
- test('calls "handleCancel" when close button (x) is clicked', () => {
+ test('should navigate to organizations list when close (x) is clicked', () => {
+ const history = {
+ push: jest.fn(),
+ };
const wrapper = mount(
-
+
-
);
- const history = wrapper.find(Router).prop('history');
- expect(history.length).toBe(1);
- expect(history.location.pathname).toEqual('/organizations/add');
+
+ expect(history.push).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Close"]').prop('onClick')();
- expect(history.length).toBe(2);
- expect(history.location.pathname).toEqual('/organizations');
+
+ expect(history.push).toHaveBeenCalledWith('/organizations');
});
- test('Successful form submission triggers redirect', (done) => {
- const handleSuccess = jest.spyOn(OrganizationAdd.WrappedComponent.prototype, 'handleSuccess');
- const mockedResp = { data: { id: 1, related: { instance_groups: '/bar' } } };
- api.createOrganization = jest.fn().mockResolvedValue(mockedResp); api.associateInstanceGroup = jest.fn().mockResolvedValue('done');
+ test('successful form submission should trigger redirect', async () => {
+ const history = {
+ push: jest.fn(),
+ };
+ const orgData = {
+ name: 'new name',
+ description: 'new description',
+ custom_virtualenv: 'Buzz',
+ };
+ api.createOrganization.mockReturnValueOnce({
+ data: {
+ id: 5,
+ related: {
+ instance_groups: '/bar',
+ },
+ ...orgData,
+ }
+ });
const wrapper = mount(
-
+
);
- wrapper.find('input#add-org-form-name').simulate('change', { target: { value: 'foo' } });
- wrapper.find('button[aria-label="Save"]').prop('onClick')();
- setImmediate(() => {
- expect(handleSuccess).toHaveBeenCalled();
- done();
- });
+
+ wrapper.find('OrganizationForm').prop('handleSubmit')(orgData, [], []);
+ await sleep(0);
+
+ expect(history.push).toHaveBeenCalledWith('/organizations/5');
});
- test('changing instance groups successfully sets instanceGroups state', () => {
+ test('handleSubmit should post instance groups', async () => {
const wrapper = mount(
-
+
- ).find('OrganizationAdd');
+ );
- wrapper.find('InstanceGroupsLookup').prop('onChange')([
- {
- id: 1,
- name: 'foo'
- }
- ], 'instanceGroups');
- expect(wrapper.state('instanceGroups')).toEqual([
- {
- id: 1,
- name: 'foo'
- }
- ]);
- });
-
- test('handleFieldChange successfully sets custom_virtualenv state', () => {
- const wrapper = mount(
-
-
-
-
-
- ).find('OrganizationAdd');
- wrapper.instance().handleFieldChange('fooBar', { target: { name: 'custom_virtualenv' } });
- expect(wrapper.state('custom_virtualenv')).toBe('fooBar');
- });
-
- test('handleSubmit posts instance groups from selectedInstanceGroups', async () => {
- api.createOrganization = jest.fn().mockResolvedValue({
+ const orgData = {
+ name: 'new name',
+ description: 'new description',
+ custom_virtualenv: 'Buzz',
+ };
+ api.createOrganization.mockReturnValueOnce({
data: {
- id: 1,
- name: 'mock org',
+ id: 5,
related: {
- instance_groups: '/api/v2/organizations/1/instance_groups'
- }
+ instance_groups: '/api/v2/organizations/5/instance_groups',
+ },
+ ...orgData,
}
});
- api.associateInstanceGroup = jest.fn().mockResolvedValue('done');
- const wrapper = mount(
-
-
-
-
-
- ).find('OrganizationAdd');
- wrapper.setState({
- name: 'mock org',
- instanceGroups: [{
- id: 1,
- name: 'foo'
- }]
- });
- await wrapper.instance().handleSubmit();
- expect(api.createOrganization).toHaveBeenCalledWith({
- custom_virtualenv: '',
- description: '',
- name: 'mock org'
- });
- expect(api.associateInstanceGroup).toHaveBeenCalledWith('/api/v2/organizations/1/instance_groups', 1);
+ wrapper.find('OrganizationForm').prop('handleSubmit')(orgData, [3], []);
+ await sleep(0);
+
+ expect(api.associateInstanceGroup)
+ .toHaveBeenCalledWith('/api/v2/organizations/5/instance_groups', 3);
});
test('AnsibleSelect component renders if there are virtual environments', () => {
diff --git a/__tests__/util/validators.test.js b/__tests__/util/validators.test.js
new file mode 100644
index 0000000000..d197c61a21
--- /dev/null
+++ b/__tests__/util/validators.test.js
@@ -0,0 +1,34 @@
+import { required, maxLength } from '../../src/util/validators';
+
+describe('validators', () => {
+ test('required returns undefined if value given', () => {
+ expect(required()('some value')).toBeUndefined();
+ expect(required('oops')('some value')).toBeUndefined();
+ });
+
+ test('required returns default message if value missing', () => {
+ expect(required()('')).toEqual('This field must not be blank');
+ });
+
+ test('required returns custom message if value missing', () => {
+ expect(required('oops')('')).toEqual('oops');
+ });
+
+ test('required interprets white space as empty value', () => {
+ expect(required()(' ')).toEqual('This field must not be blank');
+ expect(required()('\t')).toEqual('This field must not be blank');
+ });
+
+ test('maxLength accepts value below max', () => {
+ expect(maxLength(10)('snazzy')).toBeUndefined();
+ });
+
+ test('maxLength accepts value equal to max', () => {
+ expect(maxLength(10)('abracadbra')).toBeUndefined();
+ });
+
+ test('maxLength rejects value above max', () => {
+ expect(maxLength(8)('abracadbra'))
+ .toEqual('This field must not exceed 8 characters');
+ });
+});
diff --git a/src/pages/Organizations/components/OrganizationForm.jsx b/src/pages/Organizations/components/OrganizationForm.jsx
index 5588f6c1cf..a197982e43 100644
--- a/src/pages/Organizations/components/OrganizationForm.jsx
+++ b/src/pages/Organizations/components/OrganizationForm.jsx
@@ -65,7 +65,7 @@ class OrganizationForm extends Component {
this.setState({ instanceGroups });
}
- async handleSubmit (values) {
+ handleSubmit (values) {
const { handleSubmit } = this.props;
const { instanceGroups, initialInstanceGroups } = this.state;
diff --git a/src/pages/Organizations/screens/Organization/OrganizationEdit.jsx b/src/pages/Organizations/screens/Organization/OrganizationEdit.jsx
index f4de4309d0..33eabfcb33 100644
--- a/src/pages/Organizations/screens/Organization/OrganizationEdit.jsx
+++ b/src/pages/Organizations/screens/Organization/OrganizationEdit.jsx
@@ -85,4 +85,5 @@ OrganizationEdit.contextTypes = {
custom_virtualenvs: PropTypes.arrayOf(PropTypes.string)
};
+export { OrganizationEdit as OrganizationEditNoRouter };
export default withRouter(OrganizationEdit);
diff --git a/src/pages/Organizations/screens/OrganizationAdd.jsx b/src/pages/Organizations/screens/OrganizationAdd.jsx
index ec69bbf9be..b750f028bc 100644
--- a/src/pages/Organizations/screens/OrganizationAdd.jsx
+++ b/src/pages/Organizations/screens/OrganizationAdd.jsx
@@ -19,8 +19,6 @@ class OrganizationAdd extends React.Component {
constructor (props) {
super(props);
- this.handleFieldChange = this.handleFieldChange.bind(this);
- this.handleInstanceGroupsChange = this.handleInstanceGroupsChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleCancel = this.handleCancel.bind(this);
this.handleSuccess = this.handleSuccess.bind(this);
@@ -30,14 +28,6 @@ class OrganizationAdd extends React.Component {
};
}
- handleFieldChange (val, evt) {
- this.setState({ [evt.target.name]: val || evt.target.value });
- }
-
- handleInstanceGroupsChange (val, targetName) {
- this.setState({ [targetName]: val });
- }
-
async handleSubmit (values, groupsToAssociate) {
const { api } = this.props;
try {
@@ -114,4 +104,5 @@ OrganizationAdd.contextTypes = {
custom_virtualenvs: PropTypes.arrayOf(PropTypes.string)
};
+export { OrganizationAdd as OrganizationAddNoRouter };
export default withRouter(OrganizationAdd);
diff --git a/src/util/validators.js b/src/util/validators.js
index 4e0f95e25b..939bb1bdec 100644
--- a/src/util/validators.js
+++ b/src/util/validators.js
@@ -11,7 +11,8 @@ export function required (message) {
export function maxLength (max) {
return value => {
- if (value.trim() > max) {
+ if (value.trim().length
+ > max) {
return i18nMark(`This field must not exceed ${max} characters`);
}
return undefined;