Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

Commit

Permalink
feat(routes): added default 404 route
Browse files Browse the repository at this point in the history
  • Loading branch information
10xLaCroixDrinker authored Feb 11, 2020
1 parent 21021e7 commit d8f1bad
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 5 deletions.
7 changes: 7 additions & 0 deletions __tests__/integration/one-app.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,13 @@ describe('Tests that can run against either local Docker setup or remote One App
},
});
});

test('not found requests are caught', async () => {
const response = await fetch(`${appInstanceUrls.fetchUrl}/this-route-does-not-exist`, defaultFetchOpts);
const body = await response.text();
expect(response.status).toBe(404);
expect(body).toContain('<div id="root">Not found</div>');
});
});

describe('internationalization', () => {
Expand Down
28 changes: 28 additions & 0 deletions __tests__/universal/__snapshots__/routes.spec.jsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`routes should clear the 404 status when leaving the unmatched route 1`] = `
Object {
"type": "@americanexpress/one-app-ducks/error/CLEAR_APPLICATION_ERROR",
}
`;

exports[`routes should set the status to 404 1`] = `
Object {
"error": Any<Error>,
"meta": Object {
"code": 404,
"collectionMethod": "applicationError",
"location": Object {
"pathname": "missing",
},
},
"type": "ADD_ERROR_TO_REPORT",
}
`;
exports[`routes should set the status to 404 2`] = `
Object {
"code": 404,
"type": "@americanexpress/one-app-ducks/error/APPLICATION_ERROR",
}
`;
51 changes: 47 additions & 4 deletions __tests__/universal/routes.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ import { fromJS } from 'immutable';
import createRoutes from '../../src/universal/routes';

jest.mock('holocron-module-route', () => () => null);
jest.mock('@americanexpress/one-app-ducks/lib/errorReporting', () => ({
addErrorToReport: jest.fn((error, meta) => ({
type: 'ADD_ERROR_TO_REPORT',
error,
meta,
})),
}));

describe('routes', () => {
const store = {
Expand All @@ -28,16 +35,52 @@ describe('routes', () => {
rootModuleName: 'fakeRootModule',
},
}),
dispatch: jest.fn((action) => {
if (typeof action === 'function') {
action(store.dispatch);
}
}),
};

it('should set up the tenancy root route', () => {
const RootRoute = createRoutes(store);
beforeEach(() => jest.clearAllMocks());

it('should set up the tenancy root route first', () => {
const RootRoute = createRoutes(store)[0];
expect(ReactTestUtils.isElement(RootRoute)).toBe(true);
expect(RootRoute.props).toEqual({ moduleName: 'fakeRootModule', store });
});

it('should not define a path', () => {
const RootRoute = createRoutes(store);
it('should not define a path on the root module', () => {
const RootRoute = createRoutes(store)[0];
expect(RootRoute.props.path).toBe(undefined);
});

it('should set up a default 404', () => {
const NotFoundRoute = createRoutes(store)[1];
expect(ReactTestUtils.isElement(NotFoundRoute)).toBe(true);
expect(NotFoundRoute.props).toEqual({
path: '*',
component: expect.any(Function),
onEnter: expect.any(Function),
onLeave: expect.any(Function),
});
});

it('should display a simple message on 404', () => {
const NotFoundRoute = createRoutes(store)[1];
expect(NotFoundRoute.props.component()).toBe('Not found');
});

it('should set the status to 404', () => {
const NotFoundRoute = createRoutes(store)[1];
NotFoundRoute.props.onEnter({ location: { pathname: 'missing' } });
expect(store.dispatch.mock.calls[1][0]).toMatchSnapshot({ error: expect.any(Error) });
expect(store.dispatch.mock.calls[2][0]).toMatchSnapshot();
});

it('should clear the 404 status when leaving the unmatched route', () => {
const NotFoundRoute = createRoutes(store)[1];
NotFoundRoute.props.onLeave();
expect(store.dispatch.mock.calls[0][0]).toMatchSnapshot();
});
});
20 changes: 19 additions & 1 deletion src/universal/routes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,28 @@

import React from 'react';
import ModuleRoute from 'holocron-module-route';
import { Route } from '@americanexpress/one-app-router';
import { applicationError, clearError } from '@americanexpress/one-app-ducks';

const createRoutes = (store) => {
const rootModuleName = store.getState().getIn(['config', 'rootModuleName']);
return <ModuleRoute moduleName={rootModuleName} store={store} />;
return [
<ModuleRoute moduleName={rootModuleName} store={store} />,
<Route
path="*"
component={() => 'Not found'}
onEnter={({ location }) => {
store.dispatch(applicationError(
404,
new Error('404: Not found'),
{ location }
));
}}
onLeave={() => {
store.dispatch(clearError());
}}
/>,
];
};

export default createRoutes;

0 comments on commit d8f1bad

Please sign in to comment.