Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.

Commit e295d7e

Browse files
authored
Merge branch 'master' into srravich/1973-ngrok-ui
2 parents 909a920 + 7234dcf commit e295d7e

10 files changed

Lines changed: 597 additions & 84 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license.
4+
//
5+
// Microsoft Bot Framework: http://botframework.com
6+
//
7+
// Bot Framework Emulator Github:
8+
// https://github.com/Microsoft/BotFramwork-Emulator
9+
//
10+
// Copyright (c) Microsoft Corporation
11+
// All rights reserved.
12+
//
13+
// MIT License:
14+
// Permission is hereby granted, free of charge, to any person obtaining
15+
// a copy of this software and associated documentation files (the
16+
// "Software"), to deal in the Software without restriction, including
17+
// without limitation the rights to use, copy, modify, merge, publish,
18+
// distribute, sublicense, and/or sell copies of the Software, and to
19+
// permit persons to whom the Software is furnished to do so, subject to
20+
// the following conditions:
21+
//
22+
// The above copyright notice and this permission notice shall be
23+
// included in all copies or substantial portions of the Software.
24+
//
25+
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
26+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32+
//
33+
34+
import { CommandServiceImpl, CommandRegistry, CommandServiceInstance } from '@bfemulator/sdk-shared';
35+
import { SharedConstants } from '@bfemulator/app-shared';
36+
37+
import { ElectronCommands } from './electronCommands';
38+
39+
describe('The misc commands', () => {
40+
let commandService: CommandServiceImpl;
41+
let registry: CommandRegistry;
42+
43+
beforeAll(() => {
44+
new ElectronCommands();
45+
const decorator = CommandServiceInstance();
46+
const descriptor = decorator({ descriptor: {} }, 'none') as any;
47+
commandService = descriptor.descriptor.get();
48+
registry = commandService.registry;
49+
});
50+
51+
it('should toggle the dev tools for open inspectors', () => {
52+
const dispatchEventSpy = jest.spyOn(window, 'dispatchEvent').mockImplementationOnce(ev => null);
53+
const command = registry.getCommand(SharedConstants.Commands.Electron.ToggleDevTools);
54+
command();
55+
56+
expect(dispatchEventSpy).toHaveBeenCalledWith(new Event('toggle-inspector-devtools'));
57+
});
58+
});

packages/app/client/src/commands/electronCommands.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,4 @@ export class ElectronCommands {
4444
protected toggleDevTools() {
4545
window.dispatchEvent(new Event('toggle-inspector-devtools'));
4646
}
47-
48-
// ---------------------------------------------------------------------------
49-
// An update is ready to install
50-
@Command(Electron.UpdateAvailable)
51-
protected emulatorUpdateAvailable(...args: any[]) {
52-
// TODO: Show a notification
53-
// eslint-disable-next-line no-console
54-
console.log('Update available', ...args);
55-
}
56-
57-
// ---------------------------------------------------------------------------
58-
// Application is up to date
59-
@Command(Electron.UpdateNotAvailable)
60-
protected emulatorUpdateNotAvailable() {
61-
// TODO: Show a notification
62-
// eslint-disable-next-line no-console
63-
console.log('Application is up to date');
64-
}
65-
66-
// ---------------------------------------------------------------------------
67-
// Open About dialog
68-
@Command(Electron.ShowAboutDialog)
69-
protected showAboutDialog() {
70-
// TODO: Show about dialog (native dialog box)
71-
}
7247
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license.
4+
//
5+
// Microsoft Bot Framework: http://botframework.com
6+
//
7+
// Bot Framework Emulator Github:
8+
// https://github.com/Microsoft/BotFramwork-Emulator
9+
//
10+
// Copyright (c) Microsoft Corporation
11+
// All rights reserved.
12+
//
13+
// MIT License:
14+
// Permission is hereby granted, free of charge, to any person obtaining
15+
// a copy of this software and associated documentation files (the
16+
// "Software"), to deal in the Software without restriction, including
17+
// without limitation the rights to use, copy, modify, merge, publish,
18+
// distribute, sublicense, and/or sell copies of the Software, and to
19+
// permit persons to whom the Software is furnished to do so, subject to
20+
// the following conditions:
21+
//
22+
// The above copyright notice and this permission notice shall be
23+
// included in all copies or substantial portions of the Software.
24+
//
25+
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
26+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32+
//
33+
34+
import { CommandServiceImpl, CommandRegistry, CommandServiceInstance } from '@bfemulator/sdk-shared';
35+
import { SharedConstants } from '@bfemulator/app-shared';
36+
37+
import { addFile, removeFile, clear } from '../state/actions/fileActions';
38+
import { addDocPendingChange } from '../state/actions/editorActions';
39+
40+
import { FileCommands } from './fileCommands';
41+
42+
const mockDispatch = jest.fn();
43+
jest.mock('../state/store', () => ({
44+
store: {
45+
dispatch: action => mockDispatch(action),
46+
},
47+
}));
48+
49+
describe('The file commands', () => {
50+
let commandService: CommandServiceImpl;
51+
let registry: CommandRegistry;
52+
const { File } = SharedConstants.Commands;
53+
54+
beforeAll(() => {
55+
new FileCommands();
56+
const decorator = CommandServiceInstance();
57+
const descriptor = decorator({ descriptor: {} }, 'none') as any;
58+
commandService = descriptor.descriptor.get();
59+
registry = commandService.registry;
60+
});
61+
62+
beforeEach(mockDispatch.mockClear);
63+
64+
it('should add a file to the store', () => {
65+
const payload: any = {
66+
type: 'leaf',
67+
name: 'somefile.txt',
68+
path: 'dir/somefile.txt',
69+
};
70+
const command = registry.getCommand(File.Add);
71+
command(payload);
72+
73+
expect(mockDispatch).toHaveBeenCalledWith(addFile(payload));
74+
});
75+
76+
it('should remove a file from the store', () => {
77+
const payload: any = {
78+
type: 'leaf',
79+
name: 'somefile.txt',
80+
path: 'dir/somefile.txt',
81+
};
82+
const command = registry.getCommand(File.Remove);
83+
command(payload);
84+
85+
expect(mockDispatch).toHaveBeenCalledWith(removeFile(payload));
86+
});
87+
88+
it('should clear the file store', () => {
89+
const command = registry.getCommand(File.Clear);
90+
command();
91+
92+
expect(mockDispatch).toHaveBeenCalledWith(clear());
93+
});
94+
95+
it('should mark a file as changed (.chat file)', () => {
96+
const filename = 'my-file.chat';
97+
const command = registry.getCommand(File.Changed);
98+
command(filename);
99+
100+
expect(mockDispatch).toHaveBeenCalledWith(addDocPendingChange(filename));
101+
});
102+
103+
it('should mark a file as changed (.transcript file)', () => {
104+
const filename = 'my-file.transcript';
105+
const command = registry.getCommand(File.Changed);
106+
command(filename);
107+
108+
expect(mockDispatch).toHaveBeenCalledWith(addDocPendingChange(filename));
109+
});
110+
});
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license.
4+
//
5+
// Microsoft Bot Framework: http://botframework.com
6+
//
7+
// Bot Framework Emulator Github:
8+
// https://github.com/Microsoft/BotFramwork-Emulator
9+
//
10+
// Copyright (c) Microsoft Corporation
11+
// All rights reserved.
12+
//
13+
// MIT License:
14+
// Permission is hereby granted, free of charge, to any person obtaining
15+
// a copy of this software and associated documentation files (the
16+
// "Software"), to deal in the Software without restriction, including
17+
// without limitation the rights to use, copy, modify, merge, publish,
18+
// distribute, sublicense, and/or sell copies of the Software, and to
19+
// permit persons to whom the Software is furnished to do so, subject to
20+
// the following conditions:
21+
//
22+
// The above copyright notice and this permission notice shall be
23+
// included in all copies or substantial portions of the Software.
24+
//
25+
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
26+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32+
//
33+
34+
import { CommandServiceImpl, CommandRegistry, CommandServiceInstance } from '@bfemulator/sdk-shared';
35+
import { SharedConstants } from '@bfemulator/app-shared';
36+
37+
import { MiscCommands } from './miscCommands';
38+
39+
const mockState = {};
40+
jest.mock('../state/store', () => ({
41+
store: {
42+
getState: () => mockState,
43+
},
44+
}));
45+
46+
describe('The misc commands', () => {
47+
let commandService: CommandServiceImpl;
48+
let registry: CommandRegistry;
49+
50+
beforeAll(() => {
51+
new MiscCommands();
52+
const decorator = CommandServiceInstance();
53+
const descriptor = decorator({ descriptor: {} }, 'none') as any;
54+
commandService = descriptor.descriptor.get();
55+
registry = commandService.registry;
56+
});
57+
58+
it('should return the store state', () => {
59+
const command = registry.getCommand(SharedConstants.Commands.Misc.GetStoreState);
60+
const state = command();
61+
62+
expect(state).toEqual(mockState);
63+
});
64+
});

packages/app/client/src/platform/settings/settingsService.ts renamed to packages/app/client/src/commands/notificationCommands.spec.ts

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -31,71 +31,52 @@
3131
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3232
//
3333

34+
import { CommandServiceImpl, CommandRegistry, CommandServiceInstance } from '@bfemulator/sdk-shared';
3435
import { SharedConstants } from '@bfemulator/app-shared';
35-
import { Command } from '@bfemulator/sdk-shared';
3636

37-
export interface EmulatorSettings {
38-
url?: string;
39-
cwd?: string;
40-
readonly cwdAsBase: string;
41-
}
37+
import { beginAdd, beginRemove } from '../state/actions/notificationActions';
4238

43-
class EmulatorSettingsImpl implements EmulatorSettings {
44-
private _url: string;
45-
private _cwd: string;
39+
import { NotificationCommands } from './notificationCommands';
4640

47-
get url(): string {
48-
if (!this._url || !this._url.length) {
49-
throw new Error('Emulator url not set');
50-
}
51-
return this._url;
52-
}
41+
const mockNotification: any = {};
42+
jest.mock('../utils', () => ({
43+
getGlobal: () => mockNotification,
44+
}));
5345

54-
set url(value: string) {
55-
this._url = value;
56-
}
46+
const mockDispatch = jest.fn();
47+
jest.mock('../state/store', () => ({
48+
store: {
49+
dispatch: action => mockDispatch(action),
50+
},
51+
}));
5752

58-
get cwd(): string {
59-
if (!this._cwd || !this._cwd.length) {
60-
throw new Error('Emulator cwd not set');
61-
}
62-
return this._cwd;
63-
}
53+
describe('The notification commands', () => {
54+
let commandService: CommandServiceImpl;
55+
let registry: CommandRegistry;
56+
const { Notifications } = SharedConstants.Commands;
6457

65-
set cwd(value: string) {
66-
this._cwd = value;
67-
}
58+
beforeAll(() => {
59+
new NotificationCommands();
60+
const decorator = CommandServiceInstance();
61+
const descriptor = decorator({ descriptor: {} }, 'none') as any;
62+
commandService = descriptor.descriptor.get();
63+
registry = commandService.registry;
64+
});
6865

69-
get cwdAsBase(): string {
70-
let base = this.cwd || '';
71-
if (!base.startsWith('/')) {
72-
base = `/${base}`;
73-
}
66+
beforeEach(mockDispatch.mockClear);
7467

75-
return base;
76-
}
77-
}
68+
it('should add a notifcation from the main process', () => {
69+
const command = registry.getCommand(Notifications.Add);
70+
command();
7871

79-
class EmulatorSettingsService {
80-
private _emulator: EmulatorSettingsImpl;
72+
expect(mockDispatch).toHaveBeenCalledWith(beginAdd(mockNotification));
73+
});
8174

82-
get emulator(): EmulatorSettingsImpl {
83-
return this._emulator;
84-
}
75+
it('should remove a notification', () => {
76+
const id = 'someId';
77+
const command = registry.getCommand(Notifications.Remove);
78+
command(id);
8579

86-
public init() {
87-
return null;
88-
}
89-
90-
constructor() {
91-
this._emulator = new EmulatorSettingsImpl();
92-
}
93-
94-
@Command(SharedConstants.Commands.Settings.ReceiveGlobalSettings)
95-
protected receiveGlobalSettings(settings: { url: string; cwd: string }): any {
96-
this.emulator.url = (settings.url || '').replace('[::]', 'localhost');
97-
this.emulator.cwd = (settings.cwd || '').replace(/\\/g, '/');
98-
}
99-
}
100-
101-
export const SettingsService = new EmulatorSettingsService();
80+
expect(mockDispatch).toHaveBeenCalledWith(beginRemove(id));
81+
});
82+
});

0 commit comments

Comments
 (0)