mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-02-17 23:45:29 -05:00
refactor: header component test (#878)
* refactor: improves <Header /> component test cases * refactor: adds destructuring for state in render block
This commit is contained in:
parent
9c4931dc77
commit
dc9460ff07
5 changed files with 679 additions and 590 deletions
|
@ -14,7 +14,6 @@ import {HEADERS} from '../../../lib/constants';
|
||||||
import classes from './header.scss';
|
import classes from './header.scss';
|
||||||
import './logo.png';
|
import './logo.png';
|
||||||
|
|
||||||
|
|
||||||
export default class Header extends React.Component {
|
export default class Header extends React.Component {
|
||||||
state = {
|
state = {
|
||||||
showLogin: false,
|
showLogin: false,
|
||||||
|
@ -31,6 +30,7 @@ export default class Header extends React.Component {
|
||||||
this.handleSubmit = this.handleSubmit.bind(this);
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
this.handleInput = this.handleInput.bind(this);
|
this.handleInput = this.handleInput.bind(this);
|
||||||
this.loadLogo = this.loadLogo.bind(this);
|
this.loadLogo = this.loadLogo.bind(this);
|
||||||
|
this.renderUserActionButton = this.renderUserActionButton.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleLoginModal() {
|
toggleLoginModal() {
|
||||||
|
@ -63,11 +63,13 @@ export default class Header extends React.Component {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (this.state.username === '' || this.state.password === '') {
|
if (this.state.username === '' || this.state.password === '') {
|
||||||
return this.setState({loginError: {
|
return this.setState({
|
||||||
title: 'Unable to login',
|
loginError: {
|
||||||
type: 'error',
|
title: 'Unable to login',
|
||||||
description: 'Username or password can\'t be empty!'
|
type: 'error',
|
||||||
}});
|
description: 'Username or password can\'t be empty!'
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -119,8 +121,8 @@ export default class Header extends React.Component {
|
||||||
if (!payload.exp || !isNumber(payload.exp)) {
|
if (!payload.exp || !isNumber(payload.exp)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// Report as expire before (real expire time - 30s)
|
||||||
const jsTimestamp = (payload.exp * 1000) - 30000; // Report as expire before (real expire time - 30s)
|
const jsTimestamp = payload.exp * 1000 - 30000;
|
||||||
const expired = Date.now() >= jsTimestamp;
|
const expired = Date.now() >= jsTimestamp;
|
||||||
|
|
||||||
if (expired) {
|
if (expired) {
|
||||||
|
@ -136,35 +138,54 @@ export default class Header extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderUserActionButton() {
|
renderUserActionButton() {
|
||||||
if (!this.isTokenExpire) { // TODO: Check jwt token expire
|
if (!this.isTokenExpire) {
|
||||||
|
// TODO: Check jwt token expire
|
||||||
const username = capitalize(storage.getItem('username'));
|
const username = capitalize(storage.getItem('username'));
|
||||||
return (
|
return (
|
||||||
<div className="user-logged">
|
<div className="user-logged">
|
||||||
<span className="user-logged-greetings" style={{marginRight: '10px'}}>Hi, {username}</span>
|
<span
|
||||||
<Button className={`${classes.headerButton} header-button-logout`} type="danger" onClick={this.handleLogout}>Logout</Button>
|
className="user-logged-greetings"
|
||||||
|
style={{marginRight: '10px'}}
|
||||||
|
>
|
||||||
|
Hi, {username}
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
className={`${classes.headerButton} header-button-logout`}
|
||||||
|
type="danger"
|
||||||
|
onClick={this.handleLogout}
|
||||||
|
>
|
||||||
|
Logout
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return <Button className={`${classes.headerButton} header-button-login`} onClick={ this.toggleLoginModal }>Login</Button>;
|
return (
|
||||||
|
<Button
|
||||||
|
className={`${classes.headerButton} header-button-login`}
|
||||||
|
onClick={this.toggleLoginModal}
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const registryURL = getRegistryURL();
|
const registryURL = getRegistryURL();
|
||||||
|
const {logo, scope, loginError, showLogin} = this.state;
|
||||||
return (
|
return (
|
||||||
<header className={ classes.header }>
|
<header className={classes.header}>
|
||||||
<div className={ classes.headerWrap }>
|
<div className={classes.headerWrap}>
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<img src={ this.state.logo } className={ classes.logo } />
|
<img src={logo} className={classes.logo} />
|
||||||
</Link>
|
</Link>
|
||||||
<figure>
|
<figure>
|
||||||
npm set { this.state.scope }registry { registryURL }
|
npm set { scope }registry { registryURL }
|
||||||
<br/>
|
<br/>
|
||||||
npm adduser --registry { registryURL }
|
npm adduser --registry { registryURL }
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
<div className={ classes.headerRight }>
|
<div className={classes.headerRight}>
|
||||||
{this.renderUserActionButton()}
|
{this.renderUserActionButton()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -172,27 +193,47 @@ export default class Header extends React.Component {
|
||||||
<Dialog
|
<Dialog
|
||||||
title="Login"
|
title="Login"
|
||||||
size="tiny"
|
size="tiny"
|
||||||
visible={ this.state.showLogin }
|
visible={showLogin}
|
||||||
onCancel={ () => this.toggleLoginModal() }
|
onCancel={this.toggleLoginModal}
|
||||||
>
|
>
|
||||||
<Form className="login-form">
|
<Form className="login-form">
|
||||||
<Dialog.Body>
|
<Dialog.Body>
|
||||||
{ this.state.loginError &&
|
{loginError && (
|
||||||
<Alert
|
<Alert
|
||||||
title={this.state.loginError.title} type={this.state.loginError.type}
|
title={loginError.title}
|
||||||
description={this.state.loginError.description} showIcon={true} closable={false}>
|
type={loginError.type}
|
||||||
</Alert>
|
description={loginError.description}
|
||||||
}
|
showIcon={true}
|
||||||
<br/>
|
closable={false}
|
||||||
<Input name="username" placeholder="Username" onChange={this.handleInput.bind(this, 'username')} />
|
/>
|
||||||
<br/><br/>
|
)}
|
||||||
<Input name="password" type="password" placeholder="Type your password" onChange={this.handleInput.bind(this, 'password')} />
|
<br />
|
||||||
|
<Input
|
||||||
|
name="username"
|
||||||
|
placeholder="Username"
|
||||||
|
onChange={this.handleInput.bind(this, 'username')}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<Input
|
||||||
|
name="password"
|
||||||
|
type="password"
|
||||||
|
placeholder="Type your password"
|
||||||
|
onChange={this.handleInput.bind(this, 'password')}
|
||||||
|
/>
|
||||||
</Dialog.Body>
|
</Dialog.Body>
|
||||||
<Dialog.Footer className="dialog-footer">
|
<Dialog.Footer className="dialog-footer">
|
||||||
<Button onClick={ () => this.toggleLoginModal() } className="cancel-login-button">
|
<Button
|
||||||
|
onClick={this.toggleLoginModal}
|
||||||
|
className="cancel-login-button"
|
||||||
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button nativeType="submit" className="login-button" onClick={ this.handleSubmit }>
|
<Button
|
||||||
|
nativeType="submit"
|
||||||
|
className="login-button"
|
||||||
|
onClick={this.handleSubmit}
|
||||||
|
>
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
</Dialog.Footer>
|
</Dialog.Footer>
|
||||||
|
|
|
@ -8,4 +8,28 @@ import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
|
||||||
configure({ adapter: new Adapter() });
|
configure({ adapter: new Adapter() });
|
||||||
|
|
||||||
global.__APP_VERSION__ = '1.0.0';
|
global.__APP_VERSION__ = '1.0.0';
|
||||||
|
|
||||||
|
class LocalStorageMock {
|
||||||
|
constructor() {
|
||||||
|
this.store = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.store = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
getItem(key) {
|
||||||
|
return this.store[key] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setItem(key, value) {
|
||||||
|
this.store[key] = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItem(key) {
|
||||||
|
delete this.store[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global.localStorage = new LocalStorageMock();
|
|
@ -1,3 +1,48 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`<Header /> component shallow renderUserActionButton - should show login button 1`] = `
|
||||||
|
<Button
|
||||||
|
className="headerButton header-button-login"
|
||||||
|
disabled={false}
|
||||||
|
loading={false}
|
||||||
|
nativeType="button"
|
||||||
|
onClick={[Function]}
|
||||||
|
plain={false}
|
||||||
|
type="default"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<Header /> component shallow renderUserActionButton - should show users as loggedin 1`] = `
|
||||||
|
<div
|
||||||
|
className="user-logged"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="user-logged-greetings"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginRight": "10px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Hi,
|
||||||
|
Sam
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
className="headerButton header-button-logout"
|
||||||
|
disabled={false}
|
||||||
|
loading={false}
|
||||||
|
nativeType="button"
|
||||||
|
onClick={[Function]}
|
||||||
|
plain={false}
|
||||||
|
type="danger"
|
||||||
|
>
|
||||||
|
Logout
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<Header /> snapshot for loggedin user should match snapshot 1`] = `"<header class=\\"header\\"><div class=\\"headerWrap\\"><a href=\\"/\\"><img src=\\"\\" class=\\"logo\\"></a><figure>npm set registry http://localhost<br>npm adduser --registry http://localhost</figure><div class=\\"headerRight\\"><div class=\\"user-logged\\"><span class=\\"user-logged-greetings\\" style=\\"margin-right: 10px;\\">Hi, Verdaccio</span><button class=\\"el-button el-button--danger headerButton header-button-logout\\" type=\\"button\\"><span>Logout</span></button></div></div></div><div><div style=\\"z-index: 1013; display: none;\\" class=\\"el-dialog__wrapper\\"><div style=\\"top: 15%;\\" class=\\"el-dialog el-dialog--tiny\\"><div class=\\"el-dialog__header\\"><span class=\\"el-dialog__title\\">Login</span><button type=\\"button\\" class=\\"el-dialog__headerbtn\\"><i class=\\"el-dialog__close el-icon el-icon-close\\"></i></button></div><form class=\\"el-form el-form--label-right login-form\\"><div class=\\"el-dialog__body\\"><br><div class=\\"el-input\\"><input type=\\"text\\" name=\\"username\\" placeholder=\\"Username\\" class=\\"el-input__inner\\" autocomplete=\\"off\\"></div><br><br><div class=\\"el-input\\"><input type=\\"password\\" name=\\"password\\" placeholder=\\"Type your password\\" class=\\"el-input__inner\\" autocomplete=\\"off\\"></div></div><div class=\\"el-dialog__footer dialog-footer\\"><button class=\\"el-button el-button--default cancel-login-button\\" type=\\"button\\"><span>Cancel</span></button><button class=\\"el-button el-button--default login-button\\" type=\\"submit\\"><span>Login</span></button></div></form></div></div><div class=\\"v-modal\\" style=\\"z-index: 1012; display: none;\\"></div></div></header>"`;
|
||||||
|
|
||||||
exports[`<Header /> snapshot test shoud match snapshot 1`] = `"<header class=\\"header\\"><div class=\\"headerWrap\\"><a href=\\"/\\"><img src=\\"\\" class=\\"logo\\"></a><figure>npm set registry http://localhost<br>npm adduser --registry http://localhost</figure><div class=\\"headerRight\\"><button class=\\"el-button el-button--default headerButton header-button-login\\" type=\\"button\\"><span>Login</span></button></div></div><div><div style=\\"z-index: 1013; display: none;\\" class=\\"el-dialog__wrapper\\"><div style=\\"top: 15%;\\" class=\\"el-dialog el-dialog--tiny\\"><div class=\\"el-dialog__header\\"><span class=\\"el-dialog__title\\">Login</span><button type=\\"button\\" class=\\"el-dialog__headerbtn\\"><i class=\\"el-dialog__close el-icon el-icon-close\\"></i></button></div><form class=\\"el-form el-form--label-right login-form\\"><div class=\\"el-dialog__body\\"><br><div class=\\"el-input\\"><input type=\\"text\\" name=\\"username\\" placeholder=\\"Username\\" class=\\"el-input__inner\\" autocomplete=\\"off\\"></div><br><br><div class=\\"el-input\\"><input type=\\"password\\" name=\\"password\\" placeholder=\\"Type your password\\" class=\\"el-input__inner\\" autocomplete=\\"off\\"></div></div><div class=\\"el-dialog__footer dialog-footer\\"><button class=\\"el-button el-button--default cancel-login-button\\" type=\\"button\\"><span>Cancel</span></button><button class=\\"el-button el-button--default login-button\\" type=\\"submit\\"><span>Login</span></button></div></form></div></div><div class=\\"v-modal\\" style=\\"z-index: 1012; display: none;\\"></div></div></header>"`;
|
exports[`<Header /> snapshot test shoud match snapshot 1`] = `"<header class=\\"header\\"><div class=\\"headerWrap\\"><a href=\\"/\\"><img src=\\"\\" class=\\"logo\\"></a><figure>npm set registry http://localhost<br>npm adduser --registry http://localhost</figure><div class=\\"headerRight\\"><button class=\\"el-button el-button--default headerButton header-button-login\\" type=\\"button\\"><span>Login</span></button></div></div><div><div style=\\"z-index: 1013; display: none;\\" class=\\"el-dialog__wrapper\\"><div style=\\"top: 15%;\\" class=\\"el-dialog el-dialog--tiny\\"><div class=\\"el-dialog__header\\"><span class=\\"el-dialog__title\\">Login</span><button type=\\"button\\" class=\\"el-dialog__headerbtn\\"><i class=\\"el-dialog__close el-icon el-icon-close\\"></i></button></div><form class=\\"el-form el-form--label-right login-form\\"><div class=\\"el-dialog__body\\"><br><div class=\\"el-input\\"><input type=\\"text\\" name=\\"username\\" placeholder=\\"Username\\" class=\\"el-input__inner\\" autocomplete=\\"off\\"></div><br><br><div class=\\"el-input\\"><input type=\\"password\\" name=\\"password\\" placeholder=\\"Type your password\\" class=\\"el-input__inner\\" autocomplete=\\"off\\"></div></div><div class=\\"el-dialog__footer dialog-footer\\"><button class=\\"el-button el-button--default cancel-login-button\\" type=\\"button\\"><span>Cancel</span></button><button class=\\"el-button el-button--default login-button\\" type=\\"submit\\"><span>Login</span></button></div></form></div></div><div class=\\"v-modal\\" style=\\"z-index: 1012; display: none;\\"></div></div></header>"`;
|
||||||
|
|
|
@ -3,14 +3,51 @@
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow, mount } from 'enzyme';
|
import { shallow, mount } from 'enzyme';
|
||||||
|
import { Base64 } from 'js-base64';
|
||||||
|
import addHours from 'date-fns/add_hours'
|
||||||
import Header from '../../../../src/webui/components/Header';
|
import Header from '../../../../src/webui/components/Header';
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
import storage from '../../../../src/webui/utils/storage';
|
import storage from '../../../../src/webui/utils/storage';
|
||||||
|
|
||||||
|
jest.mock('../../../../src/webui/utils/storage', () => {
|
||||||
|
class LocalStorageMock {
|
||||||
|
constructor() {
|
||||||
|
this.store = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.store = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
getItem(key) {
|
||||||
|
return this.store[key] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setItem(key, value) {
|
||||||
|
this.store[key] = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItem(key) {
|
||||||
|
delete this.store[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new LocalStorageMock();
|
||||||
|
});
|
||||||
|
|
||||||
jest.mock('../../../../src/webui/utils/api', () => ({
|
jest.mock('../../../../src/webui/utils/api', () => ({
|
||||||
request: require('./__mocks__/api').default.request,
|
request: require('./__mocks__/api').default.request,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
console.error = jest.fn();
|
||||||
|
|
||||||
|
const generateTokenWithTimeRange = (limit = 0) => {
|
||||||
|
const payload = {
|
||||||
|
username: 'verdaccio',
|
||||||
|
exp: Number.parseInt((addHours(new Date(), limit).getTime() / 1000), 10)
|
||||||
|
}
|
||||||
|
return `xxxxxx.${Base64.encode(JSON.stringify(payload))}.xxxxxx`;
|
||||||
|
}
|
||||||
|
|
||||||
describe('<Header /> component shallow', () => {
|
describe('<Header /> component shallow', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
|
||||||
|
@ -35,7 +72,7 @@ describe('<Header /> component shallow', () => {
|
||||||
expect(HeaderWrapper.state()).toEqual(state);
|
expect(HeaderWrapper.state()).toEqual(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should load verdaccio logo', () => {
|
it('loadLogo - should load verdaccio logo', () => {
|
||||||
const HeaderWrapper = wrapper.find(Header).dive();
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
const { loadLogo } = HeaderWrapper.instance();
|
const { loadLogo } = HeaderWrapper.instance();
|
||||||
|
|
||||||
|
@ -45,15 +82,24 @@ describe('<Header /> component shallow', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should toggleLogin modal', () => {
|
it('toggleLoginModal - should toggle login modal', () => {
|
||||||
const HeaderWrapper = wrapper.find(Header).dive();
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
const { toggleLoginModal } = HeaderWrapper.instance();
|
const { toggleLoginModal } = HeaderWrapper.instance();
|
||||||
|
|
||||||
expect(toggleLoginModal()).toBeUndefined();
|
expect(toggleLoginModal()).toBeUndefined();
|
||||||
expect(HeaderWrapper.state('showLogin')).toBeTruthy();
|
expect(HeaderWrapper.state('showLogin')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handleInput set state', () => {
|
it('toggleLoginModal - click on login button and cancel button in login dialog', () => {
|
||||||
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
|
const spy = jest.spyOn(HeaderWrapper.instance(), 'toggleLoginModal');
|
||||||
|
HeaderWrapper.find('.header-button-login').simulate('click');
|
||||||
|
HeaderWrapper.find('.cancel-login-button').simulate('click');
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
|
spy.mockRestore();
|
||||||
|
})
|
||||||
|
|
||||||
|
it('handleInput - should set username and password in state', () => {
|
||||||
const HeaderWrapper = wrapper.find(Header).dive();
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
const handleInput = HeaderWrapper.instance().handleInput;
|
const handleInput = HeaderWrapper.instance().handleInput;
|
||||||
|
|
||||||
|
@ -127,8 +173,110 @@ describe('<Header /> component shallow', () => {
|
||||||
expect(HeaderWrapper.state('loginError')).toEqual(error);
|
expect(HeaderWrapper.state('loginError')).toEqual(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renderUserActionButton - should show login button', () => {
|
||||||
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
|
const { renderUserActionButton } = HeaderWrapper.instance();
|
||||||
|
expect(renderUserActionButton()).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renderUserActionButton - should show users as loggedin', () => {
|
||||||
|
class MockedHeader extends Header {
|
||||||
|
get isTokenExpire() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wrapper = shallow(
|
||||||
|
<BrowserRouter>
|
||||||
|
<MockedHeader />
|
||||||
|
</BrowserRouter>);
|
||||||
|
const HeaderWrapper = wrapper.find(MockedHeader).dive();
|
||||||
|
const { renderUserActionButton } = HeaderWrapper.instance();
|
||||||
|
expect(renderUserActionButton()).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isTokenExpire - token is not availabe in storage', () => {
|
||||||
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
|
const { isTokenExpire } = HeaderWrapper.instance();
|
||||||
|
expect(isTokenExpire).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isTokenExpire - token is not a valid payload', () => {
|
||||||
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
|
const { isTokenExpire } = HeaderWrapper.instance();
|
||||||
|
storage.setItem('token', 'not_a_valid_token');
|
||||||
|
expect(isTokenExpire).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isTokenExpire - token should not expire in 24 hrs range', () => {
|
||||||
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
|
storage.setItem('token', generateTokenWithTimeRange(24));
|
||||||
|
expect(HeaderWrapper.instance().isTokenExpire).toBeFalsy();
|
||||||
|
storage.removeItem('token');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isTokenExpire - token should expire for present', () => {
|
||||||
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
|
storage.setItem('token', generateTokenWithTimeRange());
|
||||||
|
expect(HeaderWrapper.instance().isTokenExpire).toBeTruthy();
|
||||||
|
storage.removeItem('token');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isTokenExpire - token expiration is not available', () => {
|
||||||
|
const generateTokenWithOutExpiration = () => {
|
||||||
|
const payload = {
|
||||||
|
username: 'verdaccio'
|
||||||
|
}
|
||||||
|
return `xxxxxx.${Base64.encode(JSON.stringify(payload))}.xxxxxx`;
|
||||||
|
}
|
||||||
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
|
storage.setItem('token', generateTokenWithOutExpiration());
|
||||||
|
expect(HeaderWrapper.instance().isTokenExpire).toBeTruthy();
|
||||||
|
storage.removeItem('token');
|
||||||
|
})
|
||||||
|
|
||||||
|
it('isTokenExpire - token expiration is not a number', () => {
|
||||||
|
const generateTokenWithExpirationAsString = () => {
|
||||||
|
const payload = {
|
||||||
|
username: 'verdaccio',
|
||||||
|
exp: 'I am not a number'
|
||||||
|
};
|
||||||
|
return `xxxxxx.${Base64.encode(JSON.stringify(payload))}.xxxxxx`;
|
||||||
|
};
|
||||||
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
|
storage.setItem('token', generateTokenWithExpirationAsString());
|
||||||
|
expect(HeaderWrapper.instance().isTokenExpire).toBeTruthy();
|
||||||
|
storage.removeItem('token');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isTokenExpire - token is not a valid json token', () => {
|
||||||
|
const generateTokenWithExpirationAsString = () => {
|
||||||
|
const payload = { username: 'verdaccio', exp: 'I am not a number' };
|
||||||
|
return `xxxxxx.${Base64.encode(payload)}.xxxxxx`;
|
||||||
|
};
|
||||||
|
const result = [
|
||||||
|
'Invalid token:',
|
||||||
|
SyntaxError('Unexpected token o in JSON at position 1'),
|
||||||
|
'xxxxxx.W29iamVjdCBPYmplY3Rd.xxxxxx'
|
||||||
|
]
|
||||||
|
storage.setItem('token', generateTokenWithExpirationAsString());
|
||||||
|
wrapper.find(Header).dive().isTokenExpire;
|
||||||
|
expect(console.error).toBeCalledWith(...result);
|
||||||
|
storage.removeItem('token');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handleLogout - should clear the local stoage', () => {
|
||||||
|
const storageSpy = jest.spyOn(storage, 'clear');
|
||||||
|
const locationSpy = jest.spyOn(window.location, 'reload');
|
||||||
|
const HeaderWrapper = wrapper.find(Header).dive();
|
||||||
|
const { handleLogout } = HeaderWrapper.instance();
|
||||||
|
handleLogout();
|
||||||
|
expect(storageSpy).toHaveBeenCalled();
|
||||||
|
expect(locationSpy).toHaveBeenCalled()
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('<Header /> snapshot test', () => {
|
describe('<Header /> snapshot test', () => {
|
||||||
it('shoud match snapshot', () => {
|
it('shoud match snapshot', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
|
@ -139,3 +287,20 @@ describe('<Header /> snapshot test', () => {
|
||||||
expect(wrapper.html()).toMatchSnapshot();
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('<Header /> snapshot for loggedin user', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
storage.setItem('token', generateTokenWithTimeRange(24));
|
||||||
|
storage.setItem('username', 'verdaccio');
|
||||||
|
})
|
||||||
|
afterAll(() => {
|
||||||
|
storage.removeItem('token');
|
||||||
|
})
|
||||||
|
it('should match snapshot', () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
<BrowserRouter>
|
||||||
|
<Header />
|
||||||
|
</BrowserRouter>);
|
||||||
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue