aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils/hooks/use-breadcrumbs/use-breadcrumbs.test.tsx
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-12-12 18:50:03 +0100
committerArmand Philippot <git@armandphilippot.com>2023-12-12 18:50:03 +0100
commit85c4c42bd601270d7be0f34a0767a34bb85e29bb (patch)
tree16a07a89cf209139672592fd6988f0c028acb7e9 /src/utils/hooks/use-breadcrumbs/use-breadcrumbs.test.tsx
parent93f87c10783e3d76f1dec667779aedffcae33a39 (diff)
refactor(hooks): rewrite useBreadcrumbs hook
* use next/router to get the slug instead of using props * handle cases where the current page title is not provided * update JSON-LD schema to match the example in documentation * add tests
Diffstat (limited to 'src/utils/hooks/use-breadcrumbs/use-breadcrumbs.test.tsx')
-rw-r--r--src/utils/hooks/use-breadcrumbs/use-breadcrumbs.test.tsx232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/utils/hooks/use-breadcrumbs/use-breadcrumbs.test.tsx b/src/utils/hooks/use-breadcrumbs/use-breadcrumbs.test.tsx
new file mode 100644
index 0000000..9778aed
--- /dev/null
+++ b/src/utils/hooks/use-breadcrumbs/use-breadcrumbs.test.tsx
@@ -0,0 +1,232 @@
+import { describe, expect, it } from '@jest/globals';
+import { act, renderHook } from '@testing-library/react';
+import nextRouterMock from 'next-router-mock';
+import { MemoryRouterProvider } from 'next-router-mock/MemoryRouterProvider';
+import type { ReactNode } from 'react';
+import { IntlProvider } from 'react-intl';
+import { PAGINATED_ROUTE_PREFIX, ROUTES } from '../../constants';
+import { capitalize } from '../../helpers';
+import { useBreadcrumbs } from './use-breadcrumbs';
+
+const AllProviders = ({ children }: { children: ReactNode }) => (
+ <IntlProvider defaultLocale="en" locale="en">
+ <MemoryRouterProvider>{children}</MemoryRouterProvider>
+ </IntlProvider>
+);
+
+describe('useBreadcrumbs', () => {
+ it('returns the breadcrumbs items and its schema', async () => {
+ const currentSlug = '/current-slug';
+ const label = capitalize(
+ (currentSlug.split('/').pop() ?? currentSlug).replaceAll('-', ' ')
+ );
+
+ await act(async () => nextRouterMock.push(currentSlug));
+
+ const { result } = renderHook(() => useBreadcrumbs(), {
+ wrapper: AllProviders,
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect.assertions(4);
+
+ expect(result.current.items).toHaveLength(2);
+ expect(result.current.items[0]).toStrictEqual({
+ id: '/',
+ label: 'Home',
+ slug: '/',
+ });
+ expect(result.current.items[1]).toStrictEqual({
+ id: currentSlug,
+ label,
+ slug: currentSlug,
+ });
+ expect(result.current.schema).toStrictEqual({
+ '@type': 'BreadcrumbList',
+ '@id': 'breadcrumbs',
+ itemListElement: [
+ {
+ '@type': 'ListItem',
+ item: {
+ '@id': ROUTES.HOME,
+ name: 'Home',
+ },
+ position: 1,
+ },
+ {
+ '@type': 'ListItem',
+ item: {
+ '@id': currentSlug,
+ name: label,
+ },
+ position: 2,
+ },
+ ],
+ });
+ });
+
+ it('can render the items for the 404 page', async () => {
+ await act(async () => nextRouterMock.push(ROUTES.NOT_FOUND));
+
+ const { result } = renderHook(() => useBreadcrumbs(), {
+ wrapper: AllProviders,
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect.assertions(3);
+
+ expect(result.current.items).toHaveLength(2);
+ expect(result.current.items[0]).toStrictEqual({
+ id: '/',
+ label: 'Home',
+ slug: '/',
+ });
+ expect(result.current.items[1]).toStrictEqual({
+ id: ROUTES.NOT_FOUND,
+ label: '404: Not found',
+ slug: ROUTES.NOT_FOUND,
+ });
+ });
+
+ it('can render the items for the Blog page', async () => {
+ await act(async () => nextRouterMock.push(ROUTES.BLOG));
+
+ const { result } = renderHook(() => useBreadcrumbs(), {
+ wrapper: AllProviders,
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect.assertions(3);
+
+ expect(result.current.items).toHaveLength(2);
+ expect(result.current.items[0]).toStrictEqual({
+ id: '/',
+ label: 'Home',
+ slug: '/',
+ });
+ expect(result.current.items[1]).toStrictEqual({
+ id: ROUTES.BLOG,
+ label: 'Blog',
+ slug: ROUTES.BLOG,
+ });
+ });
+
+ it('can render the items for the paginated routes', async () => {
+ const pageNumber = 3;
+ const currentSlug = `${ROUTES.BLOG}${PAGINATED_ROUTE_PREFIX}/${pageNumber}`;
+ await act(async () => nextRouterMock.push(currentSlug));
+
+ const { result } = renderHook(() => useBreadcrumbs(), {
+ wrapper: AllProviders,
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect.assertions(4);
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect(result.current.items).toHaveLength(3);
+ expect(result.current.items[0]).toStrictEqual({
+ id: '/',
+ label: 'Home',
+ slug: '/',
+ });
+ expect(result.current.items[1]).toStrictEqual({
+ id: ROUTES.BLOG,
+ label: 'Blog',
+ slug: ROUTES.BLOG,
+ });
+ expect(result.current.items[2]).toStrictEqual({
+ id: currentSlug,
+ label: `Page ${pageNumber}`,
+ slug: currentSlug,
+ });
+ });
+
+ it('can render the items for the Projects page', async () => {
+ await act(async () => nextRouterMock.push(ROUTES.PROJECTS));
+
+ const { result } = renderHook(() => useBreadcrumbs(), {
+ wrapper: AllProviders,
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect.assertions(3);
+
+ expect(result.current.items).toHaveLength(2);
+ expect(result.current.items[0]).toStrictEqual({
+ id: '/',
+ label: 'Home',
+ slug: '/',
+ });
+ expect(result.current.items[1]).toStrictEqual({
+ id: ROUTES.PROJECTS,
+ label: 'Projects',
+ slug: ROUTES.PROJECTS,
+ });
+ });
+
+ it('can render the items for the Search page', async () => {
+ const query = 'similique';
+ const currentSlug = `${ROUTES.SEARCH}?s=${query}`;
+ await act(async () => nextRouterMock.push(currentSlug));
+
+ const { result } = renderHook(() => useBreadcrumbs(), {
+ wrapper: AllProviders,
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect.assertions(4);
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect(result.current.items).toHaveLength(3);
+ expect(result.current.items[0]).toStrictEqual({
+ id: '/',
+ label: 'Home',
+ slug: '/',
+ });
+ expect(result.current.items[1]).toStrictEqual({
+ id: ROUTES.SEARCH,
+ label: 'Search',
+ slug: ROUTES.SEARCH,
+ });
+ expect(result.current.items[2]).toStrictEqual({
+ id: currentSlug,
+ label: `Search results for "${query}"`,
+ slug: currentSlug,
+ });
+ });
+
+ it('can render the items for the Articles page', async () => {
+ const article = {
+ slug: '/the-article-slug',
+ title: 'qui ducimus rerum',
+ };
+ const currentSlug = `${ROUTES.ARTICLE}${article.slug}`;
+ await act(async () => nextRouterMock.push(currentSlug));
+
+ const { result } = renderHook(() => useBreadcrumbs(article.title), {
+ wrapper: AllProviders,
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect.assertions(4);
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect(result.current.items).toHaveLength(3);
+ expect(result.current.items[0]).toStrictEqual({
+ id: '/',
+ label: 'Home',
+ slug: '/',
+ });
+ expect(result.current.items[1]).toStrictEqual({
+ id: ROUTES.BLOG,
+ label: 'Blog',
+ slug: ROUTES.BLOG,
+ });
+ expect(result.current.items[2]).toStrictEqual({
+ id: currentSlug,
+ label: article.title,
+ slug: currentSlug,
+ });
+ });
+});