Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(multiple): le bouton retour apparait tout le temps #2324

Merged
merged 2 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/client/components/features/ButtonRetour/BackButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* @jest-environment jsdom
*/

import { render, screen } from '@testing-library/react';

import { BackButton } from '~/client/components/features/ButtonRetour/BackButton';
import { mockUseRouter } from '~/client/components/useRouter.mock';
import { mockSessionStorage } from '~/client/components/window.mock';

describe('BackButton', () => {
beforeEach(() => {
jest.resetAllMocks();
});

describe('Lorsque la variable PREVIOUS_PAGE est définie dans le sessionStorage', () => {
it('affiche le bouton de retour', () => {
// Given
mockUseRouter({});
mockSessionStorage({
getItem: jest.fn().mockReturnValue('/page-1'),
});

// When
render(<BackButton />);

// Then
expect(screen.getByRole('button', { name: 'Retour vers la page précédente' })).toBeInTheDocument();
});
});
describe('Lorsque la variable PREVIOUS_PAGE n’est pas définie dans le sessionStorage', () => {
it('n’affiche pas le bouton de retour', () => {
// Given
mockUseRouter({});
mockSessionStorage({
getItem: jest.fn().mockReturnValue(null),
});

// When
render(<BackButton />);

// Then
expect(screen.queryByRole('button', { name: 'Retour vers la page précédente' })).not.toBeInTheDocument();
});
});
});
18 changes: 6 additions & 12 deletions src/client/components/features/ButtonRetour/BackButton.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
import { useRouter } from 'next/router';
import React, { useEffect, useMemo } from 'react';
import React, { useEffect, useState } from 'react';

import { Container } from '~/client/components/layouts/Container/Container';
import {
ButtonComponent,
} from '~/client/components/ui/Button/ButtonComponent';
import { Icon } from '~/client/components/ui/Icon/Icon';
import { REFERRER } from '~/client/hooks/useReferrer';
import { PREVIOUS_PAGE } from '~/client/hooks/useDisplayBackButton';

type BackButtonProps = Omit<React.ComponentPropsWithoutRef<typeof ButtonComponent>,'label'> & {
label?: string
}

export function BackButton({ className, label= 'Retour', ...rest }: BackButtonProps) {

const router = useRouter();

const referrer = useMemo( () => {
return sessionStorage.getItem(REFERRER);
}, []);

const [displayBackButton, setDisplayBackButton] = useState(false);
useEffect(() => {
return () => {
sessionStorage.removeItem(REFERRER);
};
const previousPage = sessionStorage.getItem(PREVIOUS_PAGE);
setDisplayBackButton(!!previousPage);
}, []);

if (referrer === null) return null;

return (
displayBackButton &&
<div className={className}>
<Container>
<ButtonComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ import {

import { ConsulterAnnonce } from '~/client/components/features/Logement/Consulter/ConsulterAnnonce';
import { mockUseRouter } from '~/client/components/useRouter.mock';
import { mockSessionStorage, mockSmallScreen } from '~/client/components/window.mock';
import { mockSmallScreen } from '~/client/components/window.mock';
import { LocaleProvider } from '~/client/context/locale.context';
import { anAnnonceDeLogement } from '~/server/cms/domain/annonceDeLogement.fixture';
import { AnnonceDeLogement } from '~/server/cms/domain/annonceDeLogement.type';

describe('<ConsulterAnnonce />', () => {
beforeEach(() => {
jest.resetAllMocks();
mockSmallScreen();
mockSessionStorage({
setItem: jest.fn().mockReturnValue('/annonces'),
});
const routerReload = jest.fn();
mockUseRouter({ reload: routerReload });
});

it('affiche le le bouton retour vers la liste des annonces', () => {
jest.spyOn(Object.getPrototypeOf(sessionStorage), 'getItem').mockReturnValue('/');

const annonceDeLogement = anAnnonceDeLogement();
annonceDeLogement.titre = 'Super T3 dans le centre de Paris';

Expand Down
54 changes: 54 additions & 0 deletions src/client/hooks/useDisplayBackButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @jest-environment jsdom
*/

import { render } from '@testing-library/react';

import { mockUseRouter } from '~/client/components/useRouter.mock';
import useDisplayBackButton from '~/client/hooks/useDisplayBackButton';

function TestComponent() {
useDisplayBackButton();
return <></>;
}

describe('useDisplayBackButton', () => {
beforeEach(() => {
sessionStorage.clear();
jest.resetAllMocks();
});
describe('quand la page actuel est la première sur laquelle on navigue', () => {
it('stocke le pathname de la page dans sessionStorage', () => {
// Given
mockUseRouter({
pathname: '/',
});
const setItem = jest.spyOn(Object.getPrototypeOf(sessionStorage), 'setItem');
jest.spyOn(Object.getPrototypeOf(sessionStorage), 'getItem').mockReturnValue(null);

// When
render(<TestComponent />);

// Then
expect(setItem).toHaveBeenCalledWith('current-page', '/');
});
});

describe('quand la page actuel n’est pas la première sur laquelle on navigue', () => {
it('stocke le pathname de la page dans sessionStorage', () => {
// Given
mockUseRouter({
pathname: '/other-page',
});
const setItem = jest.spyOn(Object.getPrototypeOf(sessionStorage), 'setItem');
jest.spyOn(Object.getPrototypeOf(sessionStorage), 'getItem').mockReturnValue('/');

// When
render(<TestComponent />);

// Then
expect(setItem).toHaveBeenCalledWith('previous-page', '/');
expect(setItem).toHaveBeenLastCalledWith('current-page', '/other-page');
});
});
});
19 changes: 19 additions & 0 deletions src/client/hooks/useDisplayBackButton.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useRouter } from 'next/router';
import { useLayoutEffect } from 'react';

const CURRENT_PAGE = 'current-page';
export const PREVIOUS_PAGE = 'previous-page';

function useDisplayBackButton(): void {
const router = useRouter();

useLayoutEffect(() => {
const currentPage = sessionStorage.getItem(CURRENT_PAGE);
if (currentPage && currentPage !== router.pathname) {
sessionStorage.setItem(PREVIOUS_PAGE, currentPage);
}
sessionStorage.setItem(CURRENT_PAGE, router.pathname);
}, [router.pathname]);
}

export default useDisplayBackButton;
15 changes: 0 additions & 15 deletions src/client/hooks/useReferrer.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/client/hooks/useSessionStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ function useSessionStorage<T>(key: string): {get: () => T | null, set: (value: T
remove: () => setDefaultValue(null),
set: setDefaultValue,
};
};
}

export default useSessionStorage;
5 changes: 3 additions & 2 deletions src/pages/_app.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React, { ReactElement, ReactNode, useEffect, useMemo } from 'react';
import { Layout } from '~/client/components/layouts/Layout';
import { DependenciesProvider } from '~/client/context/dependenciesContainer.context';
import dependenciesContainer from '~/client/dependencies.container';
import useReferrer from '~/client/hooks/useReferrer';
import useDisplayBackButton from '~/client/hooks/useDisplayBackButton';
import useSessionId from '~/client/hooks/useSessionId';

export type NextPageWithLayout<P = object> = NextPage<P, P> & {
Expand All @@ -24,7 +24,8 @@ export default function App({ Component, pageProps }: AppPropsWithLayout) {
const sessionId = useSessionId();
const dependenciesContainerInstance = useMemo(() => sessionId && dependenciesContainer(sessionId), [sessionId]);
const router = useRouter();
useReferrer();

useDisplayBackButton();

useEffect(() => {
const [/* full path */, targetId] = router.asPath.match(/^[^#]*#(.+)$/) ?? [];
Expand Down