diff --git a/__tests__/pages/Login.jsx b/__tests__/pages/Login.jsx
index 09eb67b8dc..49bcffce5c 100644
--- a/__tests__/pages/Login.jsx
+++ b/__tests__/pages/Login.jsx
@@ -3,12 +3,12 @@ import { MemoryRouter } from 'react-router-dom';
import { mount, shallow } from 'enzyme';
import { I18nProvider } from '@lingui/react';
import { asyncFlush } from '../../jest.setup';
-import AtLogin from '../../src/pages/Login';
+import AWXLogin from '../../src/pages/Login';
import APIClient from '../../src/api';
describe('', () => {
let loginWrapper;
- let atLogin;
+ let awxLogin;
let loginPage;
let loginForm;
let usernameInput;
@@ -19,7 +19,7 @@ describe('', () => {
const api = new APIClient({});
const findChildren = () => {
- atLogin = loginWrapper.find('AtLogin');
+ awxLogin = loginWrapper.find('AWXLogin');
loginPage = loginWrapper.find('LoginPage');
loginForm = loginWrapper.find('LoginForm');
usernameInput = loginWrapper.find('input#pf-login-username-id');
@@ -32,7 +32,7 @@ describe('', () => {
loginWrapper = mount(
-
+
);
@@ -51,7 +51,7 @@ describe('', () => {
expect(usernameInput.props().value).toBe('');
expect(passwordInput.length).toBe(1);
expect(passwordInput.props().value).toBe('');
- expect(atLogin.state().isValidPassword).toBe(true);
+ expect(awxLogin.state().isInputValid).toBe(true);
expect(submitButton.length).toBe(1);
expect(submitButton.props().isDisabled).toBe(false);
expect(loginHeaderLogo.length).toBe(1);
@@ -61,7 +61,7 @@ describe('', () => {
loginWrapper = mount(
-
+
);
@@ -75,7 +75,7 @@ describe('', () => {
loginWrapper = mount(
-
+
);
@@ -86,49 +86,49 @@ describe('', () => {
});
test('state maps to un/pw input value props', () => {
- atLogin.setState({ username: 'un', password: 'pw' });
- expect(atLogin.state().username).toBe('un');
- expect(atLogin.state().password).toBe('pw');
+ awxLogin.setState({ username: 'un', password: 'pw' });
+ expect(awxLogin.state().username).toBe('un');
+ expect(awxLogin.state().password).toBe('pw');
findChildren();
expect(usernameInput.props().value).toBe('un');
expect(passwordInput.props().value).toBe('pw');
});
test('updating un/pw clears out error', () => {
- atLogin.setState({ isValidPassword: false });
+ awxLogin.setState({ isInputValid: false });
expect(loginWrapper.find('.pf-c-form__helper-text.pf-m-error').length).toBe(1);
usernameInput.instance().value = 'uname';
usernameInput.simulate('change');
- expect(atLogin.state().username).toBe('uname');
- expect(atLogin.state().isValidPassword).toBe(true);
+ expect(awxLogin.state().username).toBe('uname');
+ expect(awxLogin.state().isInputValid).toBe(true);
expect(loginWrapper.find('.pf-c-form__helper-text.pf-m-error').length).toBe(0);
- atLogin.setState({ isValidPassword: false });
+ awxLogin.setState({ isInputValid: false });
expect(loginWrapper.find('.pf-c-form__helper-text.pf-m-error').length).toBe(1);
passwordInput.instance().value = 'pword';
passwordInput.simulate('change');
- expect(atLogin.state().password).toBe('pword');
- expect(atLogin.state().isValidPassword).toBe(true);
+ expect(awxLogin.state().password).toBe('pword');
+ expect(awxLogin.state().isInputValid).toBe(true);
expect(loginWrapper.find('.pf-c-form__helper-text.pf-m-error').length).toBe(0);
});
test('api.login not called when loading', () => {
api.login = jest.fn().mockImplementation(() => Promise.resolve({}));
- expect(atLogin.state().loading).toBe(false);
- atLogin.setState({ loading: true });
+ expect(awxLogin.state().isLoading).toBe(false);
+ awxLogin.setState({ isLoading: true });
submitButton.simulate('click');
expect(api.login).toHaveBeenCalledTimes(0);
});
test('submit calls api.login successfully', async () => {
api.login = jest.fn().mockImplementation(() => Promise.resolve({}));
- expect(atLogin.state().loading).toBe(false);
- atLogin.setState({ username: 'unamee', password: 'pwordd' });
+ expect(awxLogin.state().isLoading).toBe(false);
+ awxLogin.setState({ username: 'unamee', password: 'pwordd' });
submitButton.simulate('click');
expect(api.login).toHaveBeenCalledTimes(1);
expect(api.login).toHaveBeenCalledWith('unamee', 'pwordd');
- expect(atLogin.state().loading).toBe(true);
+ expect(awxLogin.state().isLoading).toBe(true);
await asyncFlush();
- expect(atLogin.state().loading).toBe(false);
+ expect(awxLogin.state().isLoading).toBe(false);
});
test('submit calls api.login handles 401 error', async () => {
@@ -137,16 +137,16 @@ describe('', () => {
err.response = { status: 401, message: 'problem' };
return Promise.reject(err);
});
- expect(atLogin.state().loading).toBe(false);
- expect(atLogin.state().isValidPassword).toBe(true);
- atLogin.setState({ username: 'unamee', password: 'pwordd' });
+ expect(awxLogin.state().isLoading).toBe(false);
+ expect(awxLogin.state().isInputValid).toBe(true);
+ awxLogin.setState({ username: 'unamee', password: 'pwordd' });
submitButton.simulate('click');
expect(api.login).toHaveBeenCalledTimes(1);
expect(api.login).toHaveBeenCalledWith('unamee', 'pwordd');
- expect(atLogin.state().loading).toBe(true);
+ expect(awxLogin.state().isLoading).toBe(true);
await asyncFlush();
- expect(atLogin.state().isValidPassword).toBe(false);
- expect(atLogin.state().loading).toBe(false);
+ expect(awxLogin.state().isInputValid).toBe(false);
+ expect(awxLogin.state().isLoading).toBe(false);
});
test('submit calls api.login handles non-401 error', async () => {
@@ -155,20 +155,20 @@ describe('', () => {
err.response = { status: 500, message: 'problem' };
return Promise.reject(err);
});
- expect(atLogin.state().loading).toBe(false);
- atLogin.setState({ username: 'unamee', password: 'pwordd' });
+ expect(awxLogin.state().isLoading).toBe(false);
+ awxLogin.setState({ username: 'unamee', password: 'pwordd' });
submitButton.simulate('click');
expect(api.login).toHaveBeenCalledTimes(1);
expect(api.login).toHaveBeenCalledWith('unamee', 'pwordd');
- expect(atLogin.state().loading).toBe(true);
+ expect(awxLogin.state().isLoading).toBe(true);
await asyncFlush();
- expect(atLogin.state().loading).toBe(false);
+ expect(awxLogin.state().isLoading).toBe(false);
});
test('render Redirect to / when already authenticated', () => {
api.isAuthenticated = jest.fn();
api.isAuthenticated.mockReturnValue(true);
- loginWrapper = shallow();
+ loginWrapper = shallow();
const redirectElem = loginWrapper.find('Redirect');
expect(redirectElem.length).toBe(1);
expect(redirectElem.props().to).toBe('/');
diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx
index 207aa1491d..a2353542a9 100644
--- a/src/pages/Login.jsx
+++ b/src/pages/Login.jsx
@@ -9,52 +9,56 @@ import {
import towerLogo from '../../images/tower-logo-header.svg';
-class AtLogin extends Component {
+class AWXLogin extends Component {
constructor (props) {
super(props);
this.state = {
username: '',
password: '',
- isValidPassword: true,
- loading: false
+ isInputValid: true,
+ isLoading: false
};
+
+ this.onChangeUsername = this.onChangeUsername.bind(this);
+ this.onChangePassword = this.onChangePassword.bind(this);
+ this.onLoginButtonClick = this.onLoginButtonClick.bind(this);
}
- componentWillUnmount () {
- this.unmounting = true; // todo: state management
+ onChangeUsername (value) {
+ this.setState({ username: value, isInputValid: true });
}
- safeSetState = obj => !this.unmounting && this.setState(obj);
+ onChangePassword (value) {
+ this.setState({ password: value, isInputValid: true });
+ }
- handleUsernameChange = value => this.safeSetState({ username: value, isValidPassword: true });
-
- handlePasswordChange = value => this.safeSetState({ password: value, isValidPassword: true });
-
- handleSubmit = async event => {
- const { username, password, loading } = this.state;
+ async onLoginButtonClick (event) {
+ const { username, password, isLoading } = this.state;
const { api } = this.props;
event.preventDefault();
- if (!loading) {
- this.safeSetState({ loading: true });
+ if (isLoading) {
+ return;
+ }
- try {
- await api.login(username, password);
- } catch (error) {
- if (error.response.status === 401) {
- this.safeSetState({ isValidPassword: false });
- }
- } finally {
- this.safeSetState({ loading: false });
+ this.setState({ isLoading: true });
+
+ try {
+ await api.login(username, password);
+ } catch (error) {
+ if (error.response.status === 401) {
+ this.setState({ isInputValid: false });
}
+ } finally {
+ this.setState({ isLoading: false });
}
}
render () {
- const { username, password, isValidPassword } = this.state;
- const { api, alt, logo } = this.props;
+ const { username, password, isInputValid } = this.state;
+ const { api, alt, loginInfo, logo } = this.props;
const logoSrc = logo ? `data:image/jpeg;${logo}` : towerLogo;
if (api.isAuthenticated()) {
@@ -68,17 +72,18 @@ class AtLogin extends Component {
brandImgSrc={logoSrc}
brandImgAlt={alt || 'Ansible Tower'}
loginTitle={i18n._(t`Welcome to Ansible Tower! Please Sign In.`)}
+ textContent={loginInfo}
>
)}
@@ -87,4 +92,4 @@ class AtLogin extends Component {
}
}
-export default AtLogin;
+export default AWXLogin;