Skip to content

Commit

Permalink
404 page added (#445)
Browse files Browse the repository at this point in the history
* 404 page added

* add 404 for subpages/subroutes

* Add `exact` attribute to Fragmentarium Routes

* refactoring routes

* Add tests for fragmentarium 404 routes

* add all tests for routes

---------

Co-authored-by: Ilya Khait <[email protected]>
  • Loading branch information
kartikpaliwal and khoidt authored Mar 2, 2024
1 parent 12c96bb commit 7d0e2b3
Show file tree
Hide file tree
Showing 11 changed files with 279 additions and 19 deletions.
10 changes: 10 additions & 0 deletions src/NotFoundPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'

const NotFoundPage: React.FC = () => (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h1>404 - Not Found</h1>
<p>The page you are looking for does not exist.</p>
</div>
)

export default NotFoundPage
6 changes: 6 additions & 0 deletions src/router/aboutRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import About, { TabId, tabIds } from 'about/ui/about'
import { CachedMarkupService } from 'markup/application/MarkupService'
import { sitemapDefaults } from 'router/sitemap'
import { HeadTagsService } from 'router/head'
import NotFoundPage from 'NotFoundPage'
import { newsletters } from 'about/ui/news'

// ToDo:
Expand Down Expand Up @@ -44,6 +45,11 @@ export default function AboutRoutes({
)}
{...(sitemap && sitemapDefaults)}
/>,
<Route
key="AboutNotFound"
path="/about/*"
render={(): ReactNode => <NotFoundPage />}
/>,
<Redirect
from="/about"
to="/about/fragmentarium"
Expand Down
10 changes: 10 additions & 0 deletions src/router/bibliographyRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { BibliographySlugs, sitemapDefaults } from 'router/sitemap'
import { HeadTagsService } from 'router/head'
import AfoRegisterService from 'afo-register/application/AfoRegisterService'
import FragmentService from 'fragmentarium/application/FragmentService'
import NotFoundPage from 'NotFoundPage'

export default function BibliographyRoutes({
sitemap,
Expand All @@ -25,6 +26,7 @@ export default function BibliographyRoutes({
<Route
key="BibliographyEditorNew"
path="/bibliography/references/new-reference"
exact
render={(props): ReactNode => (
<BibliographyEditor
bibliographyService={bibliographyService}
Expand All @@ -36,6 +38,7 @@ export default function BibliographyRoutes({
<Route
key="BibliographyViewerAndEditor"
path="/bibliography/references/:id"
exact
render={(props): ReactNode => (
<HeadTagsService
title="Bibliography entry: eBL"
Expand All @@ -55,6 +58,7 @@ export default function BibliographyRoutes({
<Route
key="Bibliography references search"
path="/bibliography/references"
exact
render={(props): ReactNode => (
<HeadTagsService
title="Bibliography References: eBL"
Expand All @@ -74,6 +78,7 @@ export default function BibliographyRoutes({
<Route
key="Bibliography AfO-Register search"
path="/bibliography/afo-register"
exact
render={(props): ReactNode => (
<HeadTagsService
title="Bibliography AfO-Register: eBL"
Expand All @@ -90,6 +95,11 @@ export default function BibliographyRoutes({
)}
{...(sitemap && sitemapDefaults)}
/>,
<Route
key="BibliographyNotFound"
path="/bibliography/*"
render={(): ReactNode => <NotFoundPage />}
/>,
<Redirect
from="/bibliography"
to="/bibliography/afo-register"
Expand Down
7 changes: 6 additions & 1 deletion src/router/corpusRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Corpus, { genres } from 'corpus/ui/Corpus'
import { sitemapDefaults, ChapterSlugs, TextSlugs } from 'router/sitemap'
import MarkupService from 'markup/application/MarkupService'
import { HeadTagsService } from 'router/head'

import NotFoundPage from 'NotFoundPage'
function parseChapterId(params): ChapterId {
return {
textId: parseTextId(params),
Expand Down Expand Up @@ -149,5 +149,10 @@ export default function CorpusRoutes({
}),
})}
/>,
<Route
key="CorpusNotFound"
path="/corpus/*"
render={(): ReactNode => <NotFoundPage />}
/>,
]
}
9 changes: 9 additions & 0 deletions src/router/dictionaryRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Route } from 'react-router-dom'
import SignService from 'signs/application/SignService'
import { DictionarySlugs, sitemapDefaults } from 'router/sitemap'
import { HeadTagsService } from 'router/head'
import NotFoundPage from 'NotFoundPage'

export default function DictionaryRoutes({
sitemap,
Expand All @@ -29,6 +30,7 @@ export default function DictionaryRoutes({
<Route
key="WordEditor"
path="/dictionary/:id/edit"
exact
render={({ match }): ReactNode => (
<WordEditor
wordService={wordService}
Expand All @@ -39,6 +41,7 @@ export default function DictionaryRoutes({
<Route
key="WordDisplay"
path="/dictionary/:id"
exact
render={({ match }): ReactNode => (
<HeadTagsService
title="Dictionary entry: eBL"
Expand All @@ -61,6 +64,7 @@ export default function DictionaryRoutes({
<Route
key="Dictionary"
path="/dictionary"
exact
render={(props): ReactNode => (
<HeadTagsService
title="Search dictionary: eBL"
Expand All @@ -71,5 +75,10 @@ export default function DictionaryRoutes({
)}
{...(sitemap && sitemapDefaults)}
/>,
<Route
key="DictionaryNotFound"
path="/dictionary/*"
render={(): ReactNode => <NotFoundPage />}
/>,
]
}
12 changes: 11 additions & 1 deletion src/router/fragmentariumRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { HeadTagsService } from 'router/head'
import BibliographyService from 'bibliography/application/BibliographyService'
import { FindspotService } from 'fragmentarium/application/FindspotService'
import AfoRegisterService from 'afo-register/application/AfoRegisterService'

import NotFoundPage from 'NotFoundPage'
function parseStringParam(location: Location, param: string): string | null {
const value = parse(location.search)[param]
return _.isArray(value) ? value.join('') : value
Expand Down Expand Up @@ -78,6 +78,7 @@ export default function FragmentariumRoutes({
<Route
key="FragmentariumSearch"
path="/fragmentarium/search"
exact
render={({ location }): ReactNode => (
<HeadTagsService
title="Fragmentarium search: eBL"
Expand All @@ -99,6 +100,7 @@ export default function FragmentariumRoutes({
<Route
key="FragmentLineToVecRanking"
path="/fragmentarium/:id/match"
exact
render={({ match }): ReactNode => (
<HeadTagsService
title="Fragmentarium line to vector ranking: eBL"
Expand All @@ -118,6 +120,7 @@ export default function FragmentariumRoutes({
<Route
key="TagSignsView"
path="/fragmentarium/:id/annotate"
exact
render={({ match }): ReactNode => (
<TagSignsView
signService={signService}
Expand All @@ -129,6 +132,7 @@ export default function FragmentariumRoutes({
<Route
key="FragmentView"
path="/fragmentarium/:id"
exact
render={({ match, location }): ReactNode => (
<SessionContext.Consumer>
{(session) => (
Expand Down Expand Up @@ -157,6 +161,7 @@ export default function FragmentariumRoutes({
<Route
key="Fragmentarium"
path="/fragmentarium"
exact
render={(): ReactNode => (
<HeadTagsService
title="Fragmentarium: eBL"
Expand All @@ -176,5 +181,10 @@ export default function FragmentariumRoutes({
)}
{...(sitemap && sitemapDefaults)}
/>,
<Route
key="FragmentariumNotFound"
path="/Fragmentarium/*"
render={(): ReactNode => <NotFoundPage />}
/>,
]
}
177 changes: 177 additions & 0 deletions src/router/notFoundRoutes.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import React from 'react'
import { render, screen } from '@testing-library/react'
import { Router, Switch } from 'react-router-dom'
import { getServices } from 'test-support/AppDriver'
import { createMemoryHistory } from 'history'
import AboutRoutes from './aboutRoutes'
import FragmentariumRoutes from './fragmentariumRoutes'
import BibliographyRoutes from './bibliographyRoutes'
import CorpusRoutes from './corpusRoutes'
import DictionaryRoutes from './dictionaryRoutes'
import SignRoutes from './signRoutes'
import ToolsRoutes from './toolsRoutes'

describe('NotFoundPage rendering in FragmentariumRoutes', () => {
const nonExistentRoutes = [
'/fragmentarium/search/non-existent',
'/fragmentarium/Fragment.12345/match/non-existent',
'/fragmentarium/Fragment.12345/annotate/non-existent',
'/fragmentarium/Fragment.12345/non-existent',
]
nonExistentRoutes.forEach((path) => {
const history = createMemoryHistory({ initialEntries: [path] })
test(`renders NotFoundPage for "${path}"`, () => {
render(
<Router history={history}>
<Switch>
{[...FragmentariumRoutes({ ...getServices(), sitemap: false })]}
</Switch>
</Router>
)
expect(
screen.getByText(/The page you are looking for does not exist./i)
).toBeInTheDocument()
})
})
})

describe('NotFoundPage rendering in AboutRoutes', () => {
const nonExistentAboutRoutes = [
'/about/non-existent-page',
'/about/invalid-section',
'/about/undefined-route',
]
nonExistentAboutRoutes.forEach((path) => {
const history = createMemoryHistory({ initialEntries: [path] })
test(`renders NotFoundPage for "${path}"`, () => {
render(
<Router history={history}>
<Switch>
{[...AboutRoutes({ ...getServices(), sitemap: false })]}
</Switch>
</Router>
)
expect(
screen.getByText(/The page you are looking for does not exist./i)
).toBeInTheDocument()
})
})
})

describe('NotFoundPage rendering in BibliographyRoutes', () => {
const nonExistentAboutRoutes = [
'/bibliography/search/non-existent',
'/bibliography/afo-register/non-existent-page',
'/bibliography/afo-register/invalid-section',
'/bibliography/afo-register/undefined-route',
]
nonExistentAboutRoutes.forEach((path) => {
const history = createMemoryHistory({ initialEntries: [path] })
test(`renders NotFoundPage for "${path}"`, () => {
render(
<Router history={history}>
<Switch>
{[...BibliographyRoutes({ ...getServices(), sitemap: false })]}
</Switch>
</Router>
)
expect(
screen.getByText(/The page you are looking for does not exist./i)
).toBeInTheDocument()
})
})
})

describe('NotFoundPage rendering in CorpusRoutes', () => {
const nonExistentAboutRoutes = [
'/corpus/Corpus.12345/non-existent-page',
'/corpus/Corpus.12345/invalid-section',
'/corpus/Corpus.12345/undefined-route',
]
nonExistentAboutRoutes.forEach((path) => {
const history = createMemoryHistory({ initialEntries: [path] })
test(`renders NotFoundPage for "${path}"`, () => {
render(
<Router history={history}>
<Switch>
{[...CorpusRoutes({ ...getServices(), sitemap: false })]}
</Switch>
</Router>
)
expect(
screen.getByText(/The page you are looking for does not exist./i)
).toBeInTheDocument()
})
})
})

describe('NotFoundPage rendering in DictionaryRoutes', () => {
const nonExistentAboutRoutes = [
'/dictionary/search/non-existent',
'/dictionary/Dictionary.12345/non-existent-page',
'/dictionary/Dictionary.12345/invalid-section',
'/dictionary/Dictionary.12345/undefined-route',
]
nonExistentAboutRoutes.forEach((path) => {
const history = createMemoryHistory({ initialEntries: [path] })
test(`renders NotFoundPage for "${path}"`, () => {
render(
<Router history={history}>
<Switch>
{[...DictionaryRoutes({ ...getServices(), sitemap: false })]}
</Switch>
</Router>
)
expect(
screen.getByText(/The page you are looking for does not exist./i)
).toBeInTheDocument()
})
})
})

describe('NotFoundPage rendering in SignRoutes', () => {
const nonExistentAboutRoutes = [
'/signs/search/non-existent',
'/signs/Signs.12345/non-existent-page',
'/signs/Signs.12345/invalid-section',
'/signs/Signs.12345/undefined-route',
]
nonExistentAboutRoutes.forEach((path) => {
const history = createMemoryHistory({ initialEntries: [path] })
test(`renders NotFoundPage for "${path}"`, () => {
render(
<Router history={history}>
<Switch>
{[...SignRoutes({ ...getServices(), sitemap: false })]}
</Switch>
</Router>
)
expect(
screen.getByText(/The page you are looking for does not exist./i)
).toBeInTheDocument()
})
})
})

describe('NotFoundPage rendering in ToolsRoutes', () => {
const nonExistentAboutRoutes = [
'/tools/date-converter/non-existent-page',
'/tools/date-converter/invalid-section',
'/tools/date-converter/undefined-route',
]
nonExistentAboutRoutes.forEach((path) => {
const history = createMemoryHistory({ initialEntries: [path] })
test(`renders NotFoundPage for "${path}"`, () => {
render(
<Router history={history}>
<Switch>
{[...ToolsRoutes({ ...getServices(), sitemap: false })]}
</Switch>
</Router>
)
expect(
screen.getByText(/The page you are looking for does not exist./i)
).toBeInTheDocument()
})
})
})
2 changes: 2 additions & 0 deletions src/router/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import ToolsRoutes from 'router/toolsRoutes'

import Sitemap, { sitemapDefaults, Slugs } from 'router/sitemap'
import Header from 'Header'
import NotFoundPage from 'NotFoundPage'
import { helmetContext } from 'router/head'
import { HelmetProvider } from 'react-helmet-async'
import { FindspotService } from 'fragmentarium/application/FindspotService'
Expand Down Expand Up @@ -51,6 +52,7 @@ export default function Router(services: Services): JSX.Element {
</Route>
<Route exact path="/sitemap/sitemap.xml" />
{WebsiteRoutes(services, false)}
<Route component={NotFoundPage} />
</Switch>
</HelmetProvider>
)
Expand Down
Loading

0 comments on commit 7d0e2b3

Please sign in to comment.