Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { render } from '@bfc/test-utils';
import { ExtensionContext } from '@bfc/extension';

import AdaptiveFlowEditor from '../../src/adaptive-flow-editor/AdaptiveFlowEditor';

import { ShellApiStub } from './stubs/ShellApiStub';

describe('<VisualDesigner/>', () => {
it('can render.', () => {
const visualDesigner = render(
<ExtensionContext.Provider
value={{
shellApi: ShellApiStub,
shellData: {} as any,
plugins: [],
}}
>
<AdaptiveFlowEditor />
</ExtensionContext.Provider>
);
expect(visualDesigner).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { render, fireEvent } from '@bfc/test-utils';

import { KeyboardZone } from '../../../src/adaptive-flow-editor/components/KeyboardZone';

describe('KeyboardZone', () => {
it('can be rendered.', () => {
const zone = render(
<KeyboardZone onCommand={() => undefined}>
<span data-testid="zone-child">children</span>
</KeyboardZone>
);
expect(zone).toBeTruthy();
expect(zone.getByTestId('zone-child')).toBeTruthy();
});

it('can trigger onCommand.', () => {
const mockOnCommand = jest.fn();
const zone = render(
<KeyboardZone onCommand={mockOnCommand}>
<span data-testid="zone-child">children</span>
</KeyboardZone>
).getByTestId('keyboard-zone');

fireEvent.focus(zone);
fireEvent.keyDown(
zone,
new KeyboardEvent('keydown', {
key: 'C',
code: 'C',
ctrlKey: true,
})
);
expect(mockOnCommand).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { AttrNames } from '../../../src/adaptive-flow-editor/constants/ElementAttributes';

describe('ElementAttributes', () => {
it('should contain necessary attrs.', () => {
expect(AttrNames.SelectableElement).toBeTruthy();
expect(AttrNames.NodeElement).toBeTruthy();
expect(AttrNames.EdgeMenuElement).toBeTruthy();
expect(AttrNames.FocusedId).toBeTruthy();
expect(AttrNames.InlineLinkElement).toBeTruthy();
expect(AttrNames.SelectedId).toBeTruthy();
expect(AttrNames.Tab).toBeTruthy();
expect(AttrNames.FocusedId).toBeTruthy();
expect(AttrNames.SelectionIndex).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import {
KeyboardCommandTypes,
KeyboardPrimaryTypes,
mapShortcutToKeyboardCommand,
} from '../../../src/adaptive-flow-editor/constants/KeyboardCommandTypes';

describe('KeyboardCommandTypes', () => {
it('should be truthy.', () => {
expect(KeyboardCommandTypes).toBeTruthy();
});

it('should contain 3 categories.', () => {
expect(KeyboardCommandTypes.Cursor).toBeTruthy();
expect(KeyboardCommandTypes.Node).toBeTruthy();
expect(KeyboardCommandTypes.Operation).toBeTruthy();
});

it('<Cursor> should contain necessary commands.', () => {
const { Cursor } = KeyboardCommandTypes;

expect(Cursor.MoveUp).toBeTruthy();
expect(Cursor.MoveDown).toBeTruthy();
expect(Cursor.MoveLeft).toBeTruthy();
expect(Cursor.MoveRight).toBeTruthy();
expect(Cursor.ShortMoveUp).toBeTruthy();
expect(Cursor.ShortMoveDown).toBeTruthy();
expect(Cursor.ShortMoveLeft).toBeTruthy();
expect(Cursor.ShortMoveRight).toBeTruthy();
expect(Cursor.MovePrevious).toBeTruthy();
expect(Cursor.MoveNext).toBeTruthy();
});

it('<Node> should contain necessary actions.', () => {
const { Node } = KeyboardCommandTypes;

expect(Node.Delete).toBeTruthy();
expect(Node.Copy).toBeTruthy();
expect(Node.Cut).toBeTruthy();
expect(Node.Paste).toBeTruthy();
});

it('<Operation> should contain necessary operations.', () => {
const { Operation } = KeyboardCommandTypes;

expect(Operation.Undo).toBeTruthy();
expect(Operation.Redo).toBeTruthy();
});
});

describe('KeyboardPrimaryTypes', () => {
it('should contain 3 types.', () => {
expect(KeyboardPrimaryTypes.Cursor).toBeTruthy();
expect(KeyboardPrimaryTypes.Node).toBeTruthy();
expect(KeyboardPrimaryTypes.Operation).toBeTruthy();
});
});

describe('mapShortcutToKeyboardCommand', () => {
expect(mapShortcutToKeyboardCommand('Windows.Control.Z')).toEqual({
area: 'Operation',
command: 'undo',
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { MenuTypes, MenuEventTypes } from '../../../src/adaptive-flow-editor/constants/MenuTypes';

describe('MenuTypes', () => {
it('should contain necessary keys.', () => {
expect(MenuTypes.EdgeMenu).toBeTruthy();
expect(MenuTypes.NodeMenu).toBeTruthy();
expect(MenuEventTypes.Paste).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { ScreenReaderMessage } from '../../../src/adaptive-flow-editor/constants/ScreenReaderMessage';

describe('ScreenReaderMessage', () => {
it('should contain necessary messages.', () => {
expect(ScreenReaderMessage.EventFocused).toBeTruthy();
expect(ScreenReaderMessage.ActionFocused).toBeTruthy();
expect(ScreenReaderMessage.ActionUnfocused).toBeTruthy();
expect(ScreenReaderMessage.RangeSelection).toBeTruthy();
expect(ScreenReaderMessage.DialogOpened).toBeTruthy();
expect(ScreenReaderMessage.ActionDeleted).toBeTruthy();
expect(ScreenReaderMessage.ActionsDeleted).toBeTruthy();
expect(ScreenReaderMessage.ActionCreated).toBeTruthy();
expect(ScreenReaderMessage.ActionsCreated).toBeTruthy();
expect(ScreenReaderMessage.EventCreated).toBeTruthy();
expect(ScreenReaderMessage.ActionsCopied).toBeTruthy();
expect(ScreenReaderMessage.ActionsCut).toBeTruthy();
expect(ScreenReaderMessage.ActionsMoved).toBeTruthy();
expect(ScreenReaderMessage.ActionUndo).toBeTruthy();
expect(ScreenReaderMessage.ActionRedo).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { EditorConfig } from '../../../src/adaptive-flow-editor/constants/editorConfig';

describe('EditorConfig', () => {
it('should cover several features.', () => {
expect(EditorConfig).toBeTruthy();
expect(EditorConfig.features).toBeDefined();

expect(EditorConfig.features.showEvents).toBeDefined();
expect(EditorConfig.features.arrowNavigation).toBeDefined();
expect(EditorConfig.features.tabNavigation).toBeDefined();
expect(EditorConfig.features.keyboardNodeEditing).toBeDefined();
expect(EditorConfig.features.keyboardOperationEditing).toBeDefined();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React, { useContext } from 'react';
import { render } from '@bfc/test-utils';
import { DialogFactory } from '@bfc/shared';

import { NodeRendererContext } from '../../../src/adaptive-flow-editor/contexts/NodeRendererContext';

describe('NodeRendererContext', () => {
const CtxtConsumer = () => {
const { focusedId, focusedEvent, focusedTab, clipboardActions, dialogFactory, customSchemas } = useContext(
NodeRendererContext
);

return (
<div>
<span data-testid="focusedId-value">{focusedId}</span>
<span data-testid="focusedEvent-value">{focusedEvent}</span>
<span data-testid="focusedTab-value">{focusedTab}</span>
<span data-testid="clipboardAction-length">{clipboardActions.length}</span>
<span data-testid="dialogFactory-existence">{'' + !!dialogFactory}</span>
<span data-testid="customSchemas-length">{customSchemas.length}</span>
</div>
);
};
it('can be consumed.', () => {
const ele = render(
<NodeRendererContext.Provider
value={{
focusedId: 'id1',
focusedEvent: 'event1',
focusedTab: 'tab1',
clipboardActions: ['action1'],
dialogFactory: new DialogFactory(),
customSchemas: [{}],
}}
>
<CtxtConsumer />
</NodeRendererContext.Provider>
);

expect(ele.getByTestId('focusedId-value').textContent).toEqual('id1');
expect(ele.getByTestId('focusedEvent-value').textContent).toEqual('event1');
expect(ele.getByTestId('focusedTab-value').textContent).toEqual('tab1');
expect(ele.getByTestId('clipboardAction-length').textContent).toEqual('1');
expect(ele.getByTestId('dialogFactory-existence').textContent).toEqual('true');
expect(ele.getByTestId('customSchemas-length').textContent).toEqual('1');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React, { useContext } from 'react';
import { render } from '@bfc/test-utils';

import { SelectionContext } from '../../../src/adaptive-flow-editor/contexts/SelectionContext';

describe('SelectionContext', () => {
const ContextConsumer = () => {
const { getNodeIndex, getSelectableIds, selectedIds, setSelectedIds, selectableElements } = useContext(
SelectionContext
);
return (
<div>
<span data-testid="getNodeIndex-result">{getNodeIndex('')}</span>
<span data-testid="getSelectableIds-result">{getSelectableIds().join(',')}</span>
<span data-testid="selectedIds-str">{selectedIds.join(',')}</span>
<span data-testid="setSelectedIds-existence">{'' + !!setSelectedIds}</span>
<span data-testid="selectableElements-length">{selectableElements.length}</span>
</div>
);
};
it('can be provided.', () => {
const ele = render(
<SelectionContext.Provider
value={{
getNodeIndex: () => 1,
getSelectableIds: () => ['a', 'b', 'c'],
selectedIds: ['a'],
setSelectedIds: () => null,
selectableElements: [],
}}
>
<ContextConsumer />
</SelectionContext.Provider>
);

expect(ele.getByTestId('getNodeIndex-result').textContent).toEqual('1');
expect(ele.getByTestId('getSelectableIds-result').textContent).toEqual('a,b,c');
expect(ele.getByTestId('selectedIds-str').textContent).toEqual('a');
expect(ele.getByTestId('setSelectedIds-existence').textContent).toEqual('true');
expect(ele.getByTestId('selectableElements-length').textContent).toEqual('0');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { renderHook } from '@bfc/test-utils/lib/hooks';

import { useEditorEventApi } from '../../../src/adaptive-flow-editor/hooks/useEditorEventApi';
import { ShellApiStub } from '../stubs/ShellApiStub';
import { defaultRendererContextValue } from '../../../src/adaptive-flow-editor/contexts/NodeRendererContext';
import { defaultSelectionContextValue } from '../../../src/adaptive-flow-editor/contexts/SelectionContext';
import { NodeEventTypes } from '../../../src/adaptive-flow-renderer/constants/NodeEventTypes';

describe('useSelectionEffect', () => {
const hook = renderHook(() =>
useEditorEventApi(
{
path: '',
data: {},
nodeContext: { ...defaultRendererContextValue, focusedId: 'a' },
selectionContext: { ...defaultSelectionContextValue, selectedIds: ['a'] },
},
ShellApiStub
)
).result.current;

it('returns necessary apis.', () => {
expect(hook.handleEditorEvent).toBeTruthy();
});

it('can handle events.', () => {
const { handleEditorEvent } = hook;

handleEditorEvent('event.view.focus' as NodeEventTypes, {});
handleEditorEvent('event.view.ctrl-click' as NodeEventTypes, {});
handleEditorEvent('event.view.shift-click' as NodeEventTypes, {});
handleEditorEvent('event.view.focus-event' as NodeEventTypes, {});
handleEditorEvent('event.view.move-cursor' as NodeEventTypes, {});
handleEditorEvent('event.nav.opendialog' as NodeEventTypes, {});
handleEditorEvent('event.data.delete' as NodeEventTypes, {});
handleEditorEvent('event.data.insert' as NodeEventTypes, {});
handleEditorEvent('event.data.copy-selection' as NodeEventTypes, {});
handleEditorEvent('event.data.cut-selection' as NodeEventTypes, {});
handleEditorEvent('event.data.paste-selection' as NodeEventTypes, {});
handleEditorEvent('event.data.move-selection' as NodeEventTypes, {});
handleEditorEvent('event.data.delete-selection' as NodeEventTypes, {});
handleEditorEvent('event.data.paste-selection--keyboard' as NodeEventTypes, {});
handleEditorEvent('event.data.paste-selection--menu' as NodeEventTypes, {});
handleEditorEvent('event.operation.undo' as NodeEventTypes, {});
handleEditorEvent('event.operation.redo' as NodeEventTypes, {});
});
});
Loading