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
Show all changes
50 commits
Select commit Hold shift + click to select a range
3d02e7c
setting page UX
liweitian Oct 13, 2020
2d0490c
update UX
liweitian Oct 14, 2020
0107f93
refine css
liweitian Oct 15, 2020
b054272
update url
liweitian Oct 16, 2020
4be7091
update css and fix localStorage bug
liweitian Oct 20, 2020
0f9a9f4
refactor and refine css
liweitian Oct 21, 2020
e0d6ecb
add custom error style and fix bugs of language settings
liweitian Oct 22, 2020
4f8b6d2
localstorage migration
liweitian Oct 22, 2020
38548a8
fix delete button hidden bug
liweitian Oct 22, 2020
96aae47
update css
liweitian Oct 23, 2020
a88b04e
update Composer Setting page
liweitian Oct 23, 2020
2a63a98
save tmp code about the callout switching active language in design …
liweitian Oct 23, 2020
9d22999
changing locale button on Header
liweitian Oct 24, 2020
66f088b
lint fix
liweitian Oct 24, 2020
f314687
lint fix
liweitian Oct 24, 2020
e5d43ce
handle comments
liweitian Oct 26, 2020
63edadc
save tmp code
liweitian Oct 27, 2020
40a6518
handle comments
liweitian Oct 27, 2020
216e5d5
save tmp code
liweitian Oct 27, 2020
ef214b4
add test case
liweitian Oct 27, 2020
525a67e
Merge branch 'settingsPage' of https://github.com/liweitian/BotFramew…
liweitian Oct 27, 2020
900b8fd
add test cases
liweitian Oct 28, 2020
74151ea
add test cases
liweitian Oct 28, 2020
36a87f2
fix bugs and update router component
liweitian Oct 29, 2020
99076f5
handle comments
liweitian Oct 29, 2020
d652f0f
handle comments
liweitian Nov 2, 2020
22bfe5d
Merge branch 'feature/bot-projects' into settingsPage
liweitian Nov 3, 2020
349885d
handle comments
liweitian Nov 3, 2020
cae512a
update qna end point key after update qna subscription key
liweitian Nov 4, 2020
70a8033
code style
liweitian Nov 4, 2020
82be07a
Merge https://github.com/microsoft/BotFramework-Composer into setting…
liweitian Nov 4, 2020
89e4837
Merge branch 'feature/bot-projects' into settingsPage
liweitian Nov 10, 2020
ccf0c90
Merge branch 'settingsPage' of https://github.com/liweitian/BotFramew…
liweitian Nov 10, 2020
4b67c42
set defaultLanguage as active language if active language is deleted
liweitian Nov 11, 2020
6e28c87
Merge branch 'settingsPage' of https://github.com/liweitian/BotFramew…
liweitian Nov 11, 2020
b21339f
fix UT
liweitian Nov 11, 2020
ba0bc82
remove useless files
liweitian Nov 12, 2020
3f82c3c
Merge branch 'feature/bot-projects' into settingsPage
liweitian Nov 12, 2020
c88f2da
save tmp code
liweitian Nov 12, 2020
50a059b
sync on root key
liweitian Nov 12, 2020
242eb36
fix bug
liweitian Nov 13, 2020
be44e0a
code refine
liweitian Nov 13, 2020
2a40001
Merge branch 'feature/bot-projects' into settingsPage
liweitian Nov 13, 2020
e7b357b
fix UT
liweitian Nov 13, 2020
1438303
fix bug
liweitian Nov 13, 2020
4243c9a
Merge branch 'feature/bot-projects' into settingsPage
srinaath Nov 13, 2020
a2798f9
Refactoring function calls
Nov 13, 2020
bbd7e70
Merge branch 'settingsPage' of https://github.com/liweitian/BotFramew…
Nov 13, 2020
f38c27b
Merge branch 'feature/bot-projects' into settingsPage
liweitian Nov 16, 2020
dd64a34
lint fix
liweitian Nov 16, 2020
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
@@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Comment thread
liweitian marked this conversation as resolved.

import React from 'react';
import { act, fireEvent } from '@botframework-composer/test-utils';

import { AppIdAndPassword } from '../../../src/pages/botProject/AppIdAndPassword';
import { renderWithRecoilAndCustomDispatchers } from '../../testUtils';
import { dispatcherState } from '../../../src/recoilModel';
import { settingsState, currentProjectIdState } from '../../../src/recoilModel';

const state = {
projectId: 'test',
settings: {
defaultLanguage: 'en-us',
languages: ['en-us', 'fr-fr'],
},
};

describe('App Id and Password', () => {
it('should submit settings', async () => {
const setSettingsMock = jest.fn();
const initRecoilState = ({ set }) => {
set(currentProjectIdState, state.projectId);
set(settingsState(state.projectId), state.settings);
set(dispatcherState, {
setSettings: setSettingsMock,
});
};
const { getByTestId } = renderWithRecoilAndCustomDispatchers(
<AppIdAndPassword projectId={state.projectId} />,
initRecoilState
);
const textField1 = getByTestId('MicrosoftAppId');
await act(async () => {
await fireEvent.change(textField1, {
target: { value: 'myMicrosoftAppId' },
});
await fireEvent.blur(textField1);
});
expect(setSettingsMock).toBeCalledWith('test', {
defaultLanguage: 'en-us',
languages: ['en-us', 'fr-fr'],
luis: {
authoringKey: '',
authoringRegion: '',
},
qna: {
subscriptionKey: '',
},
MicrosoftAppId: 'myMicrosoftAppId',
});
const textField2 = getByTestId('MicrosoftPassword');
await act(async () => {
await fireEvent.change(textField2, {
target: { value: 'myMicrosoftPassword' },
});
await fireEvent.blur(textField2);
});
expect(setSettingsMock).toBeCalledWith('test', {
defaultLanguage: 'en-us',
languages: ['en-us', 'fr-fr'],
luis: {
authoringKey: '',
authoringRegion: '',
},
qna: {
subscriptionKey: '',
},
MicrosoftAppPassword: 'myMicrosoftPassword',
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { act, fireEvent, within } from '@botframework-composer/test-utils';

import { BotLanguage } from '../../../src/pages/botProject/BotLanguage';
import { renderWithRecoilAndCustomDispatchers } from '../../testUtils';
import { dispatcherState } from '../../../src/recoilModel';
import { settingsState, currentProjectIdState } from '../../../src/recoilModel';

const state = {
projectId: 'test',
settings: {
defaultLanguage: 'en-us',
languages: ['en-us', 'fr-fr'],
},
};

describe('Bot Language', () => {
it('should submit settings', () => {
const setSettingsMock = jest.fn();
const setLocaleMock = jest.fn();
const deleteLanguages = jest.fn();
const initRecoilState = ({ set }) => {
set(currentProjectIdState, state.projectId);
set(settingsState(state.projectId), state.settings);
set(dispatcherState, {
setSettings: setSettingsMock,
setLocale: setLocaleMock,
deleteLanguages: deleteLanguages,
});
};
const { getByTestId } = renderWithRecoilAndCustomDispatchers(
<BotLanguage projectId={state.projectId} />,
initRecoilState
);
const defaultLanguageContainer = getByTestId('defaultLanguage');
expect(within(defaultLanguageContainer).getByText('English (United States)')).toBeInTheDocument();
const setDefaultLanguage = getByTestId('setDefaultLanguage');
act(() => {
fireEvent.click(setDefaultLanguage);
});
expect(setLocaleMock).toBeCalledWith('fr-fr', 'test');
const remove = getByTestId('remove');
act(() => {
fireEvent.click(remove);
});
expect(deleteLanguages).toBeCalledWith({ languages: ['fr-fr'], projectId: 'test' });
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/* eslint-disable react-hooks/rules-of-hooks */

import React from 'react';
import { act, fireEvent } from '@botframework-composer/test-utils';

import { DeleteBotButton } from '../../../src/pages/botProject/DeleteBotButton';
import { renderWithRecoil } from '../../testUtils';

const state = {
projectId: 'test',
};

describe('Delete Bot Button', () => {
it('should render Delete Bot Button', () => {
const { getByText } = renderWithRecoil(<DeleteBotButton projectId={state.projectId} />);
const deleteButton = getByText('Delete');
act(() => {
fireEvent.click(deleteButton);
});
expect(getByText('Delete Bot')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/* eslint-disable react-hooks/rules-of-hooks */

import React from 'react';
import { act, fireEvent } from '@botframework-composer/test-utils';

import { PublishTargets } from '../../../src/pages/botProject/PublishTargets';
import { renderWithRecoilAndCustomDispatchers } from '../../testUtils';
import { dispatcherState, publishTypesState } from '../../../src/recoilModel';
const state = {
projectId: 'test',
publishTypes: [{ name: 'azureFunctionsPublish', description: 'Publish bot to Azure Functions (Preview)' }],
};
describe('Publish Target', () => {
const setPublishTargetsMock = jest.fn();
const initRecoilState = ({ set }) => {
set(dispatcherState, {
setPublishTargets: setPublishTargetsMock,
getPublishTargetTypes: () => {},
});
set(publishTypesState(state.projectId), [
{ name: 'azureFunctionsPublish', description: 'Publish bot to Azure Functions (Preview)' },
]);
};
it('should add new publish profile', () => {
const { getByTestId, getByText } = renderWithRecoilAndCustomDispatchers(
<PublishTargets projectId={state.projectId} />,
initRecoilState
);
const addNewPublishProfile = getByTestId('addNewPublishProfile');
act(() => {
fireEvent.click(addNewPublishProfile);
});
expect(getByText('Add a publish profile')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { act, fireEvent } from '@botframework-composer/test-utils';

import { RootBotExternalService } from '../../../src/pages/botProject/RootBotExternalService';
import { renderWithRecoilAndCustomDispatchers } from '../../testUtils';
import { dispatcherState } from '../../../src/recoilModel';
import {
settingsState,
currentProjectIdState,
projectMetaDataState,
botProjectIdsState,
dialogState,
luFilesState,
} from '../../../src/recoilModel';

const state = {
dialogs: [
{
content: {
recognizer: '',
},
id: 'dialog1',
},
{
content: {
recognizer: '',
},
id: 'dialog2',
},
],
qnaFiles: [
{
content: '',
empty: true,
id: 'dialog1.en-us',
},
],
luFiles: [
{
content: '',
empty: true,
id: 'dialog1.en-us',
},
],
projectId: 'test',
settings: {},
projectMetaDataState: {
isRootBot: true,
isRemote: false,
},
botProjectIdsState: ['test'],
};

describe('Root Bot External Service', () => {
it('should submit settings', async () => {
const setSettingsMock = jest.fn();
const setQnASettingsMock = jest.fn();
const initRecoilState = ({ set }) => {
set(currentProjectIdState, state.projectId);
set(dialogState({ projectId: state.projectId, dialogId: state.dialogs[0].id }), state.dialogs[0]);
set(dialogState({ projectId: state.projectId, dialogId: state.dialogs[1].id }), state.dialogs[1]);
set(botProjectIdsState, state.botProjectIdsState);
set(luFilesState(state.projectId), state.luFiles);
set(projectMetaDataState(state.projectId), state.projectMetaDataState);
set(settingsState(state.projectId), state.settings);
set(dispatcherState, {
setSettings: setSettingsMock,
setQnASettings: setQnASettingsMock,
});
};
const { getByTestId } = renderWithRecoilAndCustomDispatchers(
<RootBotExternalService projectId={state.projectId} />,
initRecoilState
);
const textField1 = getByTestId('rootLUISKey');
await act(async () => {
await fireEvent.change(textField1, {
target: { value: 'myRootLUISKey' },
});
await fireEvent.blur(textField1);
});
expect(setSettingsMock).toBeCalledWith('test', {
luis: {
authoringKey: 'myRootLUISKey',
authoringRegion: '',
},
qna: {
subscriptionKey: '',
},
});
const textField2 = getByTestId('rootLUISRegion');
await act(async () => {
await fireEvent.change(textField2, {
target: { value: 'myRootLUISRegion' },
});
await fireEvent.blur(textField2);
});
expect(setSettingsMock).toBeCalledWith('test', {
luis: {
authoringKey: '',
authoringRegion: 'myRootLUISRegion',
},
qna: {
subscriptionKey: '',
},
});
const textField3 = getByTestId('QnASubscriptionKey');
await act(async () => {
await fireEvent.change(textField3, {
target: { value: 'myQnASubscriptionKey' },
});
await fireEvent.blur(textField3);
});
expect(setSettingsMock).toBeCalledWith('test', {
luis: {
authoringKey: '',
authoringRegion: '',
},
qna: {
subscriptionKey: 'myQnASubscriptionKey',
},
});
expect(setQnASettingsMock).toBeCalledWith('test', 'myQnASubscriptionKey');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { act, fireEvent } from '@botframework-composer/test-utils';

import { SkillHostEndPoint } from '../../../src/pages/botProject/SkillHostEndPoint';
import { renderWithRecoilAndCustomDispatchers } from '../../testUtils';
import { dispatcherState } from '../../../src/recoilModel';
import { settingsState, currentProjectIdState } from '../../../src/recoilModel';

const state = {
projectId: 'test',
settings: {
defaultLanguage: 'en-us',
languages: ['en-us', 'fr-fr'],
},
};

describe('SkillHostEndPoint', () => {
it('should submit settings', async () => {
const setSettingsMock = jest.fn();
const initRecoilState = ({ set }) => {
set(currentProjectIdState, state.projectId);
set(settingsState(state.projectId), state.settings);
set(dispatcherState, {
setSettings: setSettingsMock,
});
};
const { getByTestId } = renderWithRecoilAndCustomDispatchers(
<SkillHostEndPoint projectId={state.projectId} />,
initRecoilState
);
const textField = getByTestId('SkillHostEndPointTextField');
await act(async () => {
await fireEvent.change(textField, {
target: { value: 'mySkillHostEndPoint' },
});
await fireEvent.blur(textField);
});
expect(setSettingsMock).toBeCalledWith('test', {
defaultLanguage: 'en-us',
languages: ['en-us', 'fr-fr'],
skillHostEndpoint: 'mySkillHostEndPoint',
luis: {
authoringKey: '',
authoringRegion: '',
},
qna: {
subscriptionKey: '',
},
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export function renderWithRecoil(subject, initRecoilState: (mutableSnapshot: Mut
);
}

export function renderWithRecoilAndCustomDispatchers(
subject,
initRecoilState: (mutableSnapshot: MutableSnapshot) => void = noop
) {
return render(<RecoilRoot initializeState={initRecoilState}>{subject}</RecoilRoot>);
}

export function wrapWithRecoil(subject, initRecoilState: (mutableSnapshot: MutableSnapshot) => void = noop) {
return (
<RecoilRoot initializeState={initRecoilState}>
Expand Down
Loading