Open jahnaviv opened 4 years ago
auth0 component:
import React from 'react';
import Auth0Lock from 'auth0-lock';
import jwtDecode from 'jwt-decode';
import PropTypes from 'prop-types';
import { setUser } from 'Utils/googleAnalytics';
import Storage from 'Utils/storage';
import './Auth0.scss';
const propTypes = {
onLogout: PropTypes.oneOfType([
PropTypes.func,
PropTypes.oneOf([undefined]),
]),
children: PropTypes.oneOfType([
PropTypes.func,
PropTypes.string,
PropTypes.element,
PropTypes.arrayOf(PropTypes.element),
PropTypes.arrayOf(PropTypes.element),
PropTypes.oneOf([undefined, false, null]),
]),
};
const defaultProps = {
children: undefined,
onLogout: undefined,
};
class Auth0 extends React.Component {
constructor(props) {
super(props);
this.auth = new Auth0Lock(process.env.AUTH0_CLIENT_ID, process.env.AUTH0_DOMAIN, {
configurationBaseUrl: 'https://cdn.auth0.com',
auth: {
responseType: 'token id_token',
redirectUrl: `${window.location.href}`,
redirect: false,
audience: `${process.env.AUTH0_AUDIENCE}`,
params: {
scope: 'openid profile email roles read:brands read:users read:analytics',
},
},
theme: {
logo: 'https://s3.amazonaws.com/insights.clearstream.tv/assets/EMX+Logo+-+primary-red.png',
primaryColor: '#c72127',
},
languageDictionary: {
title: 'EMX Digital',
},
closable: false,
});
this.auth.on('authenticated', this.onAuthenticated);
this.auth.hasRoles = this.hasRoles;
this.auth.logout = this.logout;
this.auth.isAuthenticated = this.isAuthenticated;
this.state = { authenticated: false };
}
componentWillMount = () => {
this.setState({ authenticated: this.isAuthenticated() });
};
onAuthenticated = (authResult) => {
this.auth.hide();
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
Storage.set('access_token', authResult.accessToken);
Storage.set('id_token', authResult.idToken);
Storage.set('expires_at', expiresAt);
Storage.set('user_info', authResult.idTokenPayload.name);
setUser(authResult.idTokenPayload.name.replace('@', '.'));
this.auth.getUserInfo(authResult.accessToken, (error, profile) => {
if (error) return console.log(error);
Storage.set('profile', JSON.stringify(profile));
return this.setState({ authenticated: true });
});
};
isAuthenticated = () => {
let accessToken = Storage.get('access_token');
accessToken = accessToken ? jwtDecode(accessToken) : {};
let expiresAt = 0;
if (accessToken) {
expiresAt = accessToken.exp * 1000 || 0;
}
const now = new Date().getTime();
const diff = expiresAt - now;
if (diff > 0) {
if (this.timer) {
clearTimeout(this.timer);
this.timer = undefined;
}
this.timer = setTimeout(() => this.logout(), diff);
}
const authenticated = now < expiresAt;
if (authenticated) this.auth.hide();
else this.auth.show();
return authenticated;
};
hasRoles = (...args) => {
const roles = jwtDecode(Storage.get('access_token'))['http://emxanswers.com/roles'] || [];
for (let i = 0; i < roles.length; i += 1) {
if (args.indexOf(roles[i]) > -1) return true;
}
return false;
};
logout = () => {
const {
onLogout,
} = this.props;
// Clear Access Token and ID Token from local storage
Storage.remove('access_token');
Storage.remove('id_token');
Storage.remove('expires_at');
Storage.remove('user_info');
Storage.remove('profile');
this.setState({ authenticated: false });
this.auth.show();
return onLogout && onLogout();
};
render = () => {
const {
authenticated,
} = this.state;
const {
children,
} = this.props;
this.isAuthenticated();
return typeof children === 'function'
? children({ auth: this.auth, isAuthenticated: authenticated })
: children;
};
}
Auth0.propTypes = propTypes;
Auth0.defaultProps = defaultProps;
export default Auth0;
First, don't put functions in class fields.
Second, make propType warnings fail your tests by mocking console.error
/console.warn
.
Third, write as many tests as you can using shallow
, asserting on what's rendered based on what props are passed to Auth0
.
At that point, you should have very little uncovered; you can write a mount
test for that.
test('Should call hasRoles()', () => {
wrapper.instance().onAuthenticated(authResult);
wrapper.instance().hasRoles('RTA User');
});
For this test-case its gives me error Invalid token specifiedInvalidTokenError
and its pointed to import jwtDecode from 'jwt-decode';
line
no, not like that.
I'm suggesting starting by mocking nothing, and passing different props in, and shallow-rendering it, and asserting on what it renders.
You'll have to elaborate; what is Auth0? What is an Auth0 component?