Skip to content

Commit

Permalink
Merge 2b405ac into b9401f5
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelbwambale committed Nov 23, 2018
2 parents b9401f5 + 2b405ac commit cd6b984
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 42 deletions.
6 changes: 6 additions & 0 deletions src/actions/userActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,9 @@ export const resetPassword = (passwordDetails) => dispatch => {
return toast.error('Connection Error', { autoClose: 3500, hideProgressBar: true });
});
};

export const logOut = () => dispatch => {
localStorage.removeItem('auth_token');
localStorage.removeItem('username');
dispatch({ type: LOGOUT_USER, payload: false });
};
63 changes: 43 additions & 20 deletions src/components/landingPage/LandingPage.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,49 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Articles from '../Articles/Articles';
import Dashboard from '../dashboard/Dashboard';

const LandingPage = () => (
<React.Fragment>
<div className="first-section">
<div className="container">
<div className="row">
<div className="col-12 jumbotron mx-auto lp-intro lp-text">
<p>Authors Haven is the one stop hub for knowledge.</p>
<p>Come take a look at thousands of articles.</p>
<p>You can even share your own!!!</p>
<a href="#start" className="btn ah-btn">
Join us and share your ideas
</a>
export const LandingPage = ({ isLoggedIn }) =>
(
<div>
{!isLoggedIn
? (<React.Fragment>
<div className="first-section">
<div className="container">
<div className="row">
<div className="col-12 jumbotron mx-auto lp-intro lp-text">
<p>Authors Haven is the one stop hub for knowledge.</p>
<p>Come take a look at thousands of articles.</p>
<p>You can even share your own!!!</p>
<a href="#start" className="btn ah-btn">
Join us and share your ideas
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="container-fluid article-list">
<Articles />
<div className="container-fluid article-list">
<Articles />
</div>
</React.Fragment>
) : (
<Dashboard />
)
}
</div>
</React.Fragment>
);
);

LandingPage.propTypes = {
isLoggedIn: PropTypes.bool,
};

LandingPage.defaultProps = {
isLoggedIn: false,
};

const mapStateToProps = state => ({
isLoggedIn: state.user.isLoggedIn,
});

export default LandingPage;
export default connect(mapStateToProps)(LandingPage);
10 changes: 5 additions & 5 deletions src/components/landingPage/Navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ export class Navbar extends Component {
<i className="fas fa-user" />
</a>
<div className="dropdown-menu" aria-labelledby="navbarDropdown">
<NavLink className="dropdown-item" to="/create-article/">New Article</NavLink>
<NavLink className="dropdown-item" to={`/profiles/${username}`}>Profile</NavLink>
<NavLink className="dropdown-item" exact to="/create-article/">New Article</NavLink>
<NavLink className="dropdown-item" exact to={`/profiles/${username}`}>Profile</NavLink>
<div className="dropdown-divider" />
<NavLink className="dropdown-item" to="#">Logout</NavLink>
<NavLink className="dropdown-item" to="/logout">Logout</NavLink>
</div>
</div>
</li>
Expand All @@ -71,12 +71,12 @@ export class Navbar extends Component {
: (
<React.Fragment>
<li className="nav-item active">
<NavLink className="btn ah-btn ah-btn-nav js-scroll-trigger nav-link nav-text" to="signup">
<NavLink className="btn ah-btn ah-btn-nav js-scroll-trigger nav-link nav-text" exact to="signup">
Signup
</NavLink>
</li>
<li className="nav-item">
<NavLink className="btn ah-btn ah-btn-nav js-scroll-trigger nav-link nav-text" to="login">Login</NavLink>
<NavLink className="btn ah-btn ah-btn-nav js-scroll-trigger nav-link nav-text" exact to="login">Login</NavLink>
</li>
</React.Fragment>
)
Expand Down
2 changes: 1 addition & 1 deletion src/components/login/FacebookButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class FacebookButton extends PureComponent {
render() {
const value = this.state;
if (value.redirect) {
const to = { pathname: '/' };
const to = { pathname: '/dashboard' };
return (
<Redirect to={to} />
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/login/GoogleButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class GoogleloginButton extends PureComponent {
render() {
const value = this.state;
if (value.redirect) {
const to = { pathname: '/' };
const to = { pathname: '/dashboard' };
return (
<Redirect to={to} />
);
Expand All @@ -50,7 +50,7 @@ class GoogleloginButton extends PureComponent {
<div>
<GoogleLogin
clientId="1040550554735-0lfo665jrpgkprjkqdvh9njlc46mu6rg.apps.googleusercontent.com"
redirectUri="/"
redirectUri="/dashboard"
onSuccess={this.handleGoogleResponse}
onFailure={this.handleGoogleResponse}
className="google"
Expand Down
17 changes: 14 additions & 3 deletions src/components/login/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,24 @@ export class Login extends Component {
};
}

componentDidMount() {
const { isLoggedIn } = this.props;
if (isLoggedIn === true) {
this.redirectHome();
}
}

componentWillReceiveProps(nextProps) {
if (nextProps.isLoggedIn === true) {
const { history } = this.props;
history.push('/dashboard');
this.redirectHome();
}
}

redirectHome = () => {
const { history } = this.props;
history.push('/dashboard');
};

handleInput = event => {
const { name } = event.target;
const { value } = event.target;
Expand Down Expand Up @@ -95,7 +106,7 @@ export class Login extends Component {
Login
</button>
<div className="form-group">
<Link className="forgot-password" to="/forgot-Password">Forgot password?</Link>
<Link className="forgot-password" exact to="/forgotPassword">Forgot password?</Link>
</div>
<div className="row">
<div className="col-md-6">
Expand Down
37 changes: 37 additions & 0 deletions src/components/login/Logout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import '../../assets/App.css';
import { logOut } from '../../actions/userActions';

export class Logout extends Component {
componentWillMount() {
const { isLoggedIn } = this.props;
if (isLoggedIn === true) {
const { logOut } = this.props;
logOut();
const { history } = this.props;
history.push('/login');
}
}

render() {
return null;
}
}

Logout.propTypes = {
logOut: PropTypes.func.isRequired,
history: PropTypes.object.isRequired,
isLoggedIn: PropTypes.bool,
};

Logout.defaultProps = {
isLoggedIn: false,
};

const mapStateToProps = state => ({
isLoggedIn: state.user.isLoggedIn,
});

export default connect(mapStateToProps, { logOut })(Logout);
28 changes: 28 additions & 0 deletions src/components/routes/PrivateRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Redirect, Route } from 'react-router-dom';
import React from 'react';
import decode from 'jwt-decode';

export const PrivateRoute = ({ component: Component, ...props }) => {
const authenticate = token => {
if (token) {
const decoded_token = decode(token);
if (decoded_token.exp > (Date.now()) / 1000) {
return { decoded_token };
}
}
return false;
};

const authenticated = authenticate(localStorage.getItem('auth_token'));

return (
<Route
{...props}
render={props =>
(authenticated ? <Component {...props} /> : <Redirect to="/login" />)
}
/>
);
};

export default PrivateRoute;
15 changes: 9 additions & 6 deletions src/components/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { Route, Switch } from 'react-router-dom';
import LandingPage from '../landingPage/LandingPage';
import Login from '../login/Login';
import Logout from '../login/Logout';
import NotFound from '../notFound/NotFound';
import RegisterUser from '../register/RegisterUser';
import Dashboard from '../dashboard/Dashboard';
Expand All @@ -11,20 +12,22 @@ import Comments from '../comments/Comments';
import EditArticle from '../Articles/EditArticle';
import ResetPassword from '../resetPassword/ResetPasswordPage';
import ForgotPassword from '../resetPassword/ForgotPasswordPage';
import { PrivateRoute } from './PrivateRoute';

const Routes = () => (
<Switch>
<Route exact path="/" component={LandingPage} />
<Route exact path="/login" component={Login} />
<Route exact path="/logout" component={Logout} />
<Route exact path="/signup" component={RegisterUser} />
<Route exact path="/dashboard" component={Dashboard} />
<Route exact path="/forgot-password" component={ForgotPassword} />
<Route exact path="/reset-password/:token" component={ResetPassword} />
<Route exact path="/profiles/:username" component={Profile} />
<Route exact path="/create-article" component={CreateArticle} />
<Route exact path="/articles/:article/comments/" component={Comments} />
<Route exact path="/article/:slug" component={EditArticle} />
<Route exact component={NotFound} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute exact path="/profiles/:username" component={Profile} />
<PrivateRoute exact path="/create-article" component={CreateArticle} />
<PrivateRoute exact path="/articles/:article/comments/" component={Comments} />
<PrivateRoute exact path="/article/:slug" component={EditArticle} />
<Route component={NotFound} />
</Switch>
);

Expand Down
18 changes: 18 additions & 0 deletions src/tests/actions/userActions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
facebookLoginUser,
getProfile,
updateLoginStatus,
logOut,
} from '../../actions/userActions';
import {
REGISTER_USER_SUCCESS,
Expand All @@ -19,6 +20,7 @@ import {
SOCIAL_LOGIN_SUCCESS,
GET_PROFILE_PAYLOAD,
GET_PROFILE_INITIATED,
LOGOUT_USER,
} from '../../actions/types';
import axiosInstance from '../../config/axiosInstance';

Expand Down Expand Up @@ -255,4 +257,20 @@ describe('userAction', () => {
],
);
});

it('should logout user when he/she clicks on LogOut menu', () => {
localStorage.setItem('auth_token', 'token');
store.dispatch(logOut());
expect(store.getActions()).toEqual(
[
{ type: LOGOUT_USER, payload: false },
],
);
});

it('should remove the auth_token when a user clicks on LogOut NavLink', () => {
localStorage.setItem('auth_token', 'token');
store.dispatch(logOut());
expect(!(localStorage.getItem('auth_token')));
});
});
2 changes: 1 addition & 1 deletion src/tests/components/Landingpage.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { shallow } from 'enzyme';
import React from 'react';
import configureMockStore from 'redux-mock-store';
import LandingPage from '../../components/landingPage/LandingPage';
import { LandingPage } from '../../components/landingPage/LandingPage';
import { Navbar } from '../../components/landingPage/Navbar';

it('renders the LandingPage component correctly', () => {
Expand Down
16 changes: 12 additions & 4 deletions src/tests/components/Login.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ describe('Login component', () => {
history: { push: jest.fn() },
signIn: jest.fn(),
};

const redirectHome = jest.fn();

beforeEach(() => {
mockStore({});
wrapper = shallow(<Login {...props} />);
wrapper = shallow(<Login
redirectHome={redirectHome}
componentDidMount={jest.fn()}
{...props}
/>);
});


it('should render correctly', () => {
expect(wrapper).toMatchSnapshot();
});
Expand All @@ -45,7 +48,12 @@ describe('Login component', () => {
expect(props.history.push).toBeCalledTimes(0);
});

it('should redirect on successful login', () => {
it('should redirect if isLoggedIn is true', () => {
wrapper.setProps({ isLoggedIn: true });
expect(props.history.push).toBeCalledTimes(1);
});

it('should redirect to dashboard on successful login', () => {
wrapper.setProps({ ...nextProps });
expect(props.history.push).toBeCalledWith('/dashboard');
});
Expand Down
30 changes: 30 additions & 0 deletions src/tests/components/Logout.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { shallow } from 'enzyme';
import configureMockStore from 'redux-mock-store';
import { Logout } from '../../components/login/Logout';


describe('Login component', () => {
const mockStore = configureMockStore();
let wrapper;
const props = {
history: { push: jest.fn() },
logOut: jest.fn(),
isLoggedIn: true,
};


beforeEach(() => {
mockStore({});
wrapper = shallow(<Logout {...props} />);
});

it('should redirect user to login page', () => {
wrapper.setProps({ isLoggedIn: true });
expect(props.history.push).toBeCalledTimes(1);
});

it('should render correctly', () => {
expect(wrapper).toMatchSnapshot();
});
});
Loading

0 comments on commit cd6b984

Please sign in to comment.