Skip to content
Merged
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
128 changes: 77 additions & 51 deletions packages/compass-components/src/components/context-menu.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,50 @@
import React from 'react';
import { render, screen, userEvent } from '@mongodb-js/testing-library-compass';
import {
render,
screen,
userEvent,
waitFor,
} from '@mongodb-js/testing-library-compass';
import { expect } from 'chai';
import sinon from 'sinon';
import { ContextMenuProvider } from '@mongodb-js/compass-context-menu';
import { useContextMenuItems, ContextMenu } from './context-menu';
import type { ContextMenuItem } from '@mongodb-js/compass-context-menu';

describe('useContextMenuItems', function () {
let items: ContextMenuItem[];
let onAction: sinon.SinonSpy;

function assertMenuItemsExist(items: ContextMenuItem[]) {
for (let i = 0; i < items.length; i++) {
expect(screen.getByTestId(`menu-group-0-item-${i}`)).to.exist;
}
}

function assertMenuItemsDoNotExist(items: ContextMenuItem[]) {
for (let i = 0; i < items.length; i++) {
expect(screen.queryByTestId(`menu-group-0-item-${i}`)).not.to.exist;
}
}

beforeEach(function () {
onAction = sinon.spy();
items = [
{
label: 'Test Item 1',
onAction: () => onAction(1),
},
{
label: 'Test Item 2',
onAction: () => onAction(2),
},
];
});

afterEach(function () {
sinon.restore();
});

const menuTestTriggerId = 'test-trigger';

const TestComponent = ({
Expand All @@ -29,13 +67,6 @@ describe('useContextMenuItems', function () {
};

it('works with nested providers, using the parent provider', function () {
const items = [
{
label: 'Test Item',
onAction: () => {},
},
];

const { container } = render(
<ContextMenuProvider menuWrapper={ContextMenu}>
<ContextMenuProvider menuWrapper={ContextMenu}>
Expand All @@ -53,53 +84,22 @@ describe('useContextMenuItems', function () {
});

it('renders without error', function () {
const items = [
{
label: 'Test Item',
onAction: () => {},
},
];

render(<TestComponent items={items} />);

expect(screen.getByTestId(menuTestTriggerId)).to.exist;
});

it('shows context menu with items on right click', function () {
const items = [
{
label: 'Test Item 1',
onAction: () => {},
},
{
label: 'Test Item 2',
onAction: () => {},
},
];

render(<TestComponent items={items} />);

const trigger = screen.getByTestId(menuTestTriggerId);
userEvent.click(trigger, { button: 2 });

// The menu items should be rendered
expect(screen.getByTestId('menu-group-0-item-0')).to.exist;
expect(screen.getByTestId('menu-group-0-item-1')).to.exist;
assertMenuItemsExist(items);
});

it('triggers the correct action when menu item is clicked', function () {
const onAction = sinon.spy();
const items = [
{
label: 'Test Item 1',
onAction: () => onAction(1),
},
{
label: 'Test Item 2',
onAction: () => onAction(2),
},
];

render(<TestComponent items={items} />);

const trigger = screen.getByTestId(menuTestTriggerId);
Expand All @@ -111,21 +111,47 @@ describe('useContextMenuItems', function () {
expect(onAction).to.have.been.calledOnceWithExactly(2);
});

it('closes the menu when an item is clicked', async function () {
render(<TestComponent items={items} />);

const trigger = screen.getByTestId(menuTestTriggerId);

// Open the menu with right-click
userEvent.click(trigger, { button: 2 });

// Verify the menu is open (items exist)
assertMenuItemsExist(items);

// Click on a menu item
const menuItem = screen.getByTestId('menu-group-0-item-0');
userEvent.click(menuItem);

// Verify the menu is closed (items do not exist)
await waitFor(() => assertMenuItemsDoNotExist(items));
});

it('closes the menu when clicking outside the menu', async function () {
render(<TestComponent items={items} />);

const trigger = screen.getByTestId(menuTestTriggerId);

// Open the menu with right-click
userEvent.click(trigger, { button: 2 });

// Verify the menu is open (items exist)
assertMenuItemsExist(items);

// Click outside the menu (on document body)
userEvent.click(document.body);

// Verify the menu is closed (items do not exist)
await waitFor(() => assertMenuItemsDoNotExist(items));
});

describe('with nested components', function () {
const childTriggerId = 'child-trigger';

beforeEach(function () {
const items = [
{
label: 'Test Item 1',
onAction: () => {},
},
{
label: 'Test Item 2',
onAction: () => {},
},
];

const childItems = [
{
label: 'Child Item 1',
Expand Down
Loading