Skip to content

Commit

Permalink
165573509 Chore (404): Users should be redirected to 404 page if link…
Browse files Browse the repository at this point in the history
… is missing

- If a link is not in the app-router, the app should redirect to a custom 404 page
- Write tests

[Finishes #165573509]
  • Loading branch information
JumaKahiga committed Apr 25, 2019
1 parent 7d49c0b commit a70d6b9
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 21 deletions.
3 changes: 2 additions & 1 deletion src/actions/postArticles.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ export const fetchArticle = slug => async (dispatch) => {
dispatch({ type: FETCH_ARTICLE, payload: result.data });
})
.catch((error) => {
console.log(error.response);
dispatch({
type: ACTION_FAILED,
payload: error,
payload: error.response.data.message,
});
});
};
24 changes: 15 additions & 9 deletions src/components/Articles/ViewArticle.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,25 @@ export class GetArticle extends Component {
this.onClick = this.onClick.bind(this);
}

componentWillMount() {
componentDidMount() {
const slug = this.props.match.params.slug;
this.props.fetchArticle(slug);
}

componentWillReceiveProps(newProps) {
const articles = [];
const activeUser = [];
articles.push(newProps.anArticle.article);
activeUser.push(newProps.currentUser);
this.setState({
anArticle: articles,
currentUser: activeUser[0],
});
const slug = newProps.match.params.slug;
if (newProps.errors.length>0) {
this.props.history.push(`/article/${slug}/404`)
} else{
const articles = [];
const activeUser = [];
articles.push(newProps.anArticle.article);
activeUser.push(newProps.currentUser);
this.setState({
anArticle: articles,
currentUser: activeUser[0],
});
}
}

onClick(event) {
Expand Down Expand Up @@ -180,6 +185,7 @@ const mapStateToProps = state => ({
anArticle: state.articles.item,
currentUser: state.login.user,
loggedIn: state.login.loggedIn,
errors: state.articles.errors,
});


Expand Down
53 changes: 53 additions & 0 deletions src/components/Articles/tests/viewarticle.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('components', () => {
created_at: '2019-04-10T13:30:20.231197Z',
},
},
errors: [],
match: {
params: {
slug: 'new',
Expand All @@ -63,5 +64,57 @@ describe('components', () => {
expect(enzymeWrapper.find('header').hasClass('')).toBe(true);
expect(enzymeWrapper.containsMatchingElement(<h3>Loading...</h3>)).toBeTruthy();
});
it('Should redirect to edit article when button is clicked', () => {
const { enzymeWrapper } = setup();

enzymeWrapper.setProps(
{
fetchArticle: jest.fn(),
anArticle: {
article: {
slug: 'new',
body: 'Just a test article',
author: {
username: 'tester',
},
created_at: '2019-04-10T13:30:20.231197Z',
},
},
errors: [],
match: {
params: {
slug: 'new',
},
},
history: {
push: jest.fn(),
},
},
);

const event = {
preventDefault: jest.fn(),
};
const state = {
anArticle: [{
title: 'new',
body: 'dummy',
author: {
username: 'user1',
},
created_at: '2019-04-25T11:05:47.274146Z',
tags: ['tag1', 'tag2']
}],
currentUser: {
user:{
username: 'user1',
},
},
errors: ''
};
enzymeWrapper.setState(state);
enzymeWrapper.instance().onClick(event);
expect(enzymeWrapper.instance().props.history.push).toHaveBeenCalled();
});
});
});
118 changes: 118 additions & 0 deletions src/components/ErrorPages/404.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}

body {
padding: 0;
margin: 0;
}

#notfound {
position: relative;
height: 100vh;
}

#notfound .notfound {
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}

.notfound {
max-width: 460px;
width: 100%;
text-align: center;
line-height: 1.4;
}

.notfound .notfound-404 {
position: relative;
width: 180px;
height: 180px;
margin: 0px auto 50px;
}

.notfound .notfound-404>div:first-child {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: #ffa200;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
border: 5px dashed #000;
border-radius: 5px;
}

.notfound .notfound-404>div:first-child:before {
content: '';
position: absolute;
left: -5px;
right: -5px;
bottom: -5px;
top: -5px;
-webkit-box-shadow: 0px 0px 0px 5px rgba(0, 0, 0, 0.1) inset;
box-shadow: 0px 0px 0px 5px rgba(0, 0, 0, 0.1) inset;
border-radius: 5px;
}

.notfound .notfound-404 h1 {
font-family: 'Cabin', sans-serif;
color: #000;
font-weight: 700;
margin: 0;
font-size: 90px;
position: absolute;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
left: 50%;
text-align: center;
height: 40px;
line-height: 40px;
}

.notfound h2 {
font-family: 'Cabin', sans-serif;
font-size: 33px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 7px;
}

.notfound p {
font-family: 'Cabin', sans-serif;
font-size: 16px;
color: #000;
font-weight: 400;
}

.notfound a {
font-family: 'Cabin', sans-serif;
display: inline-block;
padding: 10px 25px;
border: none;
border-radius: 40px;
color: #fff;
font-size: 14px;
font-weight: 700;
text-transform: uppercase;
text-decoration: none;
-webkit-transition: 0.2s all;
transition: 0.2s all;
}

.notfound a:hover {
background-color: #2c2c2c;
}

.link-style {
background-color: transparent !important;
}
33 changes: 33 additions & 0 deletions src/components/ErrorPages/Page404.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { Link } from 'react-router-dom';
import NavbarInstance from '../Navbar/Navbar';
import Footer from '../static/Footer';
import './404.scss';
import '../../css/bootstrap.min.css';

const Page404 = () => (
<div className="App-header">
<header>
<NavbarInstance />
</header>
<div className="notfound">
<div className="notfound-404">
<div />
<h1>404</h1>
</div>
<h2>Page not found</h2>
<p>
The page you are looking for might have been removed
had its name changed or is temporarily unavailable.
</p>
<Link to="/" className="link-style">
<button type="button" className="btn btn-outline-success">Home Page</button>
</Link>
</div>
<footer>
<Footer />
</footer>
</div>
);

export default Page404;
8 changes: 8 additions & 0 deletions src/components/ErrorPages/tests/page404.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import { shallow } from 'enzyme';
import Page404 from '../Page404';

test('Should render 404 Page', () => {
const wrapper = shallow(<Page404 />);
expect(wrapper).toMatchSnapshot();
});
7 changes: 6 additions & 1 deletion src/reducers/articlesReducer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
FETCH_ARTICLES, FETCH_ARTICLE, NEW_ARTICLE, UPDATE_ARTICLE, AUTHENTICATION_FAILED,
FETCH_ARTICLES, FETCH_ARTICLE, NEW_ARTICLE, UPDATE_ARTICLE, AUTHENTICATION_FAILED, ACTION_FAILED,
} from '../actions/types';

const initialState = {
Expand Down Expand Up @@ -37,6 +37,11 @@ export default function (state = initialState, action) {
...state,
update_item: action.payload,
};
case ACTION_FAILED:
return {
...state,
errors: action.payload,
};
default:
return state;
}
Expand Down
22 changes: 12 additions & 10 deletions src/routers/Approuter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Home from '../components/Home/Home';
import PostArticle from '../components/Articles/PostArticle';
import GetArticle from '../components/Articles/ViewArticle';
import EditArticle from '../components/Articles/UpdateArticle';
import Page404 from '../components/ErrorPages/Page404';
import { Provider } from 'react-redux';
import Register from '../components/signup/register';
import Profile from '../components/profile/Profile';
Expand All @@ -21,17 +22,18 @@ const Approuter = () => (
<div>
<Switch>
<Route path="/" component={Home} exact />
<Route path="/register" component={Register} />
<Route path="/login" component={Login} />
<Route path="/profile" component={Profile} />
<Route path="/resetpassword" component={RequestResetForm} />
<Route path="/resetform/:token" component={ResetPassword} />
<Route path="/followers" component={Followers} />
<Route path="/following" component={Following} />
<Route path="/profiles" component={ViewProfiles} />
<Route path="/articles/new" component={PostArticle} />
<Route path="/register" component={Register} exact />
<Route path="/login" component={Login} exact />
<Route path="/profile" component={Profile} exact />
<Route path="/resetpassword" component={RequestResetForm} exact />
<Route path="/resetform/:token" component={ResetPassword} exact />
<Route path="/followers" component={Followers} exact />
<Route path="/following" component={Following} exact />
<Route path="/profiles" component={ViewProfiles} exact />
<Route path="/articles/new" component={PostArticle} exact/>
<Route path="/article/:slug" component={GetArticle} exact />
<Route path="/article/:slug/edit" component={EditArticle} />
<Route path="/article/:slug/edit" component={EditArticle} exact />
<Route component={Page404} />
</Switch>
</div>
</BrowserRouter>
Expand Down

0 comments on commit a70d6b9

Please sign in to comment.