ソースを参照

fix(breadcrumbs): use actual router instead of server side props to determine ancestors

Nicolas Meienberger 2 年 前
コミット
2a246460ea

+ 16 - 8
src/client/modules/Apps/pages/AppDetailsPage/AppDetailsPage.test.tsx

@@ -1,4 +1,3 @@
-import { faker } from '@faker-js/faker';
 import React from 'react';
 import { render, screen, waitFor } from '../../../../../../tests/test-utils';
 import { AppWithInfo } from '../../../../core/types';
@@ -10,7 +9,7 @@ import { AppDetailsPage } from './AppDetailsPage';
 describe('AppDetailsPage', () => {
   it('should render', async () => {
     // Arrange
-    render(<AppDetailsPage appId="nothing" refTitle="" refSlug="" />);
+    render(<AppDetailsPage appId="nothing" />);
 
     // Assert
     await waitFor(() => {
@@ -28,10 +27,19 @@ describe('AppDetailsPage', () => {
       }),
     );
 
-    const testSlug = faker.lorem.slug();
-    const testTitle = faker.lorem.sentence();
+    jest.mock('next/router', () => {
+      const actualRouter = jest.requireActual('next-router-mock');
 
-    render(<AppDetailsPage appId={app.id} refSlug={testSlug} refTitle={testTitle} />);
+      return {
+        ...actualRouter,
+        useRouter: () => ({
+          ...actualRouter.useRouter(),
+          pathname: `/apps/${app.id}`,
+        }),
+      };
+    });
+
+    render(<AppDetailsPage appId={app.id} />);
     await waitFor(() => {
       expect(screen.getByTestId('app-details')).toBeInTheDocument();
     });
@@ -41,10 +49,10 @@ describe('AppDetailsPage', () => {
     const breadcrumbsLinks = await screen.findAllByTestId('breadcrumb-link');
 
     // Assert
-    expect(breadcrumbs[0]).toHaveTextContent(testTitle);
-    expect(breadcrumbsLinks[0]).toHaveAttribute('href', `/${testSlug}`);
+    expect(breadcrumbs[0]).toHaveTextContent('Apps');
+    expect(breadcrumbsLinks[0]).toHaveAttribute('href', '/apps');
 
     expect(breadcrumbs[1]).toHaveTextContent(app.info.name);
-    expect(breadcrumbsLinks[1]).toHaveAttribute('href', `/${testSlug}/${app.id}`);
+    expect(breadcrumbsLinks[1]).toHaveAttribute('href', `/apps/${app.id}`);
   });
 });

+ 21 - 3
src/client/modules/Apps/pages/AppDetailsPage/AppDetailsPage.tsx

@@ -1,5 +1,6 @@
 import { NextPage } from 'next';
 import React from 'react';
+import { useRouter } from 'next/router';
 import { Layout } from '../../../../components/Layout';
 import { ErrorPage } from '../../../../components/ui/ErrorPage';
 import { trpc } from '../../../../utils/trpc';
@@ -7,11 +8,20 @@ import { AppDetailsContainer } from '../../containers/AppDetailsContainer/AppDet
 
 interface IProps {
   appId: string;
-  refSlug: string;
-  refTitle: string;
 }
 
-export const AppDetailsPage: NextPage<IProps> = ({ appId, refSlug, refTitle }) => {
+type Path = { refSlug: string; refTitle: string };
+const paths: Record<string, Path> = {
+  'app-store': { refSlug: 'app-store', refTitle: 'App Store' },
+  apps: { refSlug: 'apps', refTitle: 'Apps' },
+};
+
+export const AppDetailsPage: NextPage<IProps> = ({ appId }) => {
+  const router = useRouter();
+
+  const basePath = router.pathname.split('/').slice(1)[0];
+  const { refSlug, refTitle } = paths[basePath || 'apps'] || { refSlug: 'apps', refTitle: 'Apps' };
+
   const { data, error } = trpc.app.getApp.useQuery({ id: appId });
 
   const breadcrumb = [
@@ -27,3 +37,11 @@ export const AppDetailsPage: NextPage<IProps> = ({ appId, refSlug, refTitle }) =
     </Layout>
   );
 };
+
+AppDetailsPage.getInitialProps = (ctx) => {
+  const { query } = ctx;
+
+  const appId = String(query.id);
+
+  return { appId };
+};

+ 1 - 13
src/pages/app-store/[id].tsx

@@ -1,13 +1 @@
-import { AppDetailsPage } from '../../client/modules/Apps/pages/AppDetailsPage';
-
-const Page = AppDetailsPage;
-
-Page.getInitialProps = (ctx) => {
-  const { query } = ctx;
-
-  const appId = String(query.id);
-
-  return { appId, refSlug: 'app-store', refTitle: 'App Store' };
-};
-
-export default Page;
+export { AppDetailsPage as default } from '../../client/modules/Apps/pages/AppDetailsPage';

+ 1 - 13
src/pages/apps/[id].tsx

@@ -1,13 +1 @@
-import { AppDetailsPage } from '../../client/modules/Apps/pages/AppDetailsPage';
-
-const Page = AppDetailsPage;
-
-Page.getInitialProps = (ctx) => {
-  const { query } = ctx;
-
-  const appId = String(query.id);
-
-  return { appId, refSlug: 'apps', refTitle: 'Apps' };
-};
-
-export default Page;
+export { AppDetailsPage as default } from '../../client/modules/Apps/pages/AppDetailsPage';