From c6212f927daf3c928f479afa052e4772216a2d8a Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Tue, 21 Nov 2023 16:10:20 +0100
Subject: refactor(components): replace items prop in Navbar component

* replace `items` prop with `children` prop: it is more readable this
way,
* handle navbar item state inside NavbarItem component: it avoid using
three differents states and their methods to do exactly the same thing
* remove useAutofocus hook since we can't use it anymore
* add `onActivation` and `activationHandlerDelay` prop to NavbarItem
component to be able to focus the search input only when the item is
activated (it replicates the functioning of useAutofocus hook)
* replace `ref` type in SearchForm component: it does not make sense to
use an input ref for a form. Instead I use useImperativeHandle to
provide different a focus method to the given ref.
---
 .../navbar/navbar-item/navbar-item.test.tsx        | 63 ++++++++++++----------
 1 file changed, 35 insertions(+), 28 deletions(-)

(limited to 'src/components/organisms/navbar/navbar-item/navbar-item.test.tsx')

diff --git a/src/components/organisms/navbar/navbar-item/navbar-item.test.tsx b/src/components/organisms/navbar/navbar-item/navbar-item.test.tsx
index 2e7edea..e531ff6 100644
--- a/src/components/organisms/navbar/navbar-item/navbar-item.test.tsx
+++ b/src/components/organisms/navbar/navbar-item/navbar-item.test.tsx
@@ -1,24 +1,7 @@
-import { describe, expect, it } from '@jest/globals';
+import { describe, expect, it, jest } from '@jest/globals';
 import { render, screen as rtlScreen } from '@testing-library/react';
 import { userEvent } from '@testing-library/user-event';
-import { useBoolean } from '../../../../utils/hooks';
-import { NavbarItem, type NavbarItemProps } from './navbar-item';
-
-const ControlledNavbarItem = ({
-  isActive,
-  ...props
-}: Omit<NavbarItemProps, 'onDeactivate' | 'onToggle'>) => {
-  const { deactivate, state, toggle } = useBoolean(isActive);
-
-  return (
-    <NavbarItem
-      {...props}
-      isActive={state}
-      onDeactivate={deactivate}
-      onToggle={toggle}
-    />
-  );
-};
+import { NavbarItem } from './navbar-item';
 
 describe('NavbarItem', () => {
   it('renders a labelled checkbox to open/close a modal', async () => {
@@ -27,14 +10,9 @@ describe('NavbarItem', () => {
     const user = userEvent.setup();
 
     render(
-      <ControlledNavbarItem
-        icon="arrow"
-        id="vel"
-        isActive={false}
-        label={label}
-      >
+      <NavbarItem icon="arrow" id="vel" label={label}>
         {modal}
-      </ControlledNavbarItem>
+      </NavbarItem>
     );
 
     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
@@ -58,9 +36,9 @@ describe('NavbarItem', () => {
     const user = userEvent.setup();
 
     render(
-      <ControlledNavbarItem icon="arrow" id="et" isActive label={label}>
+      <NavbarItem icon="arrow" id="et" label={label}>
         {modal}
-      </ControlledNavbarItem>
+      </NavbarItem>
     );
 
     // eslint-disable-next-line @typescript-eslint/no-magic-numbers
@@ -68,6 +46,8 @@ describe('NavbarItem', () => {
 
     const controller = rtlScreen.getByRole('checkbox', { name: label });
 
+    await user.click(controller);
+
     expect(controller).toBeChecked();
 
     if (controller.parentElement) await user.click(controller.parentElement);
@@ -76,4 +56,31 @@ describe('NavbarItem', () => {
     // Since the visibility is declared in CSS we cannot use this assertion.
     //expect(rtlScreen.getByText(modal)).not.toBeVisible();
   });
+
+  /* eslint-disable max-statements */
+  it('accepts an activation handler', async () => {
+    const handler = jest.fn();
+    const user = userEvent.setup();
+    const label = 'qui';
+
+    render(
+      <NavbarItem icon="arrow" id="aut" label={label} onActivation={handler}>
+        Some contents
+      </NavbarItem>
+    );
+
+    // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+    expect.assertions(3);
+
+    expect(handler).not.toHaveBeenCalled();
+
+    await user.click(rtlScreen.getByLabelText(label));
+
+    /* For some reasons (probably setTimeout) it is called twice but if I use
+    jest fake timers the test throws `Exceeded timeout`... So I leave it with 2
+    for now. */
+    expect(handler).toHaveBeenCalledTimes(2);
+    expect(handler).toHaveBeenCalledWith(true);
+  });
+  /* eslint-enable max-statements */
 });
-- 
cgit v1.2.3

