Skip to content

Commit

Permalink
Merge branch 'main' into julong/publish-code-clean
Browse files Browse the repository at this point in the history
* main:
  fix: language err for build luis in azure deploy (microsoft#4155)
  fix: Unify skill and skill setting dispatchers (microsoft#4173)
  • Loading branch information
alanlong9278 committed Sep 21, 2020
2 parents dd67908 + 9ba5e84 commit 1c38e63
Show file tree
Hide file tree
Showing 26 changed files with 322 additions and 346 deletions.
26 changes: 17 additions & 9 deletions Composer/packages/client/__tests__/components/skill.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,24 @@ jest.mock('../../src/components/Modal/dialogStyle', () => ({}));

const skills: Skill[] = [
{
id: 'email-skill',
content: {},
manifestUrl: 'https://yuesuemailskill0207-gjvga67.azurewebsites.net/manifest/manifest-1.0.json',
name: 'Email-Skill',
description: 'The Email skill provides email related capabilities and supports Office and Google calendars.',
endpointUrl: 'https://yuesuemailskill0207-gjvga67.azurewebsites.net/api/messages',
msAppId: '79432da8-0f7e-4a16-8c23-ddbba30ae85d',
protocol: '',
endpoints: [],
body: '',
},
{
id: 'point-of-interest-skill',
content: {},
manifestUrl: 'https://hualxielearn2-snskill.azurewebsites.net/manifest/manifest-1.0.json',
name: 'Point Of Interest Skill',
description: 'The Point of Interest skill provides PoI search capabilities leveraging Azure Maps and Foursquare.',
endpointUrl: 'https://hualxielearn2-snskill.azurewebsites.net/api/messages',
msAppId: 'e2852590-ea71-4a69-9e44-e74b5b6cbe89',
protocol: '',
endpoints: [],
body: '',
},
];

Expand Down Expand Up @@ -101,7 +101,7 @@ describe('<SkillForm />', () => {
it('should render the skill form, and update skill manifest url', () => {
jest.useFakeTimers();

(httpClient.post as jest.Mock).mockResolvedValue({ endpoints: [] });
(httpClient.get as jest.Mock).mockResolvedValue({ endpoints: [] });

const onDismiss = jest.fn();
const onSubmit = jest.fn();
Expand Down Expand Up @@ -203,7 +203,7 @@ describe('<SkillForm />', () => {
});

it('should try and retrieve manifest if manifest url meets other criteria', async () => {
(httpClient.post as jest.Mock) = jest.fn().mockResolvedValue({ data: 'skill manifest' });
(httpClient.get as jest.Mock) = jest.fn().mockResolvedValue({ data: 'skill manifest' });

const formData = { manifestUrl: 'https://skill' };
const formDataErrors = { manifestUrl: 'error' };
Expand All @@ -223,7 +223,11 @@ describe('<SkillForm />', () => {
manifestUrl: 'Validating',
})
);
expect(httpClient.post).toBeCalledWith(`/projects/${projectId}/skill/check`, { url: formData.manifestUrl });
expect(httpClient.get).toBeCalledWith(`/projects/${projectId}/skill/retrieve-skill-manifest`, {
params: {
url: formData.manifestUrl,
},
});
expect(setSkillManifest).toBeCalledWith('skill manifest');
expect(setValidationState).toBeCalledWith(
expect.objectContaining({
Expand All @@ -238,7 +242,7 @@ describe('<SkillForm />', () => {
});

it('should show error when it could not retrieve skill manifest', async () => {
(httpClient.post as jest.Mock) = jest.fn().mockRejectedValue({ message: 'skill manifest' });
(httpClient.get as jest.Mock) = jest.fn().mockRejectedValue({ message: 'skill manifest' });

const formData = { manifestUrl: 'https://skill' };

Expand All @@ -257,7 +261,11 @@ describe('<SkillForm />', () => {
manifestUrl: 'Validating',
})
);
expect(httpClient.post).toBeCalledWith(`/projects/${projectId}/skill/check`, { url: formData.manifestUrl });
expect(httpClient.get).toBeCalledWith(`/projects/${projectId}/skill/retrieve-skill-manifest`, {
params: {
url: formData.manifestUrl,
},
});
expect(setSkillManifest).not.toBeCalled();
expect(setValidationState).toBeCalledWith(
expect.objectContaining({
Expand Down
14 changes: 9 additions & 5 deletions Composer/packages/client/src/components/CreateSkillModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Stack, StackItem } from 'office-ui-fabric-react/lib/Stack';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { useRecoilValue } from 'recoil';
import debounce from 'lodash/debounce';
import { Skill } from '@bfc/shared';
import { SkillSetting } from '@bfc/shared';

import { addSkillDialog } from '../constants';
import httpClient from '../utils/httpUtil';
Expand All @@ -31,7 +31,7 @@ export const msAppIdRegex = /^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A

export interface CreateSkillModalProps {
projectId: string;
onSubmit: (data: Skill) => void;
onSubmit: (data: SkillSetting) => void;
onDismiss: () => void;
}

Expand Down Expand Up @@ -83,7 +83,11 @@ export const validateManifestUrl = async ({
} else {
try {
setValidationState({ ...validationState, manifestUrl: ValidationState.Validating });
const { data } = await httpClient.post(`/projects/${projectId}/skill/check`, { url: manifestUrl });
const { data } = await httpClient.get(`/projects/${projectId}/skill/retrieve-skill-manifest`, {
params: {
url: manifestUrl,
},
});
setFormDataErrors(errors);
setSkillManifest(data);
setValidationState({ ...validationState, manifestUrl: ValidationState.Validated });
Expand Down Expand Up @@ -118,7 +122,7 @@ export const validateName = ({
export const CreateSkillModal: React.FC<CreateSkillModalProps> = ({ projectId, onSubmit, onDismiss }) => {
const skills = useRecoilValue(skillsState(projectId));

const [formData, setFormData] = useState<Partial<Skill>>({});
const [formData, setFormData] = useState<Partial<SkillSetting>>({});
const [formDataErrors, setFormDataErrors] = useState<SkillFormDataErrors>({});
const [validationState, setValidationState] = useState({
endpoint: ValidationState.NotValidated,
Expand Down Expand Up @@ -208,7 +212,7 @@ export const CreateSkillModal: React.FC<CreateSkillModalProps> = ({ projectId, o
Object.values(validationState).every((validation) => validation === ValidationState.Validated) &&
!Object.values(formDataErrors).some(Boolean)
) {
onSubmit(formData as Skill);
onSubmit({ name: skillManifest.name, ...formData } as SkillSetting);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const DisplayManifestModal: React.FC<DisplayManifestModalProps> = ({
height={'100%'}
id={'modaljsonview'}
options={{ readOnly: true }}
value={JSON.parse(selectedSkill.body ?? '')}
value={selectedSkill.content}
onChange={() => {}}
/>
</div>
Expand Down
4 changes: 2 additions & 2 deletions Composer/packages/client/src/pages/skills/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { RouteComponentProps } from '@reach/router';
import React, { useCallback, useState } from 'react';
import formatMessage from 'format-message';
import { useRecoilValue } from 'recoil';
import { Skill } from '@bfc/shared';
import { SkillSetting } from '@bfc/shared';

import { dispatcherState, settingsState, botNameState } from '../../recoilModel';
import { Toolbar, IToolbarItem } from '../../components/Toolbar';
Expand Down Expand Up @@ -48,7 +48,7 @@ const Skills: React.FC<RouteComponentProps<{ projectId: string }>> = (props) =>
];

const onSubmitForm = useCallback(
(skill: Skill) => {
(skill: SkillSetting) => {
addSkill(projectId, skill);
setShowAddSkillDialogModal(false);
},
Expand Down
12 changes: 6 additions & 6 deletions Composer/packages/client/src/pages/skills/skill-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,22 +126,22 @@ const SkillList: React.FC<SkillListProps> = ({ projectId }) => {
const [selectedSkillUrl, setSelectedSkillUrl] = useState<string | null>(null);

const handleViewManifest = (item) => {
if (item && item.name && item.body) {
if (item && item.name && item.content) {
setSelectedSkillUrl(item.manifestUrl);
}
};

const handleEditSkill = (targetId) => (skillData) => {
updateSkill(projectId, { skillData, targetId });
const handleEditSkill = (projectId, skillId) => (skillData) => {
updateSkill(projectId, skillId, skillData);
};

const items = useMemo(
() =>
skills.map((skill, index) => ({
skills.map((skill) => ({
skill,
onDelete: () => removeSkill(projectId, skill.manifestUrl),
onDelete: () => removeSkill(projectId, skill.id),
onViewManifest: () => handleViewManifest(skill),
onEditSkill: handleEditSkill(index),
onEditSkill: handleEditSkill(projectId, skill.id),
})),
[skills, projectId]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import { useRecoilValue } from 'recoil';
import { act } from '@bfc/test-utils/lib/hooks';

import { renderRecoilHook } from '../../../../__tests__/testUtils';
import { settingsState, currentProjectIdState } from '../../atoms';
import { settingsState, currentProjectIdState, skillsState } from '../../atoms';
import { dispatcherState } from '../../../recoilModel/DispatcherWrapper';
import { Dispatcher } from '..';
import { settingsDispatcher } from '../setting';
import httpClient from '../../../utils/httpUtil';

jest.mock('../../../utils/httpUtil');

const projectId = '1235a.2341';

Expand Down Expand Up @@ -65,17 +68,19 @@ const settings = {
maxImbalanceRatio: 10,
maxUtteranceAllowed: 15000,
},
skill: {},
};

describe('setting dispatcher', () => {
let renderedComponent, dispatcher: Dispatcher;
beforeEach(() => {
const useRecoilTestHook = () => {
const settings = useRecoilValue(settingsState(projectId));
const skills = useRecoilValue(skillsState(projectId));
const currentDispatcher = useRecoilValue(dispatcherState);

return {
settings,
skills,
currentDispatcher,
};
};
Expand All @@ -84,6 +89,7 @@ describe('setting dispatcher', () => {
states: [
{ recoilState: settingsState(projectId), initialValue: settings },
{ recoilState: currentProjectIdState, initialValue: projectId },
{ recoilState: skillsState(projectId), initialValue: [] },
],
dispatcher: {
recoilState: dispatcherState,
Expand Down Expand Up @@ -151,4 +157,38 @@ describe('setting dispatcher', () => {
});
expect(renderedComponent.current.settings.runtime.customRuntime).toBeTruthy();
});

it('should update skills state', async () => {
(httpClient.get as jest.Mock).mockResolvedValue({
data: { description: 'description', endpoints: [{ endpointUrl: 'https://test' }] },
});

await act(async () => {
await dispatcher.setSettings(projectId, {
skill: {
foo: {
msAppId: '00000000-0000',
endpointUrl: 'https://skill-manifest/api/messages',
name: 'foo',
manifestUrl: 'https://skill-manifest',
},
},
} as any);
});

expect(renderedComponent.current.skills).toEqual(
expect.arrayContaining([
{
id: 'foo',
name: 'foo',
manifestUrl: 'https://skill-manifest',
msAppId: '00000000-0000',
endpointUrl: 'https://skill-manifest/api/messages',
description: 'description',
endpoints: expect.any(Array),
content: expect.any(Object),
},
])
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,17 @@ const mockDialogComplete = jest.fn();
const projectId = '42345.23432';

const makeTestSkill: (number) => Skill = (n) => ({
id: 'id' + n,
manifestUrl: 'url' + n,
name: 'skill' + n,
protocol: 'GET',
description: 'test skill' + n,
endpointUrl: 'url',
endpoints: [{ test: 'foo' }],
msAppId: 'ID',
body: 'body',
content: {
description: 'test skill' + n,
endpoints: [{ test: 'foo' }],
},
});

describe('skill dispatcher', () => {
Expand Down Expand Up @@ -143,19 +146,30 @@ describe('skill dispatcher', () => {

it('updateSkill', async () => {
await act(async () => {
dispatcher.updateSkill(projectId, {
targetId: 0,
skillData: makeTestSkill(100),
dispatcher.updateSkill(projectId, 'id1', {
msAppId: 'test',
manifestUrl: 'test',
endpointUrl: 'test',
name: 'test',
});
});

expect(renderedComponent.current.skills).not.toContain(makeTestSkill(1));
expect(renderedComponent.current.skills).toContainEqual(makeTestSkill(100));
expect(renderedComponent.current.skills[0]).toEqual(
expect.objectContaining({
id: 'id1',
content: {},
name: 'test',
msAppId: 'test',
manifestUrl: 'test',
endpointUrl: 'test',
endpoints: [],
})
);
});

it('removeSkill', async () => {
await act(async () => {
dispatcher.removeSkill(projectId, makeTestSkill(1).manifestUrl);
dispatcher.removeSkill(projectId, makeTestSkill(1).id);
});
expect(renderedComponent.current.skills).not.toContain(makeTestSkill(1));
});
Expand All @@ -176,32 +190,6 @@ describe('skill dispatcher', () => {
expect(renderedComponent.current.onAddSkillDialogComplete.func).toBe(undefined);
});

describe('addSkillDialogSuccess', () => {
it('with a function in onAddSkillDialogComplete', async () => {
await act(async () => {
dispatcher.addSkillDialogBegin(mockDialogComplete, projectId);
});
await act(async () => {
dispatcher.addSkillDialogSuccess(projectId);
});
expect(mockDialogComplete).toHaveBeenCalledWith(null);
expect(renderedComponent.current.showAddSkillDialogModal).toBe(false);
expect(renderedComponent.current.onAddSkillDialogComplete.func).toBe(undefined);
});

it('with nothing in onAddSkillDialogComplete', async () => {
await act(async () => {
dispatcher.addSkillDialogCancel(projectId);
});
await act(async () => {
dispatcher.addSkillDialogSuccess(projectId);
});
expect(mockDialogComplete).not.toHaveBeenCalled();
expect(renderedComponent.current.showAddSkillDialogModal).toBe(false);
expect(renderedComponent.current.onAddSkillDialogComplete.func).toBe(undefined);
});
});

it('displayManifestModal', async () => {
await act(async () => {
dispatcher.displayManifestModal('foo', projectId);
Expand Down
Loading

0 comments on commit 1c38e63

Please sign in to comment.