2018-10-25 04:16:24 +03:00
import React from 'react' ;
import { MemoryRouter } from 'react-router-dom' ;
2018-10-30 22:08:45 +03:00
import { mount , shallow } from 'enzyme' ;
2018-12-10 18:16:52 +03:00
import { I18nProvider } from '@lingui/react' ;
2018-11-02 20:44:13 +03:00
import { asyncFlush } from '../../jest.setup' ;
2018-11-30 00:50:17 +03:00
import AtLogin from '../../src/pages/Login' ;
2018-11-02 20:44:13 +03:00
import api from '../../src/api' ;
2018-10-30 22:08:45 +03:00
2018-11-30 00:50:17 +03:00
describe ( '<Login />' , ( ) => {
2018-10-30 22:08:45 +03:00
let loginWrapper ;
2018-11-30 00:50:17 +03:00
let atLogin ;
2018-10-30 22:08:45 +03:00
let loginPage ;
let loginForm ;
let usernameInput ;
let passwordInput ;
let submitButton ;
2018-11-30 00:50:17 +03:00
let loginHeaderLogo ;
2018-10-25 04:16:24 +03:00
2018-10-30 22:08:45 +03:00
const findChildren = ( ) => {
2018-11-30 00:50:17 +03:00
atLogin = loginWrapper . find ( 'AtLogin' ) ;
2018-10-30 22:08:45 +03:00
loginPage = loginWrapper . find ( 'LoginPage' ) ;
2018-11-30 00:50:17 +03:00
loginForm = loginWrapper . find ( 'LoginForm' ) ;
usernameInput = loginWrapper . find ( 'input#pf-login-username-id' ) ;
passwordInput = loginWrapper . find ( 'input#pf-login-password-id' ) ;
2018-10-25 04:16:24 +03:00
submitButton = loginWrapper . find ( 'Button[type="submit"]' ) ;
2018-11-30 00:50:17 +03:00
loginHeaderLogo = loginWrapper . find ( 'LoginHeaderBrand Brand' ) ;
2018-10-30 22:08:45 +03:00
} ;
beforeEach ( ( ) => {
2018-12-10 18:16:52 +03:00
loginWrapper = mount (
< MemoryRouter >
< I18nProvider >
< AtLogin / >
< / I18nProvider >
< / MemoryRouter >
) ;
2018-10-30 22:08:45 +03:00
findChildren ( ) ;
} ) ;
afterEach ( ( ) => {
loginWrapper . unmount ( ) ;
2018-10-25 04:16:24 +03:00
} ) ;
test ( 'initially renders without crashing' , ( ) => {
expect ( loginWrapper . length ) . toBe ( 1 ) ;
2018-11-30 00:50:17 +03:00
expect ( loginPage . length ) . toBe ( 1 ) ;
2018-10-30 22:08:45 +03:00
expect ( loginForm . length ) . toBe ( 1 ) ;
2018-10-25 04:16:24 +03:00
expect ( usernameInput . length ) . toBe ( 1 ) ;
2018-10-30 22:08:45 +03:00
expect ( usernameInput . props ( ) . value ) . toBe ( '' ) ;
2018-10-25 04:16:24 +03:00
expect ( passwordInput . length ) . toBe ( 1 ) ;
2018-10-30 22:08:45 +03:00
expect ( passwordInput . props ( ) . value ) . toBe ( '' ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . isValidPassword ) . toBe ( true ) ;
2018-10-25 04:16:24 +03:00
expect ( submitButton . length ) . toBe ( 1 ) ;
2018-10-30 22:08:45 +03:00
expect ( submitButton . props ( ) . isDisabled ) . toBe ( false ) ;
2018-11-30 00:50:17 +03:00
expect ( loginHeaderLogo . length ) . toBe ( 1 ) ;
} ) ;
test ( 'custom logo renders Brand component with correct src and alt' , ( ) => {
2018-12-10 18:16:52 +03:00
loginWrapper = mount (
< MemoryRouter >
< I18nProvider >
< AtLogin logo = "images/foo.jpg" alt = "Foo Application" / >
< / I18nProvider >
< / MemoryRouter >
) ;
2018-11-30 00:50:17 +03:00
findChildren ( ) ;
expect ( loginHeaderLogo . length ) . toBe ( 1 ) ;
expect ( loginHeaderLogo . props ( ) . src ) . toBe ( 'data:image/jpeg;images/foo.jpg' ) ;
expect ( loginHeaderLogo . props ( ) . alt ) . toBe ( 'Foo Application' ) ;
2018-10-30 22:08:45 +03:00
} ) ;
2018-11-30 00:50:17 +03:00
test ( 'default logo renders Brand component with correct src and alt' , ( ) => {
2018-12-10 18:16:52 +03:00
loginWrapper = mount (
< MemoryRouter >
< I18nProvider >
< AtLogin / >
< / I18nProvider >
< / MemoryRouter >
) ;
2018-10-30 22:08:45 +03:00
findChildren ( ) ;
2018-11-30 00:50:17 +03:00
expect ( loginHeaderLogo . length ) . toBe ( 1 ) ;
expect ( loginHeaderLogo . props ( ) . src ) . toBe ( 'tower-logo-header.svg' ) ;
expect ( loginHeaderLogo . props ( ) . alt ) . toBe ( 'Ansible Tower' ) ;
2018-10-30 22:08:45 +03:00
} ) ;
test ( 'state maps to un/pw input value props' , ( ) => {
2018-11-30 00:50:17 +03:00
atLogin . setState ( { username : 'un' , password : 'pw' } ) ;
expect ( atLogin . state ( ) . username ) . toBe ( 'un' ) ;
expect ( atLogin . state ( ) . password ) . toBe ( 'pw' ) ;
2018-10-30 22:08:45 +03:00
findChildren ( ) ;
expect ( usernameInput . props ( ) . value ) . toBe ( 'un' ) ;
expect ( passwordInput . props ( ) . value ) . toBe ( 'pw' ) ;
} ) ;
test ( 'updating un/pw clears out error' , ( ) => {
2018-11-30 00:50:17 +03:00
atLogin . setState ( { isValidPassword : 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 ( loginWrapper . find ( '.pf-c-form__helper-text.pf-m-error' ) . length ) . toBe ( 0 ) ;
atLogin . setState ( { isValidPassword : 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 ( loginWrapper . find ( '.pf-c-form__helper-text.pf-m-error' ) . length ) . toBe ( 0 ) ;
2018-10-25 04:16:24 +03:00
} ) ;
2018-10-31 19:04:59 +03:00
test ( 'api.login not called when loading' , ( ) => {
api . login = jest . fn ( ) . mockImplementation ( ( ) => Promise . resolve ( { } ) ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . loading ) . toBe ( false ) ;
atLogin . setState ( { loading : true } ) ;
submitButton . simulate ( 'click' ) ;
2018-10-30 22:08:45 +03:00
expect ( api . login ) . toHaveBeenCalledTimes ( 0 ) ;
2018-10-31 19:04:59 +03:00
} ) ;
test ( 'submit calls api.login successfully' , async ( ) => {
api . login = jest . fn ( ) . mockImplementation ( ( ) => Promise . resolve ( { } ) ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . loading ) . toBe ( false ) ;
atLogin . setState ( { username : 'unamee' , password : 'pwordd' } ) ;
submitButton . simulate ( 'click' ) ;
2018-10-30 22:08:45 +03:00
expect ( api . login ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( api . login ) . toHaveBeenCalledWith ( 'unamee' , 'pwordd' ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . loading ) . toBe ( true ) ;
2018-10-31 19:04:59 +03:00
await asyncFlush ( ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . loading ) . toBe ( false ) ;
2018-10-30 22:08:45 +03:00
} ) ;
2018-10-25 04:16:24 +03:00
2018-10-31 19:04:59 +03:00
test ( 'submit calls api.login handles 401 error' , async ( ) => {
2018-10-30 22:08:45 +03:00
api . login = jest . fn ( ) . mockImplementation ( ( ) => {
2018-10-31 19:04:59 +03:00
const err = new Error ( '401 error' ) ;
err . response = { status : 401 , message : 'problem' } ;
return Promise . reject ( err ) ;
2018-10-30 22:08:45 +03:00
} ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . loading ) . toBe ( false ) ;
expect ( atLogin . state ( ) . isValidPassword ) . toBe ( true ) ;
atLogin . setState ( { username : 'unamee' , password : 'pwordd' } ) ;
submitButton . simulate ( 'click' ) ;
2018-10-30 22:08:45 +03:00
expect ( api . login ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( api . login ) . toHaveBeenCalledWith ( 'unamee' , 'pwordd' ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . loading ) . toBe ( true ) ;
2018-10-31 19:04:59 +03:00
await asyncFlush ( ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . isValidPassword ) . toBe ( false ) ;
expect ( atLogin . state ( ) . loading ) . toBe ( false ) ;
2018-10-30 22:08:45 +03:00
} ) ;
2018-10-25 04:16:24 +03:00
2018-10-31 19:04:59 +03:00
test ( 'submit calls api.login handles non-401 error' , async ( ) => {
2018-10-30 22:08:45 +03:00
api . login = jest . fn ( ) . mockImplementation ( ( ) => {
2018-10-31 19:04:59 +03:00
const err = new Error ( '500 error' ) ;
err . response = { status : 500 , message : 'problem' } ;
return Promise . reject ( err ) ;
2018-10-30 22:08:45 +03:00
} ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . loading ) . toBe ( false ) ;
atLogin . setState ( { username : 'unamee' , password : 'pwordd' } ) ;
submitButton . simulate ( 'click' ) ;
2018-10-30 22:08:45 +03:00
expect ( api . login ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( api . login ) . toHaveBeenCalledWith ( 'unamee' , 'pwordd' ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . loading ) . toBe ( true ) ;
2018-10-31 19:04:59 +03:00
await asyncFlush ( ) ;
2018-11-30 00:50:17 +03:00
expect ( atLogin . state ( ) . loading ) . toBe ( false ) ;
2018-10-30 22:08:45 +03:00
} ) ;
test ( 'render Redirect to / when already authenticated' , ( ) => {
api . isAuthenticated = jest . fn ( ) ;
api . isAuthenticated . mockReturnValue ( true ) ;
2018-11-30 00:50:17 +03:00
loginWrapper = shallow ( < AtLogin / > ) ;
2018-10-30 22:08:45 +03:00
const redirectElem = loginWrapper . find ( 'Redirect' ) ;
expect ( redirectElem . length ) . toBe ( 1 ) ;
expect ( redirectElem . props ( ) . to ) . toBe ( '/' ) ;
} ) ;
} ) ;