Skip to content

Commit

Permalink
fix bug where logicAppName is not cleaned in test executor namespace,…
Browse files Browse the repository at this point in the history
… update template files example trigger mock outputs, update tests
  • Loading branch information
andrew-eldridge committed Feb 28, 2025
1 parent 83d65eb commit e559fa1
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,16 @@ async function generateUnitTestFromRun(
workflowName,
paths.logicAppName
);

// Get cleaned versions of strings
const cleanedUnitTestName = unitTestName.replace(/-/g, '_');
const cleanedWorkflowName = workflowName.replace(/-/g, '_');
const cleanedLogicAppName = paths.logicAppName.replace(/-/g, '_');

// Create the testSettings.config file for the unit test
ext.outputChannel.appendLog(localize('creatingTestSettingsConfig', 'Creating testSettings.config file for unit test...'));
await createTestSettingsConfigFile(paths.workflowTestFolderPath, workflowName, paths.logicAppName);
await createTestExecutorFile(paths.logicAppTestFolderPath, paths.logicAppName);
await createTestExecutorFile(paths.logicAppTestFolderPath, cleanedLogicAppName);

try {
ext.outputChannel.appendLog(localize('unzippingFiles', `Unzipping Mock.json into: ${paths.unitTestFolderPath}`));
Expand All @@ -230,8 +236,11 @@ async function generateUnitTestFromRun(
await createCsFile(
paths.unitTestFolderPath!,
unitTestName,
cleanedUnitTestName,
workflowName,
cleanedWorkflowName,
paths.logicAppName,
cleanedLogicAppName,
actionName,
actionOutputClassName,
actionMockClassName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,19 @@ async function generateBlankCodefulUnitTest(
)
);

// Get cleaned versions of strings
const cleanedUnitTestName = unitTestName.replace(/-/g, '_');
const cleanedWorkflowName = workflowName.replace(/-/g, '_');
const cleanedLogicAppName = logicAppName.replace(/-/g, '_');

// Ensure directories exist
ext.outputChannel.appendLog(localize('ensuringDirectories', 'Ensuring required directories exist...'));
await Promise.all([fs.ensureDir(logicAppTestFolderPath), fs.ensureDir(workflowTestFolderPath), fs.ensureDir(unitTestFolderPath)]);

// Create the testSettings.config file for the unit test
ext.outputChannel.appendLog(localize('creatingTestSettingsConfig', 'Creating testSettings.config file for unit test...'));
await createTestSettingsConfigFile(workflowTestFolderPath, workflowName, logicAppName);
await createTestExecutorFile(logicAppTestFolderPath, logicAppName);
await createTestExecutorFile(logicAppTestFolderPath, cleanedLogicAppName);

// Get the first actionMock in foundActionMocks
const [actionName, actionOutputClassName] = Object.entries(foundActionMocks)[0] || [];
Expand All @@ -216,8 +221,11 @@ async function generateBlankCodefulUnitTest(
await createCsFile(
unitTestFolderPath,
unitTestName,
cleanedUnitTestName,
workflowName,
cleanedWorkflowName,
logicAppName,
cleanedLogicAppName,
actionName,
actionOutputClassName,
actionMockClassName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -878,11 +878,18 @@ namespace <%= LogicAppName %>.Tests

const readFileSpy = vi.spyOn(fse, 'readFile').mockResolvedValue(testBlankClassFileTemplate);

const cleanedUnitTestName = unitTestName.replace(/-/g, '_');
const cleanedWorkflowName = workflowName.replace(/-/g, '_');
const cleanedLogicAppName = logicAppName.replace(/-/g, '_');

await createCsFile(
unitTestFolderPath,
unitTestName,
cleanedUnitTestName,
workflowName,
cleanedWorkflowName,
logicAppName,
cleanedLogicAppName,
actionName,
actionOutputClassName,
actionMockClassName,
Expand Down Expand Up @@ -1063,11 +1070,18 @@ namespace <%= LogicAppName %>.Tests

const readFileSpy = vi.spyOn(fse, 'readFile').mockResolvedValue(testClassFileTemplate);

const cleanedUnitTestName = unitTestName.replace(/-/g, '_');
const cleanedWorkflowName = workflowName.replace(/-/g, '_');
const cleanedLogicAppName = logicAppName.replace(/-/g, '_');

await createCsFile(
unitTestFolderPath,
unitTestName,
cleanedUnitTestName,
workflowName,
cleanedWorkflowName,
logicAppName,
cleanedLogicAppName,
actionName,
actionOutputClassName,
actionMockClassName,
Expand Down Expand Up @@ -1162,11 +1176,18 @@ namespace <%= LogicAppName %>.Tests

const readFileSpy = vi.spyOn(fse, 'readFile').mockResolvedValue(testBlankClassFileWithoutActionsTemplate);

const cleanedUnitTestName = unitTestName.replace(/-/g, '_');
const cleanedWorkflowName = workflowName.replace(/-/g, '_');
const cleanedLogicAppName = logicAppName.replace(/-/g, '_');

await createCsFile(
unitTestFolderPath,
unitTestName,
cleanedUnitTestName,
workflowName,
cleanedWorkflowName,
logicAppName,
cleanedLogicAppName,
actionName,
actionOutputClassName,
actionMockClassName,
Expand Down Expand Up @@ -1292,11 +1313,18 @@ namespace <%= LogicAppName %>.Tests

const readFileSpy = vi.spyOn(fse, 'readFile').mockResolvedValue(testClassFileWithoutActionsTemplate);

const cleanedUnitTestName = unitTestName.replace(/-/g, '_');
const cleanedWorkflowName = workflowName.replace(/-/g, '_');
const cleanedLogicAppName = logicAppName.replace(/-/g, '_');

await createCsFile(
unitTestFolderPath,
unitTestName,
cleanedUnitTestName,
workflowName,
cleanedWorkflowName,
logicAppName,
cleanedLogicAppName,
actionName,
actionOutputClassName,
actionMockClassName,
Expand Down Expand Up @@ -1396,7 +1424,7 @@ namespace <%= LogicAppName %>.Tests
}
}`;
const logicAppName: string = 'MyLogicApp';
const logicAppName: string = 'My-LogicApp';
const unitTestFolderPath: string = 'unitTestFolderPath';
let readFileSpy: any;
let writeFileSpy: any;
Expand All @@ -1415,21 +1443,24 @@ namespace <%= LogicAppName %>.Tests

it('should create a test executor file when does not exist', async () => {
const pathExistsSpy = vi.spyOn(fse, 'pathExists').mockResolvedValue(false);
const cleanedLogicAppName = logicAppName.replace(/-/g, '_');

await createTestExecutorFile(unitTestFolderPath, logicAppName);
await createTestExecutorFile(unitTestFolderPath, cleanedLogicAppName);

expect(pathExistsSpy).toHaveBeenCalledTimes(1);
expect(readFileSpy).toHaveBeenCalledTimes(1);
expect(writeFileSpy).toHaveBeenCalledTimes(1);
const writeFileSpyCalledWith = writeFileSpy.mock.calls[writeFileSpy.mock.calls.length - 1];
expect(writeFileSpyCalledWith[0]).toEqual(path.join('unitTestFolderPath', 'TestExecutor.cs'));
expect(writeFileSpyCalledWith[1]).toEqual(expect.stringContaining(`namespace ${logicAppName}.Tests`));
expect(writeFileSpyCalledWith[1]).not.toEqual(expect.stringContaining(`namespace ${logicAppName}.Tests`));
expect(writeFileSpyCalledWith[1]).toEqual(expect.stringContaining(`namespace ${cleanedLogicAppName}.Tests`));
});

it('should not create a test executor file when it already exists', async () => {
const pathExistsSpy = vi.spyOn(fse, 'pathExists').mockResolvedValue(true);
const cleanedLogicAppName = logicAppName.replace(/-/g, '_');

await createTestExecutorFile(unitTestFolderPath, logicAppName);
await createTestExecutorFile(unitTestFolderPath, cleanedLogicAppName);

expect(pathExistsSpy).toHaveBeenCalledTimes(1);
expect(readFileSpy).not.toHaveBeenCalled();
Expand Down
30 changes: 15 additions & 15 deletions apps/vs-code-designer/src/app/utils/unitTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,11 +378,13 @@ export async function updateCsprojFile(csprojFilePath: string, workflowName: str

/**
* Creates a .cs file in the specified unit test folder using a template.
* Converts any "-" characters in LogicAppName, WorkflowName, and UnitTestName to "_" only in code-related contexts.
* @param {string} unitTestFolderPath - The path to the unit test folder.
* @param {string} unitTestName - The name of the unit test.
* @param {string} cleanedUnitTestName - The cleaned name of the unit test.
* @param {string} workflowName - The name of the workflow.
* @param {string} cleanedWorkflowName - The cleaned name of the workflow.
* @param {string} logicAppName - The name of the logic app.
* @param {string} cleanedLogicAppName - The cleaned name of the logic app.
* @param {string} actionName - The name of the action.
* @param {string} actionOutputClassName - The name of the action output class.
* @param {string} actionMockClassName - The name of the action mock class.
Expand All @@ -392,8 +394,11 @@ export async function updateCsprojFile(csprojFilePath: string, workflowName: str
export async function createCsFile(
unitTestFolderPath: string,
unitTestName: string,
cleanedUnitTestName: string,
workflowName: string,
cleanedWorkflowName: string,
logicAppName: string,
cleanedLogicAppName: string,
actionName: string,
actionOutputClassName: string,
actionMockClassName: string,
Expand Down Expand Up @@ -422,24 +427,20 @@ export async function createCsFile(

let templateContent = await fse.readFile(templatePath, 'utf-8');

const sanitizedUnitTestName = unitTestName.replace(/-/g, '_');
const sanitizedWorkflowName = workflowName.replace(/-/g, '_');
const sanitizedLogicAppName = logicAppName.replace(/-/g, '_');

templateContent = templateContent.replace(/namespace <%= LogicAppName %>\.Tests/g, `namespace ${sanitizedLogicAppName}.Tests`);
templateContent = templateContent.replace(/public class <%= UnitTestName %>/g, `public class ${sanitizedUnitTestName}`);
templateContent = templateContent.replace(/<see cref="<%= UnitTestName %>" \/>/g, `<see cref="${sanitizedUnitTestName}" />`);
templateContent = templateContent.replace(/public <%= UnitTestName %>\(\)/g, `public ${sanitizedUnitTestName}()`);
templateContent = templateContent.replace(/namespace <%= LogicAppName %>\.Tests/g, `namespace ${cleanedLogicAppName}.Tests`);
templateContent = templateContent.replace(/public class <%= UnitTestName %>/g, `public class ${cleanedUnitTestName}`);
templateContent = templateContent.replace(/<see cref="<%= UnitTestName %>" \/>/g, `<see cref="${cleanedUnitTestName}" />`);
templateContent = templateContent.replace(/public <%= UnitTestName %>\(\)/g, `public ${cleanedUnitTestName}()`);
templateContent = templateContent.replace(
/public async Task <%= WorkflowName %>_<%= UnitTestName %>_ExecuteWorkflow/g,
`public async Task ${sanitizedWorkflowName}_${sanitizedUnitTestName}_ExecuteWorkflow`
`public async Task ${cleanedWorkflowName}_${cleanedUnitTestName}_ExecuteWorkflow`
);

templateContent = templateContent
.replace(/<%= LogicAppName %>/g, logicAppName)
.replace(/<%= WorkflowName %>/g, workflowName)
.replace(/<%= UnitTestName %>/g, unitTestName)
.replace(/<%= SanitizedWorkflowName %>/g, sanitizedWorkflowName)
.replace(/<%= SanitizedWorkflowName %>/g, cleanedWorkflowName)
.replace(/<%= ActionMockName %>/g, actionName)
.replace(/<%= ActionMockOutputClassName %>/g, actionOutputClassName)
.replace(/<%= ActionMockClassName %>/g, actionMockClassName)
Expand All @@ -458,9 +459,9 @@ export async function createCsFile(
* Creates a testSettings.config file in the specified unit test folder using a template.
* Converts any "-" characters in LogicAppName, WorkflowName, and UnitTestName to "_" only in code-related contexts.
* @param {string} logicAppTestFolderPath - The path to the logicapp folder within Tests.
* @param {string} logicAppName - The name of the logic app.
* @param {string} cleanedLogicAppName - The cleaned name of the logic app.
*/
export async function createTestExecutorFile(logicAppTestFolderPath: string, logicAppName: string): Promise<void> {
export async function createTestExecutorFile(logicAppTestFolderPath: string, cleanedLogicAppName: string): Promise<void> {
const templateFolderName = 'UnitTestTemplates';
const executorTemplateFileName = 'TestExecutorFile';
const templatePath = path.join(__dirname, 'assets', templateFolderName, executorTemplateFileName);
Expand All @@ -473,15 +474,14 @@ export async function createTestExecutorFile(logicAppTestFolderPath: string, log
}

let templateContent = await fse.readFile(templatePath, 'utf-8');
templateContent = templateContent.replace(/<%= LogicAppName %>/g, logicAppName);
templateContent = templateContent.replace(/<%= LogicAppName %>/g, cleanedLogicAppName);

await fse.writeFile(csFilePath, templateContent);
ext.outputChannel.appendLog(localize('createdTestExecutorFile', 'Created TestExecutor.cs file at: {0}', csFilePath));
}

/**
* Creates a testSettings.config file in the specified unit test folder using a template.
* Converts any "-" characters in LogicAppName, WorkflowName, and UnitTestName to "_" only in code-related contexts.
* @param {string} unitTestFolderPath - The path to the unit test folder.
* @param {string} workflowName - The name of the workflow.
* @param {string} logicAppName - The name of the logic app.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace <%= LogicAppName %>.Tests
// Generate mock trigger data.
var triggerMockOutput = new <%= TriggerMockOutputClassName %>();
// Sample of how to set the properties of the triggerMockOutput
// triggerMockOutput.Body.Flag = true;
// triggerMockOutput.Body.Id = "SampleId";
var triggerMock = new <%= TriggerMockClassName %>(outputs: triggerMockOutput);

// Generate mock action data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace <%= LogicAppName %>.Tests
// Generate mock trigger data.
var triggerMockOutput = new <%= TriggerMockOutputClassName %>();
// Sample of how to set the properties of the triggerMockOutput
// triggerMockOutput.Body.Flag = true;
// triggerMockOutput.Body.Id = "SampleId";
var triggerMock = new <%= TriggerMockClassName %>(outputs: triggerMockOutput);

// ACT
Expand Down

0 comments on commit e559fa1

Please sign in to comment.