Skip to content

Commit

Permalink
chore: extract build logic from components page (microsoft#4153)
Browse files Browse the repository at this point in the history
* add build util to package build logic

* refactor

* test fix

* code refactor

Co-authored-by: Dong Lei <donglei@microsoft.com>
  • Loading branch information
alanlong9278 and boydc2014 committed Sep 24, 2020
1 parent e2510d3 commit 4137a2c
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 254 deletions.
93 changes: 93 additions & 0 deletions Composer/packages/client/__tests__/utils/buildUtil.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { DialogInfo, LuFile } from '@bfc/shared';

import { createCrossTrainConfig } from '../../src/utils/buildUtil';

describe('createCrossTrainConfig', () => {
it('should create crosstrain config', () => {
const dialogs = [
{
id: 'main',
luFile: 'main',
isRoot: true,
intentTriggers: [
{ intent: 'dia1_trigger', dialogs: ['dia1'] },
{ intent: 'dia2_trigger', dialogs: ['dia2'] },
{ intent: 'dias_trigger', dialogs: ['dia5', 'dia6'] },
{ intent: 'no_dialog', dialogs: [] },
{ intent: '', dialogs: ['start_dialog_without_intent'] },
],
},
{
id: 'dia1',
luFile: 'dia1',
intentTriggers: [
{ intent: 'dia3_trigger', dialogs: ['dia3'] },
{ intent: 'dia4_trigger', dialogs: ['dia4'] },
],
},
{
id: 'dia2',
luFile: 'dia2',
intentTriggers: [],
},
{
id: 'dia3',
luFile: 'dia3',
intentTriggers: [],
},
{
id: 'dia4',
luFile: 'dia4',
intentTriggers: [],
},
{
id: 'dia5',
luFile: 'dia5',
intentTriggers: [],
},
{
id: 'dia6',
luFile: 'dia6',
intentTriggers: [],
},
{
id: 'start_dialog_without_intent',
luFile: 'start_dialog_without_intent',
intentTriggers: [],
},
{
id: 'dialog_without_lu',
intentTriggers: [],
},
];
const luFiles = [
{
id: 'main.en-us',
intents: [
{ Name: 'dia1_trigger' },
{ Name: 'dia2_trigger' },
{ Name: 'dias_trigger' },
{ Name: 'no_dialog' },
{ Name: 'dialog_without_lu' },
],
},
{ id: 'dia1.en-us', intents: [{ Name: 'dia3_trigger' }, { Name: 'dia4_trigger' }] },
{ id: 'dia2.en-us' },
{ id: 'dia3.en-us' },
{ id: 'dia5.en-us' },
{ id: 'dia6.en-us' },
];
const config = createCrossTrainConfig(dialogs as DialogInfo[], luFiles as LuFile[]);
expect(config.rootIds.length).toEqual(1);
expect(config.rootIds[0]).toEqual('main.en-us.lu');
expect(config.triggerRules['main.en-us.lu'].dia1_trigger).toEqual('dia1.en-us.lu');
expect(config.triggerRules['main.en-us.lu'].no_dialog).toEqual('');
expect(config.triggerRules['main.en-us.lu'].dia1_trigger).toEqual('dia1.en-us.lu');
expect(config.triggerRules['main.en-us.lu'].dias_trigger.length).toBe(2);
expect(config.triggerRules['dia1.en-us.lu'].dia3_trigger).toEqual('dia3.en-us.lu');
expect(config.triggerRules['dia1.en-us.lu']['dia4.en-us.lu']).toBeUndefined();
});
});
87 changes: 1 addition & 86 deletions Composer/packages/client/__tests__/utils/luUtil.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { LuFile, DialogInfo, Diagnostic, DiagnosticSeverity } from '@bfc/shared';

import { getReferredLuFiles, createCrossTrainConfig, checkLuisBuild } from '../../src/utils/luUtil';
import { getReferredLuFiles, checkLuisBuild } from '../../src/utils/luUtil';

describe('getReferredLuFiles', () => {
it('returns referred luFiles from dialog', () => {
Expand All @@ -13,91 +13,6 @@ describe('getReferredLuFiles', () => {
expect(referred.length).toEqual(1);
expect(referred[0].id).toEqual('a.en-us');
});

it('should create crosstrain config', () => {
const dialogs = [
{
id: 'main',
luFile: 'main',
isRoot: true,
intentTriggers: [
{ intent: 'dia1_trigger', dialogs: ['dia1'] },
{ intent: 'dia2_trigger', dialogs: ['dia2'] },
{ intent: 'dias_trigger', dialogs: ['dia5', 'dia6'] },
{ intent: 'no_dialog', dialogs: [] },
{ intent: '', dialogs: ['start_dialog_without_intent'] },
],
},
{
id: 'dia1',
luFile: 'dia1',
intentTriggers: [
{ intent: 'dia3_trigger', dialogs: ['dia3'] },
{ intent: 'dia4_trigger', dialogs: ['dia4'] },
],
},
{
id: 'dia2',
luFile: 'dia2',
intentTriggers: [],
},
{
id: 'dia3',
luFile: 'dia3',
intentTriggers: [],
},
{
id: 'dia4',
luFile: 'dia4',
intentTriggers: [],
},
{
id: 'dia5',
luFile: 'dia5',
intentTriggers: [],
},
{
id: 'dia6',
luFile: 'dia6',
intentTriggers: [],
},
{
id: 'start_dialog_without_intent',
luFile: 'start_dialog_without_intent',
intentTriggers: [],
},
{
id: 'dialog_without_lu',
intentTriggers: [],
},
];
const luFiles = [
{
id: 'main.en-us',
intents: [
{ Name: 'dia1_trigger' },
{ Name: 'dia2_trigger' },
{ Name: 'dias_trigger' },
{ Name: 'no_dialog' },
{ Name: 'dialog_without_lu' },
],
},
{ id: 'dia1.en-us', intents: [{ Name: 'dia3_trigger' }, { Name: 'dia4_trigger' }] },
{ id: 'dia2.en-us' },
{ id: 'dia3.en-us' },
{ id: 'dia5.en-us' },
{ id: 'dia6.en-us' },
];
const config = createCrossTrainConfig(dialogs as DialogInfo[], luFiles as LuFile[]);
expect(config.rootIds.length).toEqual(1);
expect(config.rootIds[0]).toEqual('main.en-us.lu');
expect(config.triggerRules['main.en-us.lu'].dia1_trigger).toEqual('dia1.en-us.lu');
expect(config.triggerRules['main.en-us.lu'].no_dialog).toEqual('');
expect(config.triggerRules['main.en-us.lu'].dia1_trigger).toEqual('dia1.en-us.lu');
expect(config.triggerRules['main.en-us.lu'].dias_trigger.length).toBe(2);
expect(config.triggerRules['dia1.en-us.lu'].dia3_trigger).toEqual('dia3.en-us.lu');
expect(config.triggerRules['dia1.en-us.lu']['dia4.en-us.lu']).toBeUndefined();
});
});

it('check the lu files before publish', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ import {
botLoadErrorState,
} from '../../recoilModel';
import settingsStorage from '../../utils/dialogSettingStorage';
import { QnaConfig, BotStatus, LuisConfig } from '../../constants';
import { BotStatus } from '../../constants';
import { isAbsHosted } from '../../utils/envUtil';
import useNotifications from '../../pages/notifications/useNotifications';
import { navigateTo, openInEmulator } from '../../utils/navigation';
import { getReferredQnaFiles } from '../../utils/qnaUtil';

import { getReferredLuFiles } from './../../utils/luUtil';
import { isBuildConfigComplete, needsBuild } from './../../utils/buildUtil';
import { PublishDialog } from './publishDialog';
import { ErrorCallout } from './errorCallout';
import { EmulatorOpenButton } from './emulatorOpenButton';
Expand Down Expand Up @@ -153,15 +152,14 @@ export const TestController: React.FC<{ projectId: string }> = (props) => {
}
}

async function handlePublish(config: IPublishConfig) {
async function handleBuild(config: IPublishConfig) {
setBotStatus(BotStatus.publishing, projectId);
dismissDialog();
const { luis, qna } = config;
const endpointKey = settings.qna?.endpointKey;
await setSettings(projectId, {
...settings,
luis: luis,
qna: Object.assign({}, settings.qna, qna, { endpointKey }),
qna: Object.assign({}, settings.qna, qna),
});
await build(luis, qna, projectId);
}
Expand All @@ -175,48 +173,24 @@ export const TestController: React.FC<{ projectId: string }> = (props) => {
await publishToTarget(projectId, defaultPublishConfig, { comment: '' }, sensitiveSettings);
}

function isConfigComplete(config) {
let complete = true;
if (getReferredLuFiles(luFiles, dialogs).length > 0) {
if (Object.values(LuisConfig).some((luisConfigKey) => config.luis[luisConfigKey] === '')) {
complete = false;
}
}
if (getReferredQnaFiles(qnaFiles, dialogs).length > 0) {
if (Object.values(QnaConfig).some((qnaConfigKey) => config.qna[qnaConfigKey] === '')) {
complete = false;
}
}
return complete;
}

// return true if dialogs have one with default recognizer.
function needsPublish(dialogs) {
let isDefaultRecognizer = false;
if (dialogs.some((dialog) => typeof dialog.content.recognizer === 'string')) {
isDefaultRecognizer = true;
}
return isDefaultRecognizer;
}

async function handleStart() {
dismissCallout();
const config = Object.assign(
{},
{
luis: settings.luis,
qna: {
subscriptionKey: settings.qna?.subscriptionKey,
qnaRegion: settings.qna?.qnaRegion,
endpointKey: settings.qna?.endpointKey,
},
qna: settings.qna,
}
);
if (!isAbsHosted() && needsPublish(dialogs)) {
if (botStatus === BotStatus.failed || botStatus === BotStatus.pending || !isConfigComplete(config)) {
if (!isAbsHosted() && needsBuild(dialogs)) {
if (
botStatus === BotStatus.failed ||
botStatus === BotStatus.pending ||
!isBuildConfigComplete(config, dialogs, luFiles, qnaFiles)
) {
openDialog();
} else {
await handlePublish(config);
await handleBuild(config);
}
} else {
await handleLoadBot();
Expand Down Expand Up @@ -278,7 +252,7 @@ export const TestController: React.FC<{ projectId: string }> = (props) => {
isOpen={modalOpen}
projectId={projectId}
onDismiss={dismissDialog}
onPublish={handlePublish}
onPublish={handleBuild}
/>
)}
</Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useRecoilCallback, CallbackInterface } from 'recoil';
import { ILuisConfig, IQnAConfig } from '@bfc/shared';

import * as luUtil from '../../utils/luUtil';
import * as buildUtil from '../../utils/buildUtil';
import { Text, BotStatus } from '../../constants';
import httpClient from '../../utils/httpUtil';
import luFileStatusStorage from '../../utils/luFileStatusStorage';
Expand Down Expand Up @@ -48,7 +49,7 @@ export const builderDispatcher = () => {
}
try {
//TODO crosstrain should add locale
const crossTrainConfig = luUtil.createCrossTrainConfig(dialogs, referredLuFiles);
const crossTrainConfig = buildUtil.createCrossTrainConfig(dialogs, referredLuFiles);
await httpClient.post(`/projects/${projectId}/build`, {
luisConfig,
qnaConfig,
Expand Down
Loading

0 comments on commit 4137a2c

Please sign in to comment.