diff --git a/src/App.js b/src/App.js
index b351422c..ba40b7e8 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,6 +1,7 @@
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import './App.scss';
+import NotFound from './common/NotFound';
const App = (MainHeader, Home, MenuLayout, CreateServer) => () => (
@@ -11,6 +12,7 @@ const App = (MainHeader, Home, MenuLayout, CreateServer) => () => (
+
diff --git a/src/common/MenuLayout.js b/src/common/MenuLayout.js
index 62c9c256..93662271 100644
--- a/src/common/MenuLayout.js
+++ b/src/common/MenuLayout.js
@@ -6,6 +6,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import classnames from 'classnames';
import * as PropTypes from 'prop-types';
import { serverType } from '../servers/prop-types';
+import NotFound from './NotFound';
import './MenuLayout.scss';
const MenuLayout = (TagsList, ShortUrls, AsideMenu, CreateShortUrl, ShortUrlVisits) =>
@@ -38,7 +39,8 @@ const MenuLayout = (TagsList, ShortUrls, AsideMenu, CreateShortUrl, ShortUrlVisi
}
render() {
- const { selectedServer } = this.props;
+ const { selectedServer, match } = this.props;
+ const { params: { serverId } } = match;
const burgerClasses = classnames('menu-layout__burger-icon', {
'menu-layout__burger-icon--active': this.state.showSideBar,
});
@@ -88,6 +90,9 @@ const MenuLayout = (TagsList, ShortUrls, AsideMenu, CreateShortUrl, ShortUrlVisi
path="/server/:serverId/manage-tags"
component={TagsList}
/>
+ }
+ />
diff --git a/src/common/NotFound.js b/src/common/NotFound.js
new file mode 100644
index 00000000..d34e0143
--- /dev/null
+++ b/src/common/NotFound.js
@@ -0,0 +1,23 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import * as PropTypes from 'prop-types';
+
+const propTypes = {
+ to: PropTypes.string,
+ btnText: PropTypes.string,
+};
+
+const NotFound = ({ to = '/', btnText = 'Home' }) => (
+
+
Oops! We could not find requested route.
+
+ Use your browser{'\''}s back button to navigate to the page you have previously come from, or just press this button.
+
+
+
{btnText}
+
+);
+
+NotFound.propTypes = propTypes;
+
+export default NotFound;
diff --git a/test/App.test.js b/test/App.test.js
index 1a112ae7..c9df2d9c 100644
--- a/test/App.test.js
+++ b/test/App.test.js
@@ -19,12 +19,17 @@ describe('', () => {
it('renders app main routes', () => {
const routes = wrapper.find(Route);
- const expectedRoutesCount = 3;
- const second = 2;
+ const expectedRoutesCount = 4;
+ const expectedPaths = [
+ '/server/create',
+ '/',
+ '/server/:serverId',
+ ];
+ expect.assertions(expectedPaths.length + 1);
expect(routes).toHaveLength(expectedRoutesCount);
- expect(routes.at(0).prop('path')).toEqual('/server/create');
- expect(routes.at(1).prop('path')).toEqual('/');
- expect(routes.at(second).prop('path')).toEqual('/server/:serverId');
+ expectedPaths.forEach((path, index) => {
+ expect(routes.at(index).prop('path')).toEqual(path);
+ });
});
});
diff --git a/test/common/NotFound.test.js b/test/common/NotFound.test.js
new file mode 100644
index 00000000..a230cc56
--- /dev/null
+++ b/test/common/NotFound.test.js
@@ -0,0 +1,48 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import { Link } from 'react-router-dom';
+import NotFound from '../../src/common/NotFound';
+
+describe('', () => {
+ let wrapper;
+ const createWrapper = (props = {}) => {
+ wrapper = shallow();
+ const content = wrapper.text();
+
+ return { wrapper, content };
+ };
+
+ afterEach(() => wrapper && wrapper.unmount());
+
+ it('shows expected error title', () => {
+ const { content } = createWrapper();
+
+ expect(content).toContain('Oops! We could not find requested route.');
+ });
+
+ it('shows expected error message', () => {
+ const { content } = createWrapper();
+
+ expect(content).toContain(
+ 'Use your browser\'s back button to navigate to the page you have previously come from, or just press this button.'
+ );
+ });
+
+ it('shows a link to the home', () => {
+ const { wrapper } = createWrapper();
+ const link = wrapper.find(Link);
+
+ expect(link.prop('to')).toEqual('/');
+ expect(link.prop('className')).toEqual('btn btn-outline-primary btn-lg');
+ expect(link.prop('children')).toEqual('Home');
+ });
+
+ it('shows a link with provided props', () => {
+ const { wrapper } = createWrapper({ to: '/foo/bar', btnText: 'Hello' });
+ const link = wrapper.find(Link);
+
+ expect(link.prop('to')).toEqual('/foo/bar');
+ expect(link.prop('className')).toEqual('btn btn-outline-primary btn-lg');
+ expect(link.prop('children')).toEqual('Hello');
+ });
+});