Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add UI for generate unit test #6282

Draft
wants to merge 1 commit into
base: developer/UnitTestCodeful
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions Localize/lang/strings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"++ZVe/": "Testing",
"+0H8Or": "Warning: input node type does not match the schema node's type",
"+0ua83": "Parameters",
"+0yxlR": "Function display",
"+3rROX": "Protected",
"+5Jp42": "By",
Expand All @@ -12,6 +13,7 @@
"+KXX+O": "Select function from",
"+M72+a": "Overview",
"+R90eK": "Retry policy interval is invalid, must match ISO 8601 duration format",
"+SHn9P": "Save blank unit test",
"+Uvo/p": "Alt text for down chevron",
"+ZSBrq": "Context menu for {title} card",
"+ijo/2": "Paste last used expression",
Expand Down Expand Up @@ -277,6 +279,7 @@
"7ZR1xr": "Add an action",
"7aJqIH": "Optional. The locale to be used when formatting (defaults to 'en-us').",
"7adnmH": "Back to template library",
"7eo4/d": "Create unit test",
"7fZkLA": "Disable static result",
"7gUE8h": "This will revert your workflow to the state it was in before Copilot's edit. If you made additional edits to the workflow after Copilot's, you will lose them. This action cannot be undone. Do you want to continue?",
"7jcTNd": "Enter a valid email.",
Expand Down Expand Up @@ -644,6 +647,7 @@
"Lub7NN": "Required. The expressions that may be true.",
"LvLksz": "Loading outputs",
"Lx8HRl": "(UTC+02:00) Damascus",
"LxRzQm": "Assertions",
"M/gUE8": "About",
"M/m3nG": "Action timeout",
"M0bbZk": "Flow Checker",
Expand Down Expand Up @@ -780,6 +784,7 @@
"QBK72a": "Add custom modules, uncover new scenarios, and find troubleshooting tips",
"QGbUXX": "Status code",
"QNfUf/": "Full screen",
"QQmbz+": "Save unit test definition",
"QVtqAn": "Description",
"QZBPUx": "Returns a single value matching the key name from form-data or form-encoded trigger output",
"QZrxUk": "String functions",
Expand Down Expand Up @@ -1051,9 +1056,11 @@
"Zi9gQK": "Add new item",
"ZihyUf": "Close",
"ZkjTbp": "Learn more about dynamic content.",
"ZvAp7m": "Save",
"ZyDq4/": "Show a different suggestion",
"_++ZVe/.comment": "Title for testing section",
"_+0H8Or.comment": "Warning message for when input node type does not match schema node type",
"_+0ua83.comment": "Button text for parameters",
"_+0yxlR.comment": "Label for the function display radio group",
"_+3rROX.comment": "Label in the chatbot header stating that the users information is protected in this chatbot",
"_+5Jp42.comment": "Title for publisher",
Expand All @@ -1065,6 +1072,7 @@
"_+KXX+O.comment": "Path to the function to select",
"_+M72+a.comment": "Button text for whole overview",
"_+R90eK.comment": "error message for invalid retry interval",
"_+SHn9P.comment": "Button test for save blank unit test",
"_+Uvo/p.comment": "Alt text for down chevron",
"_+ZSBrq.comment": "Accessibility label",
"_+ijo/2.comment": "Token picker for 'Paste last used expression'",
Expand Down Expand Up @@ -1330,6 +1338,7 @@
"_7ZR1xr.comment": "Text on example action node",
"_7aJqIH.comment": "Optional locale parameter to apply formatNumber function with",
"_7adnmH.comment": "Button to navigate back to the template library",
"_7eo4/d.comment": "Button text for create unit test",
"_7fZkLA.comment": "Label for toggle to disable static result",
"_7gUE8h.comment": "Warning description of what undoing operation will do to the workflow",
"_7jcTNd.comment": "Error validation message for emails",
Expand Down Expand Up @@ -1697,6 +1706,7 @@
"_Lub7NN.comment": "Required expression parameters to apply or function",
"_LvLksz.comment": "Loading outputs text",
"_Lx8HRl.comment": "Time zone value ",
"_LxRzQm.comment": "Button text for unit test asssertions",
"_M/gUE8.comment": "The tab label for the about tab on the operation panel",
"_M/m3nG.comment": "title for action timeout setting",
"_M0bbZk.comment": "Header for the errors panel",
Expand Down Expand Up @@ -1833,6 +1843,7 @@
"_QBK72a.comment": "This is a message give link to user to find out more about this action",
"_QGbUXX.comment": "Response status code for test map API",
"_QNfUf/.comment": "Full Screen token picker",
"_QQmbz+.comment": "Button text for save unit test definition",
"_QVtqAn.comment": "Label for description column.",
"_QZBPUx.comment": "Label for description of custom triggerFormDataValue Function",
"_QZrxUk.comment": "Label for string functions",
Expand Down Expand Up @@ -2104,6 +2115,7 @@
"_Zi9gQK.comment": "Label to add item to property editor",
"_ZihyUf.comment": "Label for the close button in the chatbot header",
"_ZkjTbp.comment": "Text for dynamic content link",
"_ZvAp7m.comment": "Button text for save",
"_ZyDq4/.comment": "Text for the show different suggestion flow button",
"_a7j3gS.comment": "Required number parameter to divide in mod function",
"_aAXnqw.comment": "Required number of occurrences to get nthIndexOf function with",
Expand Down Expand Up @@ -2525,6 +2537,7 @@
"_oZMhX/.comment": "Text of Tooltip to expand",
"_ocW+RF.comment": "Title for the details section in the template overview tab",
"_odQ554.comment": "Response body for test map API",
"_ohOaXj.comment": "Button text for errors",
"_ohpbkw.comment": "title for retry policy exponential interval setting",
"_onXUu0.comment": "Text to tell users to click to add comments",
"_oqgNX3.comment": "Accessibility label for workflow name",
Expand Down Expand Up @@ -2620,6 +2633,7 @@
"_sFbnCs.comment": "Time zone value ",
"_sFwHQc.comment": "aria label description for cancel button",
"_sKy720.comment": "Error message when the workflow name is empty.",
"_sOnphB.comment": "Button text for resubmit",
"_sRpETS.comment": "Warning message for when custom value does not match schema node type",
"_sVQe34.comment": "The description for the test tab parameters.",
"_sVcvcG.comment": "The tab label for the monitoring name and state tab on the create workflow panel",
Expand Down Expand Up @@ -3287,6 +3301,7 @@
"oZMhX/": "Expand",
"ocW+RF": "Details",
"odQ554": "Response body",
"ohOaXj": "Errors",
"ohpbkw": "Exponential interval",
"onXUu0": "Add a note",
"oqgNX3": "Workflow name",
Expand Down Expand Up @@ -3382,6 +3397,7 @@
"sFbnCs": "(UTC-05:00) Chetumal",
"sFwHQc": "Cancel creating a connection",
"sKy720": "Must provide value for workflow name.",
"sOnphB": "Resubmit",
"sRpETS": "Warning: custom value does not match the schema node's type",
"sVQe34": "Provide parameters to test the output.",
"sVcvcG": "Basics",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
useNodesInitialized,
serializeUnitTestDefinition,
useAssertionsValidationErrors,
getNodeOutputOperations,
getCustomCodeFilesWithData,
resetDesignerDirtyState,
collapsePanel,
Expand Down Expand Up @@ -126,6 +127,14 @@ export const DesignerCommandBar = ({
alert('Check console for unit test serialization');
});

const { isLoading: isSavingBlankUnitTest, mutate: saveBlankUnitTestMutate } = useMutation(async () => {
const designerState = DesignerStore.getState();
const operationContents = await getNodeOutputOperations(designerState);

console.log(operationContents);
alert('Check console for blank unit test operationContents');
});

const { isLoading: isDownloadingDocument, mutate: downloadDocument } = useMutation(async () => {
const designerState = DesignerStore.getState();
const workflow = await serializeWorkflow(designerState);
Expand Down Expand Up @@ -161,6 +170,7 @@ export const DesignerCommandBar = ({
const haveSettingsErrors = Object.keys(allSettingsErrors ?? {}).length > 0;
const allConnectionErrors = useAllConnectionErrors();
const haveConnectionErrors = Object.keys(allConnectionErrors ?? {}).length > 0;
const saveBlankUnitTestIsDisabled = !isUnitTest || isSavingBlankUnitTest || haveAssertionErrors;

const haveErrors = useMemo(
() => allInputErrors.length > 0 || haveWorkflowParameterErrors || haveSettingsErrors || haveConnectionErrors,
Expand All @@ -187,6 +197,7 @@ export const DesignerCommandBar = ({
);
},
onClick: () => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
isDesignerView ? saveWorkflowMutate() : saveWorkflowFromCode(() => dispatch(resetDesignerDirtyState(undefined)));
},
},
Expand All @@ -205,6 +216,20 @@ export const DesignerCommandBar = ({
saveUnitTestMutate();
},
},
{
key: 'saveBlankUnitTest',
text: 'Save Blank Unit Test',
onRenderIcon: () => {
return isSavingBlankUnitTest ? (
<Spinner size="small" />
) : (
<FontIcon aria-label="Save" iconName="Save" className={classNames.azureBlue} />
);
},
onClick: () => {
saveBlankUnitTestMutate();
},
},
{
key: 'discard',
disabled: isSaving || !isDesignerView,
Expand Down Expand Up @@ -323,6 +348,8 @@ export const DesignerCommandBar = ({
isSaving,
isDesignerView,
showConnectionsPanel,
isSavingBlankUnitTest,
saveBlankUnitTestIsDisabled,
haveErrors,
isDarkMode,
isCopilotReady,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ import { exec } from 'child_process';
import { writeFileSync, readFileSync } from 'fs';
import * as path from 'path';
import { env, ProgressLocation, Uri, ViewColumn, window, workspace } from 'vscode';
import * as vscode from 'vscode';
import type { WebviewPanel, ProgressOptions } from 'vscode';
import type { IAzureConnectorsContext } from '../azureConnectorWizard';
import { saveBlankUnitTest } from '../unitTest/saveBlankUnitTest';

export default class OpenDesignerForLocalProject extends OpenDesignerBase {
private readonly workflowFilePath: string;
Expand Down Expand Up @@ -197,6 +200,10 @@ export default class OpenDesignerForLocalProject extends OpenDesignerBase {
await this.validateWorkflow(this.panelMetadata.workflowContent);
break;
}
case ExtensionCommand.saveBlankUnitTest: {
await saveBlankUnitTest(this.context as IAzureConnectorsContext, vscode.Uri.file(this.workflowFilePath), msg.definition);
break;
}
case ExtensionCommand.saveUnitTest: {
await saveUnitTestDefinition(this.projectPath, this.workflowName, this.unitTestName, msg.definition);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import * as vscode from 'vscode';
import type { WebviewPanel } from 'vscode';
import { Uri, ViewColumn } from 'vscode';
import { getArtifactsInLocalProject } from '../../../utils/codeless/artifacts';
import { saveBlankUnitTest } from '../unitTest/saveBlankUnitTest';

export default class OpenMonitoringViewForLocal extends OpenMonitoringViewBase {
private projectPath: string | undefined;
Expand Down Expand Up @@ -141,6 +142,10 @@ export default class OpenMonitoringViewForLocal extends OpenMonitoringViewBase {
await createUnitTest(this.context as IAzureConnectorsContext, vscode.Uri.file(this.workflowFilePath), message.runId);
break;
}
case ExtensionCommand.saveBlankUnitTest: {
await saveBlankUnitTest(this.context as IAzureConnectorsContext, vscode.Uri.file(this.workflowFilePath), message.definition);
break;
}
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { getWorkflowNode } from '../../utils/workspace';
import type { IAzureConnectorsContext } from './azureConnectorWizard';
import { openMonitoringView } from './openMonitoringView/openMonitoringView';
import { createUnitTest } from './unitTest/createUnitTest';
import { saveBlankUnitTest } from './unitTest/saveBlankUnitTest';
import type { IActionContext } from '@microsoft/vscode-azext-utils';
import type { ICallbackUrlResponse } from '@microsoft/vscode-extension-logic-apps';
import { ExtensionCommand, ProjectName } from '@microsoft/vscode-extension-logic-apps';
Expand Down Expand Up @@ -161,6 +162,10 @@ export async function openOverview(context: IAzureConnectorsContext, node: vscod
await createUnitTest(context, workflowNode as vscode.Uri, message.runId);
break;
}
case ExtensionCommand.saveBlankUnitTest: {
await saveBlankUnitTest(this.context as IAzureConnectorsContext, vscode.Uri.file(this.workflowFilePath), message.definition);
break;
}
default:
break;
}
Expand Down Expand Up @@ -194,6 +199,7 @@ async function getLocalWorkflowCallbackInfo(
method: HTTP_METHODS.POST,
});
return JSON.parse(response);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
return undefined;
}
Expand Down
47 changes: 47 additions & 0 deletions apps/vs-code-designer/src/app/utils/unitTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,53 @@ export const saveUnitTestDefinition = async (
});
};

/**
* Saves the blank unit test definition for a workflow.
* @param {string} projectPath The path of the project.
* @param {string} workflowName The name of the workflow.
* @param {string} unitTestName The name of the unit test.
* @param {any} unitTestDefinition The unit test definition.
* @returns A Promise that resolves when the unit test definition is saved.
*/
export const saveBlankUnitTestDefinition = async (
projectPath: string,
workflowName: string,
unitTestName: string,
unitTestDefinition: any
): Promise<void> => {
await callWithTelemetryAndErrorHandling(saveUnitTestEvent, async () => {
const options: vscode.ProgressOptions = {
location: vscode.ProgressLocation.Notification,
title: localize('azureFunctions.savingWorkflow', 'Saving Blank Unit Test Definition...'),
};

await vscode.window.withProgress(options, async () => {
const projectName = path.basename(projectPath);
const testsDirectory = getTestsDirectory(projectPath);
const unitTestsPath = getUnitTestsPath(testsDirectory.fsPath, projectName, workflowName, unitTestName);
const workflowTestsPath = getWorkflowTestsPath(testsDirectory.fsPath, projectName, workflowName);

if (!fs.existsSync(workflowTestsPath)) {
fs.mkdirSync(workflowTestsPath, { recursive: true });
}
try {
fs.writeFileSync(unitTestsPath, JSON.stringify(unitTestDefinition, null, 4));
await vscode.workspace.updateWorkspaceFolders(
vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0,
null,
{ uri: testsDirectory }
);
} catch (error) {
vscode.window.showErrorMessage(
`${localize('saveFailure', 'Blank Unit Test Definition not saved.')} ${error.message}`,
localize('OK', 'OK')
);
throw error;
}
});
});
};

/**
* Retrieves the name of the unit test from the given file path.
* @param {string} filePath - The path of the unit test file.
Expand Down
1 change: 1 addition & 0 deletions apps/vs-code-designer/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export const extensionCommand = {
dataMapSaveMapDefinition: 'azureLogicAppsStandard.dataMap.saveMapDefinition',
dataMapSaveMapXslt: 'azureLogicAppsStandard.dataMap.saveMapXslt',
createUnitTest: 'azureLogicAppsStandard.createUnitTest',
saveBlankUnitTest: 'azureLogicAppsStandard.saveBlankUnitTest',
editUnitTest: 'azureLogicAppsStandard.editUnitTest',
openUnitTestResults: 'azureLogicAppsStandard.openUnitTestResults',
runUnitTest: 'azureLogicAppsStandard.runUnitTest',
Expand Down
10 changes: 10 additions & 0 deletions apps/vs-code-designer/src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,11 @@
"category": "Azure Logic Apps",
"icon": "$(tasklist)"
},
{
"command": "azureLogicAppsStandard.saveBlankUnitTest",
"title": "Create blank unit test",
"category": "Azure Logic Apps"
},
{
"command": "azureLogicAppsStandard.editUnitTest",
"title": "Edit unit test",
Expand Down Expand Up @@ -709,6 +714,11 @@
"when": "false",
"group": "navigation@4"
},
{
"command": "azureLogicAppsStandard.saveBlankUnitTest",
"when": "resourceFilename==workflow.json",
"group": "navigation@4"
},
{
"command": "azureLogicAppsStandard.openUnitTestResults",
"when": "false",
Expand Down
Loading
Loading