Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,18 @@ describe('<FileSelector/>', () => {
expect(await component.findByText('You do not have permission to save bots here')).toBeInTheDocument();
});

it('should update folder name', async () => {
it('should create a new folder', async () => {
const component = renderComponent();
const createFolderBtn = await component.findByText('create new folder');
fireEvent.click(createFolderBtn);
const textField = await component.findByTestId('newFolderTextField');
fireEvent.change(textField, { target: { value: 'newFolder' } });
fireEvent.keyDown(textField, { key: 'Enter' });
//locally this should be 'C:\\test-folder\\Desktop', but it should be 'C:/test-folder/Desktop' online
expect(createFolder).toBeCalledWith('C:/test-folder/Desktop', 'newFolder');
//locally this should be 'C:\\test-folder\\Desktop', but online it should be 'C:/test-folder/Desktop'
expect(
createFolder.mock.calls[0][0] === 'C:/test-folder/Desktop' ||
createFolder.mock.calls[0][0] === 'C:\\test-folder\\Desktop'
).toBeTruthy();
expect(createFolder.mock.calls[0][1]).toBe('newFolder');
});
});
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