Skip to content

Commit

Permalink
Unit test remediation
Browse files Browse the repository at this point in the history
  • Loading branch information
justinwilaby committed Apr 15, 2019
1 parent ae80126 commit 6fe0c29
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 30 deletions.
20 changes: 19 additions & 1 deletion packages/app/client/src/commands/emulatorCommands.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
import { DebugMode, newNotification, SharedConstants } from '@bfemulator/app-shared';
import { newNotification, SharedConstants } from '@bfemulator/app-shared';
import { CommandRegistryImpl } from '@bfemulator/sdk-shared';
import { combineReducers, createStore } from 'redux';

Expand Down Expand Up @@ -158,4 +158,22 @@ describe('The emulator commands', () => {
state = mockStore.getState();
expect(state.chat.changeKey).toBe(3);
});

it('should open a chat file', async () => {
const callSpy = jest.spyOn(CommandServiceImpl, 'call').mockResolvedValue(true);
const remoteCallSpy = jest.spyOn(CommandServiceImpl, 'remoteCall').mockResolvedValue(true);

const { handler: openChatFileHandler } = registry.getCommand(SharedConstants.Commands.Emulator.OpenChatFile);
await openChatFileHandler('some/path.chat', true);
expect(remoteCallSpy).toHaveBeenCalledWith(SharedConstants.Commands.Emulator.OpenChatFile, 'some/path.chat');
expect(callSpy).toHaveBeenCalledWith(
SharedConstants.Commands.Emulator.ReloadTranscript,
'some/path.chat',
undefined,
{
activities: undefined,
inMemory: true,
}
);
});
});
17 changes: 17 additions & 0 deletions packages/app/client/src/commands/uiCommands.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ import {
import { CommandServiceImpl } from '../platform/commands/commandServiceImpl';

import { registerCommands } from './uiCommands';
import { DebugMode } from '@bfemulator/app-shared';
import { BotActionType } from '../data/action/botActions';
import { ExplorerActions } from '../data/action/explorerActions';
import { SWITCH_DEBUG_MODE } from '../data/action/debugModeAction';

jest.mock('../ui/dialogs', () => ({
AzureLoginPromptDialogContainer: class {},
Expand Down Expand Up @@ -145,4 +149,17 @@ describe('the uiCommands', () => {
themeName: 'light',
});
});

it('should orchestrate the switch to sidecar debug mode', async () => {
const dispatchedActions = [];
store.dispatch = action => {
dispatchedActions.push(action);
return action;
};
registry.getCommand(Commands.SwitchDebugMode).handler(DebugMode.Sidecar);
expect(dispatchedActions.length).toBe(4);
[EditorActions.closeAll, BotActionType.close, ExplorerActions.Show, SWITCH_DEBUG_MODE].forEach((type, index) =>
expect(type).toEqual(dispatchedActions[index].type)
);
});
});
12 changes: 9 additions & 3 deletions packages/app/client/src/ui/editor/emulator/emulator.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,7 @@ describe('<Emulator/>', () => {
});

it('should start a new conversation', async () => {
const mockInitConversation = jest.fn(() => null);
instance.initConversation = mockInitConversation;
const initConversationSpy = jest.spyOn(instance, 'initConversation');
const options = {
conversationId: 'convo1',
conversationMode: instance.props.mode,
Expand All @@ -310,7 +309,14 @@ describe('<Emulator/>', () => {

expect(mockUnsubscribe).toHaveBeenCalled();
expect(mockRemoteCallsMade).toHaveLength(0);
expect(mockInitConversation).toHaveBeenCalledWith(instance.props, options);
expect(initConversationSpy).toHaveBeenCalledWith(instance.props, options);
});

it('should start a new conversation when a new document is given as props', async () => {
const startNewConversationSpy = jest.spyOn(instance, 'startNewConversation');
const nextProps = { document: { documentId: 'newDoc' } };
instance.componentWillReceiveProps(nextProps);
expect(startNewConversationSpy).toHaveBeenCalledWith(nextProps);
});

it('should start a new conversation with a new conversation id', async () => {
Expand Down
1 change: 0 additions & 1 deletion packages/app/client/src/ui/editor/emulator/emulator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ export class EmulatorComponent extends React.Component<EmulatorProps, {}> {

if (switchedDocuments) {
if (switchedToThisDocument) {
window.removeEventListener('keydown', keyboardEventListener);
window.addEventListener('keydown', keyboardEventListener);
} else {
window.removeEventListener('keydown', keyboardEventListener);
Expand Down
88 changes: 63 additions & 25 deletions packages/app/client/src/ui/editor/emulator/parts/chat/chat.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,51 +32,68 @@
//

import * as React from 'react';
import { mount, shallow, ShallowWrapper } from 'enzyme';
import ReactWebChat from 'botframework-webchat';
import { mount, ReactWrapper } from 'enzyme';
import { Provider } from 'react-redux';
import ReactWebChat, { createDirectLine } from 'botframework-webchat';
import { ActivityTypes } from 'botframework-schema';
import { DebugMode, ValueTypes } from '@bfemulator/app-shared';

import { CommandServiceImpl } from '../../../../../platform/commands/commandServiceImpl';
import { EmulatorMode } from '../../emulator';

import { Chat, ChatProps } from './chat';
import { ChatProps } from './chat';
import { ChatContainer } from './chatContainer';
import webChatStyleOptions from './webChatTheme';
import { bot } from '../../../../../data/reducer/bot';
import { chat } from '../../../../../data/reducer/chat';
import { editor } from '../../../../../data/reducer/editor';
import { combineReducers, createStore } from 'redux';
import { clientAwareSettings } from '../../../../../data/reducer/clientAwareSettingsReducer';

jest.mock('../../../../dialogs', () => ({
AzureLoginPromptDialogContainer: () => ({}),
AzureLoginSuccessDialogContainer: () => ({}),
BotCreationDialog: () => ({}),
DialogService: { showDialog: () => Promise.resolve(true) },
SecretPromptDialog: () => ({}),
}));
const mockStore = createStore(combineReducers({ bot, chat, clientAwareSettings, editor }), {
clientAwareSettings: {
currentUser: { id: '123', name: 'Current User' },
users: {
currentUserId: '123',
usersById: { '123': { id: '123', name: 'Current User' } },
},
},
});

jest.mock('./chat.scss', () => ({}));
jest.mock('../../../../../data/store', () => ({
get store() {
return mockStore;
},
}));

const defaultDocument = {
directLine: {
token: 'direct line token',
},
directLine: createDirectLine({
secret: '1234',
domain: 'http://localhost/v3/directline',
webSocket: false,
}),
inspectorObjects: [],
botId: '456',
};

function render(overrides: Partial<ChatProps> = {}): ShallowWrapper {
function render(overrides: Partial<ChatProps> = {}): ReactWrapper {
const props = {
document: defaultDocument,
endpoint: {},
mode: 'livechat' as EmulatorMode,
onStartConversation: jest.fn(),
currentUser: { id: '123', name: 'Current User' },
locale: 'en-US',
selectedActivity: {},
...overrides,
} as ChatProps;

return shallow(<Chat {...props} />);
return mount(
<Provider store={mockStore}>
<ChatContainer {...props} />
</Provider>
);
}

describe('<Chat />', () => {
describe('<ChatContainer />', () => {
describe('when there is no direct line client', () => {
it('renders a `not connected` message', () => {
const component = render({ document: {} } as any);
Expand Down Expand Up @@ -198,13 +215,14 @@ describe('<Chat />', () => {
});

describe('event handlers', () => {
let dispatchSpy;
beforeEach(() => {
dispatchSpy = jest.spyOn(mockStore, 'dispatch').mockReturnValue(true);
});
it('should invoke the appropriate functions defined in the props', () => {
const next = () => (kids: any) => kids;
const showContextMenuForActivity = jest.fn();
const chat = render({
debugMode: DebugMode.Sidecar,
showContextMenuForActivity,
setInspectorObject: () => void 0,
});
const card = {
activity: {
Expand All @@ -217,12 +235,32 @@ describe('event handlers', () => {
const webChat = chat.find(ReactWebChat);
const middleware = webChat.prop('activityMiddleware') as any;
const children = 'a child node';
const updateSelectedActivitySpy = jest.spyOn(chat.instance() as any, 'updateSelectedActivity');
const activityWrapper = mount(middleware()(next)(card)(children));
activityWrapper.simulate('keyDown', { key: ' ', target: { tagName: 'DIV', classList: [] } });
expect(dispatchSpy).toHaveBeenCalledWith({
payload: {
documentId: undefined,
objs: [
{
id: 'activity-id',
showInInspector: true,
type: 'trace',
value: { type: 'event' },
valueType: 'https://www.botframework.com/schemas/botState',
},
],
},
type: 'CHAT/INSPECTOR/OBJECTS/SET',
});
activityWrapper.simulate('click', { target: { tagName: 'DIV', classList: [] } });
expect(dispatchSpy).toHaveBeenCalledWith({
payload: {
documentId: undefined,
objs: [{ showInInspector: true }],
},
type: 'CHAT/INSPECTOR/OBJECTS/SET',
});
activityWrapper.simulate('contextmenu', { target: { tagName: 'DIV', classList: [] } });
expect(updateSelectedActivitySpy).toHaveBeenCalled();
expect(showContextMenuForActivity).toHaveBeenCalled();
expect(dispatchSpy).toHaveBeenCalledWith({ payload: undefined, type: 'CHAT/CONTEXT_MENU/SHOW' });
});
});

0 comments on commit 6fe0c29

Please sign in to comment.