From 7b099578c880b29385b2709b92f00cc7c535d0e0 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Fri, 2 Nov 2018 17:47:59 -0400 Subject: [PATCH] update App.jsx and improve coverage abstract LogoutButton to component --- __tests__/App.test.jsx | 35 ++++++++++++++++++++++ __tests__/components/LogoutButton.test.jsx | 27 +++++++++++++++++ src/App.jsx | 13 ++------ src/components/LogoutButton.jsx | 26 ++++++++++++++++ 4 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 __tests__/components/LogoutButton.test.jsx create mode 100644 src/components/LogoutButton.jsx diff --git a/__tests__/App.test.jsx b/__tests__/App.test.jsx index e6c7057b88..0a9a9dd58b 100644 --- a/__tests__/App.test.jsx +++ b/__tests__/App.test.jsx @@ -5,6 +5,9 @@ import api from '../src/api'; import Dashboard from '../src/pages/Dashboard'; import Login from '../src/pages/Login'; +const DEFAULT_ACTIVE_GROUP = 'views_group'; +const DEFAULT_ACTIVE_ITEM = 'views_group_dashboard'; + describe('', () => { test('renders without crashing', () => { const appWrapper = shallow(); @@ -34,4 +37,36 @@ describe('', () => { const login = appWrapper.find(Login); expect(login.length).toBe(0); }); + + test('onNavSelect sets state.activeItem and state.activeGroup', () => { + const appWrapper = shallow(); + appWrapper.instance().onNavSelect({ itemId: 'foo', groupId: 'bar' }); + expect(appWrapper.state().activeItem).toBe('foo'); + expect(appWrapper.state().activeGroup).toBe('bar'); + }); + + test('onNavToggle sets state.isNavOpen to opposite', () => { + const appWrapper = shallow(); + expect(appWrapper.state().isNavOpen).toBe(true); + appWrapper.instance().onNavToggle(); + expect(appWrapper.state().isNavOpen).toBe(false); + }); + + test('onLogoClick sets selected nav back to defaults', () => { + const appWrapper = shallow(); + appWrapper.setState({ activeGroup: 'foo', activeItem: 'bar' }); + expect(appWrapper.state().activeItem).toBe('bar'); + expect(appWrapper.state().activeGroup).toBe('foo'); + appWrapper.instance().onLogoClick(); + expect(appWrapper.state().activeItem).toBe(DEFAULT_ACTIVE_ITEM); + expect(appWrapper.state().activeGroup).toBe(DEFAULT_ACTIVE_GROUP); + }); + + test('api.logout called from logout button', () => { + api.logout = jest.fn(); + const appWrapper = mount(); + const logoutButton = appWrapper.find('LogoutButton'); + logoutButton.props().onDevLogout(); + expect(api.logout).toHaveBeenCalledTimes(1); + }); }); diff --git a/__tests__/components/LogoutButton.test.jsx b/__tests__/components/LogoutButton.test.jsx new file mode 100644 index 0000000000..e185193321 --- /dev/null +++ b/__tests__/components/LogoutButton.test.jsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import LogoutButton from '../../src/components/LogoutButton'; + +let buttonWrapper; +let buttonElem; +let userIconElem; + +const findChildren = () => { + buttonElem = buttonWrapper.find('Button'); + userIconElem = buttonWrapper.find('UserIcon'); +}; + +describe('', () => { + test('initially renders without crashing', () => { + const onDevLogout = jest.fn(); + buttonWrapper = mount(); + findChildren(); + expect(buttonWrapper.length).toBe(1); + expect(buttonElem.length).toBe(1); + expect(userIconElem.length).toBe(1); + buttonElem.simulate('keyDown', { keyCode: 40, which: 40 }); + expect(onDevLogout).toHaveBeenCalledTimes(0); + buttonElem.simulate('keyDown', { keyCode: 13, which: 13 }); + expect(onDevLogout).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/App.jsx b/src/App.jsx index 1d9a3beae9..3852933e6e 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -8,8 +8,6 @@ import { import { BackgroundImage, BackgroundImageSrc, - Button, - ButtonVariant, Nav, NavExpandable, NavList, @@ -18,12 +16,12 @@ import { PageHeader, PageSidebar } from '@patternfly/react-core'; -import { UserIcon } from '@patternfly/react-icons'; import { global_breakpoint_md as breakpointMd } from '@patternfly/react-tokens'; import api from './api'; // import About from './components/About'; +import LogoutButton from './components/LogoutButton'; import TowerLogo from './components/TowerLogo'; import ConditionalRedirect from './components/ConditionalRedirect'; @@ -78,13 +76,6 @@ class App extends React.Component { this.setState({ activeGroup: 'views_group', activeItem: 'views_group_dashboard' }); } - onDevLogout = () => { - api.logout() - .then(() => { - this.setState({ activeGroup: 'views_group', activeItem: 'views_group_dashboard' }); - }); - } - render () { const { activeItem, activeGroup, isNavOpen } = this.state; const { logo, loginInfo } = this.props; @@ -112,7 +103,7 @@ class App extends React.Component { header={( } - avatar={} + avatar={} showNavToggle onNavToggle={this.onNavToggle} /> diff --git a/src/components/LogoutButton.jsx b/src/components/LogoutButton.jsx new file mode 100644 index 0000000000..71bdf020eb --- /dev/null +++ b/src/components/LogoutButton.jsx @@ -0,0 +1,26 @@ +import React from 'react'; + +import { + Button, + ButtonVariant +} from '@patternfly/react-core'; + +import { UserIcon } from '@patternfly/react-icons'; + +const LogoutButton = ({ onDevLogout }) => ( + +); + +export default LogoutButton;