Skip to content

Commit

Permalink
707: Broke unit tests into two files. All tests pass now.
Browse files Browse the repository at this point in the history
  • Loading branch information
tombogle committed Feb 22, 2024
1 parent 75bfb95 commit b5c3580
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ function MenuColumn(
return (
<Grid id={id} item xs="auto" className={`papi-menu-column ${className ?? ''}`}>
<h3 className={`papi-menu-column-header ${className ?? ''}`}>{metadata.label}</h3>
{/* It would seem as though this List component were unnecessary, since it only contains one
thing, but the "dense" property does affect the layout of the items (in a way I don't fully
understand). There might be a better way. */}
<List id={id} dense className={className ?? ''}>
<TopLevelMenu
commandHandler={commandHandler}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { PlatformMenus } from 'platform-bible-utils';
import { fireEvent, render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import GridMenu from './grid-menu.component';
import { Command } from './menu-item.component';
import NonValidatingDocumentCombiner from '../test-utils/non-validating-document-combiner';
import * as jsonMenu from './sample.composed.full.menu.json';

let lastCommandHandled: string;
let numberOfCommandsHandled: number = 0;

function RememberLastMenuCommand(command: Command) {
lastCommandHandled = command.command;
numberOfCommandsHandled += 1;
}

describe('GridMenu', () => {
const topMenuCombiner = new NonValidatingDocumentCombiner(jsonMenu, {
copyDocuments: false,
ignoreDuplicateProperties: true,
});

// Assert the type that schema validation should have already sorted out
// eslint-disable-next-line no-type-assertion/no-type-assertion
const menuData = topMenuCombiner.output as PlatformMenus;

it('handles click event correctly', () => {
render(
<GridMenu multiColumnMenu={menuData.mainMenu} commandHandler={RememberLastMenuCommand} />,
);

const sendReceiveProjectsItem = screen.queryByText('%sendReceiveProjects%');
expect(sendReceiveProjectsItem).toBeDefined();

sendReceiveProjectsItem && fireEvent.click(sendReceiveProjectsItem);

expect(numberOfCommandsHandled).toBe(1);
expect(lastCommandHandled).toBe('paratext.sendReceiveProjects');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { PlatformMenus } from 'platform-bible-utils';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import GridMenu from './grid-menu.component';
import { MouseEventHandler, PropsWithChildren } from 'react';
import NonValidatingDocumentCombiner from '../test-utils/non-validating-document-combiner';
import * as jsonMenu from './sample.composed.full.menu.json';

jest.mock('@mui/material', () => {
const mui = jest.requireActual('@mui/material'); // Import the actual MUI components

return {
...mui, // Spread the actual MUI exports

// Mocked components
MenuItem: ({
divider,
className,
children,
}: {
divider: boolean | undefined;
className: string | undefined;
onClick?: MouseEventHandler<HTMLLIElement> | undefined;
} & PropsWithChildren) => {
const dividerStyle = divider ? ' hasDivider' : '';
return (
<li className={`${className || ''}${dividerStyle}`} role="menuitem">
{children}
</li>
);
},
};
});

function HandleMenuCommandNoOp() {
}

describe('GridMenu renders', () => {
const topMenuCombiner = new NonValidatingDocumentCombiner(jsonMenu, {
copyDocuments: false,
ignoreDuplicateProperties: true,
});

// Assert the type that schema validation should have already sorted out
// eslint-disable-next-line no-type-assertion/no-type-assertion
const menuData = topMenuCombiner.output as PlatformMenus;
render(
<GridMenu multiColumnMenu={menuData.mainMenu} commandHandler={HandleMenuCommandNoOp} />,
);

it('column label correctly', () => {
const expectedColumns = [
screen.queryByText('%mainMenu_Paratext%'),
screen.queryByText('%mainMenu_Window%'),
screen.queryByText('%mainMenu_Layout%'),
screen.queryByText('%mainMenu_Help%'),
];

expectedColumns.forEach((column) => {
expect(column).toBeInTheDocument();
expect(column).toHaveAttribute(
'class',
expect.stringMatching(/\bpapi-menu-column-header\b/),
);
});
});

const allMenuItems = screen.queryAllByRole('menuitem');

// We expect all the top-level menu items to be laid out in the grid, but not the ones which
// belong to a submenu.
// (Note: In our test data, groups that are in submenus have the text "Sub" in them.)
const expectedMenuItems = jsonMenu.mainMenu.items.filter(
(i) => 'group' in i && !/sub/i.test(i.group),
);

it('the correct total number of items', () => {
expect(allMenuItems.length).toBe(expectedMenuItems.length);
});

it('the correct total number of groups with dividers', () => {
let cGroupsWithDividers = 0;
allMenuItems.forEach((m) => {
if (m.outerHTML?.match('hasDivider')) cGroupsWithDividers += 1;
});

// In the test data, only 4 of the column-level groups contain menu items. They are in two
// columns and there should be no divider for the final group in each column.
expect(cGroupsWithDividers).toBe(2);
});

it('the last group in a column without a final separator', () => {
const htmlForAddParatextVideoItem = allMenuItems.map((i) => i.outerHTML).find((html) => html &&
/%video_AddParatextVideo%/.test(html),
);

expect(htmlForAddParatextVideoItem).toBeDefined();
expect(htmlForAddParatextVideoItem).not.toMatch('hasDivider');
});
});
133 changes: 0 additions & 133 deletions lib/platform-bible-react/src/components/gridMenu.component.test.tsx

This file was deleted.

0 comments on commit b5c3580

Please sign in to comment.