globalCanvasEscape.test.tsx2.8 KBView on GitHub import { act, fireEvent, render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router';
import React from 'react';
/**
* Escape closes the canvas dropped over the page — the ⇧Q calendar above all, which you reach
* from anywhere and so need to get out of from anywhere.
*
* The one thing it must NOT do is close out from under a layer of its own: the date picker, the
* event composer, a confirm dialog. Escape there belongs to that layer.
*/
jest.mock('@/modules/calendar/components/CalendarCanvasSurface', () => ({
CalendarCanvasSurface: () => {
const R = require('react');
return R.createElement('div', { 'data-testid': 'calendar-canvas' }, 'CALENDAR');
},
}));
jest.mock('@/modules/canvas/components/CanvasRenderer', () => ({
CanvasRenderer: () => null,
}));
import { GlobalCanvas } from '@/components/ui/GlobalCanvas';
import { useCedarStore } from '@/store/CedarStore';
const openCalendarCanvas = () =>
act(() => {
useCedarStore.setState((s) => ({ ...s, isGlobalCanvasOpen: true, activeCanvasId: 'calendar' }));
});
const renderCanvas = () =>
render(
<MemoryRouter>
<GlobalCanvas />
</MemoryRouter>,
);
describe('Escape and the global canvas', () => {
afterEach(() => {
act(() => {
useCedarStore.setState((s) => ({ ...s, isGlobalCanvasOpen: false, activeCanvasId: null }));
});
});
it('closes the calendar canvas', () => {
openCalendarCanvas();
renderCanvas();
expect(screen.getByTestId('calendar-canvas')).toBeInTheDocument();
act(() => {
fireEvent.keyDown(document, { key=[redacted] });
});
expect(useCedarStore.getState().isGlobalCanvasOpen).toBe(false);
});
it('leaves it alone while a dialog or popover on top of it owns the key', () => {
openCalendarCanvas();
renderCanvas();
const dialog = document.createElement('div');
dialog.setAttribute('role', 'dialog');
document.body.appendChild(dialog);
act(() => {
fireEvent.keyDown(document, { key=[redacted] });
});
expect(useCedarStore.getState().isGlobalCanvasOpen).toBe(true);
dialog.remove();
// …and an Escape a layer has already handled (Radix calls preventDefault on the topmost
// one) is not a second chance to close the canvas.
const handledFirst = (e: KeyboardEvent) => e.preventDefault();
document.addEventListener('keydown', handledFirst, true);
act(() => {
fireEvent.keyDown(document.body, { key=[redacted] });
});
expect(useCedarStore.getState().isGlobalCanvasOpen).toBe(true);
document.removeEventListener('keydown', handledFirst, true);
// With nothing on top, the same key closes it.
act(() => {
fireEvent.keyDown(document.body, { key=[redacted] });
});
expect(useCedarStore.getState().isGlobalCanvasOpen).toBe(false);
});
});