From afff60e3b93271d89679df77edf38ecf6e5d92e3 Mon Sep 17 00:00:00 2001
From: Albina <51043550+albinazs@users.noreply.github.com>
Date: Fri, 17 Feb 2023 01:51:00 +0200
Subject: [PATCH] Add unit tests for MinimapItem (#10083)

Co-authored-by: Thibaud Colas <thibaudcolas@gmail.com>
---
 CHANGELOG.txt                                 |   2 +-
 .../components/Minimap/MinimapItem.test.tsx   | 108 ++++++++++++++++++
 docs/releases/5.0.md                          |   4 +-
 3 files changed, 111 insertions(+), 3 deletions(-)
 create mode 100644 client/src/components/Minimap/MinimapItem.test.tsx

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 3df3253d11..47d10bc4be 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -32,7 +32,7 @@ Changelog
  * Maintenance: Refactor accessibility checker userbar item (Albina Starykova)
  * Maintenance: Removed unused `Page.get_static_site_paths` method (Yosr Karoui)
  * Maintenance: Provisional Django 5.0 compatibility fixes (Sage Abdullah)
- * Maintenance: Add unit tests for `CollapseAll` component (Albina Starykova)
+ * Maintenance: Add unit tests for `CollapseAll` and `MinimapItem` components (Albina Starykova)
  * Maintenance: Code quality fixes (GLEF1X)
  * Maintenance: Refactor image / document / snippet usage views into a shared generic view (Sage Abdullah)
  * Maintenance: Rename the Stimulus `AutoFieldController` to the less confusing `SubmitController` (Loveth Omokaro)
diff --git a/client/src/components/Minimap/MinimapItem.test.tsx b/client/src/components/Minimap/MinimapItem.test.tsx
new file mode 100644
index 0000000000..abb812b44b
--- /dev/null
+++ b/client/src/components/Minimap/MinimapItem.test.tsx
@@ -0,0 +1,108 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import MinimapItem from './MinimapItem';
+
+const mockItem = {
+  anchor: document.createElement('a'),
+  toggle: document.createElement('button'),
+  panel: document.createElement('div'),
+  href: '',
+  label: 'text with more than 26 characters',
+  icon: '',
+  required: true,
+  errorCount: 1,
+  level: 'h1' as const,
+};
+
+const mockProps = {
+  item: mockItem,
+  intersects: false,
+  expanded: false,
+  onClick: () => {},
+};
+
+describe('MinimapItem', () => {
+  it('exists', () => {
+    expect(MinimapItem).toBeDefined();
+  });
+
+  it('renders error count if has errors', () => {
+    const wrapper = shallow(<MinimapItem {...mockProps} />);
+    const errors = wrapper.find('.w-minimap-item__errors');
+    expect(errors.text()).toBe('1');
+    expect(errors.prop('aria-label')).toBe('1 error');
+  });
+
+  it("doesn't render error count if no errors", () => {
+    const item = { ...mockItem, errorCount: 0 };
+    const wrapper = shallow(<MinimapItem {...mockProps} item={item} />);
+    expect(wrapper.find('.w-minimap-item__errors')).toHaveLength(0);
+  });
+
+  it('shows correct text for multiple errors', () => {
+    const item = { ...mockItem, errorCount: 2 };
+    const wrapper = shallow(<MinimapItem {...mockProps} item={item} />);
+    expect(wrapper.find('.w-minimap-item__errors').prop('aria-label')).toBe(
+      '2 errors',
+    );
+  });
+
+  it('truncates long label texts', () => {
+    const wrapper = shallow(<MinimapItem {...mockProps} />);
+    expect(wrapper.text()).toBe('1<Icon />text with more than 26 cha…*');
+  });
+
+  it('does not truncate short label texts', () => {
+    const item = { ...mockItem, label: 'short text' };
+    const wrapper = shallow(<MinimapItem {...mockProps} item={item} />);
+    expect(wrapper.text()).toBe('1<Icon />short text*');
+  });
+
+  it('applies aria-current by default', () => {
+    const wrapper = shallow(<MinimapItem {...mockProps} />);
+    expect(wrapper.find('a').prop('aria-current')).toBe(false);
+  });
+
+  it('applies aria-current when intersects', () => {
+    const wrapper = shallow(<MinimapItem {...mockProps} intersects />);
+    expect(wrapper.find('a').prop('aria-current')).toBe(true);
+  });
+
+  it('is not focusable by default', () => {
+    const wrapper = shallow(<MinimapItem {...mockProps} />);
+    expect(wrapper.find('a').prop('tabIndex')).toBe(-1);
+  });
+
+  it('becomes focusable when expanded', () => {
+    const wrapper = shallow(<MinimapItem {...mockProps} expanded />);
+    expect(wrapper.find('a').prop('tabIndex')).toBeUndefined();
+  });
+
+  it("doesn't render Icon element if heading level is h1", () => {
+    const wrapper = shallow(<MinimapItem {...mockProps} />);
+    expect(wrapper.find('.w-minimap-item__icon')).toHaveLength(0);
+  });
+
+  it("doesn't render Icon element if heading level is h2", () => {
+    const item = { ...mockItem, level: 'h2' as const };
+    const wrapper = shallow(<MinimapItem {...mockProps} item={item} />);
+    expect(wrapper.find('.w-minimap-item__icon')).toHaveLength(0);
+  });
+
+  it('renders Icon element if heading level is not h1 or h2', () => {
+    const item = { ...mockItem, level: 'h3' as const };
+    const wrapper = shallow(<MinimapItem {...mockProps} item={item} />);
+    expect(wrapper.find('.w-minimap-item__icon')).toHaveLength(1);
+  });
+
+  it('renders requiredMark element if required', () => {
+    const wrapper = shallow(<MinimapItem {...mockProps} />);
+    expect(wrapper.find('.w-required-mark')).toHaveLength(1);
+  });
+
+  it("doesn't render requiredMark element if not required", () => {
+    const item = { ...mockItem, required: false };
+    const wrapper = shallow(<MinimapItem {...mockProps} item={item} />);
+    expect(wrapper.find('.w-required-mark')).toHaveLength(0);
+  });
+});
diff --git a/docs/releases/5.0.md b/docs/releases/5.0.md
index ee6e83b130..cf9276a8ce 100644
--- a/docs/releases/5.0.md
+++ b/docs/releases/5.0.md
@@ -51,11 +51,11 @@ depth: 1
  * Refactor accessibility checker userbar item (Albina Starykova)
  * Removed unused `Page.get_static_site_paths` method (Yosr Karoui)
  * Provisional Django 5.0 compatibility fixes (Sage Abdullah)
- * Add unit tests for `CollapseAll` component (Albina Starykova)
+ * Add unit tests for `CollapseAll` and `MinimapItem` components (Albina Starykova)
  * Code quality fixes (GLEF1X)
  * Refactor image / document / snippet usage views into a shared generic view (Sage Abdullah)
  * Rename the Stimulus `AutoFieldController` to the less confusing `SubmitController` (Loveth Omokaro)
- * Maintenance: Replace `script` tags with `template` tag for image/document bulk uploads (Rishabh Kumar Bahukhandi)
+ * Replace `script` tags with `template` tag for image/document bulk uploads (Rishabh Kumar Bahukhandi)
 
 ## Upgrade considerations