1
Fork 0

Rework Routes.tsx and SharePage.tsx routing

This commit is contained in:
viktorstrate 2022-02-01 12:54:00 +01:00
parent 722e639bb1
commit ba01927707
No known key found for this signature in database
GPG Key ID: 3F855605109C1E8A
4 changed files with 181 additions and 104 deletions

View File

@ -1,5 +1,5 @@
import React from 'react'
import { MemoryRouter } from 'react-router-dom'
import { MemoryRouter, Routes, Route } from 'react-router-dom'
import { MockedProvider } from '@apollo/client/testing'
import {
@ -8,8 +8,9 @@ import {
waitForElementToBeRemoved,
} from '@testing-library/react'
import SharePage, {
import {
SHARE_TOKEN_QUERY,
TokenRoute,
VALIDATE_TOKEN_PASSWORD_QUERY,
} from './SharePage'
@ -21,13 +22,6 @@ jest.mock('../../hooks/useScrollPagination')
describe('load correct share page, based on graphql query', () => {
const token = 'TOKEN123'
const matchMock = {
url: `/share`,
params: {},
path: `/share`,
isExact: false,
}
const historyMock = [{ pathname: `/share/${token}` }]
const graphqlMocks = [
@ -101,7 +95,9 @@ describe('load correct share page, based on graphql query', () => {
}}
>
<MemoryRouter initialEntries={historyMock}>
<SharePage match={matchMock} />
<Routes>
<Route path="/share/:token" element={<TokenRoute />} />
</Routes>
</MemoryRouter>
</MockedProvider>
)
@ -176,13 +172,93 @@ describe('load correct share page, based on graphql query', () => {
}}
>
<MemoryRouter initialEntries={historyMock}>
<SharePage match={matchMock} />
<Routes>
<Route path="/share/:token" element={<TokenRoute />} />
</Routes>
</MemoryRouter>
</MockedProvider>
)
expect(screen.getByText('Loading...')).toBeInTheDocument()
await waitForElementToBeRemoved(() => screen.getByText('Loading...'))
expect(screen.getByTestId('Layout')).toBeInTheDocument()
expect(screen.getByTestId('AlbumSharePage')).toBeInTheDocument()
})
test('load subalbum of a shared album', async () => {
const subalbumID = '456'
const subalbumHistoryMock = [{ pathname: `/share/${token}/${subalbumID}` }]
const subalbumPageMocks = [
{
request: {
query: SHARE_TOKEN_QUERY,
variables: {
token,
password: null,
},
},
result: {
data: {
shareToken: {
token: token,
album: {
id: subalbumID,
},
media: null,
},
},
},
},
{
request: {
query: SHARE_ALBUM_QUERY,
variables: {
id: subalbumID,
token: token,
password: null,
limit: 200,
offset: 0,
mediaOrderBy: 'date_shot',
mediaOrderDirection: 'ASC',
},
},
result: {
data: {
album: {
id: '1',
title: 'album_title',
subAlbums: [],
thumbnail: {
url: 'https://photoview.example.com/album_thumbnail.jpg',
},
media: [],
},
},
},
},
]
render(
<MockedProvider
mocks={[...graphqlMocks, ...subalbumPageMocks]}
addTypename={false}
defaultOptions={{
// disable cache, required to make fragments work
watchQuery: { fetchPolicy: 'no-cache' },
query: { fetchPolicy: 'no-cache' },
}}
>
<MemoryRouter initialEntries={subalbumHistoryMock}>
<Routes>
<Route path="/share/:token/*" element={<TokenRoute />} />
</Routes>
</MemoryRouter>
</MockedProvider>
)
expect(screen.getByText('Loading...')).toBeInTheDocument()
await waitForElementToBeRemoved(() => screen.getByText('Loading...'))
expect(screen.getByTestId('Layout')).toBeInTheDocument()

View File

@ -1,6 +1,6 @@
import React from 'react'
import { useQuery, gql } from '@apollo/client'
import { Route, useParams } from 'react-router-dom'
import { Route, Routes, useParams } from 'react-router-dom'
import styled from 'styled-components'
import {
getSharePassword,
@ -111,10 +111,10 @@ const AuthorizedTokenRoute = () => {
}
return (
<>
<Routes>
<Route path=":subAlbum" element={<SharedSubAlbumPage />} />
<Route
path="/"
index
element={
<AlbumSharePage
albumID={data.shareToken.album.id}
@ -123,7 +123,7 @@ const AuthorizedTokenRoute = () => {
/>
}
/>
</>
</Routes>
)
}

View File

@ -1,25 +0,0 @@
/**
* Light lazy-loadable wrapper for share page module
*/
import React from 'react'
import type { TFunction } from 'react-i18next'
import { Route } from 'react-router-dom'
import { NotFoundPage } from '../../components/routes/Routes'
const TokenRoute = React.lazy(() =>
import('./SharePage').then(x => ({
default: x.TokenRoute,
}))
)
const sharePageRoute = ({ t }: { t: TFunction }) => {
return (
<>
<Route path={':token'} element={<TokenRoute />} />
<Route index element={<NotFoundPage t={t} />} />
</>
)
}
export default sharePageRoute

View File

@ -1,11 +1,10 @@
import React from 'react'
import {
Route,
Routes as RouterRoutes,
Navigate,
useNavigate,
NavigateFunction,
Outlet,
useRoutes,
} from 'react-router-dom'
import Layout from '../layout/Layout'
@ -13,8 +12,6 @@ import { authToken, clearTokenCookie } from '../../helpers/authentication'
import { TFunction, useTranslation } from 'react-i18next'
import Loader from '../../primitives/Loader'
import AuthorizedRoute from './AuthorizedRoute'
import sharePageRoute from '../../Pages/SharePage/sharePageRoute'
import peoplePageRoute from '../../Pages/PeoplePage/peoplePageRoute'
const AlbumsPage = React.lazy(
() => import('../../Pages/AllAlbumsPage/AlbumsPage')
@ -30,14 +27,102 @@ const InitialSetupPage = React.lazy(
() => import('../../Pages/LoginPage/InitialSetupPage')
)
const SharePageTokenRoute = React.lazy(() =>
import('../../Pages/SharePage/SharePage').then(x => ({
default: x.TokenRoute,
}))
)
const SettingsPage = React.lazy(
() => import('../../Pages/SettingsPage/SettingsPage')
)
const PeoplePage = React.lazy(() =>
import('../../Pages/PeoplePage/PeoplePage').then(x => ({
default: x.PeoplePage,
}))
)
const PersonPage = React.lazy(() =>
import('../../Pages/PeoplePage/PeoplePage').then(x => ({
default: x.PersonPage,
}))
)
const Routes = () => {
const { t } = useTranslation()
const navigate = useNavigate()
const authorized = (element: React.ReactNode) => (
<AuthorizedRoute>{element}</AuthorizedRoute>
)
const routes = useRoutes([
{
index: true,
element: <IndexPage />,
},
{
path: '/login',
element: <LoginPage />,
},
{
path: '/logout',
element: <LogoutPage navigate={navigate} />,
},
{
path: '/initialSetup',
element: <InitialSetupPage />,
},
{
path: '/share/:token/*',
element: <SharePageTokenRoute />,
},
{
path: '/albums',
element: authorized(<AlbumsPage />),
},
{
path: '/album/:id',
element: authorized(<AlbumPage />),
},
{
path: '/timeline',
element: authorized(<TimelinePage />),
},
{
path: '/places',
element: authorized(<PlacesPage />),
},
{
path: '/settings',
element: authorized(<SettingsPage />),
},
{
path: '/people',
element: authorized(<Outlet />),
children: [
{
path: ':person',
element: <PersonPage />,
},
{
index: true,
element: <PeoplePage />,
},
],
},
{
// for backwards-compatibility
path: '/photos',
element: <Navigate to="/timeline" />,
},
{
path: '*',
element: <NotFoundPage t={t} />,
},
])
return (
<React.Suspense
fallback={
@ -46,66 +131,7 @@ const Routes = () => {
</Layout>
}
>
<RouterRoutes>
<Route path="/login" element={<LoginPage />} />
<Route path="/logout" element={<LogoutPage navigate={navigate} />} />
<Route path="/initialSetup" element={<InitialSetupPage />} />
<Route path="/share">{sharePageRoute({ t })}</Route>
<Route
path="/albums"
element={
<AuthorizedRoute>
<AlbumsPage />
</AuthorizedRoute>
}
/>
<Route
path="/album/:id"
element={
<AuthorizedRoute>
<AlbumPage />
</AuthorizedRoute>
}
/>
<Route
path="/timeline"
element={
<AuthorizedRoute>
<TimelinePage />
</AuthorizedRoute>
}
/>
<Route
path="/places"
element={
<AuthorizedRoute>
<PlacesPage />
</AuthorizedRoute>
}
/>
<Route
path="/people"
element={
<AuthorizedRoute>
<Outlet />
</AuthorizedRoute>
}
>
{peoplePageRoute()}
</Route>
<Route
path="/settings"
element={
<AuthorizedRoute>
<SettingsPage />
</AuthorizedRoute>
}
/>
<Route index element={<IndexPage />} />
{/* For backwards compatibility */}
<Route path="/photos" element={<Navigate to="/timeline" />} />
<Route element={<NotFoundPage t={t} />} />
</RouterRoutes>
{routes}
</React.Suspense>
)
}